/* xwords web client — shared styles. Light theme. Built on Bootstrap 5;
   this file tweaks a few things and adds page-specific bits. */

body {
    min-height: 100vh;
    background: #fff;
}

/* ── Navbar ─────────────────────────────────────────────────────────────── */
/* Old-client convention: deep blue navbar with white text everywhere. */
.navbar {
    background-color: #1565c0 !important;
    color: #fff;
}
.navbar .navbar-brand,
.navbar .navbar-brand img,
.navbar .nav-link,
.navbar .navbar-text {
    color: #fff !important;
}
.navbar .nav-link:hover,
.navbar .nav-link.active {
    color: #fff !important;
    text-decoration: underline;
}
/* Outline buttons that sit directly on the dark navbar bar
   (Sign out, etc.) — light text on dark bg. */
.navbar .btn-outline-secondary,
.navbar .btn-outline-primary {
    color: rgba(255,255,255,.9);
    border-color: rgba(255,255,255,.4);
    background: transparent;
}
.navbar .btn-outline-secondary:hover,
.navbar .btn-outline-primary:hover {
    color: #fff;
    border-color: rgba(255,255,255,.7);
    background-color: rgba(255,255,255,.1);
}
/* Override inside dropdown menus, which are light-background. The
   navbar rule above would otherwise paint these as white-on-white
   and they'd be invisible. Higher-specificity wins via the extra
   `.dropdown-menu` segment. */
.navbar .dropdown-menu .btn-outline-secondary,
.navbar .dropdown-menu .btn-outline-primary {
    color: #6c757d;
    border-color: #6c757d;
    background: transparent;
}
.navbar .dropdown-menu .btn-outline-secondary:hover,
.navbar .dropdown-menu .btn-outline-primary:hover {
    color: #fff;
    border-color: #6c757d;
    background-color: #6c757d;
}

.navbar-brand {
    font-weight: 700;
    letter-spacing: -.02em;
}
.navbar-brand .brand-mark {
    width: 24px; height: 24px; vertical-align: -6px; margin-right: .35rem;
    /* The favicon is a colored grid; show as-is on the dark navbar. */
    background: #fff;
    border-radius: 3px;
}

/* ── Tables / lists ─────────────────────────────────────────────────────── */
.table-admin {
    font-size: .92rem;
}
.table-admin th {
    font-weight: 600;
    color: var(--bs-secondary-color);
    border-bottom-width: 2px;
}
.table-admin td.actions {
    text-align: right;
    white-space: nowrap;
}
.table-admin td.actions .btn {
    margin-left: .25rem;
}

.cover-swatch {
    display: inline-block;
    width: 18px; height: 18px;
    border-radius: 3px;
    border: 1px solid rgba(0,0,0,.15);
    vertical-align: middle;
    margin-right: .4rem;
}

