// ─── Seat tray ──────────────────────────────────────────────────────────────
//
// Structure:
//   #id_tray_wrap            — fixed right edge, flex row, slides on :has(.open)
//     #id_tray_handle        — $handle-exposed wide; contains grip + button
//       #id_tray_grip        — position:absolute; ::before/::after = concentric rects
//       #id_tray_btn         — circle button (z-index:1, paints above grip)
//     #id_tray               — 280px panel; covers grip's rightward extension when open
//
// Closed: wrap translateX($tray-w) → only button circle visible at right edge.
// Open:   translateX(0) → full tray panel slides in; grip rects visible as handle.
//
// Grid layout (portrait):
//   8 explicit rows; columns auto-added as items arrive (grid-auto-flow: column).
//   --tray-cell-size set by JS from tray.clientHeight / 8 → always square cells.
//
// Grid layout (landscape):
//   8 explicit columns; rows auto-added as items arrive (grid-auto-flow: row).
//   --tray-cell-size set by JS from tray.clientWidth / 8 → always square cells.

$tray-w:         280px;
$handle-rect-w:  10000px;
$handle-rect-h:  4.5rem;  // visible rail thickness — scales w. rem; ≈ btn (3rem) + breathing room
$handle-exposed:   3rem;  // matches #id_tray_btn so the btn fills the exposed handle area
                          // (previously 48px → flex-shrink squished the btn on rem > 16px viewports)
$handle-r:         1rem;
$tray-bevel:    0.3rem;  // inner bevel ring; grid must sit inside this

#id_tray_wrap.role-select-phase {
    #id_tray_handle { visibility: hidden; pointer-events: none; }
}

#id_tray_wrap {
    position: fixed;
    // left set by JS: closed = vw - handleW; open = vw - wrapW
    // top/bottom set by JS from nav/footer measurements
    // right intentionally absent — wrap has fixed CSS width (handle + tray)
    // so the open edge only reaches the viewport boundary when fully open.
    top: 0;
    bottom: 0;
    z-index: 310;
    pointer-events: none;
    display: flex;
    flex-direction: row;
    align-items: stretch;
    transition: left 0.35s cubic-bezier(0.4, 0, 0.2, 1);

    &.tray-dragging { transition: none; }
    &.wobble        { animation: tray-wobble      .45s ease; }
    &.snap          { animation: tray-snap        0.30s ease; }
}

#id_tray_handle {
    flex-shrink: 0;
    position: relative;
    width: $handle-exposed;
    display: flex;
    align-items: center;
    justify-content: center;
}

#id_tray_grip {
    position: absolute;
    top: 50%;
    left: calc(#{$handle-exposed} / 2 - 0.125rem);
    transform: translateY(-50%);
    width: $handle-rect-w;
    height: $handle-rect-h;
    pointer-events: none;
    // Border + overflow:hidden on the grip itself clips ::before's shadow with correct radius
    border-radius: $handle-r;
    border: 0.15rem solid rgba(var(--secUser), 1);
    overflow: hidden;

    // Inset inner window: box-shadow spills outward to fill the opaque frame area,
    // clipped to grip's rounded edge by overflow:hidden. background:transparent = see-through hole.
    &::before {
        content: '';
        position: absolute;
        inset: 0.4rem;
        border-radius: calc(#{$handle-r} - 0.35rem);
        border: 0.15rem solid rgba(var(--secUser), 1);
        background: transparent;
        box-shadow: 0 0 0 200px rgba(var(--priUser), 1);
    }

    &::after {
        content: none;
    }
}

#id_tray_btn {
    pointer-events: auto;
    position: relative;
    z-index: 1;  // above #id_tray_grip
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    background-color: rgba(var(--priUser), 1);
    border: 0.15rem solid rgba(var(--secUser), 1);
    cursor: grab;
    display: inline-flex;
    align-items: center;
    justify-content: center;

    i {
        font-size: 1.75rem;
        color: rgba(var(--secUser), 1);
        pointer-events: none;
    }

    &:active { cursor: grabbing; }
    &.open {
        cursor: pointer;
        border-color: rgba(var(--quaUser), 1);
        i { color: rgba(var(--quaUser), 1); }
    }
}

