/* Daily Board — the Day view of the H&P Planning module.
   The table itself reuses .table-wrap and .player-table, so the board reads
   like the squad grid with different columns. The hp- prefix is the module
   chrome; the db- prefix is the board itself. */

.db-container {
    padding: 0;
}

/* ── Module chrome ──
   The toolbar shape (62px, lanes, page title) comes from the shared toolbar
   lists in styles.css; only the module-owned pieces live here. */

/* One line at any width: the lanes shrink and the summary ellipsizes
   instead of wrapping below the toolbar's divider. */
.hp-toolbar {
    justify-content: space-between;
    flex-wrap: nowrap;
    overflow: hidden;
}

/* §4a: Module Tabs are seam-anchored, so the lane that holds them must reach
   the full 62px and the toolbar's 14px vertical padding is negated on that
   lane only. The title keeps its own vertical centring inside the tall lane. */
.hp-toolbar-left {
    flex: 0 1 auto;
    min-width: 0;
    align-self: stretch;
    align-items: stretch;
    margin-top: -14px;
    margin-bottom: -14px;
}

.hp-toolbar-left .hp-page-title {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
}

/* Lane shrink priority, left to right. The tab row clips first, behind the
   §4a mask fade, and the active tab is scrolled into view; then the centre
   disclosure ellipses its own label. The right lane carries one counted fact
   and never clips, so the primary act stays reachable at 1180px. */
.hp-toolbar-center {
    position: relative;
    flex: 0 1 auto;
    min-width: 0;
    justify-content: center;
}

.hp-toolbar-right {
    flex: 0 0 auto;
    margin-left: auto;
}

.hp-page-title {
    white-space: nowrap;
}

/* ── The toolbar-centre disclosure ──
   One button stating the resolved choice. The label parts ellipsize; the
   separator and the chevron never do. */

.hp-disclosure {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 100%;
}

.hp-disclosure > span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hp-disclosure > .nv-chev,
.hp-disclosure > .hp-disclosure-sep {
    flex: 0 0 auto;
}

.hp-disclosure-sep {
    color: var(--ink-line-strong);
}

.hp-disclosure-dim {
    color: var(--text-secondary);
}

/* The popover the disclosure opens: an anchored transient float, so it takes
   the overlay plane. It sits on the fixed layer — the toolbar clips its own
   overflow to hold the lanes on one line, and would clip an absolute child.
   HPPlanning.placePop() sets its position under the disclosure. */
.hp-pop {
    position: fixed;
    z-index: 200;
    width: 340px;
    padding: 14px;
    background: var(--surface-overlay);
    border: 1px solid var(--ink-line-strong);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-pop);
    text-align: left;
}

.hp-pop-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 0;
}

.hp-pop-row + .hp-pop-row {
    border-top: 1px solid var(--ink-line);
}

.hp-pop-row > select,
.hp-pop-row > .hub-date-trigger,
.hp-pop-row > .hub-date-control {
    flex: 1;
    min-width: 0;
}

/* The two session-time controls share the row's remaining width. Their
   trigger fills its wrapper, so without this bound the empty "Select
   time" trigger takes its content width and overflows the popover. */
.hp-pop-row > .hub-time-control {
    flex: 1 1 0;
    min-width: 0;
}

.hp-pop-label {
    min-width: 78px;
    color: var(--text-tertiary);
    font-size: 0.65rem;
    font-weight: 650;
    letter-spacing: 0.045em;
    text-transform: uppercase;
}

.hp-pop-to {
    color: var(--text-tertiary);
    font-size: 0.7rem;
}

.hp-pop-foot {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--ink-line);
}

