/* Shell chrome only: tab bar, status cluster, boot/login/error states.
   Grid, filter and popup styling live in grid.css / filters.css / popup.css. */

.app-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

/* --- tab bar + status cluster --- */

.tab-bar {
    display: flex;
    align-items: center;
    gap: 4px;
    min-height: var(--tab-bar-height);
    padding: 0 12px;
    background: var(--surface);
    /* The thick seam between tab bar and filter bar below it — the two are one
       merged sticky header, so this replaces what used to be a plain --border
       hairline. */
    border-bottom: 2px solid #fff;
    position: sticky;
    top: 0;
    z-index: 10;
}

.tab-bar-brand {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 700;
    letter-spacing: 0.08em;
    margin-right: 16px;
    color: var(--text);
}

/* MultiFillIcon's paths use fill="currentColor" (an SVG attribute, resolved
   via the CSS `color` property, not `fill`) — inherits .tab-bar-brand's
   color above, same token .tab-bar-user renders in. */
.tab-bar-brand-icon {
    height: 24px;
    width: 24px;
}

.tab-bar-brand-button {
    display: inline-flex;
    padding: 0;
    border: none;
    background: transparent;
    color: inherit;
}

/* Fixed full-window as well as fullscreen, so a refused fullscreen request
   still covers the page. */
.dream-stage {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    background: #000;
}

.dream-stage[hidden] {
    display: none;
}

.dream-video {
    width: 100%;
    height: 100%;
    object-fit: contain;
    opacity: 0;
    transition: opacity 800ms ease-in;
}

.dream-video.is-playing {
    opacity: 1;
}

.tab-bar-user {
    font-weight: 700;
    margin-right: 16px;
    color: var(--text);
}

.tab-bar-link {
    display: block;
    padding: 10px 16px;
    color: var(--text-dim);
    border-bottom: 2px solid transparent;
}

.tab-bar-link:hover {
    color: var(--text);
    text-decoration: none;
}

.tab-bar-link.is-active {
    color: var(--text);
    font-weight: 700;
    border-bottom-color: var(--accent);
}

/* Fills the tab bar's remaining space between the nav links and the status
   cluster, centering within that space rather than the whole bar. */
.marathon-banner {
    flex: 1;
    color: #c0fe04;
    font-weight: 700;
    text-align: center;
}

.status-cluster {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-left: auto;
    font-size: 12px;
    color: var(--text-dim);
}

.status-cluster button {
    padding: 3px 8px;
    font-size: 12px;
}

.status-cluster button.is-success {
    color: var(--status-success);
}

.status-cluster button.is-error {
    color: var(--status-error);
}

.status-cluster button.is-offline {
    color: var(--status-error);
}

.status-cluster button.is-synced {
    color: var(--status-success);
}

.status-cluster button.is-pending {
    color: var(--damage-solar);
}

.status-cluster button.is-disabled {
    color: var(--damage-solar);
}

.leader-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px;
    border: 1px solid var(--border);
    border-radius: 10px;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.leader-badge::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--text-dim);
}

.leader-badge.is-leader::before {
    background: var(--damage-strand);
}

.leader-badge.is-follower::before {
    background: var(--rarity-rare);
}

/* --- main region --- */

.app-main {
    flex: 1;
    padding: 16px;
}

/* --- boot / login / centred states --- */

.centred-panel {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    min-height: 100vh;
    padding: 24px;
    text-align: center;
}

.centred-panel .panel-body {
    max-width: 460px;
    color: var(--text-dim);
}

/* Covers the whole shell while AppShell waits for the default tab's data and
   icons (AppShell.js bootReady) — the six pages are already mounted and
   loading underneath, just not shown yet. */
.boot-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: var(--surface);
}

/* Boot screen's class-icon cross-fade (components/BootIcons.js) — stacked and
   absolutely positioned so only opacity ever changes, never layout. */
.boot-icon-stack {
    position: relative;
    width: 200px;
    height: 200px;
}

.boot-icon {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 1000ms ease-in-out;
}

.boot-icon.is-active {
    opacity: 1;
}

.boot-icon-svg {
    width: 100%;
    height: 100%;
    fill: var(--text);
}