// Grip borders → --quaUser when tray is open (btn.open precedes grip in DOM so :has() needed)
#id_tray_wrap:has(#id_tray_btn.open) #id_tray_grip {
    border-color: rgba(var(--quaUser), 1);
    &::before { border-color: rgba(var(--quaUser), 1); }
}

// ─── Role card: scrawl fade-in ───────────────────────────────────────────────
@keyframes tray-role-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.tray-role-card {
    padding:  0.5rem;  // breathing room around role art (post-bleed-trim)
    overflow: hidden;
    background: transparent;
    // Dotted borders on .tray-cell would otherwise shrink the content box
    // and push a `width/height: 100%` img off-centre. Flex centring +
    // sizing the img to the full grid track keeps it visually centred
    // while preserving the dotted grid markings.
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    &:focus { outline: none; }

    img {
        display: block;
        width:  100%;
        height: 100%;
        object-fit: cover;
        object-position: center;
        transition: rotate 0.25s ease;
    }

    // Hover/touch tilts the scrawl 7° counter-clockwise; :focus persists the
    // tilt after a click (cell receives tabindex="0" from tray.js); .tt-active
    // (set by TrayTooltip while the portal is open for this cell) keeps the
    // tilt while the user is hovering the portal itself rather than the cell.
    &:hover > img,
    &:focus > img,
    &.tt-active > img {
        rotate: -7deg;
    }

    // Cell stays static; only the scrawl image fades in.
    &.fade-in img {
        animation: tray-role-fade-in 1s ease forwards;
    }
}

// Hosts the same compact rank-+-icon Sig card used in the Sea Select center
// (.sig-stage-card.sea-sig-card). Width is sized so the 5:8-aspect card
// height ≈ tray cell height.
.tray-sig-card {
    padding: 0;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    &:focus { outline: none; }

    .sig-stage-card.sea-sig-card {
        --sig-card-w: calc(var(--tray-cell-size, 48px) * 5 / 8);
        // `rotate` is independent of `transform`, so the existing -5° baseline
        // (set on .sig-stage-card.sea-sig-card via transform) is preserved and
        // this rotates 7° clockwise on top of it.
        transition: rotate 0.25s ease;
    }
    &:hover > .sig-stage-card,
    &:focus > .sig-stage-card,
    &.tt-active > .sig-stage-card {
        rotate: 7deg;
    }

    // Fade-in mirrors .tray-role-card.fade-in img — the .sig-stage-card child
    // fades from opacity 0 to 1 once placeSig() lands.
    &.fade-in > .sig-stage-card {
        animation: tray-role-fade-in 1s ease forwards;
    }
}

@keyframes tray-wobble {
    0%, 100% { transform: translateX(0); }
    20%      { transform: translateX(-8px); }
    40%      { transform: translateX(6px); }
    60%      { transform: translateX(-5px); }
    80%      { transform: translateX(3px); }
}

// Inverted wobble — handle overshoots past the wall on close, then bounces back.
@keyframes tray-snap {
    0%, 100% { transform: translateX(0); }
    20%      { transform: translateX(8px); }
    40%      { transform: translateX(-6px); }
    60%      { transform: translateX(5px); }
    80%      { transform: translateX(-3px); }
}

