/* ── Padelytics app-frame ── desktop left rail + dashboard grid.
   Mobile (<1024px): legacy single column + floating bottom nav (unchanged).
   Desktop (>=1024px): persistent left rail + multi-column dashboard. */

/* ── Canvas glow ── lives behind everything, on the body ── */
body{background:var(--page-glow), var(--bg);background-attachment:fixed;}

/* ── App-shell body reset ── the rankings shell loads player.css for the
   detail pane, and player.css sets `body{max-width:900px;margin:0 auto}` for
   the standalone player page. That must NOT cap the app-shell — the rail +
   panes are full-bleed. `.has-rail` is on every app-shell body, never on the
   standalone player page, so this scopes the reset cleanly. */
body.has-rail{max-width:none;margin:0;padding:0;}
@media (max-width:1023px){
    /* background-attachment:fixed is broken for gradient backgrounds on iOS Safari —
       reset to scroll on mobile so the glow paints reliably. */
    body{background:var(--page-glow-mobile), var(--bg);background-attachment:scroll;}
}

/* ── App shell ── */
.app-shell{display:block;}

/* ── Desktop rail ── hidden on mobile ── */
.app-rail{display:none;}

/* ── Mobile content wrapper ── keeps the legacy column on phones ── */
.app-main{
    max-width:520px;margin:0 auto;padding:16px 16px 96px;
}

/* ── Dashboard grid ── primary + context columns; single column on mobile ── */
.dashboard{display:flex;flex-direction:column;gap:var(--space-3);}
.dash-primary{min-width:0;}
.dash-context{display:flex;flex-direction:column;gap:var(--space-3);}

/* ════════ DESKTOP ════════ */
@media (min-width:1024px){
    .app-shell{
        display:grid;
        grid-template-columns:var(--rail-w) 1fr;
        min-height:100vh;
        /* full-bleed — the rail pins to the viewport's left edge, no centered
           island. The content (.app-main) is what gets capped, below. */
    }

    .app-rail{
        display:flex;flex-direction:column;gap:2px;
        padding:28px 14px 24px;
        background:var(--bg-raised);
        box-shadow:inset -1px 0 0 0 var(--card-border);
        position:sticky;top:0;height:100vh;overflow-y:auto;
    }
    .rail-logo{
        display:flex;align-items:center;gap:12px;
        padding:0 8px 28px;text-decoration:none;
    }
    /* heartbeat brand mark — sized for the rail; .brand-mark provides the
       glow + animation, this just sets the box. */
    .rail-mark{width:32px;height:32px;flex-shrink:0;}
    .rail-wordmark{
        font-family:var(--font-display);font-size:16px;font-weight:700;
        color:var(--text);letter-spacing:-0.01em;
        display:inline-flex;align-items:flex-end;
    }
    .rail-wordmark .brand-dot{margin:0 0 3px 3px;}
    .rail-item{
        display:flex;align-items:center;gap:12px;
        padding:10px 12px;border-radius:10px;
        font-family:var(--font-body);font-size:14px;font-weight:500;
        color:var(--text-muted);text-decoration:none;
        transition:color 0.16s ease,background 0.16s ease;
    }
    .rail-item svg{width:16px;height:16px;stroke:currentColor;fill:none;
        stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;}
    .rail-item:hover{color:var(--text);background:rgba(255,255,255,0.04);}
    .rail-item.active{
        color:var(--accent);background:var(--accent-dim);
    }
    .rail-item.active svg{stroke:var(--accent);}
    .rail-sub{
        display:flex;align-items:center;gap:8px;
        padding:8px 12px 8px 36px;border-radius:10px;
        font-family:var(--font-body);font-size:13px;font-weight:500;
        color:var(--text-dim);text-decoration:none;
        transition:color 0.16s ease,background 0.16s ease;
    }
    .rail-sub:hover{color:var(--text);background:rgba(255,255,255,0.04);}
    .rail-sub.active{
        color:var(--accent);background:var(--accent-dim);
    }
    .rail-foot{
        margin-top:auto;padding:18px 12px 0;
        box-shadow:inset 0 1px 0 0 var(--card-border);
        font-family:var(--font-mono),monospace;
        font-size:10px;color:var(--text-dim);
        display:flex;flex-direction:column;gap:6px;line-height:1.5;
        letter-spacing:0.04em;
    }
    .rail-foot-line{display:block;}
    .rail-foot-logo{border-radius:2px;display:inline-block;vertical-align:-1px;margin:0 1px;}
    .rail-foot a{color:var(--text-muted);text-decoration:none;}
    .rail-foot a:hover{color:var(--accent);}

    /* content column — capped for readable line lengths, centred in the
       space the rail leaves so the rail itself stays flush to the edge */
    .app-main{
        max-width:var(--content-max);margin:0 auto;padding:28px 32px 40px;
    }

    /* dashboard becomes two columns on desktop */
    .dashboard{
        flex-direction:row;align-items:flex-start;gap:var(--space-4);
    }
    .dash-primary{flex:1;}
    .dash-context{width:248px;flex-shrink:0;}

    /* the floating bottom nav is desktop-hidden (see components.css) */
}