.status-pill {
    display: inline-block;
    padding: .15rem .5rem;
    border-radius: 1rem;
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .02em;
}
.status-pill.warning { background: #fef3c7; color: #92400e; }
.status-pill.success { background: #d1fae5; color: #065f46; }
.status-pill.muted   { background: #e5e7eb; color: #374151; }

.drop-zone {
    border: 2px dashed var(--bs-border-color);
    border-radius: .5rem;
    padding: 2rem 1rem;
    text-align: center;
    color: var(--bs-secondary-color);
    transition: background-color .12s, border-color .12s;
    cursor: pointer;
}
.drop-zone:hover, .drop-zone.dragover {
    border-color: var(--bs-primary);
    background-color: rgba(13, 110, 253, .06);
}
.drop-zone input[type=file] { display: none; }
.drop-zone .filename { font-weight: 600; }

.toast-container {
    position: fixed; top: 1rem; right: 1rem; z-index: 1100;
    display: flex; flex-direction: column; gap: .5rem;
}
.toast-card {
    min-width: 240px; max-width: 360px;
    padding: .65rem .9rem;
    border-radius: .35rem;
    color: #fff;
    box-shadow: 0 4px 14px rgba(0,0,0,.18);
}
.toast-card.success { background: #198754; }
.toast-card.error   { background: #b02a37; }
.toast-card.info    { background: #0d6efd; }

.login-box {
    max-width: 440px; width: 100%;
    text-align: center; padding: 2.5rem;
    margin: 4rem auto;
}
.login-box .grid-logo svg { margin-bottom: 1.5rem; }

.auth-loading {
    text-align: center; color: var(--bs-secondary-color);
    padding: 4rem 1rem;
}

/* ────────────────────────────────────────────────────────────────────── */
/* SOLVER */
/* ────────────────────────────────────────────────────────────────────── */

/* Toolbar — three slots: left | center timer | right. Matches old client. */
.solver-toolbar {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: .5rem;
    padding: .5rem 0;
    border-top: 1px solid var(--bs-border-color);
    border-bottom: 1px solid var(--bs-border-color);
    margin-bottom: .75rem;
}
.solver-toolbar .toolbar-left,
.solver-toolbar .toolbar-right {
    display: flex; gap: .35rem; align-items: center;
}
.solver-toolbar .toolbar-center {
    display: flex; justify-content: center;
}
.solver-toolbar .btn { font-size: .9rem; }

/* Timer button: outline-primary, with pause/play icon and tabular-nums time. */
.timer-btn {
    font-variant-numeric: tabular-nums;
    min-width: 5.5em;
    display: inline-flex; align-items: center; gap: .35rem;
}
.timer-btn[hidden] { display: none !important; }

/* Read-only timer for non-host cosolve participants. Looks like a label,
   not a button: no hover transition, no pointer cursor, no opacity dip
   from the [disabled] attribute. */
.timer-btn.timer-readonly {
    pointer-events: none;
    cursor: default;
    opacity: 1;             /* override Bootstrap [disabled] dim */
    background: transparent;
    border-color: transparent;
    color: var(--bs-body-color);
}

/* Banner clue (light blue, black text — matches old client). */
.solver-clue-bar {
    background: #ccf2ff;
    color: #000;
    border-radius: 6px;
    padding: .45rem .75rem;
    font-size: 1.05rem;
    line-height: 1.4;
    min-height: calc(1.4em * 2.5 + .7rem);
    display: flex; align-items: center; gap: .5rem;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    margin-bottom: .5rem;
}
.solver-clue-bar .clue-label {
    font-weight: 700; color: #000; white-space: nowrap;
}

/* Solver frame: grid | drag-divider | clues. The frame is `position: relative`
   so the pause overlay can absolute-position over the entire content. */
.solver-frame {
    display: grid;
    grid-template-columns: var(--grid-frac, 60%) 4px 1fr;
    gap: 0;
    align-items: start;
    position: relative;
}

.solver-grid-col {
    display: flex; flex-direction: column;
    min-width: 0;
    padding-right: .5rem;
}

.solver-grid {
    width: 100%;
    aspect-ratio: 1 / 1;
    background: #fff;
    border: 2px solid #000;
    user-select: none;
    cursor: default;
    display: block;
}

/* Drag divider between grid and clues. Visible only in side-by-side
   layout; hidden when stacked or when clues are hidden. */
.solver-divider {
    width: 4px;
    cursor: col-resize;
    background: #ccc;
    align-self: stretch;
    display: flex; align-items: center; justify-content: center;
    transition: background-color .12s;
    user-select: none;
    min-height: 100%;
}
.solver-divider:hover, .solver-divider.dragging {
    background: #1565c0;
}
.solver-divider-grip {
    color: #888;
    font-size: 1rem;
}

/* Clue area — two panes stacked vertically (across on top, down below). */
.solver-clues {
    display: grid;
    grid-template-rows: 1fr 1fr;
    gap: 1rem;
    max-height: 80vh;
    min-height: 400px;
    padding-left: .5rem;
}
.clue-pane {
    display: flex; flex-direction: column;
    border: 1px solid var(--bs-border-color);
    border-radius: .35rem;
    overflow: hidden;
    min-height: 0;
}
.clue-pane h6 {
    margin: 0;
    padding: .4rem .7rem;
    background: #f3f4f6;
    border-bottom: 1px solid var(--bs-border-color);
    font-size: .85rem;
    color: #1565c0;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
}
.clue-list {
    overflow-y: auto;
    padding: .25rem 0;
    flex: 1;
}
.clue-item {
    display: flex;
    padding: .25rem .7rem;
    cursor: pointer;
    font-size: .95rem;
    line-height: 1.4;
    gap: .5rem;
    align-items: flex-start;
    border-radius: 4px;
}
.clue-item:hover    { background: rgba(128,128,128,.15); }
.clue-item.active-word { background: #dbf6ff; color: #000; } /* word, not clue */
.clue-item.active-clue { background: #a2e4fa; color: #000; } /* the active clue */
.clue-item .clue-num {
    font-weight: 700; font-size: .9rem;
    min-width: 2.2rem; text-align: right; padding-right: .35rem;
    flex-shrink: 0;
}
.clue-item .clue-text { flex: 1; min-width: 0; }

/* ── Layout variants (clue list placement) ─────────────────────────── */
/*
 * stack:  clues to the right of the grid; across-pane above down-pane.
 * side:   clues to the right of the grid; across-pane next to down-pane.
 * hidden: clues entirely gone, banner remains.
 *
 * Both stack and side place clues to the right of the grid (with the
 * draggable divider). They differ only in how the across-pane and
 * down-pane are arranged relative to each other.
 */

/* "stack" is the default — already implemented by base .solver-frame and
   .solver-clues styles above (grid | divider | tall stacked panes). */

/* Side: across-pane next to down-pane, both still to the right of the grid. */
.solver-frame.layout-side .solver-clues {
    grid-template-rows: none;
    grid-template-columns: 1fr 1fr;
}

/* Hidden: clues entirely gone, banner remains. */
.solver-frame.layout-hidden {
    grid-template-columns: 1fr;
}
.solver-frame.layout-hidden .solver-divider,
.solver-frame.layout-hidden .solver-clues {
    display: none;
}

/* Narrow viewport: collapse to hidden layout regardless of setting. */
@media (max-width: 760px) {
    .solver-frame {
        grid-template-columns: 1fr !important;
    }
    .solver-divider, .solver-clues {
        display: none !important;
    }
}

/* ── Pause overlay ──────────────────────────────────────────────────── */
.pause-overlay {
    position: absolute; inset: 0;
    background: rgba(0,0,0,0.82);
    z-index: 100;
    cursor: default;     /* clickable variant overrides */
    display: flex; align-items: center; justify-content: center;
    flex-direction: column;
    border-radius: 4px;
}
.pause-overlay.clickable { cursor: pointer; }
.pause-overlay .pause-text {
    color: #fff; font-size: 2rem; font-weight: 700; letter-spacing: .05em;
}
.pause-overlay .pause-sub {
    color: #ccc; font-size: 1rem; margin-top: .5rem;
}

/* Pencil-mode active state */
.btn-pencil-on {
    background-color: #1565c0;
    color: #fff;
    border-color: #1565c0;
}
.btn-pencil-on:hover {
    background-color: #104a93;
    color: #fff;
}

/* Completion modal */
.completion-overlay {
    position: fixed; inset: 0;
    background: rgba(0,0,0,.6);
    display: flex; align-items: center; justify-content: center;
    z-index: 1200;
}
.completion-card {
    background: #fff;
    color: #000;
    border-radius: .5rem;
    padding: 2rem 2.5rem;
    text-align: center;
    box-shadow: 0 16px 50px rgba(0,0,0,.4);
    max-width: 24rem;
}
.completion-card h2 { margin-bottom: .5rem; }
.completion-card .time {
    font-variant-numeric: tabular-nums;
    font-size: 2rem; font-weight: 700; color: #198754;
    margin: .5rem 0 1rem;
}

/* Version pill on the right of the nav links — looks small + muted. */
.nav-version-pill {
    margin-left: 1rem;
}
.nav-version-pill .nav-link {
    color: rgba(255,255,255,0.5) !important;
    font-variant-numeric: tabular-nums;
    cursor: default;
    pointer-events: none;
}

/* ── Cosolve UI ────────────────────────────────────────────────────────── */
.cosolve-frame {
    display: flex;
    flex-direction: column;
    max-width: 720px;
    margin: 0 auto;
    position: relative;
}
.cosolve-participants {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;          /* increased from .5rem so names breathe */
    align-items: center;
    padding: .35rem .5rem;
    background: #f3f4f6;
    border: 1px solid var(--bs-border-color);
    border-radius: .35rem;
    font-size: .9rem;
}
.cosolve-participant {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
}
.cosolve-color-dot {
    width: 0.85rem; height: 0.85rem;
    border-radius: 50%;
    border: 1px solid rgba(0,0,0,.15);
    flex: 0 0 auto;
}
/* Admin-only display: the participant who is currently primary gets a
   star instead of a circle. Color matches their assigned color (or
   black hollow for primary spectators, who otherwise have no marker). */
.cosolve-color-dot.primary {
    width: 1.05rem; height: 1.05rem;
    background: transparent !important;
    border: none;
    /* Star drawn via inline SVG background-image, color via mask. */
    -webkit-mask: var(--star-mask);
            mask: var(--star-mask);
    -webkit-mask-size: contain;
            mask-size: contain;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    background-color: var(--star-color, #888) !important;
    --star-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><polygon points='12,2 15,9 22,9 16,14 18,21 12,17 6,21 8,14 2,9 9,9'/></svg>");
}
.cosolve-color-dot.primary.spectator-primary {
    /* Hollow black star for primary spectators. */
    -webkit-mask: var(--star-hollow-mask);
            mask: var(--star-hollow-mask);
    background-color: #000 !important;
    --star-hollow-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'><polygon points='12,2 15,9 22,9 16,14 18,21 12,17 6,21 8,14 2,9 9,9'/></svg>");
    display: inline-block;
}
.cosolve-color-dot.disconnected {
    background: transparent !important;
    border-width: 2.5px;
}
.cosolve-color-dot.spectator {
    display: none; /* spectators get no dot */
}
.cosolve-color-dot.spectator.primary {
    display: inline-block; /* but a primary spectator gets a hollow star */
}
.cosolve-participant.disconnected .name {
    color: var(--bs-secondary-color);
}
/* Own instance (the bar entry that represents this browser tab): bold
   so the local user can spot themselves at a glance. Note: this matches
   on the .me class which is set per-instance (socketId === mySocketId),
   not per-user, so the user's other tabs are NOT bold. */
.cosolve-participant.me .name { font-weight: 700; }

/* Role-management menu shown when host/cohost clicks a participant. */
.cosolve-participant.clickable {
    cursor: pointer;
}
.cosolve-participant.clickable:hover .name {
    text-decoration: underline;
}
.role-menu {
    position: absolute;
    z-index: 1080;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: .375rem;
    box-shadow: 0 .25rem .75rem rgba(0,0,0,.15);
    padding: .25rem 0;
    min-width: 200px;
}
.role-menu-header {
    padding: .25rem .75rem;
    font-weight: 600;
    color: var(--bs-secondary-color);
    font-size: .875rem;
}
.role-menu-item {
    display: block;
    width: 100%;
    text-align: left;
    padding: .25rem .75rem;
    border: 0;
    background: transparent;
    font-size: .875rem;
}
.role-menu-item:hover:not(:disabled) {
    background: var(--bs-tertiary-bg);
}
.role-menu-item:disabled {
    opacity: .5;
    cursor: default;
}

/* Invite badge on the In Progress nav link */
.nav-link.has-invites::after {
    content: attr(data-invite-count);
    display: inline-block;
    margin-left: .35rem;
    background: #dc3545;
    color: #fff;
    font-size: .7rem;
    font-weight: 700;
    border-radius: .75rem;
    min-width: 1.25rem;
    padding: 0 .35rem;
    text-align: center;
    line-height: 1.25rem;
}