.hp-summary {
    color: var(--text-secondary);
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.hp-summary-count {
    color: var(--text-primary);
    font-weight: 750;
}

/* ── Toolbar-centre controls ── */

.db-slot-switch {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.db-plan-label {
    color: var(--text-tertiary);
    font-size: 0.6rem;
    font-weight: 750;
    letter-spacing: 0.045em;
    text-transform: uppercase;
}

.db-slot-single {
    color: var(--text-tertiary);
    font-size: 0.7rem;
    font-weight: 650;
}

/* ── Cells ── */

.player-table td.db-cell {
    padding: 3px 10px;
    text-align: center;
}

.db-mark {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
    min-width: 34px;
    height: 24px;
    padding: 0 4px;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-tertiary);
    font-family: inherit;
    line-height: 1;
    cursor: pointer;
}

.db-mark:hover {
    background: var(--ink-wash);
}

/* An empty cell carries no glyph. Its add target appears on row hover and
   on keyboard focus, so the grid at rest shows only what is planned. */
.db-add {
    /* Middle-aligned like the marks: the two are inline boxes with
       different baselines, so left to the baseline the add circle hangs
       below the mark beside it. */
    vertical-align: middle;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 1px dashed transparent;
    border-radius: var(--radius-pill);
    background: transparent;
    color: transparent;
    font: inherit;
    font-size: 0.75rem;
    line-height: 1;
    cursor: pointer;
}

.player-table tr:hover .db-add,
.db-add:focus-visible {
    border-color: var(--ink-line-strong);
    color: var(--text-tertiary);
}

.db-add:hover:not(:disabled) {
    border-color: var(--accent);
    color: var(--accent);
}

.db-add:focus-visible {
    outline: 1px solid var(--accent);
    outline-offset: 1px;
}

.db-add:disabled {
    cursor: default;
}

/* A cell holds one mark per activity, side by side in creation order. An
   occupied cell keeps an add target after its marks, revealed on the same
   row hover as the empty cell's, so a second entry of the same type never
   needs an empty cell. */
.db-mark + .db-mark {
    margin-left: 4px;
}

.db-mark + .db-add {
    margin-left: 2px;
}

/* ── The cell token family ──
   One shape at every state: an outline is open, a bar says how it closed,
   and done says its time. The accent ring marks waiting and nothing else. */

.db-tok {
    position: relative;
    display: inline-block;
    box-sizing: border-box;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    vertical-align: -3px;
}

.db-tok-waiting {
    border: 1.5px solid var(--accent);
}

.db-tok-cancelled,
.db-tok-not-executed {
    border: 1.5px solid var(--text-tertiary);
    color: var(--text-tertiary);
}

.db-tok-cancelled::after,
.db-tok-not-executed::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 13px;
    height: 1.5px;
    margin: -0.75px 0 0 -6.5px;
    background: currentColor;
}

.db-tok-cancelled::after {
    transform: rotate(-45deg);
}

.db-tok-done {
    width: auto;
    height: auto;
    padding: 2px 8px 2px 6px;
    border-radius: var(--radius-pill);
    background: var(--accent-soft);
    color: var(--text-primary);
    font-size: 0.68rem;
    font-weight: 700;
    vertical-align: 0;
}

.db-mark-time {
    margin-left: 4px;
    color: var(--text-secondary);
    font-size: 0.6rem;
    font-weight: 650;
}

/* An Individual Testing mark names its test, or "n tests" when a
   player holds a battery in the slot. */
.db-mark-test {
    max-width: 72px;
    margin-left: 4px;
    overflow: hidden;
    color: var(--text-secondary);
    font-size: 0.6rem;
    font-weight: 650;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.db-mark-note {
    position: absolute;
    top: 2px;
    right: 4px;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--text-tertiary);
}

.db-conflict {
    display: inline-block;
    margin-left: 6px;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: var(--status-modified);
    color: var(--surface-field);
    font-size: 0.6rem;
    font-weight: 800;
    line-height: 15px;
    text-align: center;
    vertical-align: middle;
}

/* ── Availability ──
   One way everywhere in this module: a dot and plain text, never a filled
   status pill. The colour is the platform's own availability tier, and since
   2026-08-18 available is the null state: no dot, quiet label, so the board
   shows the exceptions first. */

/* An exception is a word in the row's own type: near-white and a weight
   up from Available, never capitals. The uppercase word the squad grid
   uses reads as a shout here, where the row is sparse and the word sits
   beside a column of quiet "Available" (Risto, 2026-08-25). */