#id_tray {
    --tray-bevel: #{$tray-bevel};  // exposed to JS via getComputedStyle for cell-size math
    flex: 1;
    min-width: 0;
    margin-left: 0.5rem;  // small gap so tray appears slightly off-screen on drag start
    pointer-events: auto;
    position: relative;
    z-index: 1;  // above #id_tray_grip pseudo-elements
    background: rgba(var(--duoUser), 1);
    border-left:2.5rem solid rgba(var(--quaUser), 1);
    border-top: 2.5rem solid rgba(var(--quaUser), 1);
    border-bottom: 2.5rem solid rgba(var(--quaUser), 1);
    padding: $tray-bevel;  // inset grid inside the bevel ring on every felt-facing side
    box-shadow:
        -0.25rem 0 0.5rem rgba(0, 0, 0, 0.55),
        inset 0 0 0 $tray-bevel rgba(var(--quiUser), 0.45),      // prominent bevel ring at wall edge
        inset 0.6rem 0 1.5rem -0.5rem rgba(0, 0, 0, 1),          // left wall depth
        inset 0.6rem 0 1.5rem -0.5rem rgba(var(--quiUser), 0.5),  // left wall depth (hue)
        inset 0 0.6rem 1.5rem -0.5rem rgba(0, 0, 0, 1),          // top wall depth
        inset 0 0.6rem 1.5rem -0.5rem rgba(var(--quiUser), 0.5),   // top wall depth (hue)
        inset 0 -0.6rem 1.5rem -0.5rem rgba(0, 0, 0, 1),         // bottom wall depth
        inset 0 -0.6rem 1.5rem -0.5rem rgba(var(--quiUser), 0.5)   // bottom wall depth (hue)
    ;
    overflow: hidden;  // clip #id_tray_grid to the felt interior
}

#id_tray_grid {
    display: grid;
    // Portrait: 8 explicit rows; columns auto-added as items arrive.
    // --tray-cell-size set by JS from tray.clientHeight / 8 → always square cells.
    grid-template-rows: repeat(8, var(--tray-cell-size, 48px));
    grid-auto-flow: column;
    grid-auto-columns: var(--tray-cell-size, 48px);
}

.tray-cell {
    border-color: rgba(var(--priUser), 0.35);
    border-right:  2px dotted rgba(var(--priUser), 0.35);
    border-bottom: 2px dotted rgba(var(--priUser), 0.35);
    position: relative;

    // Whatever a cell holds (role-card img, sig stage card, future Celtic Cross
    // / sky wheel / dice) gets a soft drop shadow to lift it off the felt.
    // Applied to the child rather than the cell itself so the dotted grid
    // borders stay shadow-free.
    > * {
        box-shadow: 1px 1px 5px rgba(0, 0, 0, 1);
    }
    // Img children (SVG/PNG with transparent regions): use filter drop-shadow
    // instead so the shadow traces the rendered silhouette, not the SVG viewport.
    > img {
        box-shadow: none;
        filter: drop-shadow(1px 1px 2px rgba(0, 0, 0, 1));
    }
}

// ─── Tray: landscape reorientation ─────────────────────────────────────────
//
// Must come AFTER the portrait tray rules above to win the cascade
// (same specificity — later declaration wins).
//
// In landscape the tray slides DOWN from the top instead of in from the right.
// Structure (column-reverse): tray panel above, handle below.
// JS controls style.top for the Y-axis slide:
//   Closed: top = -(trayH)           → only handle visible at y = 0
//   Open:   top = gearBtnTop - wrapH → handle bottom at gear btn top
//
// The wrap fits horizontally between the fixed left-nav and right-footer sidebars.