/* classWarlock's glyph only fills ~half the 32x32 viewBox vertically (unlike
   Titan/Hunter, which span it fully), so it renders visibly smaller at the
   same box size — scaled up so its rendered height matches (~150px of the
   200px box). */
.boot-icon[data-class="classWarlock"] .boot-icon-svg {
    transform: scale(1.5);
    transform-origin: center;
}

@keyframes blink-fade {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.15; }
}

/* BootPanel's message text while loading (AppShell's "Transmit In Progress"
   overlay) — not applied to the plain boot/error states, which don't pulse. */
.blink-text {
    animation: blink-fade 1.25s ease-in-out infinite;
}

/* Login screen's traveller glyph, orbited by a ship ring (outer) and a
   sparrow ring (inner). Ported from debug.html's prototype.
   Ships orbit at a radius that overshoots the frame's own edges by 98px
   (top/bottom included, as they sweep through those points) — without this,
   the h1/paragraph text above and below would clip through the orbiting
   ships. */
.traveller-frame {
    position: relative;
    width: 200px;
    height: 200px;
    margin: 98px 0;
}

/* Orbit wrapper spins around the frame's centre (matches the glyph's centre
   since it's the same size/position as .traveller-frame); the ship/sparrow
   sits fixed at the wrapper's edge, so it sweeps around the traveller and
   spins in place as the wrapper rotates. */
.traveller-frame .ship-orbit {
    position: absolute;
    inset: 0;
    animation: orbit-ccw 8s linear infinite;
}

.traveller-frame .ship-orbit-right {
    animation-name: orbit-cw;
}

.traveller-frame .ship-pos {
    position: absolute;
    top: 50%;
    width: 48px;
    height: 48px;
    transform: translateY(-50%);
}

.traveller-frame .ship-pos-left {
    right: calc(100% + 50px);
}

.traveller-frame .ship-pos-right {
    left: calc(100% + 50px);
}

.traveller-frame .ship {
    width: 100%;
    height: 100%;
    object-fit: contain;
    transform: scaleY(-1);
}

/* Sparrow inner ring — same mechanism as the ship outer ring, just a
   smaller offset so its radius is shorter and it circles closer to the
   traveller while still clearing the frame edge. */
.traveller-frame .sparrow-orbit {
    position: absolute;
    inset: 0;
    animation: orbit-cw 8s linear infinite;
}

.traveller-frame .sparrow-orbit-right {
    animation-name: orbit-ccw;
}

.traveller-frame .sparrow-pos {
    position: absolute;
    top: 50%;
    width: 56px;
    height: 56px;
    transform: translateY(-50%);
}

.traveller-frame .sparrow-pos-left {
    right: calc(100% + 2px);
}

.traveller-frame .sparrow-pos-right {
    left: calc(100% + 2px);
}

.traveller-frame .sparrow {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

@keyframes orbit-cw {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

@keyframes orbit-ccw {
    from { transform: rotate(0deg); }
    to { transform: rotate(-360deg); }
}

.traveller-glyph {
    width: 200px;
    height: 200px;
    fill: var(--text);
}

/* --- banners --- */

.banner {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 10px 12px;
    margin-bottom: 12px;
    background: var(--surface-raised);
    border: 1px solid var(--border);
    border-left: 3px solid var(--damage-solar);
    border-radius: 3px;
}

.banner-message {
    flex: 1;
    word-break: break-word;
}

/* --- bundle import progress --- */

.bundle-progress {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    margin-bottom: 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 3px;
    font-size: 13px;
}

.bundle-progress-track {
    flex: 1;
    height: 6px;
    background: var(--surface-raised);
    border-radius: 3px;
    overflow: hidden;
}

.bundle-progress-fill {
    height: 100%;
    background: var(--accent);
    transition: width 120ms linear;
}

.bundle-progress-track.is-indeterminate .bundle-progress-fill {
    width: 30%;
    animation: bundle-progress-slide 1.1s ease-in-out infinite;
}

@keyframes bundle-progress-slide {
    0% {
        margin-left: -30%;
    }

    100% {
        margin-left: 100%;
    }
}