.db-avail {
    display: inline-flex;
    align-items: center;
    color: var(--text-primary);
    font-size: 0.74rem;
    font-weight: 600;
    white-space: nowrap;
}

.db-avail-out {
    color: var(--status-injured);
}

.db-avail-quiet {
    color: var(--text-tertiary);
    font-weight: 500;
}

/* ── The state legend ──
   The shared legend-bar disclosure under the table, exactly where the
   squad grid keeps its own. Only the items are module-owned. */

.db-legend-item {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--text-tertiary);
    font-size: 0.66rem;
    letter-spacing: 0.02em;
}

.db-legend-blank {
    color: var(--text-tertiary);
}

/* ── The row filter ──
   Above the table, on the content gutters: which players the board shows.
   The players with nothing planned stay off the board by default. */

.db-scope {
    display: flex;
    margin: 0 24px 14px;
}

/* The area each column belongs to, under its label. */
.db-col-area {
    display: block;
    margin-top: 2px;
    color: var(--text-tertiary);
    font-size: 0.58rem;
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* ── The cell modal ──
   One modal for every cell of the board, occupied or empty. It sits on the
   shared .modal shell, which is chrome height with the scrim and the shadow
   carrying its elevation; only its own head, body and foot live here. */

.db-editor-modal {
    display: flex;
    flex-direction: column;
    /* Wide enough that the fullest foot — four state acts plus Discard and
       Save — sits on one level. */
    max-width: 680px;
    overflow: hidden;
}

.db-modal-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--ink-line);
}

.db-modal-head h3 {
    margin: 0;
    color: var(--text-primary);
    font-size: 0.95rem;
    font-weight: 700;
}

.db-modal-context {
    min-width: 0;
    overflow: hidden;
    color: var(--text-secondary);
    font-size: 0.75rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.db-modal-head .ac-btn {
    margin-left: auto;
    flex: 0 0 auto;
}

.db-modal-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 16px 18px;
}

/* Practitioner, the time, and the per-player length. The practitioner
   picker takes the room because its options are the longest strings. */
.db-field-grid {
    /* 140px fits the enhanced time trigger's "Select time" placeholder
       beside its clock icon; at 112px the placeholder truncated. */
    display: grid;
    grid-template-columns: minmax(0, 1fr) 140px 84px;
    gap: 12px;
}

/* A grid, so the control stretches to the field without this module
   reaching in and restyling a shared class. */
.db-field {
    display: grid;
    min-width: 0;
    margin-bottom: 12px;
}

.db-field-grid .db-field {
    margin-bottom: 0;
    /* Label row, then an exact control track: the three controls share one
       top edge and one height, whatever the grid stretch hands the field. */
    grid-template-rows: auto 36px;
    align-content: start;
}

.db-field-grid + .db-field {
    margin-top: 12px;
}

/* A grid item defaults to min-width auto, so a control whose intrinsic
   width exceeds its track — the enhanced time trigger in the 112px column,
   a select with a long option — would push the row apart. Bounding every
   child keeps the columns honest; the controls stretch to the track. */
.db-field > * {
    min-width: 0;
}

/* One control height across the modal grid: the enhanced time trigger
   must sit level with the select and the number input beside it. */
.db-field .hub-time-control {
    width: 100%;
    height: 36px;
}

.db-field > select,
.db-field > input,
.db-field .hub-time-trigger {
    height: 36px;
    min-height: 36px;
}

.db-field > span {
    display: block;
    margin-bottom: 5px;
    color: var(--text-tertiary);
    font-size: 0.62rem;
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* ── The test picker on a new Individual Testing entry ── */

.db-test-pick {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    max-height: 220px;
    padding: 2px 0;
    overflow-y: auto;
}

.nv-seg + .db-test-pick {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border-color);
}