@media (orientation: landscape) {
    $sidebar-w: 4rem;
    $tray-landscape-max-w: 960px;  // cap tray width on very wide screens

    #id_tray_wrap {
        flex-direction: column-reverse; // tray panel above, handle below
        left:   $sidebar-w;
        right:  $sidebar-w;
        top:    auto;    // JS controls style.top for the Y-axis slide
        bottom: auto;
        transition: top 0.35s cubic-bezier(0.4, 0, 0.2, 1);

        &.tray-dragging { transition: none; }
        &.wobble        { animation: tray-wobble-landscape 0.45s ease; }
        &.snap          { animation: tray-snap-landscape   0.30s ease; }

    }

    #id_tray_handle {
        width:  auto;             // full width of wrap
        height: $handle-exposed;  // same exposed dimension as portrait — scales w. rem
    }

    #id_tray_grip {
        // Rotate 90°: centred horizontally, extends vertically.
        // bottom mirrors portrait's left: grip starts at handle centre and extends
        // toward the tray (upward in column-reverse layout).
        bottom: calc(#{$handle-exposed} / 2 - 0.125rem); // $handle-exposed / 2 from handle bottom
        top:    auto;
        left: 50%;
        transform: translateX(-50%);
        width:  $handle-rect-h;   // narrow visible dimension — scales w. rem
        height: $handle-rect-w;   // extends upward into tray area
    }

    #id_tray {
        // Borders: left/right/bottom are visible walls; top edge is open.
        // Bottom faces the handle (same logic as portrait's left border facing handle).
        border-left:   2.5rem solid rgba(var(--quaUser), 1);
        border-right:  2.5rem solid rgba(var(--quaUser), 1);
        border-bottom: 2.5rem solid rgba(var(--quaUser), 1);
        border-top:    none;

        margin-left:   0;           // portrait horizontal gap no longer needed
        margin-bottom: 0.5rem;      // gap between tray bottom and handle top

        // Cap width on ultra-wide screens; center within the handle shelf.
        width: 100%;
        max-width: $tray-landscape-max-w;
        align-self: center;

        box-shadow:
            0 0.25rem 0.5rem rgba(0, 0, 0, 0.55),
            inset 0 0 0 $tray-bevel rgba(var(--quiUser), 0.45),         // prominent bevel ring
            inset 0 -0.6rem 1.5rem -0.5rem rgba(0, 0, 0, 1),           // bottom wall depth
            inset 0 -0.6rem 1.5rem -0.5rem rgba(var(--quaUser), 0.5),  // bottom wall depth (hue)
            inset 0.6rem 0 1.5rem -0.5rem rgba(0, 0, 0, 1),            // left wall depth
            inset 0.6rem 0 1.5rem -0.5rem rgba(var(--quaUser), 0.5),   // left wall depth (hue)
            inset -0.6rem 0 1.5rem -0.5rem rgba(0, 0, 0, 1),           // right wall depth
            inset -0.6rem 0 1.5rem -0.5rem rgba(var(--quaUser), 0.5)   // right wall depth (hue)
        ;
        flex: 1;            // fill wrap height (JS sets wrap height = gearBtnTop)
        height: auto;
        min-height: unset;
        overflow: hidden;   // clip #id_tray_grid to the felt interior
    }

    #id_tray_grid {
        // Landscape: 8 explicit columns; rows auto-added as items arrive.
        // --tray-cell-size set by JS from tray.clientWidth / 8 → always square cells.
        grid-template-columns: repeat(8, var(--tray-cell-size, 48px));
        grid-template-rows: none;  // clear portrait's 8-row template
        grid-auto-flow: row;
        grid-auto-rows: var(--tray-cell-size, 48px);
        // Anchor grid to the handle-side (bottom) of the tray so the first row
        // is visible when partially open; additional rows grow upward.
        // Inset by --tray-bevel so the grid sits inside the bevel ring rather
        // than under it (matches the portrait padding inset of the same width).
        position: absolute;
        bottom: var(--tray-bevel, 0.3rem);
        left:   var(--tray-bevel, 0.3rem);
    }

    // In landscape the first row sits at the bottom; border-top divides it from
    // the felt above. border-bottom would face the wall — swap it out.
    .tray-cell {
        border-color: rgba(var(--priUser), 0.35);
        border-top:    2px dotted rgba(var(--priUser), 0.35);
        border-bottom: none;
    }

    // Role card: same fade-in in landscape — no override needed.

    @keyframes tray-wobble-landscape {
        0%, 100% { transform: translateY(0); }
        20%      { transform: translateY(-8px); }
        40%      { transform: translateY(6px); }
        60%      { transform: translateY(-5px); }
        80%      { transform: translateY(3px); }
    }

    // Inverted wobble — wrap overshoots upward on close, then bounces back.
    @keyframes tray-snap-landscape {
        0%, 100% { transform: translateY(0); }
        20%      { transform: translateY(8px); }
        40%      { transform: translateY(-6px); }
        60%      { transform: translateY(5px); }
        80%      { transform: translateY(-3px); }
    }
}

// ≥1800px uses the same landscape tray rules as narrower landscape — no override block needed.