/* ════════ MASTER-DETAIL (spec §4.4) ════════
   A master-detail tab's partial root is `.tab-panel.md-layout`, containing
   `#app-list` (the list pane) + `#app-detail` (the detail pane). The router
   sets `body.md-active` whenever such a partial is mounted; the server also
   sets it on cold load so there is no layout flash. */

/* Mobile / narrow: by default the list pane is the content. When the URL
   selects a tournament/player (body.has-md-detail), we flip to the detail
   pane — same single-pane behavior but showing the editorial view instead
   of the list. Server sets the body class on cold load; router syncs it
   on SPA navigation. */
.md-layout > #app-detail{display:none;}
.md-layout > #app-list{display:block;}
body.has-md-detail .md-layout > #app-list{display:none;}
body.has-md-detail .md-layout > #app-detail{display:block;padding:0 18px calc(96px + env(safe-area-inset-bottom));}

/* Mobile-only "back to Lab" chip rendered at the top of every lab-detail
   article. Hidden on desktop where the list pane is always visible to
   the left of the detail. Reuses the same slim mono pill language as
   the standalone .page-topbar-back. */
.lab-detail-back{display:none;}
.lab-detail-back svg{width:13px;height:13px;flex-shrink:0;transition:transform 0.18s ease;}
@media (max-width:1023px){
    body.has-md-detail .lab-detail-back{
        display:inline-flex;align-items:center;gap:8px;
        padding:8px 14px 8px 11px;margin:14px 0 8px;border-radius:999px;
        background:var(--bg-raised);
        border:1px solid var(--card-border);
        color:var(--text-muted);
        font-family:var(--font-mono),monospace;
        font-size:11px;font-weight:600;
        letter-spacing:0.12em;text-transform:uppercase;
        text-decoration:none;
        transition:color 0.15s ease, background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
    }
    body.has-md-detail .lab-detail-back:hover{
        color:var(--accent);background:var(--accent-dim);border-color:var(--accent-border);
    }
    body.has-md-detail .lab-detail-back:hover svg{transform:translateX(-2px);}
    body.has-md-detail .lab-detail-back:active{transform:scale(0.97);}
}

@media (min-width:1024px){
    /* The content area becomes two independently-scrolling panes pinned to the
       viewport height — selecting a player never scrolls the list away. The
       selectors are body+id scoped so they win over any legacy `.tab-panel`
       rule in rankings.css regardless of file order. */
    body.md-active .app-main{
        max-width:none;margin:0;padding:0;
        height:100vh;overflow:hidden;
        display:flex;flex-direction:column;
    }
    body.md-active .app-main > .nav,
    body.md-active .app-main > #dpf-search{flex-shrink:0;}
    body.md-active #app-content{flex:1;min-height:0;overflow:hidden;}

    body.md-active #app-content > .tab-panel.md-layout{
        height:100%;
        display:grid;grid-template-columns:var(--list-w) 1fr;
    }
    body.md-active #app-content > .md-layout > #app-list{
        display:block;overflow-y:auto;
        box-shadow:inset -1px 0 0 0 var(--divider);
        padding:24px 18px 40px;
    }
    body.md-active #app-content > .md-layout > #app-detail{
        display:block;overflow-y:auto;
        padding:28px 32px 48px;
        transition:opacity 0.15s ease;
    }
    body.md-active #app-content > .md-layout > #app-detail.loading{
        opacity:0.4;pointer-events:none;
    }
}