.db-test-cat {
    grid-column: 1 / -1;
    margin: 6px 0 2px 2px;
    color: var(--text-tertiary);
    font-size: 0.575rem;
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.db-test-cat:first-child {
    margin-top: 0;
}

.db-test-opt {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 3px 2px;
    font-size: 0.78rem;
    cursor: pointer;
}

.db-test-opt .ac-lbl {
    color: var(--text-secondary);
}

.db-test-opt:has(input:disabled) {
    cursor: default;
    opacity: 0.55;
}

.db-test-switch-state {
    margin-left: 6px;
    color: var(--text-tertiary);
    font-weight: 500;
}

.db-modal-state {
    margin: 2px 0 0;
    color: var(--text-tertiary);
    font-size: 0.72rem;
    line-height: 1.5;
}

/* Two lanes on one level: the state acts left, the decision acts right.
   The modal is sized so the fullest permission set still fits without
   wrapping or clipping the commit. */
.db-modal-foot {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    padding: 13px 18px;
    border-top: 1px solid var(--ink-line);
    background: var(--surface-raised);
}

.db-modal-lane {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.db-modal-lane-end {
    margin-left: auto;
}

/* The loading state is the shared .loading-state block, which centres the
   spinner as well as the text. Only the empty message is module-owned. */
.db-empty {
    padding: 40px 0;
    color: var(--text-tertiary);
    font-size: 0.8rem;
    text-align: center;
}


/* A cancelled or not-executed activity keeps its place, visibly closed
   without work. Closed entries recede; open entries hold the eye. The
   state sits on the mark, not the cell, because a cell may hold several
   entries in different states. */
.db-mark-cancelled,
.db-mark-not-executed,
.db-mark-done {
    opacity: 0.72;
}

.db-mark-cancelled:hover,
.db-mark-not-executed:hover,
.db-mark-done:hover {
    opacity: 1;
}

/* The structure the platform proposes, stated inside the day popover under
   the rows it would change: visibly a proposal, not saved state. The
   editors' variant is a button; everyone else reads the text. */
.db-planned-block {
    align-items: flex-start;
}

.db-planned-list {
    display: grid;
    gap: 6px;
    min-width: 0;
}

.db-planned-row {
    display: grid;
    gap: 2px;
}

.db-planned-item {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
}

.db-planned-row span {
    color: var(--text-tertiary);
    font-size: 0.62rem;
    font-weight: 650;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.db-planned-row b {
    min-width: 0;
    color: var(--text-primary);
    font-size: 0.78rem;
    font-weight: 600;
}

.db-planned-empty {
    color: var(--text-tertiary);
    font-size: 0.72rem;
}

.db-proposal {
    display: block;
    margin-top: 10px;
    color: var(--text-tertiary);
    font-size: 0.7rem;
    font-weight: 650;
    line-height: 1.5;
    text-align: left;
}

/* ── Task times ── */

/* The team-session window, stated in the day popover. Every block and
   default task time resolves against it, so moving it moves the whole
   schedule at once. */
.db-window-label {
    color: var(--text-secondary);
    font-size: 0.72rem;
    font-weight: 650;
    white-space: nowrap;
}

/* ── Frozen player column ──
   The board scrolls sideways to reach the after-session columns; the name
   stays put so a row never loses its player (Risto, 2026-08-27). The cell
   paints its own ground because a sticky cell floats above the row's
   zebra and hover washes, which are on the row, not the cell. */
.db-table-wrap .player-table thead tr.squad-assessment-label-row th.col-name,
.db-table-wrap .player-table td.col-name {
    position: sticky;
    left: 0;
    border-right: 1px solid var(--ink-line);
}
.db-table-wrap .player-table thead tr.squad-assessment-label-row th.col-name {
    z-index: 13;
}
.db-table-wrap .player-table td.col-name {
    z-index: 3;
    background-color: var(--surface-recess);
}
.db-table-wrap .player-table tbody tr:nth-child(odd) td.col-name {
    background-image: linear-gradient(var(--ink-zebra), var(--ink-zebra));
}
.db-table-wrap .player-table tbody tr:hover td.col-name {
    background-image: linear-gradient(var(--ink-wash), var(--ink-wash));
}
