/* =========================================================================
   Reset & Base
   ========================================================================= */
/*
 * Design tokens live in css/tokens.css and load before this file --
 * see docs/dev/MOBILE_DESIGN_FRAMEWORK.md (section 4.1). Do not
 * re-declare --bg, --accent, --text-base, --radius, etc. here.
 */
*, *::before, *::after { box-sizing: border-box; }
body, h1, h2, h3, h4, h5, h6, p, ul, ol, li { margin: 0; padding: 0; }
[x-cloak] { display: none !important; }

html { background: var(--bg); overflow-x: hidden; }
body {
    font-family: var(--font);
    font-size: var(--text-base);
    line-height: 1.5;
    background: var(--bg);
    color: var(--text);
    min-height: 100vh;
    min-height: 100dvh;
}

/* Scrollbars */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

/* =========================================================================
   Login Screen
   ========================================================================= */
.login-screen {
    position: fixed; inset: 0;
    background: var(--bg);
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    z-index: 9999;
    padding: 2rem;
}

.login-logo {
    font-size: 3rem;
    font-weight: 800;
    letter-spacing: 0.2em;
    color: var(--accent);
    margin-bottom: 0.25rem;
    text-shadow: 0 0 40px rgba(74,144,217,0.2);
}
.login-sub {
    color: var(--text-muted);
    font-size: 16px;
    letter-spacing: 0.15em;
    margin-bottom: 3rem;
    text-transform: uppercase;
}
.login-card { width: 100%; max-width: 320px; }

.pin-input {
    width: 100%;
    padding: 14px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    font-family: var(--mono);
    font-size: 1.8rem;
    text-align: center;
    letter-spacing: 0.4em;
    margin-bottom: 1rem;
    caret-color: var(--accent);
    color-scheme: dark;
}
.pin-input:focus { outline: none; border-color: var(--accent); }
.pin-input::placeholder { color: var(--text-muted); letter-spacing: 0.2em; font-size: 16px; }

.login-btn {
    width: 100%;
    padding: 14px;
    background: var(--accent);
    color: #000;
    border: none;
    border-radius: var(--radius);
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s, transform 0.1s;
}
.login-btn:hover { background: var(--accent-hover); }
.login-btn:active { transform: scale(0.98); }
.login-btn:disabled { opacity: 0.4; cursor: default; transform: none; }

.login-msg {
    text-align: center;
    font-size: 16px;
    margin-top: 12px;
    min-height: 24px;
    color: var(--text-muted);
}
.remember-label {
    display: flex; align-items: center; gap: 8px;
    justify-content: center;
    font-size: 16px;
    margin-bottom: 12px;
    color: var(--text-muted);
    cursor: pointer;
}
.remember-label input { accent-color: var(--accent); }
.login-back {
    display: block; margin: 8px auto 0;
    font-size: 16px;
    border: 0; background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}
.login-back:hover { color: var(--text); }

/* =========================================================================
   App Shell
   ========================================================================= */
.app-shell {
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
}

/* Top Bar */
.top-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 20px;
    height: 52px;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
    z-index: 50;
}
.top-bar-logo {
    font-size: 18px;
    font-weight: 800;
    letter-spacing: 0.12em;
    color: var(--accent);
    flex-shrink: 0;
}
.top-bar-version {
    /* Status-bar chrome, non-interactive -- 13px is within the UI floor. */
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.02em;
    color: var(--text-muted);
    flex-shrink: 0;
    margin-left: -2px;
    align-self: center;
}
.nav-tabs {
    display: flex;
    gap: 0;
    align-items: center;
    flex: 1;
    justify-content: center;
}
.nav-tab {
    padding: 14px 20px;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-muted);
    border: none;
    background: none;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    transition: color 0.15s, border-color 0.15s;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.nav-tab:hover { color: var(--text); }
.nav-tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}
.top-bar-actions {
    display: flex;
    gap: 4px;
    align-items: center;
    flex-shrink: 0;
}

/* Icon button (top bar, modal close, etc.) */
.icon-btn {
    padding: 8px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 0.15s, border-color 0.15s;
}
.icon-btn:hover { color: var(--text); border-color: var(--text-muted); }

/* Quick Add Bar */
.quick-add-bar {
    padding: 12px 20px;
    background: var(--bg-surface);
    border-bottom: 1px solid var(--border);
}
.quick-add-form {
    display: flex;
    gap: 8px;
    align-items: center;
    max-width: 900px;
    margin: 0 auto;
}
.quick-add-input {
    flex: 1;
    padding: 10px 14px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 16px;
    color-scheme: dark;
}
.quick-add-input:focus { outline: none; border-color: var(--accent); }
.quick-add-input::placeholder { color: var(--text-muted); }
.quick-add-select {
    padding: 10px 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 16px;
    color-scheme: dark;
}
.quick-add-btn {
    padding: 10px 20px;
    background: var(--accent);
    color: #000;
    border: none;
    border-radius: var(--radius-sm);
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
}
.quick-add-btn:hover { background: var(--accent-hover); }

/* =========================================================================
   Main Content
   ========================================================================= */
.main-content {
    flex: 1;
    overflow-y: auto;
    padding: 24px;
}

.loading-state {
    text-align: center;
    padding: 60px 20px;
    color: var(--text-muted);
    font-size: 18px;
}
.empty-state {
    padding: 24px;
    text-align: center;
    color: var(--text-muted);
    font-size: 16px;
}

.badge {
    background: var(--accent-dim);
    color: var(--accent);
    font-size: 14px;
    font-weight: 700;
    padding: 2px 10px;
    border-radius: 12px;
}

/* =========================================================================
   Task Rows (shared between home + grid)
   ========================================================================= */
.task-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-bottom: 1px solid rgba(30, 45, 61, 0.5);
    transition: background 0.1s;
}
.task-row:hover { background: var(--bg-elevated); }
.task-row:last-child { border-bottom: none; }

.task-done-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 2px;
    display: flex;
    flex-shrink: 0;
}
.task-done-btn:hover { color: var(--green); }

.task-cancel-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 2px;
    display: flex;
    flex-shrink: 0;
}
.task-cancel-btn:hover { color: var(--red); }

.task-title {
    flex: 1;
    font-size: 16px;
    cursor: pointer;
    color: var(--text);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.task-title:hover { color: var(--accent); }

.task-badge {
    font-size: 14px;
    font-weight: 600;
    flex-shrink: 0;
    white-space: nowrap;
}
.task-date {
    font-size: 14px;
    color: var(--text-muted);
    flex-shrink: 0;
}
.task-project {
    font-size: 14px;
    color: var(--text-muted);
    flex-shrink: 0;
    max-width: 120px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.focus-toggle-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 4px;
    display: flex;
    flex-shrink: 0;
    /* default: full opacity on touch (no hover signal available) */
    transition: opacity 0.15s, color 0.15s;
}
@media (hover: hover) and (pointer: fine) {
    /* hover-capable devices only: dim to 50% until hovered */
    .focus-toggle-btn { opacity: 0.5; }
    .focus-toggle-btn:hover { opacity: 1; }
}
.focus-toggle-btn.in-focus {
    color: var(--yellow);
    opacity: 1;
}

/* =========================================================================
   Grid Tab
   ========================================================================= */
.grid-header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 16px;
    max-width: 1200px;
}
.filter-bar {
    display: flex;
    gap: 6px;
    margin-bottom: 16px;
    flex-wrap: wrap;
    max-width: 1200px;
}
.filter-pill {
    padding: 8px 16px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 20px;
    color: var(--text-muted);
    font-size: 16px;
    cursor: pointer;
    transition: all 0.15s;
}
.filter-pill:hover { border-color: var(--text-muted); color: var(--text); }
.filter-pill.active {
    background: var(--accent-dim);
    border-color: var(--accent);
    color: var(--accent);
}

.task-list {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    max-width: 1200px;
    overflow: hidden;
}

/* =========================================================================
   Modal
   ========================================================================= */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 20px;
}
.modal-dialog {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    width: 100%;
    max-width: 600px;
    max-height: 85vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}
.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
}
.modal-title {
    font-size: 18px;
    font-weight: 700;
}
.modal-body {
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 16px 20px;
    border-top: 1px solid var(--border);
}

/* Form fields */
.field-label {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.field-input, .field-select, .field-textarea {
    width: 100%;
    padding: 10px 14px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 16px;
    font-family: inherit;
    color-scheme: dark;
}
.field-input:focus, .field-select:focus, .field-textarea:focus {
    outline: none;
    border-color: var(--accent);
}
.field-textarea {
    resize: vertical;
    min-height: 80px;
}
.field-row {
    display: flex;
    gap: 12px;
}
.field-half { flex: 1; display: flex; flex-direction: column; gap: 4px; }

/* Read-only "Shows as:" composed-title preview under the modal Title field. */
.field-preview {
    margin-top: 6px;
    font-size: 14px;
    color: var(--text-muted);
}
.field-preview span {
    color: var(--text);
    font-weight: 600;
}

/* Detail-view parent-epic backlink */
.detail-parent-link {
    display: flex;
    align-items: center;
    gap: 6px;
    background: var(--accent-dim);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    padding: 7px 10px;
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
}
.detail-parent-link:hover { border-color: var(--accent); color: var(--text); }
.detail-parent-link strong { color: var(--text); }

/* Detail-view objective breadcrumb (task #1584) -- dashed border marks it as
   a secondary/navigational link, distinct from the solid parent-epic link. */
.detail-objective-breadcrumb {
    display: flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    padding: 7px 10px;
    margin-top: 8px;
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
}
.detail-objective-breadcrumb:hover { border-color: var(--accent); color: var(--text); }
.detail-objective-breadcrumb strong { color: var(--text); }

/* Detail-view sub-tasks (read-write) */
.subtasks-block { display: flex; flex-direction: column; gap: 2px; }
.subtask-count {
    margin-left: 8px;
    font-family: var(--mono);
    color: var(--accent);
    text-transform: none;
    letter-spacing: 0;
}
.subtask-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 4px;
    font-size: 16px;
    border-bottom: 1px solid rgba(30, 45, 61, 0.3);
}
.subtask-check {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1.5px solid var(--text-muted);
    border-radius: var(--radius-sm);
    background: transparent;
    color: #000;
    cursor: pointer;
}
.subtask-check-on { background: var(--green); border-color: var(--green); }
.subtask-title { flex: 1; cursor: pointer; }
.subtask-title:hover { color: var(--accent-hover); }
.subtask-done .subtask-title { text-decoration: line-through; color: var(--text-muted); }
.subtask-unlink {
    flex: 0 0 auto;
    display: flex;
    padding: 2px;
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
}
.subtask-unlink:hover { color: var(--red); }
.subtask-add { margin-top: 8px; }
.meta-row {
    display: flex;
    gap: 20px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
}
.meta-item {
    font-size: 14px;
    color: var(--text-muted);
}

/* Buttons */
.btn {
    padding: 10px 20px;
    border-radius: var(--radius-sm);
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    border: none;
    transition: background 0.15s;
}
.btn-primary {
    background: var(--accent);
    color: #000;
}
.btn-primary:hover { background: var(--accent-hover); }
.btn-secondary {
    background: var(--bg);
    color: var(--text-muted);
    border: 1px solid var(--border);
}
.btn-secondary:hover { color: var(--text); border-color: var(--text-muted); }

/* =========================================================================
   Toast
   ========================================================================= */
.toast-container {
    position: fixed;
    bottom: 20px;
    right: 20px;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: 400px;
}
.toast {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 16px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
.toast-success { border-left: 3px solid var(--green); }
.toast-error { border-left: 3px solid var(--red); }
.toast-info { border-left: 3px solid var(--accent); }

.toast-action {
    background: none;
    border: none;
    color: var(--accent);
    font-weight: 700;
    font-size: 16px;
    cursor: pointer;
    padding: 0;
    white-space: nowrap;
}
.toast-action:hover { text-decoration: underline; }

.toast-close {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 2px;
    display: flex;
    flex-shrink: 0;
}
.toast-close:hover { color: var(--text); }

/* =========================================================================
   Board (Kanban)
   ========================================================================= */
.board-container {
    /* height-lock + overflow:hidden are applied at >=768px only (see the
       --bp-md board block). On mobile the columns stack vertically and the
       page scrolls; locking here would trap ~1800px of stacked columns in a
       ~650px box and clip everything past the first screenful (the mobile
       column body has no inner scroll). */
    display: flex;
    flex-direction: column;
}
.board-columns {
    display: flex;
    gap: 12px;
    flex: 1;
    overflow-x: auto;
    overflow-y: hidden;
    padding-bottom: 12px;
}
.board-column {
    flex: 1;
    min-width: 240px;
    max-width: 320px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    transition: border-color 0.15s;
}
.board-column.drag-over {
    border-color: var(--accent);
    background: rgba(74, 144, 217, 0.05);
}
.board-col-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.board-col-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}
.board-col-title {
    font-size: 16px;
    font-weight: 700;
    flex: 1;
}
.board-col-count {
    font-size: 14px;
    color: var(--text-muted);
    background: var(--bg);
    padding: 2px 8px;
    border-radius: 10px;
}
.board-col-body {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
}
.board-col-empty {
    text-align: center;
    padding: 24px;
    color: var(--text-muted);
    font-size: 14px;
}
.board-card {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 12px;
    margin-bottom: 6px;
    cursor: grab;
    transition: border-color 0.15s, transform 0.1s;
    position: relative;
}
.board-card:hover { border-color: var(--text-muted); }
.board-card:active { cursor: grabbing; transform: scale(0.98); }
.board-card-title {
    font-size: 16px;
    color: var(--text);
    cursor: pointer;
    margin-bottom: 6px;
    line-height: 1.3;
}
.board-card-title:hover { color: var(--accent); }
.board-card-meta {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    font-size: 14px;
}
.board-card-date { color: var(--text-muted); }
.board-card-project { color: var(--text-muted); }
.board-card-pri { font-weight: 600; }
.board-card-claim {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-top: 6px;
    font-size: 14px;
    color: var(--yellow);
}
.board-card-claim::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--yellow);
    flex-shrink: 0;
}
.board-card-actions {
    position: absolute;
    top: 10px;
    right: 10px;
    /* default: always visible (touch devices have no hover) */
    transition: opacity 0.15s;
}
@media (hover: hover) and (pointer: fine) {
    /* hover-capable devices only: dim until parent card is hovered */
    .board-card-actions { opacity: 0; }
    .board-card:hover .board-card-actions { opacity: 1; }
}

/* =========================================================================
   Focus Tab
   ========================================================================= */
.focus-container {
    height: calc(100vh - 120px);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.focus-two-col {
    display: flex;
    gap: 16px;
    flex: 1;
    min-height: 0;
    padding: 0 4px;
}
.focus-col {
    display: flex;
    flex-direction: column;
    min-width: 0;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.focus-col-main {
    flex: 1;
    min-width: 320px;
}
.focus-col-pool {
    flex: 1;
    min-width: 320px;
}
.focus-col-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.focus-col-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--text);
    flex-shrink: 0;
}
.focus-col-count {
    font-size: 14px;
    color: var(--text);
    font-weight: 500;
    flex-shrink: 0;
}
.focus-col-created {
    font-size: 13px;
    color: var(--text-muted);
    font-weight: 400;
    flex-shrink: 0;
}
.focus-pool-select {
    flex: 0 0 auto;
    max-width: 160px;
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 6px 10px;
    font-size: 14px;
    color-scheme: dark;
}
.focus-header-form {
    flex: 1;
    min-width: 0;
    margin: 0;
    display: flex;
    align-items: stretch;
    gap: 6px;
}
.focus-quick-input {
    flex: 1;
    min-width: 0;
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 6px 12px;
    font-size: 16px;
    color-scheme: dark;
}
.focus-quick-input::placeholder {
    color: var(--text-muted);
}
.focus-quick-input:focus {
    outline: none;
    border-color: var(--accent);
}
.focus-quick-dir {
    flex: 0 0 auto;
    background: var(--bg-elevated);
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 0 10px;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
}
.focus-quick-dir:hover {
    color: var(--text);
    border-color: var(--accent);
}
.focus-col-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 4px 0;
}

/* ===== Home redesign: 3-column layout (task #1451) ======================
   35 / 30 / 35 at desktop -- Col 1 (col1) is a stacked flex wrapper holding
   the [Focus | In Focus] toggle panel over the Tasks pool; Col 2 (cal) the
   full-height Calendar; Col 3 (ctx) the contextual Notes/Detail pane. The
   grid-TEMPLATE lives in the mobile-first cascade near the bottom of this
   file (stack < 1200px, three columns >= 1200px); this block holds the
   shared props + grid-area assignments + the new component styles. */
.home-grid {
    flex: 1;
    min-height: 0;
    display: grid;
    gap: 12px;
    padding: 0 4px;
}
.home-col1          { grid-area: col1; }
.focus-col-calendar { grid-area: cal; }
.focus-col-ctx      { grid-area: ctx; }
/* The grid sizes the columns -- drop the flex-era fixed minimums. */
.home-grid .focus-col { min-width: 0; }

/* Column 1 -- stacked: toggle panel (top, ~40% cap) over Tasks (fills rest). */
.home-col1 {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
    min-height: 0;
}
.focus-col-top   { flex: 0 1 auto; min-height: 0; }
.home-col1-bot   { flex: 1 1 auto; min-height: 0; }

/* Segmented toggle -- [Focus | In Focus] (Col 1 header) and
   [Detail | Notes] (Col 3 header). Flat, accent-dim active state. */
.seg-toggle {
    display: inline-flex;
    flex-shrink: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
}
.seg-btn {
    background: transparent;
    color: var(--text-muted);
    border: none;
    padding: 6px 14px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    font-family: var(--font);
    line-height: 1.2;
}
.seg-btn + .seg-btn { border-left: 1px solid var(--border); }
.seg-btn.seg-on { background: var(--accent-dim); color: var(--accent); }
.seg-btn:hover:not(.seg-on):not(:disabled) { color: var(--text); }
/* Disabled seg button (task #1456 fix 2): Col 3 'Detail' before any task has
   been opened this session -- greyed, non-interactive, no hover lift. */
.seg-btn:disabled { opacity: 0.4; cursor: not-allowed; color: var(--text-muted); }

/* Contextual column (Col 3) -- Notes body fills the pane. Detail body reuses
   .detail-pane-body (defined with the modal styles). */
.ctx-notes-body {
    flex: 1;
    min-height: 0;
    padding: 8px;
    display: flex;
}
.ctx-notes-body .home-notes {
    flex: 1;
    width: 100%;
    resize: none;
    /* Task #1456 fix 3: the Notes editing surface is pure #000 (== --bg, the
       app's base), not the navy --bg-input fill. John requested no fill on
       this surface; the 1px border keeps it delineated on the black panel. */
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
    font-size: 16px;
    font-family: var(--font);
    line-height: 1.5;
    box-sizing: border-box;
}
.ctx-notes-body .home-notes:focus { outline: none; border-color: var(--accent); }
.ctx-notes-body .home-notes::placeholder { color: var(--text-muted); }

/* ---- Two-row calendar header (task #1451) -----------------------------
   Deliberate two-row layout so the single flow row no longer wraps and
   splits the << >> pair. Row 1: view + Today + step-nav (< >), then a
   spacer, then right-aligned add/link. Row 2: month/day/year + jump-nav
   (<< >>) OR the schedule window select. flex-wrap:nowrap on both rows. */
.cal-header-2row {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.cal-header-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: nowrap;
    min-width: 0;
}
.cal-header-spacer { flex: 1; min-width: 8px; }
/* In the two-row header the add button no longer needs the float trick. */
.cal-header-2row .cal-add-btn { margin-left: 0; }

/* ---- Week view (task #1451) -------------------------------------------
   7 day-columns + a slim hour gutter, full column height, scrolls
   internally. Event cells use a denser type scale than the day view --
   the domain-standard calendar-cell convention -- held at the readable
   floors (14px titles, 13px chrome) per the UI rules. */
.cal-week {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}
.cal-week-head {
    display: flex;
    flex-shrink: 0;
    border-bottom: 1px solid var(--border);
}
.cal-week-gutter {
    width: 44px;
    flex-shrink: 0;
    border-right: 1px solid var(--border);
}
.cal-week-dayhead {
    flex: 1;
    min-width: 0;
    text-align: center;
    padding: 4px 2px;
    border-right: 1px solid var(--border-soft);
}
.cal-week-dayhead:last-child { border-right: none; }
.cal-week-dow {
    font-size: var(--text-chrome);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.cal-week-dnum { font-size: 15px; font-weight: 600; color: var(--text); line-height: 1.3; }
.cal-week-dayhead.is-today .cal-week-dnum { color: var(--accent); }
/* All-day events in the week header (below the date). Compact chips -- the
   timed grid has no room for them, and dropping them silently would hide
   real events. Source stripe matches the timed blocks. */
.cal-week-allday {
    margin: 2px 2px 0;
    padding: 1px 4px;
    font-size: 13px;
    line-height: 1.25;
    text-align: left;
    color: var(--text);
    background: rgba(74, 144, 217, 0.22);
    border-left: 2px solid var(--accent);
    border-radius: 3px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
}
.cal-week-allday[data-source="google"] {
    background: rgba(45, 214, 107, 0.20);
    border-left-color: var(--green);
}
.cal-week-body {
    flex: 1;
    display: flex;
    overflow-y: auto;
    position: relative;
    min-height: 0;
}
.cal-week-hours {
    width: 44px;
    flex-shrink: 0;
    border-right: 1px solid var(--border);
}
.cal-week-hourlabel {
    height: 40px;
    font-size: 13px;
    color: var(--text-muted);
    padding: 1px 5px;
    box-sizing: border-box;
    text-align: right;
}
.cal-week-cols { flex: 1; display: flex; min-width: 0; }
.cal-week-col {
    flex: 1;
    min-width: 0;
    border-right: 1px solid var(--border-soft);
    position: relative;
}
.cal-week-col:last-child { border-right: none; }
.cal-week-hourcell { height: 40px; border-bottom: 1px dotted var(--border); cursor: pointer; }
.cal-week-hourcell:hover { background: var(--accent-dim); }
.cal-week-col-overlay { position: absolute; inset: 0; pointer-events: none; }
.cal-week-col .cal-event {
    font-size: 14px;
    padding: 2px 5px;
    border-left-width: 2px;
    min-height: 18px;
}
.cal-week-col .cal-event .cal-event-title {
    font-size: 14px;
    font-weight: 600;
    white-space: normal;
    line-height: 1.15;
    overflow: hidden;
}
.cal-week-col .cal-event .cal-event-time { font-size: 13px; margin-top: 0; }

/* ---- Month grid (task #1456 fix 4, the 'Calendar' view) ----------------
   A month-at-a-glance grid that fills the calendar pane: a Sun-start weekday
   header row over 5-6 equal-height week rows. Each day cell shows its number
   and stacked event chips; the whole grid scrolls internally when the rows
   overflow the pane at the locked width. Source color echoes the hour-grid:
   M365 = accent (blue), Google = green. */
.cal-month {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}
.cal-month-dowrow {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    border-bottom: 1px solid var(--border);
    flex: 0 0 auto;
}
.cal-month-dow {
    padding: 6px 4px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.cal-month-grid {
    flex: 1;
    min-height: 0;
    display: grid;
    /* rows set inline (grid-template-rows: repeat(N,1fr)) from calendarMonthRows */
    overflow-y: auto;
}
.cal-month-week {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    min-height: 0;
}
.cal-month-cell {
    border-right: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    padding: 3px 4px 4px;
    min-width: 0;
    min-height: 64px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    cursor: pointer;
    overflow: hidden;
}
.cal-month-week > .cal-month-cell:last-child { border-right: none; }
.cal-month-cell:hover { background: var(--accent-dim); }
.cal-month-cell.is-outmonth { background: #060a10; }
.cal-month-cell.is-outmonth .cal-month-daynum { color: var(--text-muted); opacity: 0.6; }
.cal-month-daynum {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    line-height: 1.2;
    flex: 0 0 auto;
}
.cal-month-cell.is-today .cal-month-daynum {
    color: #fff;
    background: var(--accent);
    border-radius: 50%;
    width: 22px;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    align-self: flex-start;
}
.cal-month-events {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-height: 0;
    overflow: hidden;
}
.cal-month-chip {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 1px 4px;
    border-radius: 3px;
    background: var(--accent-dim);
    cursor: pointer;
    min-width: 0;
}
.cal-month-chip:hover { background: rgba(74, 144, 217, 0.30); }
.cal-month-chip[data-source="google"] { background: rgba(45, 214, 107, 0.18); }
.cal-month-chip[data-source="google"]:hover { background: rgba(45, 214, 107, 0.30); }
.cal-month-chip-dot {
    flex: 0 0 auto;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
}
.cal-month-chip[data-source="google"] .cal-month-chip-dot { background: var(--green); }
.cal-month-chip-title {
    font-size: 14px;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

/* In Focus column (legacy "rocks" class names) */
.rocks-body { display: flex; flex-direction: column; gap: 8px; padding: 8px; }
.rock-card {
    background: var(--bg-elevated);
    border-radius: var(--radius-sm);
    padding: 6px 10px;
    cursor: pointer;
}
.rock-card:hover { background: #141c26; }
.rock-card-dragover { background: var(--accent-dim); }
.rock-card-row { display: flex; align-items: center; gap: 8px; }
.rock-card-title {
    flex: 1;
    min-width: 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.rock-card-x {
    flex: 0 0 auto;
    display: flex;
    padding: 2px;
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
}
.rock-card-x:hover { color: var(--red); }
.detail-header-save:hover { color: var(--green); }
.rock-bar-row { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.rock-bar {
    width: 52px;
    flex: 0 0 52px;
    height: 6px;
    background: var(--border);
    border-radius: 3px;
    overflow: hidden;
}
.rock-bar > i { display: block; height: 100%; background: var(--accent); }
.rock-bar-count {
    flex: 0 0 auto;
    font-family: var(--mono);
    font-size: 13px;
    color: var(--text-muted);
}

/* Detail pane (Now band, third column) */
.detail-pane-body { padding: 14px; }
.detail-fields { display: flex; flex-direction: column; gap: 12px; }
.detail-pane-foot { margin-top: 14px; display: flex; justify-content: flex-end; }
/* Detail pane idle placeholder -- the scratch moved up to the Notes panel. */
.detail-empty {
    color: var(--text-muted);
    font-size: 15px;
    line-height: 1.5;
    padding: 16px 4px;
}

/* Notes panel -- always-on quick scratch in row-1 cols 5-6. Same look as the
   former Detail-idle scratch; bound to the same scratchText state. */
.home-notes-body { display: flex; flex-direction: column; min-height: 0; padding: 8px; }
.home-notes {
    flex: 1;
    width: 100%;
    min-height: 120px;
    background: var(--bg);
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-family: inherit;
    font-size: 15px;
    padding: 10px 12px;
    resize: none;
    color-scheme: dark;
    box-sizing: border-box;
}
.home-notes:focus { outline: none; border-color: var(--accent); border-style: solid; }
.home-notes::placeholder { color: var(--text-muted); }

/* Row-1 panel-2 view toggle (Schedule | Calendar). Leftmost header control,
   so no margin-left:auto (unlike the sibling schedule-view-select). Matches
   that select's compact 14px header-control sizing. */
.home-view-select {
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 4px 8px;
    font-size: 14px;
    color-scheme: dark;
    font-family: var(--font);
    cursor: pointer;
    flex-shrink: 0;
    font-weight: 500;
}
.home-view-select:focus { outline: none; border-color: var(--accent); }

/* Schedule digest panel -- 7-day chronological list of the unified
   calendar feed (M365 + Google primary), date-grouped. Row source dot
   colors match the day-view column's stripe scheme: blue for M365,
   green for Google. Click a row to open the shared edit modal. */
/* Today's long-form date in the Schedule header center. Two siblings
   carry margin-left: auto (this + the view select) so flex splits the
   free space equally between them -- the date lands centered between
   the title/count cluster on the left and the dropdown on the right. */
.schedule-today-date {
    margin-left: auto;
    font-size: 14px;
    color: var(--text);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.schedule-view-select {
    margin-left: auto;
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 4px 8px;
    font-size: 14px;
    color-scheme: dark;
    font-family: var(--font);
    cursor: pointer;
    flex-shrink: 0;
}
.schedule-view-select:focus { outline: none; border-color: var(--accent); }

.schedule-body {
    padding: 6px 8px;
    overflow-y: auto;
}
.schedule-day-group { margin-bottom: 10px; }
.schedule-day-header {
    font-size: var(--text-chrome);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text);
    padding: 6px 4px 4px;
    border-bottom: 1px solid var(--border-soft);
    margin-bottom: 4px;
}
.schedule-event-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 4px;
    border-bottom: 1px solid rgba(30, 45, 61, 0.3);
    cursor: pointer;
}
.schedule-event-row:last-child { border-bottom: none; }
.schedule-event-row:hover { background: rgba(255, 255, 255, 0.04); }
.schedule-source-dot {
    flex: 0 0 8px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent);   /* M365 default */
}
.schedule-event-row[data-source="google"] .schedule-source-dot {
    background: var(--green);
}
.schedule-event-time {
    flex: 0 0 auto;
    font-family: var(--mono);
    font-size: var(--text-sm);
    color: var(--text);
    min-width: 56px;
}
.schedule-event-title {
    flex: 1;
    min-width: 0;
    font-size: var(--text-base);
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.schedule-error {
    padding: 12px 8px;
    color: var(--text-muted);
    font-size: var(--text-sm);
}

/* Per-project Active / Backlog flip -- Focus column header, project mode. */
.focus-ptabs {
    display: flex;
    gap: 6px;
    padding: 8px 16px;
    flex-shrink: 0;
}
.focus-ptab {
    flex: 1;
    background: var(--bg-elevated);
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 6px 10px;
    font-size: 16px;
    font-family: inherit;
    cursor: pointer;
}
.focus-ptab:hover { color: var(--text); }
.focus-ptab-on {
    background: var(--accent-dim);
    color: var(--accent);
    border-color: var(--accent);
}

/* Compact rows -- the core of Focus */
.focus-compact-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 16px;
    min-height: 34px;
    cursor: grab;
    transition: background 0.1s;
    border-bottom: 1px solid transparent;
}
/* Curated Focus row only (no .focus-pool-row marker, task #1800): its
   action icons (project-select, done, remove) read as too spread out at
   the base 8px gap once the project-select's value text is hidden above --
   tightened here rather than on the shared base rule so Tasks-pool /
   objective-lens / unassigned-tray rows (.focus-pool-row, up to 5 controls,
   already tuned for their own density) are untouched. Also excludes
   .tree-row -- the Objectives tab's tree view reuses .focus-compact-row
   too (panel.php ~1173, dot+title+status-select+done+remove, a separate
   feature this task doesn't touch) and carries no .focus-pool-row marker
   either. */
.focus-compact-row:not(.focus-pool-row):not(.tree-row) {
    gap: 4px;
}
/* Curated Focus row's 3-icon action cluster (project-select, done, remove),
   wrapped in its own flex container so the ICON-to-icon spacing can be
   tightened independently of the row's title-to-controls gap above (task
   #1803, follow-up to #1800 -- that gap must NOT shrink further, only the
   inter-icon spacing). */
.focus-row-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    flex-shrink: 0;
}
.focus-col-main .focus-compact-row {
    background: var(--bg-elevated);
    border-radius: var(--radius-sm);
    margin: 2px 8px;
    padding: 6px 10px;
}
.focus-compact-row:hover {
    background: var(--bg-elevated);
}
.focus-col-main .focus-compact-row:hover {
    background: #141c26;
}
.focus-compact-row:active {
    cursor: grabbing;
}
.focus-row-dragover {
    border-top: 2px solid var(--accent);
}
.focus-row-done {
    flex-shrink: 0;
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 2px;
    display: flex;
    align-items: center;
}
.focus-row-done:hover {
    color: var(--green);
}
.focus-row-dot {
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    border-radius: 50%;
}
.focus-row-title {
    flex: 1;
    min-width: 0;
    font-size: 16px;
    line-height: 1.3;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}
.focus-row-title:hover {
    color: var(--accent);
}
.focus-row-project {
    flex-shrink: 0;
    font-size: 13px;
    color: var(--text-muted);
    max-width: 120px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Inline project picker in the curated Focus column (task #1800). The
   selected value's text (the "--" unassigned placeholder, or an assigned
   project name) is redundant clutter next to the dropdown indicator --
   hidden here. A plain `color: transparent` is NOT enough on its own:
   confirmed live (render-compare, task #1800) that Chromium draws the
   native <select> arrow using the element's OWN color, so a transparent
   select loses its arrow too, not just its text. Fixed by disabling the
   native control's appearance entirely and drawing a fixed-color chevron
   via background-image instead -- decoupled from `color`, so it survives
   regardless of what the (still fully functional) native popup would have
   drawn. Still a real <select>: unchanged @change/setTaskProject handler,
   full keyboard operability, tap opens the native project list. */
.focus-row-project-select {
    flex-shrink: 0;
    width: 22px;
    font-family: inherit;
    font-size: var(--text-base);
    color: transparent;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    /* Solid bg, not transparent: a transparent <select> lets the OS render
       its native option popup white. var(--bg-elevated) is #000 -- matches
       the row beneath it, so the closed control still reads as a bare badge.
       Chevron is a fixed-color inline SVG (matches the old --text-muted
       #6b839e), centered -- independent of the select's own `color`. */
    background: var(--bg-elevated)
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b839e' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E")
        no-repeat center center;
    background-size: 13px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    padding: 0;
    cursor: pointer;
    color-scheme: dark;
}
.focus-row-project-select:hover {
    border-color: var(--border);
}
.focus-row-project-select:focus {
    outline: none;
    border-color: var(--accent);
}
.focus-row-remove,
.focus-row-move {
    flex-shrink: 0;
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 2px;
    display: flex;
    align-items: center;
}
.focus-row-remove:hover { color: var(--red); }
.focus-row-move:hover { color: var(--accent); }

/* Tasks-column row: inline Status select. Sits between the row title and
   the action buttons; updateTaskField persists the change + reloads. Solid
   bg + color-scheme:dark so the OS draws a dark option popup, not white. */
.focus-row-status-select {
    flex-shrink: 0;
    max-width: 140px;
    font-family: inherit;
    font-size: 14px;
    color: var(--text);
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 4px 6px;
    color-scheme: dark;
    cursor: pointer;
}
.focus-row-status-select:hover { border-color: var(--accent); }
.focus-row-status-select:focus { outline: none; border-color: var(--accent); }

.focus-empty {
    padding: 24px 16px;
    color: var(--text-muted);
    text-align: center;
    font-size: 16px;
}

/* Drop zone highlight when dragging over the focus column */
.focus-col-main.drag-over {
    border-color: var(--accent);
}

/* Calendar day-view (third column). Backed by api/calendar.php?date=...
   24-hour grid with absolutely-positioned event bars overlaid. */
.focus-col-calendar {
    flex: 1;
    min-width: 320px;
}
.cal-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    row-gap: 6px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.cal-today-btn {
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 6px 12px;
    font-size: 14px;
    cursor: pointer;
}
.cal-today-btn:hover { border-color: var(--accent); }
/* Header action chips (+ add event, disconnect provider). margin-left:auto
   lives on .cal-add-btn so the whole right-aligned group floats together;
   .cal-disconnect-btn follows with the header's gap. Putting margin-left:
   auto on both would split the free space between them. */
.cal-add-btn,
.cal-disconnect-btn {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    cursor: pointer;
    padding: 6px;
    display: flex;
    align-items: center;
}
.cal-add-btn { margin-left: auto; }
.cal-add-btn:hover { color: var(--accent); border-color: var(--accent); }
.cal-disconnect-btn:hover { color: var(--red); border-color: var(--red); }
/* Expired-token state (task #1492): the provider row still exists but
   ensureValidToken()'s refresh is failing (e.g. revoked consent) -- render
   it distinctly (persistent amber, not just on hover) so it reads as
   "needs reconnect", not just "click here to disconnect". */
.cal-disconnect-btn.cal-provider-expired {
    color: var(--yellow);
    border-color: var(--yellow);
}

/* Mixed-state "+ Provider" chip (task #1492): one provider is connected
   (the grid is live, so the empty-state Connect button isn't shown) and
   the OTHER configured provider isn't -- this lets it be added without
   losing the grid. Text chip rather than an icon since there's no good
   universal "connect" glyph and the label ('Microsoft'/'Google') matters. */
.cal-connect-chip {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    cursor: pointer;
    padding: 6px 10px;
    font-size: 13px;
    display: flex;
    align-items: center;
    gap: 2px;
}
.cal-connect-chip:hover { color: var(--accent); border-color: var(--accent); }
.cal-connect-chip:disabled { opacity: 0.6; cursor: default; }

/* The calendar header is a deliberate two-row layout at ALL widths now
   (.cal-header-2row, task #1451) -- the old mobile-only flex `order` split
   is retired. The disconnect/connect-chip controls stay desktop-only: rare
   actions that just crowd the phone header. */
@media (max-width: 767.98px) {
    .cal-disconnect-btn,
    .cal-connect-chip { display: none; }
}

/* Month / Day / Year jump dropdowns. Month is sized to fit the longest
   month name ('September' = 9 chars) plus the dropdown chevron and
   horizontal padding -- about 11ch is the right floor and keeps the
   widget from stealing space when shorter months are selected. */
.cal-ym-select {
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 6px 8px;
    font-size: 14px;
    color-scheme: dark;
    font-family: var(--font);
    cursor: pointer;
}
.cal-ym-select:focus { outline: none; border-color: var(--accent); }
.cal-month-select { flex: 0 0 auto; width: 11ch; }
.cal-day-select { flex: 0 0 auto; }
.cal-year-select { flex: 0 0 auto; }

/* Empty state when calendar provider is configured but not yet connected
   (or env vars are missing on the server). Shows a Connect CTA. */
.cal-empty-state {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px 24px;
    text-align: center;
}
.cal-empty-state > div { max-width: 320px; }
.cal-empty-msg {
    font-size: 16px;
    color: var(--text);
    margin: 0 0 16px;
}
.cal-empty-hint {
    font-size: 14px;
    color: var(--text-muted);
    margin: 16px 0 0;
    line-height: 1.5;
}
/* Stacks one Connect button per configured-but-disconnected provider
   (task #1492 -- was a single always-Microsoft button). */
.cal-connect-row {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
}
.cal-connect-btn {
    background: var(--accent);
    color: #000;
    border: none;
    border-radius: var(--radius-sm);
    padding: 10px 18px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
}
.cal-connect-btn:hover { background: var(--accent-hover); }
.cal-connect-btn:disabled { opacity: 0.6; cursor: default; }
/* Source-color match with the event chips elsewhere (m365=accent/blue,
   google=green -- see .cal-month-chip[data-source] / .cal-event[data-source]). */
.cal-connect-btn-google { background: var(--green); }
.cal-connect-btn-google:hover { background: var(--green); filter: brightness(1.1); }
.cal-live { display: contents; }

/* Calendar event create/edit modal */
.cal-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: 9000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.cal-modal {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    width: 100%;
    max-width: 480px;
    max-height: 90vh;
    overflow-y: auto;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
}
.cal-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
}
.cal-modal-title {
    font-size: 18px;
    font-weight: 700;
    color: var(--text);
}
.cal-modal-form {
    padding: 16px 20px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.cal-form-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.cal-form-row-inline {
    flex-direction: row;
    align-items: center;
    gap: 8px;
    font-size: 16px;
    color: var(--text);
}
.cal-form-label {
    font-size: 14px;
    color: var(--text-muted);
    font-weight: 600;
}
.cal-form-input {
    padding: 8px 10px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 16px;
    color-scheme: dark;
    font-family: var(--font);
}
.cal-form-input:focus {
    outline: none;
    border-color: var(--accent);
}
.cal-form-static {
    flex: 1;
    padding: 8px 0;
    font-size: 16px;
    color: var(--text-muted);
}
.cal-form-textarea {
    min-height: 72px;
    resize: vertical;
    font-family: var(--font);
}
.cal-modal-footer {
    display: flex;
    align-items: center;
    gap: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
    margin-top: 4px;
}
.cal-form-spacer { flex: 1; }
.cal-form-btn {
    padding: 8px 16px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    background: transparent;
    color: var(--text);
}
.cal-form-btn:disabled { opacity: 0.5; cursor: default; }
.cal-form-btn-primary {
    background: var(--accent);
    color: #000;
    border-color: var(--accent);
}
.cal-form-btn-primary:hover:not(:disabled) { background: var(--accent-hover); }
.cal-form-btn-secondary:hover:not(:disabled) { border-color: var(--text-muted); }
.cal-form-btn-danger {
    color: var(--red);
    border-color: var(--red);
}
.cal-form-btn-danger:hover:not(:disabled) {
    background: var(--red);
    color: #fff;
}
.cal-nav-btn {
    background: transparent;
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 6px 8px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.cal-nav-btn:hover { border-color: var(--accent); }
.cal-date {
    margin-left: 8px;
    font-size: 16px;
    font-weight: 600;
    color: var(--text);
}
.cal-allday-strip {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px 12px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.cal-event-allday {
    position: static;
    background: rgba(74, 144, 217, 0.22);    /* tinted accent (M365 default) */
    color: var(--text);
    border-left: 3px solid var(--accent);
    padding: 4px 8px 4px 10px;
    font-size: 14px;
    border-radius: 3px;
    cursor: pointer;
}
.cal-event-allday[data-source="google"] {
    background: rgba(45, 214, 107, 0.20);
    border-left-color: var(--green);
}
.cal-grid {
    flex: 1;
    overflow-y: auto;
    position: relative;
}
.cal-hour-row {
    display: flex;
    height: 40px;
    border-bottom: 1px dotted var(--border);
}
.cal-hour-label {
    width: 56px;
    flex-shrink: 0;
    padding: 2px 8px;
    font-size: 13px;
    white-space: nowrap;
    color: var(--text);
    border-right: 1px solid var(--border);
    box-sizing: border-box;
}
.cal-hour-cell {
    flex: 1;
    cursor: pointer;
}
.cal-hour-cell:hover {
    background: var(--accent-dim);
}
.cal-hour-cell-dragover {
    background: var(--accent-dim);
    outline: 1px dashed var(--accent);
    outline-offset: -2px;
}
.cal-events-overlay {
    position: absolute;
    top: 0;
    left: 56px;
    right: 0;
    bottom: 0;
    pointer-events: none;
}
.cal-event {
    position: absolute;
    background: rgba(74, 144, 217, 0.22);   /* tinted accent (M365 default) */
    color: var(--text);
    padding: 2px 8px 2px 10px;
    border-left: 3px solid var(--accent);    /* source stripe (M365 default) */
    border-radius: 3px;
    font-size: 14px;
    min-height: 24px;
    overflow: hidden;
    pointer-events: auto;
    cursor: pointer;
    box-sizing: border-box;
}
.cal-event[data-source="google"] {
    background: rgba(45, 214, 107, 0.20);    /* tinted green */
    border-left-color: var(--green);
}
.cal-event-title {
    font-size: 16px;
    font-weight: 600;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cal-event-time {
    font-size: 13px;
    opacity: 0.85;
    margin-top: 2px;
}
.cal-now-line {
    position: absolute;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--red, #e0625e);
    pointer-events: none;
}
.cal-now-line::before {
    content: '';
    position: absolute;
    left: -5px;
    top: -4px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--red, #e0625e);
}

/* =========================================================================
   Grid (Table view)
   ========================================================================= */
.grid-toolbar {
    display: flex;
    gap: 8px;
    margin-bottom: 12px;
    flex-wrap: wrap;
    align-items: center;
}
.grid-search {
    flex: 1;
    min-width: 200px;
    padding: 10px 14px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 16px;
    color-scheme: dark;
}
.grid-search:focus { outline: none; border-color: var(--accent); }
.grid-search::placeholder { color: var(--text-muted); }
.grid-filter-select {
    padding: 10px 12px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 16px;
    color-scheme: dark;
}
.grid-clear-btn {
    padding: 10px 16px;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: 16px;
    cursor: pointer;
}
.grid-clear-btn:hover { color: var(--text); border-color: var(--text-muted); }

/* Batch bar */
.batch-bar {
    display: flex;
    gap: 10px;
    align-items: center;
    padding: 10px 16px;
    background: var(--accent-dim);
    border: 1px solid var(--accent);
    border-radius: var(--radius-sm);
    margin-bottom: 12px;
}
.batch-count {
    font-size: 16px;
    font-weight: 600;
    color: var(--accent);
}
.batch-apply-btn {
    padding: 8px 16px;
    background: var(--accent);
    color: #000;
    border: none;
    border-radius: var(--radius-sm);
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
}
.batch-apply-btn:hover { background: var(--accent-hover); }
.batch-apply-btn:disabled { opacity: 0.4; cursor: default; }

/* Table */
.grid-table-wrap {
    overflow-x: auto;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.grid-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 16px;
    table-layout: fixed;
}
.grid-table thead {
    background: var(--bg);
    position: sticky;
    top: 0;
    z-index: 1;
}
.grid-table th {
    padding: 12px 14px;
    text-align: left;
    font-weight: 600;
    color: var(--text-muted);
    font-size: 14px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
    position: relative;
}
.grid-th-sortable { cursor: pointer; user-select: none; }
.grid-th-sortable:hover { color: var(--text); }
.grid-th-check { width: 40px; text-align: center; }
.grid-th-check input { accent-color: var(--accent); }
.grid-th-cancel { width: 36px; }
.grid-th-done { width: 40px; }
.grid-th-resizable { overflow: hidden; text-overflow: ellipsis; }
.grid-resizer {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    width: 6px;
    cursor: col-resize;
    user-select: none;
    background: transparent;
    transition: background 0.1s;
}
.grid-resizer:hover { background: var(--accent); }

.grid-row {
    transition: background 0.1s;
}
.grid-row:hover { background: var(--bg-elevated); }
.grid-row-selected { background: var(--accent-dim) !important; }

.grid-table td {
    padding: 10px 14px;
    border-bottom: 1px solid rgba(30, 45, 61, 0.4);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.grid-td-check,
.grid-td-cancel,
.grid-td-done {
    text-align: center;
    padding: 8px 4px;
    overflow: visible;
}
.grid-td-check { width: 40px; }
.grid-td-check input { accent-color: var(--accent); }
.grid-td-cancel { width: 36px; }
.grid-td-done { width: 40px; }
.task-cancel-btn,
.task-done-btn {
    display: inline-flex;
    margin: 0 auto;
}
.grid-inline-select {
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 4px 6px;
    font-size: 14px;
    color-scheme: dark;
    max-width: 100%;
}
.grid-inline-select:hover { border-color: var(--accent); }
.grid-inline-select:focus { outline: none; border-color: var(--accent); }
.grid-td-title {
    cursor: pointer;
    color: var(--text);
    max-width: 400px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.grid-td-title:hover { color: var(--accent); }
.grid-td-date { color: var(--text-muted); }
.grid-td-project { color: var(--text-muted); }

.grid-footer {
    padding: 10px 16px;
    color: var(--text-muted);
    font-size: 14px;
}

/* =========================================================================
   Board Toolbar
   ========================================================================= */
.board-toolbar {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-bottom: 12px;
    flex-wrap: wrap;
}
.board-filter-select {
    padding: 8px 12px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 16px;
    color-scheme: dark;
}
.board-filter-count {
    font-size: 14px;
    color: var(--text-muted);
    margin-left: auto;
}
.board-filter-clear {
    padding: 8px 14px;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: 16px;
    cursor: pointer;
}
.board-filter-clear:hover { color: var(--text); border-color: var(--text-muted); }

/* =========================================================================
   Objectives (WBS tree, task #1584)
   ========================================================================= */
.objectives-container {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.objectives-toolbar {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
}
.objectives-add-form {
    display: flex;
    gap: 8px;
    flex: 1;
    min-width: 220px;
}
/* min-width:0 overrides the <input> default intrinsic content width, which
   otherwise refuses to shrink in a flex row and pushes the Add button off
   the mobile viewport (task #1584 render-compare catch). */
.objectives-add-form .grid-search { flex: 1; min-width: 0; }
.objectives-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.objective-card {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.objective-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    cursor: pointer;
}
.objective-header:hover { background: var(--bg-elevated); }
.objective-chevron {
    flex-shrink: 0;
    display: flex;
    color: var(--text-muted);
    transition: transform 0.15s;
}
.objective-chevron-open { transform: rotate(90deg); }
.objective-title {
    flex: 1;
    min-width: 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.objective-progress-track {
    flex-shrink: 0;
    width: 100px;
    height: 6px;
    background: var(--bg-input);
    border-radius: 3px;
    overflow: hidden;
    display: none;
}
.objective-progress-fill {
    display: block;
    height: 100%;
    background: var(--accent);
}
.objective-rollup {
    flex-shrink: 0;
    font-family: var(--mono);
    font-size: 14px;
    color: var(--text-muted);
}
.objective-status-select {
    flex-shrink: 0;
    font-family: inherit;
    font-size: 14px;
    color: var(--text);
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 4px 6px;
    color-scheme: dark;
    cursor: pointer;
}
.objective-body {
    border-top: 1px solid var(--border);
    padding: 8px 0;
}
.objective-loading {
    padding: 16px;
    color: var(--text-muted);
    font-size: 14px;
}
.workstream-group + .workstream-group {
    margin-top: 10px;
}
.workstream-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4px 16px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.workstream-rollup {
    font-family: var(--mono);
    text-transform: none;
    letter-spacing: 0;
}
/* Tree rows reuse .focus-compact-row + .focus-row-* (Home Col-1 pool row
   idiom) -- padding-left is set inline per row for depth-based indent. */
.tree-row-inprogress { background: var(--accent-dim); border-radius: var(--radius-sm); }
.contributes-block {
    margin-top: 10px;
    padding: 8px 16px;
    border-top: 1px dashed var(--border);
}
.contributes-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 6px;
}
.contributes-row {
    padding: 5px 10px;
    margin-bottom: 4px;
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: 14px;
    cursor: pointer;
}
.contributes-row:hover { color: var(--text); border-color: var(--accent); }

@media (min-width: 768px) { /* --bp-md -- room for the progress bar next to title+rollup+status */
    .objective-progress-track { display: block; }
}

/* =========================================================================
   Objectives DnD engine + Home objective lens (task #1610)
   Reuses .focus-compact-row / .workstream-* / .contributes-* (Objectives
   tree idiom, task #1584) for row/header/contributes-box chrome; adds only
   the drag-over states + lens-specific containers those don't already cover.
   ========================================================================= */
.focus-objective-select { max-width: 150px; }

/* Home lens grouped-row density (task #1615): the shared .focus-compact-row
   (min-height 34px) is airier than the locked mockup's 26-29px .trow --
   tighten it here, scoped to .obj-lens only (not the global row, which
   other pixel-locked surfaces already rely on) and to desktop only so the
   mobile touch-target sweep's 44px floor further down this file still wins
   on small screens. */
@media (min-width: 768px) {
    .obj-lens .focus-compact-row {
        padding: 4px 16px;
        min-height: 27px;
    }
    /* The status <select>'s own intrinsic box (padding + border) was still
       driving the row taller than the tightened wrapper allowed -- shrink it
       to match, same desktop-only scope. */
    .obj-lens .focus-row-status-select {
        padding: 1px 6px;
        font-size: 13px;
    }
}

/* "+ new workstream" footer affordance (task #1615) -- same small-caps
   idiom as .workstream-header, muted until hover, flat input on click. */
.ws-add-footer {
    padding: 6px 16px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    cursor: pointer;
}
.ws-add-footer:hover {
    color: var(--accent);
}
.ws-add-row {
    padding: 4px 16px 8px;
}
.ws-add-input {
    width: 100%;
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 6px 12px;
    font-size: 14px;
    color-scheme: dark;
}
.ws-add-input::placeholder {
    color: var(--text-muted);
}
.ws-add-input:focus {
    outline: none;
    border-color: var(--accent);
}

/* Drag-over visuals -- same insertion-line/full-tint language as the wiki
   tree (.wiki-drop-before/after/into), reused here so drag feedback reads
   consistently across every draggable surface in the app. */
.workstream-header-lit {
    background: var(--accent-dim);
}
.workstream-header-lit .workstream-label,
.workstream-header-lit .workstream-rollup {
    color: var(--accent);
}
.focus-compact-row-drop-before {
    box-shadow: inset 0 2px 0 0 var(--accent);
}
.focus-compact-row-drop-after {
    box-shadow: inset 0 -2px 0 0 var(--accent);
}
.focus-compact-row-nest {
    background: var(--accent-dim) !important;
    outline: 1px dashed var(--accent);
    outline-offset: -2px;
}
.focus-row-tid {
    flex-shrink: 0;
    color: var(--text-muted);
    font-family: var(--mono);
    font-size: 12px;
}

.obj-contributes { cursor: default; }
.obj-contributes-lit {
    background: var(--accent-dim);
    outline: 1px dashed var(--accent);
    outline-offset: -2px;
}
.obj-contributes-hint {
    padding: 4px 10px;
    color: var(--text-muted);
    font-size: 13px;
}

.obj-unassigned {
    border-top: 1px solid var(--border);
    background: var(--bg-elevated);
    flex-shrink: 0;
}
.obj-detach-strip {
    margin: 6px 12px 8px;
    padding: 8px 0;
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    text-align: center;
    color: var(--text-muted);
    font-size: 13px;
}
.obj-detach-strip-lit {
    background: var(--accent-dim);
    border-color: var(--accent);
    color: var(--accent);
}

/* Tasks panel objective progress meter (task #1622) -- replaces the removed
   OBJECTIVE strip (#1610/#1615). Slim bar + n/m (pct) row directly under the
   panel header, shown only while an objective is selected. */
.obj-meter {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 16px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.obj-meter-bar {
    flex: 1;
    min-width: 0;
    height: 4px;
    background: var(--bg-input);
    border-radius: 2px;
    overflow: hidden;
}
.obj-meter-bar i {
    display: block;
    height: 100%;
    background: var(--accent);
}
.obj-meter-pct {
    flex-shrink: 0;
    font-family: var(--mono);
    font-size: 13px;
    color: var(--accent);
}

/* Center-column Tasks panel (task #1633) -- the Schedule dropdown's 'Tasks'
   option; a full second instance of the left column's Tasks pool (see
   partials/tasks-panel.php). .focus-col-calendar is already a flex column
   (see .focus-col above); this fills the remaining space alongside the
   (now hidden-in-tasks-mode) .cal-header-2row, so its .focus-col-body child
   gets a bounded height to scroll within, same as the left panel's own
   internal layout. */
.cal-tasks-panel {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

/* =========================================================================
   Scratchpad
   ========================================================================= */
.pad-container {
    height: calc(100vh - 120px);
}
.pad-layout {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: 0;
    height: 100%;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.pad-sidebar {
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.pad-sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.pad-sidebar-title {
    font-size: 16px;
    font-weight: 700;
    color: var(--text);
}
.pad-list {
    flex: 1;
    overflow-y: auto;
}
.pad-list-item {
    padding: 12px 16px;
    cursor: pointer;
    border-bottom: 1px solid rgba(30, 45, 61, 0.4);
    transition: background 0.1s;
}
.pad-list-item:hover { background: var(--bg-elevated); }
.pad-list-active {
    background: var(--accent-dim) !important;
    border-left: 3px solid var(--accent);
}
.pad-list-item-title {
    font-size: 16px;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pad-list-item-meta {
    font-size: 14px;
    color: var(--text-muted);
    margin-top: 2px;
}
.pad-pin-icon {
    color: var(--yellow);
    margin-right: 4px;
}
.pad-editor {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.pad-editor-inner {
    display: flex;
    flex-direction: column;
    height: 100%;
}
.pad-editor-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.pad-title-input {
    flex: 1;
    padding: 6px 10px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 18px;
    font-weight: 700;
    color-scheme: dark;
}
.pad-title-input:focus {
    outline: none;
    border-color: var(--border);
    background: var(--bg);
}
.pad-title-input::placeholder { color: var(--text-muted); }
.pad-delete-btn:hover { color: var(--red) !important; }
.pad-content-input {
    flex: 1;
    padding: 16px 20px;
    background: var(--bg);
    border: none;
    color: var(--text);
    font-size: 16px;
    font-family: var(--mono);
    line-height: 1.6;
    resize: none;
    color-scheme: dark;
}
.pad-content-input:focus { outline: none; }
.pad-content-input::placeholder { color: var(--text-muted); }
.pad-content-nowrap {
    white-space: pre;
    overflow-x: auto;
}
.pad-content-wrapper {
    flex: 1;
    display: flex;
    overflow: hidden;
    min-height: 0;
}
.pad-line-gutter {
    flex-shrink: 0;
    margin: 0;
    padding: 16px 8px 16px 12px;
    text-align: right;
    color: var(--text-muted);
    font-family: var(--mono);
    font-size: 16px;
    line-height: 1.6;
    user-select: none;
    white-space: pre;
    overflow: hidden;
    border-right: 1px solid var(--border);
    min-width: 36px;
    background: var(--bg);
}

/* Filesystem section in scratchpad sidebar */
.pad-fs-section {
    border-top: 1px solid var(--border);
    padding: 12px 0;
    flex-shrink: 0;
}
.pad-fs-unsupported {
    padding: 8px 16px;
    color: var(--text-muted);
    font-size: 14px;
}
.pad-fs-connect {
    width: calc(100% - 24px);
    margin: 0 12px;
    padding: 8px 12px;
    background: transparent;
    color: var(--accent);
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 14px;
    text-align: left;
}
.pad-fs-connect:hover {
    background: var(--bg-elevated);
    border-color: var(--accent);
}
.pad-fs-connected {
    display: flex;
    flex-direction: column;
}
.pad-fs-header {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px 12px 8px;
}
.pad-fs-name {
    flex: 1;
    min-width: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pad-fs-btn {
    padding: 4px;
    border: none;
}
.pad-fs-list {
    max-height: 280px;
    overflow-y: auto;
}
.pad-fs-item {
    padding: 8px 16px;
    font-size: 14px;
}
.pad-fs-icon {
    color: var(--text-muted);
    /* non-interactive chrome -- 13px chrome floor (was 11px, illegible on mobile) */
    font-size: var(--text-chrome);
    font-family: var(--mono);
    margin-right: 6px;
}
.pad-fs-path {
    flex-shrink: 1;
    font-size: 13px;
    color: var(--text-muted);
    font-family: var(--mono);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    max-width: 300px;
}
.icon-btn-active {
    color: var(--accent);
    border-color: var(--accent);
}

/* iOS PWA install hint banner. Pure-JS shown via #ios-install-hint --
   stays out of Alpine to avoid load-order coupling. */
#ios-install-hint {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 14px;
    background: var(--accent);
    color: #000;
    font-size: 14px;
    line-height: 1.4;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}
#ios-install-hint span { flex: 1; min-width: 0; }
#ios-install-hint strong { font-weight: 700; }
#ios-install-hint button {
    flex-shrink: 0;
    background: transparent;
    border: none;
    color: #000;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    padding: 0 4px;
    font-weight: 700;
}
#ios-install-hint button:hover { opacity: 0.7; }

/* =========================================================================
   Wiki Tab
   ========================================================================= */
.wiki-filters {
    display: flex;
    gap: 6px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
}
.wiki-filter-select {
    flex: 0 0 auto;
    min-width: 120px;
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 4px 8px;
    font-size: 14px;
    color-scheme: dark;
}
.wiki-filter-search {
    flex: 1;
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 4px 8px;
    font-size: 14px;
    color-scheme: dark;
}
.wiki-add-project-btn {
    flex-shrink: 0;
    padding: 4px;
}
.wiki-filter-search::placeholder { color: var(--text-muted); }
.wiki-group {
    margin-bottom: 4px;
}
.wiki-group-header {
    padding: 6px 12px 2px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.wiki-type-badge {
    font-size: 13px;
    font-weight: 500;
    margin-right: 4px;
    flex-shrink: 0;
}
.wiki-active-type {
    font-size: 14px;
    font-weight: 600;
    flex-shrink: 0;
}

/* Wiki tree row -- replaces the old grouped pad-list-item layout. Indent is
   inline-style on the element (padding-left = 12 + depth * 16). */
.wiki-row-inner { display: contents; }
.wiki-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 10px 12px;
    cursor: pointer;
    border-bottom: 1px solid rgba(30, 45, 61, 0.3);
    transition: background 0.1s;
    font-size: 16px;
    color: var(--text);
}
.wiki-row:hover { background: var(--bg-elevated); }
.wiki-row-active {
    background: var(--accent-dim) !important;
    border-left: 3px solid var(--accent);
}
.wiki-row-section {
    text-transform: uppercase;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.5px;
    color: var(--text-muted);
}
.wiki-row-section .wiki-row-title { color: var(--text-muted); }
.wiki-row-title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wiki-row-actions {
    display: flex;
    gap: 2px;
    flex-shrink: 0;
    /* default: always visible (touch devices have no hover) */
    transition: opacity 0.15s;
}
@media (hover: hover) and (pointer: fine) {
    /* hover-capable devices only: dim until parent row is hovered */
    .wiki-row-actions { opacity: 0; }
    .wiki-row:hover .wiki-row-actions { opacity: 1; }
}
.wiki-row-act {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 2px;
    display: flex;
    align-items: center;
}
.wiki-row-act:hover { color: var(--accent); }
.wiki-row-act-del:hover { color: var(--red); }

.wiki-section-hint {
    padding: 24px;
    color: var(--text-muted);
    font-size: 16px;
    line-height: 1.5;
}
.wiki-section-hint strong { color: var(--text); }

/* Drag-drop visuals. Insertion line for before/after, full-row tint for
   into/header. Dragged row dims so the drop target stays the visual focus. */
.wiki-row-dragging { opacity: 0.4; }
.wiki-drop-before {
    box-shadow: inset 0 2px 0 0 var(--accent);
}
.wiki-drop-after {
    box-shadow: inset 0 -2px 0 0 var(--accent);
}
.wiki-drop-into {
    background: var(--accent-dim) !important;
    outline: 1px dashed var(--accent);
    outline-offset: -2px;
}
.wiki-group-header.wiki-drop-into {
    background: var(--accent-dim);
    outline: 1px dashed var(--accent);
}

/* =========================================================================
   TFDJS Tab -- Tools For DJs Support intake (operator review surface)
   ========================================================================= */
.tfdjs-container {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 16px 24px 24px;
    min-height: calc(100vh - 120px);
    position: relative;
}

.tfdjs-toolbar {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 12px 16px;
    background: rgba(74, 144, 217, 0.04);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    flex-wrap: wrap;
}
.tfdjs-filter-group { display: flex; align-items: center; gap: 8px; }
.tfdjs-filter-label {
    color: var(--text-muted);
    font-size: 14px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.tfdjs-filter-select {
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 8px 12px;
    font-family: inherit;
    font-size: 15px;
    color-scheme: dark;
    cursor: pointer;
    min-width: 120px;
}
.tfdjs-filter-select:focus { outline: none; border-color: var(--accent); }
.tfdjs-filter-count {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

.tfdjs-split {
    display: grid;
    grid-template-columns: minmax(320px, 420px) 1fr;
    gap: 16px;
    flex: 1;
    min-height: 0;
}

/* --- LIST (left) --- */
.tfdjs-list {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow-y: auto;
    max-height: calc(100vh - 220px);
}
.tfdjs-row {
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
    cursor: pointer;
    transition: background 0.12s;
}
.tfdjs-row:hover { background: rgba(74, 144, 217, 0.05); }
.tfdjs-row.active { background: var(--accent-dim); border-left: 3px solid var(--accent); padding-left: 13px; }
.tfdjs-row-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
    flex-wrap: wrap;
}
.tfdjs-status-pill {
    padding: 3px 10px;
    border-radius: 999px;
    /* interactive status pill -- 16px floor per UI Rules (was 12px) */
    font-size: var(--text-base);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.tfdjs-type-chip {
    padding: 3px 8px;
    border-radius: var(--radius-sm);
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
}
.tfdjs-row-date {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}
.tfdjs-row-subject {
    color: var(--text);
    font-weight: 600;
    font-size: 15px;
    line-height: 1.4;
    margin-bottom: 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.tfdjs-row-meta {
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: var(--text-muted);
    font-size: 13px;
}
.tfdjs-row-source {
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    background: rgba(255,255,255,0.04);
    /* interactive source pill -- 16px floor per UI Rules (was 12px) */
    font-size: var(--text-base);
}

/* --- DETAIL (right) --- */
.tfdjs-detail {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow-y: auto;
    max-height: calc(100vh - 220px);
}
.tfdjs-detail-card {
    padding: 24px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}
.tfdjs-detail-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
}
.tfdjs-detail-subject {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--text);
}
.tfdjs-detail-meta {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px 24px;
    padding: 16px;
    background: rgba(74, 144, 217, 0.04);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}
.tfdjs-detail-meta > div { display: flex; flex-direction: column; gap: 2px; }
.tfdjs-detail-meta dt {
    color: var(--text-muted);
    /* non-interactive label -- 13px chrome floor (was 12px) */
    font-size: var(--text-chrome);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.tfdjs-detail-meta dd { color: var(--text); font-size: 15px; }
.tfdjs-detail-meta code {
    font-family: var(--mono);
    font-size: 14px;
    color: var(--accent);
}

.tfdjs-status-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}
.tfdjs-status-label {
    color: var(--text-muted);
    font-size: 14px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-right: 4px;
}
.tfdjs-status-btn {
    padding: 6px 12px;
    border-radius: var(--radius-sm);
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.12s;
}
.tfdjs-status-btn:hover { border-color: var(--accent); color: var(--text); }
.tfdjs-status-btn.active { font-weight: 700; }

/* Distinct from --purple (already the waiting_user status color) so a
   ticket that is both waiting_user AND triaged doesn't show two
   same-color badges in the same row/header. */
.tfdjs-triage-chip {
    padding: 3px 8px;
    border-radius: var(--radius-sm);
    background: rgba(45, 217, 196, 0.14);
    color: #2dd9c4;
    font-size: var(--text-base);
    font-weight: 700;
}
.tfdjs-triage-block {
    background: rgba(45, 217, 196, 0.06);
    border: 1px solid rgba(45, 217, 196, 0.35);
    border-radius: var(--radius-sm);
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.tfdjs-triage-header {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.tfdjs-triage-badge {
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(45, 217, 196, 0.2);
    color: #2dd9c4;
    font-size: var(--text-chrome);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.tfdjs-triage-timestamp {
    color: var(--text-muted);
    font-size: var(--text-chrome);
}
.tfdjs-triage-content {
    color: var(--text);
    font-size: 15px;
    line-height: 1.6;
}
.tfdjs-triage-content p { margin: 0 0 8px 0; }
.tfdjs-triage-content p:last-child { margin-bottom: 0; }
.tfdjs-triage-content ul { margin: 0 0 8px 20px; padding: 0; }
.tfdjs-triage-content li { margin-bottom: 4px; }
.tfdjs-triage-content strong { color: var(--text); font-weight: 700; }
.tfdjs-triage-content code {
    font-family: var(--mono);
    font-size: 14px;
    background: rgba(255, 255, 255, 0.06);
    padding: 1px 5px;
    border-radius: var(--radius-xs);
    color: var(--accent-hover);
}

.tfdjs-detail-body {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 16px;
    color: var(--text);
    font-size: 15px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-wrap: break-word;
}

.tfdjs-thread {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.tfdjs-thread-title {
    color: var(--text-muted);
    font-size: 14px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.tfdjs-reply {
    padding: 12px 16px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
}
.tfdjs-reply-outbound { background: var(--accent-dim); border-color: var(--accent); }
.tfdjs-reply-inbound  { background: rgba(255,255,255,0.02); }
.tfdjs-reply-head {
    display: flex;
    justify-content: space-between;
    margin-bottom: 8px;
    font-size: 13px;
    color: var(--text-muted);
}
.tfdjs-reply-direction { font-weight: 700; }
.tfdjs-reply-body { color: var(--text); font-size: 14px; line-height: 1.5; white-space: pre-wrap; }

.tfdjs-reply-compose {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}
.tfdjs-reply-label {
    color: var(--text-muted);
    font-size: 14px;
    font-weight: 600;
}
.tfdjs-reply-label code {
    color: var(--accent);
    font-family: var(--mono);
    font-size: 13px;
}
.tfdjs-reply-textarea {
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 12px;
    font-family: inherit;
    font-size: 15px;
    line-height: 1.5;
    resize: vertical;
    min-height: 100px;
    color-scheme: dark;
}
.tfdjs-reply-textarea:focus { outline: none; border-color: var(--accent); }
.tfdjs-reply-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.tfdjs-reply-hint { color: var(--text-muted); font-size: 13px; }

.tfdjs-empty {
    padding: 32px 16px;
    color: var(--text-muted);
    text-align: center;
    font-size: 15px;
}
.tfdjs-empty-center {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 200px;
}

.tfdjs-toast {
    position: fixed;
    bottom: 24px;
    right: 24px;
    padding: 12px 20px;
    border-radius: var(--radius);
    background: var(--bg);
    border: 1px solid var(--accent);
    color: var(--text);
    font-size: 15px;
    font-weight: 600;
    z-index: 1000;
    box-shadow: 0 4px 16px rgba(0,0,0,0.5);
}
.tfdjs-toast-success { border-color: var(--green); color: var(--green); }
.tfdjs-toast-error { border-color: var(--red); color: var(--red); }

/* =========================================================================
   Responsive
   ========================================================================= */
@media (max-width: 768px) {
    .top-bar { padding: 0 12px; }
    .nav-tab { padding: 12px 10px; font-size: 14px; }
    .main-content { padding: 16px; }
    .modal-dialog { max-width: 100%; }
    .field-row { flex-direction: column; }
    .toast-container { left: 12px; right: 12px; bottom: 12px; max-width: none; }
    /* Pad/Wiki: release the desktop height-lock so the page scrolls on mobile.
       The lock + overflow:hidden otherwise traps the list + editor in a
       viewport-height box -- the scratchpad list was crushed to ~200px (one
       visible item) with a dead editor filling the rest. Wiki re-specifies its
       own sidebar/editor-sheet rules in the --bp-md wiki block below. */
    .pad-container { height: auto; }
    .pad-layout { grid-template-columns: 1fr; grid-template-rows: auto auto; }
    .pad-sidebar { border-right: none; border-bottom: 1px solid var(--border); max-height: 50vh; }
    .pad-container:not(.wiki-tab) .pad-editor { min-height: 55vh; }
    .tfdjs-split { grid-template-columns: 1fr; }
    .tfdjs-list, .tfdjs-detail { max-height: none; }
    .tfdjs-toolbar { gap: 12px; }
}

/* =========================================================================
   Books Tab -- double-entry accounting
   ========================================================================= */
.books-container { display: flex; flex-direction: column; gap: 18px; }

.books-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border);
}
.books-toolbar-group { display: flex; align-items: center; gap: 10px; }
.books-label {
    font-size: 14px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.books-select, .books-input {
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 9px 12px;
    font-size: 16px;
    font-family: var(--font);
    color-scheme: dark;
}
.books-select:focus, .books-input:focus { outline: none; border-color: var(--accent); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }

.btn-danger { background: var(--red); color: #000; }
.btn-danger:hover { filter: brightness(1.1); }

.books-editor {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
    background: var(--bg);
}
.books-editor-title { font-size: 18px; font-weight: 600; margin-bottom: 16px; }
.books-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px;
}
.books-form-grid label {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 14px;
    color: var(--text-muted);
}
.books-form-wide { grid-column: 1 / -1; }
.books-check {
    flex-direction: row !important;
    align-items: center;
    gap: 8px !important;
    font-size: 16px !important;
    color: var(--text) !important;
}
.books-check input { width: 18px; height: 18px; accent-color: var(--accent); }
.books-editor-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 18px;
}
.books-spacer { flex: 1; }

.books-coa-title { font-size: 20px; font-weight: 700; }
.books-coa { display: flex; flex-direction: column; gap: 22px; }
.books-empty {
    padding: 40px;
    text-align: center;
    color: var(--text-muted);
    font-size: 16px;
}
.books-group { display: flex; flex-direction: column; }
.books-group-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 2px solid var(--border);
    margin-bottom: 2px;
}
.books-group-name {
    font-size: 17px;
    font-weight: 700;
    color: var(--text);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.books-group-count { font-size: 14px; color: var(--text-muted); }
.books-acct-row {
    display: grid;
    grid-template-columns: 90px 260px 1fr auto;
    align-items: center;
    gap: 16px;
    padding: 11px 12px;
    border-bottom: 1px solid var(--border);
    cursor: pointer;
    transition: background 0.12s;
}
.books-acct-row:hover { background: rgba(74, 144, 217, 0.06); }
.books-acct-row.inactive { opacity: 0.45; }
.books-acct-code {
    font-family: var(--mono);
    font-size: 15px;
    color: var(--accent);
}
.books-acct-name { font-size: 16px; color: var(--text); font-weight: 600; }
.books-acct-desc { font-size: 15px; color: var(--text-muted); }
.books-acct-inactive {
    font-size: 13px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.books-toast {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    padding: 12px 22px;
    border-radius: var(--radius-sm);
    font-size: 15px;
    font-weight: 600;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    color: var(--text);
    z-index: 200;
}
.books-toast-success { border-color: var(--green); color: var(--green); }
.books-toast-error { border-color: var(--red); color: var(--red); }
.books-toast-info { border-color: var(--accent); color: var(--accent); }

@media (max-width: 768px) {
    .books-toolbar { gap: 12px; }
    .books-acct-row { grid-template-columns: 64px 1fr auto; gap: 10px; }
    .books-acct-desc { display: none; }
}

/* =========================================================================
   Books Tab -- Phase 2 (transactions / journal)
   ========================================================================= */
.books-subnav {
    display: inline-flex;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
}
.books-subnav-btn {
    padding: 9px 16px;
    font-size: 15px;
    font-weight: 600;
    background: var(--bg);
    color: var(--text-muted);
    border: none;
    cursor: pointer;
}
.books-subnav-btn:hover { color: var(--text); }
.books-subnav-btn.active { background: var(--accent); color: #000; }

.books-entry-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 4px;
}

.books-mode-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}
.books-mode-tab {
    padding: 8px 16px;
    font-size: 15px;
    font-weight: 600;
    background: var(--bg);
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.books-mode-tab:hover { color: var(--text); border-color: var(--text-muted); }
.books-mode-tab.active { background: var(--accent-dim); color: var(--accent); border-color: var(--accent); }

.books-lines { display: flex; flex-direction: column; gap: 8px; }
.books-lines-head,
.books-line-row {
    display: grid;
    grid-template-columns: 1fr 160px 160px 40px;
    gap: 12px;
    align-items: center;
}
.books-lines-head {
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    padding: 0 2px;
}
.books-line-remove {
    width: 34px;
    height: 34px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--bg);
    color: var(--text-muted);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}
.books-line-remove:hover:not(:disabled) { color: var(--red); border-color: var(--red); }
.books-line-remove:disabled { opacity: 0.3; cursor: not-allowed; }
.books-add-line { align-self: flex-start; margin-top: 4px; }

.books-balance {
    display: flex;
    gap: 24px;
    align-items: center;
    margin-top: 12px;
    padding: 12px 16px;
    border-radius: var(--radius-sm);
    font-size: 16px;
    border: 1px solid var(--border);
}
.books-balance strong { font-family: var(--mono); margin-left: 6px; }
.books-balance-flag {
    margin-left: auto;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 14px;
}
.books-balance.balanced { border-color: var(--green); }
.books-balance.balanced .books-balance-flag { color: var(--green); }
.books-balance.unbalanced { border-color: var(--orange); }
.books-balance.unbalanced .books-balance-flag { color: var(--orange); }

.books-journal { display: flex; flex-direction: column; gap: 10px; }
.books-entry {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.books-entry-head {
    display: grid;
    grid-template-columns: 120px 1fr auto auto;
    gap: 16px;
    align-items: center;
    padding: 12px 16px;
    cursor: pointer;
    transition: background 0.12s;
}
.books-entry-head:hover { background: rgba(74, 144, 217, 0.06); }
.books-entry-date { font-family: var(--mono); font-size: 15px; color: var(--text-muted); }
.books-entry-memo { font-size: 16px; font-weight: 600; color: var(--text); }
.books-entry-src {
    /* non-interactive chrome badge -- 13px chrome floor (was 12px) */
    font-size: var(--text-chrome);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 2px 8px;
}
.books-entry-total {
    font-family: var(--mono);
    font-size: 17px;
    font-weight: 700;
    color: var(--text);
}
.books-entry-lines {
    border-top: 1px solid var(--border);
    padding: 6px 16px 10px;
}
.books-entry-line {
    display: grid;
    grid-template-columns: 1fr 140px 140px;
    gap: 12px;
    padding: 5px 0;
    font-size: 15px;
}
.books-entry-acct { color: var(--text); }
.books-entry-debit,
.books-entry-credit {
    font-family: var(--mono);
    text-align: right;
    color: var(--text);
}

@media (max-width: 768px) {
    .books-lines-head, .books-line-row { grid-template-columns: 1fr 90px 90px 36px; gap: 8px; }
    .books-entry-head { grid-template-columns: 80px 1fr auto; }
    .books-entry-src { display: none; }
    .books-entry-line { grid-template-columns: 1fr 90px 90px; }
}

/* =========================================================================
   Books Tab -- Phase 3 (reports)
   ========================================================================= */
.books-report-controls {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 16px;
    align-items: flex-end;
}
.books-rt-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
.books-report-dates { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.books-report-dates label {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 14px;
    color: var(--text-muted);
}

.books-report {
    margin-top: 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 24px 28px;
    max-width: 760px;
}
.books-report-title { font-size: 22px; font-weight: 700; }
.books-report-period {
    font-size: 15px;
    color: var(--text-muted);
    margin: 2px 0 18px;
}

.books-statement { display: flex; flex-direction: column; }
.books-stmt-section {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    margin-top: 16px;
    padding-bottom: 4px;
}
.books-stmt-section:first-child { margin-top: 0; }
.books-stmt-row {
    display: flex;
    justify-content: space-between;
    gap: 24px;
    padding: 6px 0;
    font-size: 16px;
}
.books-stmt-row > span:last-child { font-family: var(--mono); }
.books-stmt-row > span:first-child { color: var(--text); }
.books-stmt-subtotal {
    border-top: 1px solid var(--border);
    font-weight: 600;
}
.books-stmt-total {
    border-top: 2px solid var(--border);
    font-weight: 700;
    font-size: 17px;
    margin-top: 2px;
}
.books-stmt-grand {
    border-top: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    font-weight: 800;
    font-size: 18px;
    margin-top: 8px;
    color: var(--accent);
}
.books-stmt-grand > span:last-child { color: var(--accent); }

.books-tb { display: flex; flex-direction: column; }
.books-tb-head,
.books-tb-row {
    display: grid;
    grid-template-columns: 1fr 140px 140px;
    gap: 16px;
    padding: 7px 0;
    font-size: 16px;
}
.books-tb-head {
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
}
.books-tb-head span:not(:first-child),
.books-tb-row span:not(:first-child) {
    text-align: right;
    font-family: var(--mono);
}
.books-tb-row { border-bottom: 1px solid var(--border); }
.books-tb-total {
    border-bottom: none;
    border-top: 2px solid var(--border);
    font-weight: 700;
}
.books-ledger-row { grid-template-columns: 110px 1fr 120px 120px 130px; }
/* The ledger's second column is the memo -- keep it left-aligned, body font. */
.books-ledger-row span:nth-child(2) {
    text-align: left;
    font-family: var(--font);
}

.books-report-flag {
    margin-top: 16px;
    display: inline-block;
    padding: 6px 14px;
    border-radius: var(--radius-sm);
    font-size: 14px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.books-report-flag.ok { color: var(--green); border: 1px solid var(--green); }
.books-report-flag.bad { color: var(--red); border: 1px solid var(--red); }

@media (max-width: 768px) {
    .books-ledger-row { grid-template-columns: 64px 1fr 80px 80px 90px; gap: 8px; }
    .books-tb-head, .books-tb-row { grid-template-columns: 1fr 90px 90px; }
    .books-report { padding: 18px; }
}

/* =========================================================================
   Books Tab -- Phase 4 (PDF export via the browser print path)
   ========================================================================= */
.books-print-actions { margin-top: 4px; }
.books-print-header { display: none; }

@media print {
    @page { size: landscape; margin: 1.4cm; }
    html, body { background: #fff !important; }
    body { color: #000 !important; }

    /* Print only the active report -- hide every piece of app chrome. */
    .top-bar, .books-toolbar, .books-report-controls, .books-print-actions,
    .quick-add-bar, .toast-container, .books-toast,
    #ios-install-hint { display: none !important; }
    .main-content { padding: 0 !important; }

    /* Document header -- the business name above the statement. */
    .books-print-header {
        display: block !important;
        font-size: 24px;
        font-weight: 700;
        color: #000 !important;
        margin-bottom: 6px;
    }

    /* The report becomes a plain black-on-white document. */
    .books-report {
        border: none !important;
        max-width: none !important;
        margin: 0 !important;
        padding: 0 !important;
    }
    .books-report-title { color: #000 !important; }
    .books-report-period { color: #555 !important; }
    .books-stmt-section { color: #555 !important; }
    .books-stmt-row, .books-stmt-row > span,
    .books-tb-head, .books-tb-head span,
    .books-tb-row, .books-tb-row span { color: #000 !important; }
    .books-stmt-subtotal { border-color: #999 !important; }
    .books-stmt-total { border-color: #000 !important; }
    .books-stmt-grand { border-color: #000 !important; }
    .books-stmt-grand, .books-stmt-grand > span { color: #000 !important; }
    .books-tb-head { border-color: #000 !important; }
    .books-tb-row { border-color: #ccc !important; }
    .books-tb-total { border-color: #000 !important; }
    .books-report-flag { color: #000 !important; border-color: #000 !important; }
}

/* =========================================================================
   MOBILE DESIGN FRAMEWORK -- Phase 2 (Chrome)
   ---
   docs/dev/MOBILE_DESIGN_FRAMEWORK.md sections 4.2 (breakpoints), 4.6
   (navigation pattern). New components below; mobile-only overrides of
   legacy desktop-chrome at the bottom of this block.

   Breakpoints (mobile-first, min-width only):
     --bp-sm: 480px, --bp-md: 768px, --bp-lg: 1024px, --bp-xl: 1280px
   ========================================================================= */

/* ---- Top bar: safe-area-inset (notch / Dynamic Island) ----------------- */
.top-bar {
    padding-top: var(--safe-top);
    padding-left: calc(var(--space-5) + var(--safe-left));
    padding-right: calc(var(--space-5) + var(--safe-right));
    /* Original top-bar padding was `0 20px`; safe-area variants resolve
       to 0px on devices without a notch, so desktop is byte-identical. */
}

/* ---- Mobile Bottom Tab Bar -------------------------------------------- */
/* Five primary tabs + "More". Hidden at >=768px. */
.bottom-tabs {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: var(--z-bottomnav);
    display: flex;
    align-items: stretch;
    background: var(--bg-elevated);
    border-top: 1px solid var(--border);
    padding-left: var(--safe-left);
    padding-right: var(--safe-right);
    padding-bottom: var(--safe-bottom);
}
.bottom-tab {
    flex: 1 1 0;
    min-height: var(--touch-min);
    padding: var(--space-2) var(--space-1);
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    border-top: 2px solid transparent;
    transition: color 0.15s, border-color 0.15s;
}
.bottom-tab.active {
    color: var(--accent);
    border-top-color: var(--accent);
}
.bottom-tab-more { /* same shape; styling hook for future icon swap */ }

/* ---- Mobile Floating Action Button (Quick Add) ------------------------ */
.mobile-fab {
    position: fixed;
    right: calc(var(--space-4) + var(--safe-right));
    /* sit above the bottom-tab bar (~56px nominal + safe-area) */
    bottom: calc(var(--space-4) + 56px + var(--safe-bottom));
    z-index: var(--z-fab);
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--accent);
    color: #000;
    border: none;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.5),
                0 0 0 1px var(--border) inset;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, transform 0.08s ease-out;
}
.mobile-fab:hover { background: var(--accent-hover); }
.mobile-fab:active { transform: scale(0.94); }

/* ---- Mobile Overflow Drawer (right-side, secondary tabs) -------------- */
.overflow-drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: var(--z-drawer);
}
.overflow-drawer {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: min(80vw, 320px);
    z-index: calc(var(--z-drawer) + 1);
    background: var(--bg-sheet);
    border-left: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    padding-top: var(--safe-top);
    padding-right: var(--safe-right);
    padding-bottom: var(--safe-bottom);
    transform: translateX(100%);
    transition: transform 0.2s ease-out;
    /* hidden by default; .open below slides it in */
    visibility: hidden;
}
.overflow-drawer.open {
    transform: translateX(0);
    visibility: visible;
}
.overflow-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-4) var(--space-5);
    border-bottom: 1px solid var(--border);
}
.overflow-drawer-title {
    font-size: var(--text-xl);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text);
}
.overflow-drawer-list {
    display: flex;
    flex-direction: column;
    padding: var(--space-2) 0;
}
.overflow-drawer-item {
    display: block;
    width: 100%;
    text-align: left;
    min-height: var(--touch-min);
    padding: var(--space-3) var(--space-5);
    background: transparent;
    border: none;
    color: var(--text);
    font-size: var(--text-base);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    border-left: 3px solid transparent;
}
.overflow-drawer-item:hover { background: var(--tap-feedback); }
.overflow-drawer-item.active {
    color: var(--accent);
    border-left-color: var(--accent);
}
.overflow-drawer-item-secondary {
    color: var(--text-muted);
    font-weight: 500;
    margin-top: auto;        /* push to bottom of drawer-list flow */
}

/* ========================================================================
   Mobile-only overrides (visible only at <768px)
   ========================================================================
   The legacy desktop chrome stays visible at >=768px (these rules turn
   it off below the breakpoint) and the mobile chrome above stays
   visible at <768px (these rules turn it off at >=768px).
   ======================================================================== */

/* Default = mobile: hide top-bar nav-tabs, add bottom padding to
   main-content so the bottom-tab + FAB don't cover the last row of
   content. */
.nav-tabs { display: none; }
.main-content {
    /* enough room to clear the bottom-tab bar (~56px) + a buffer */
    padding-bottom: calc(72px + var(--safe-bottom));
}

@media (min-width: 768px) { /* --bp-md -- desktop chrome takes over */
    .nav-tabs { display: flex; }
    .bottom-tabs { display: none; }
    .mobile-fab { display: none; }
    .overflow-drawer,
    .overflow-drawer-backdrop { display: none; }
    .main-content {
        /* restore the original 24px padding from the desktop block */
        padding-bottom: var(--space-6);
    }
}

/* ---- Quick Add bar -- mobile slide-up sheet, desktop top slide-down --- */
/* Default (mobile): slide-up sheet pinned above the bottom-tab bar. */
.quick-add-bar {
    position: fixed;
    left: 0; right: 0;
    bottom: calc(56px + var(--safe-bottom));     /* sit above bottom-tab */
    z-index: var(--z-sheet);
    background: var(--bg-sheet);
    border-top: 1px solid var(--border);
    border-bottom: none;
    padding: var(--space-3) calc(var(--space-4) + var(--safe-left))
             var(--space-3) calc(var(--space-4) + var(--safe-right));
    box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.5);
}
.quick-add-form {
    /* on mobile, stack the form so the input has room before the buttons */
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
    max-width: none;
    margin: 0;
}
.quick-add-input,
.quick-add-select,
.quick-add-btn {
    min-height: var(--touch-min);
}

@media (min-width: 768px) { /* --bp-md -- legacy top-bar slide-down */
    .quick-add-bar {
        position: static;
        background: var(--bg-surface);
        border-top: none;
        border-bottom: 1px solid var(--border);
        padding: var(--space-3) var(--space-5);
        box-shadow: none;
    }
    .quick-add-form {
        flex-direction: row;
        align-items: center;
        gap: var(--space-2);
        max-width: 900px;
        margin: 0 auto;
    }
}

/* =========================================================================
   MOBILE DESIGN FRAMEWORK -- Phase 3 (Surfaces)
   ---
   docs/dev/MOBILE_DESIGN_FRAMEWORK.md sections 4.4 (touch targets),
   4.5 (hover-only gate), 4.7 (modal -> sheet pattern).

   The hover-only gates for .board-card-actions, .wiki-row-actions, and
   .focus-toggle-btn are applied inline at their definitions earlier in
   this file (in the @media (hover: hover) and (pointer: fine) blocks).
   This block carries the modal-to-sheet conversion and the
   touch-target sweep, both as mobile-only overrides.
   ========================================================================= */

/* ---- Modal -> bottom-sheet at <640px ----------------------------------- */
/* Targets the existing .modal-overlay/.modal-dialog (task detail) and
   .cal-modal-backdrop/.cal-modal (calendar event) without renaming. The
   sheet behavior is achieved by anchoring the overlay to the bottom edge,
   stretching the dialog to full width, squaring its bottom corners, and
   padding for the home-indicator safe area. At >=640px the original
   centered-card rules at the modal definitions above take effect. */
@media (max-width: 639.98px) {
    /* Task detail modal */
    .modal-overlay {
        align-items: flex-end;
        padding: 0;
    }
    .modal-dialog {
        max-width: 100%;
        max-height: calc(100dvh - var(--space-10));
        border-radius: var(--radius) var(--radius) 0 0;
        border-bottom: none;
        padding-bottom: var(--safe-bottom);
    }

    /* Calendar event modal */
    .cal-modal-backdrop {
        align-items: flex-end;
        padding: 0;
    }
    .cal-modal {
        max-width: 100%;
        max-height: calc(100dvh - var(--space-10));
        border-radius: var(--radius) var(--radius) 0 0;
        border-bottom: none;
        padding-bottom: var(--safe-bottom);
    }
}

/* ---- Touch-target sweep (mobile only) ---------------------------------- */
/* The design doc offers two patterns: pseudo-element hit-area extension
   (preserves the compact visual) and container-grow (visually chunkier
   buttons). For dense action rows like .focus-compact-row, pseudo-element
   extension would cause overlapping hit areas between adjacent icons,
   producing wrong-button taps. So container-grow is used instead --
   the SVG icon visual stays the same size; only the button container
   expands to 44x44. This is gated to <768px so desktop keeps its
   compact, dense look. */
@media (max-width: 767.98px) {
    .icon-btn,
    .task-done-btn, .task-cancel-btn,
    .focus-row-done, .focus-row-move, .focus-row-remove,
    .rock-card-x,
    .wiki-row-act,
    .cal-today-btn, .cal-nav-btn {
        min-width: var(--touch-min);
        min-height: var(--touch-min);
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* Tappable rows -- expand row height to 44px floor */
    .focus-compact-row,
    .task-row,
    .family-event-row,
    .board-card {
        min-height: var(--touch-min);
    }
}

/* ---- Home compact rows + headers -- mobile readability (task #1051) ----- */
/* On a phone the Tasks-pool compact rows put the title in a flex:1 cell next
   to a ~140px inline status/project <select> and 3-4 44px touch-target buttons
   (dot + title + status-select + move/done/remove). Together those exceed the
   row width, so the title collapsed to a single ellipsised character ("T.").
   Wrap the row: the title claims the first line and the controls flow onto a
   second line. Scoped to .focus-pool-row (pool / objective-lens / unassigned-
   tray rows -- the crowded ones) only. The curated top Focus column
   (.focus-compact-row with no .focus-pool-row marker) has fewer controls
   (title + project-select + done + remove) and reverted to the base
   single-row ellipsis-truncate layout in task #1790 -- wrapping wasted
   vertical space there without the crowding this rule exists to fix. Headers
   get the wrap treatment too so the quick-add input is full-width and
   typeable instead of a squeezed sliver, and the Schedule date shows in full
   instead of clipping. */
@media (max-width: 767.98px) {
    .focus-pool-row {
        flex-wrap: wrap;
        row-gap: 4px;
    }
    .focus-pool-row .focus-row-title {
        flex: 1 1 auto;
        min-width: 65%;        /* keep dot + title on line 1; force controls below */
        white-space: normal;   /* show the full title, not a one-char ellipsis */
        padding: 2px 0;
    }

    /* task #1790's mobile-only 64px project-select cap (freeing title width
       from the desktop 140px control) is obsolete as of task #1800: the
       select's value text is now hidden at every width and its base width
       is a fixed 22px chevron-only hit area, already narrower than 64px. */

    .focus-col-header {
        flex-wrap: wrap;
        row-gap: 6px;
    }
    .focus-header-form {
        flex-basis: 100%;      /* quick-add drops to its own full-width line */
        order: 10;
    }
    .schedule-today-date {
        flex-basis: 100%;      /* date shows in full instead of clipping */
        order: 10;
        margin-left: 0;
        white-space: normal;
        overflow: visible;
    }

    /* Schedule: tighten the loose vertical rhythm between day groups. */
    .schedule-day-group { margin-bottom: 6px; }
    .schedule-event-row { padding: 5px 4px; }
}

/* =========================================================================
   MOBILE DESIGN FRAMEWORK -- Phase 4 (Tabs)
   ---
   docs/dev/MOBILE_DESIGN_FRAMEWORK.md section 4.8.

   Per-tab mobile layouts. Mobile is the base case; desktop is a
   progressive enhancement via min-width media queries. The legacy
   @media (max-width: 768px) blocks above remain for tabs that are
   already handled correctly (Pad, TFDJS, Books -- see the audit).

   Tabs NOT fully reworked in this phase (acceptance-checklist items
   for the implementation follow-up to convert as needed):
     - Tasks-Grid card-stack (kept as horizontal-scroll table; the
       Phase 3 touch-target sweep already enlarged the row hit areas)
     - Board collapsible status sections (kept as vertical stack
       without collapse state; requires app() data hook)
     - Wiki detail-as-sheet (Phase 3 already removed the hover-only
       blocker; detail-sheet flow requires JS changes)
     - TFDJS push-navigation (Phase 2 inherits the legacy 768px
       split-to-stack at @media :2474; push-nav requires JS)
   These are CSS-only-feasible portions; full HTML/JS restructure
   for the dropped items lives in a Phase 4.5 follow-up if wanted.
   ========================================================================= */

/* ---- Home tab -- mobile-first responsive grid (task #1451) ------------- */
/* Collapse model:
     >=1200px  3 columns 35/30/35, viewport-locked (panes scroll internally,
               no page scroll). The design's native width.
     <1200     single-column stack, natural page scroll, reading order
               Col1(toggle panel -> Tasks) -> Calendar -> Notes/Detail.
   The Calendar pane carries a ~24h intrinsic height. Below the locked width
   the grid rows are auto-sized, so without a cap the calendar balloons and
   shoves the rest off-screen. It is capped in the page-scroll width so its
   internal grid scrolls; at the locked width the cap is released so it fills
   its grid cell and scrolls there. */
.home-grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    grid-template-areas:
        "col1"
        "cal"
        "ctx";
}
.focus-container {
    height: auto;
    overflow: visible;
}
/* Page-scroll width (<1200): bound the calendar so it scrolls internally
   instead of dictating the row height. Released to auto at >=1200. Col 1's
   top panel is capped so a long Focus/In-Focus list scrolls internally
   rather than pushing the Tasks pool far down the page. */
.focus-col-calendar { height: 520px; }
.focus-col-top { max-height: 60vh; }

@media (min-width: 1200px) { /* 3-column, viewport-locked -- the native layout */
    .home-grid {
        grid-template-columns: 35fr 35fr 30fr;
        grid-template-rows: 1fr;
        grid-template-areas: "col1 cal ctx";
    }
    .focus-container {
        height: calc(100vh - 120px);
        overflow: hidden;
    }
    .focus-col-calendar { height: auto; }
    .home-col1 { height: 100%; }
    /* Col 1 fixed 33/67 split (task #1631, supersedes #1456's 50/50): Focus
       1 : Tasks 2 -- measured from John's drawn target line 2026-07-14; the
       objective lens lives in Tasks and needs the height. Both still scroll
       internally past their share. */
    .focus-col-top { flex: 1 1 0; min-height: 0; max-height: none; }
    .home-col1-bot { flex: 2 1 0; min-height: 0; }
}

/* ---- Board tab -- vertical stack on mobile ----------------------------- */
/* Base (mobile): vertical stack of collapsible status sections. Each column
   gets full width; the page scrolls vertically. No horizontal scroll. The
   header is a 44px tap-target that toggles the body; the chevron echoes the
   collapsed state. State persists per-status in localStorage via boardTab(). */
.board-columns {
    flex-direction: column;
    overflow-x: visible;
    overflow-y: visible;
}
.board-column {
    min-width: 0;
    max-width: none;
    /* let body grow to its content; no inner overflow on mobile */
}
.board-col-header {
    cursor: pointer;
    min-height: 44px;
}
.board-col-chevron {
    font-size: 16px;
    color: var(--text-muted);
    width: 14px;
    flex-shrink: 0;
}
.board-col-body {
    overflow-y: visible;
}
.board-col-collapsed .board-col-body {
    display: none;
}

@media (min-width: 768px) { /* --bp-md -- restore desktop kanban */
    .board-container {
        height: calc(100vh - 120px);
        overflow: hidden;
    }
    .board-columns {
        flex-direction: row;
        overflow-x: auto;
        overflow-y: hidden;
    }
    .board-column {
        min-width: 240px;
        max-width: 320px;
    }
    .board-col-header {
        cursor: default;
        min-height: 0;
    }
    .board-col-chevron {
        display: none;
    }
    .board-col-body {
        overflow-y: auto;
    }
    /* Desktop ignores the collapse flag -- side-by-side kanban needs all
       columns visible at once. */
    .board-col-collapsed .board-col-body {
        display: block;
    }
}

/* ---- TFDJS tab -- push-navigation on mobile --------------------------- */
/* Base (mobile): only one of list/detail is visible at a time; .tfdjs-split
   carries .tfdjs-mobile-list or .tfdjs-mobile-detail (driven by
   tfdjsTab.mobileView). Tapping a row flips to detail; the back chevron
   flips back. Desktop (>=768px) ignores the toggle -- the split renders
   both panes side-by-side as before. */
.tfdjs-back-btn {
    display: none;
}
@media (max-width: 767.98px) {
    .tfdjs-split.tfdjs-mobile-list  .tfdjs-detail { display: none; }
    .tfdjs-split.tfdjs-mobile-detail .tfdjs-list  { display: none; }
    .tfdjs-split.tfdjs-mobile-detail .tfdjs-detail {
        animation: tfdjs-slide-in 0.2s ease-out;
    }
    .tfdjs-split.tfdjs-mobile-list .tfdjs-list {
        animation: tfdjs-slide-back 0.18s ease-out;
    }
    .tfdjs-back-btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 44px;
        min-height: 44px;
        flex-shrink: 0;
    }
}
@keyframes tfdjs-slide-in {
    from { transform: translateX(8%);  opacity: 0.4; }
    to   { transform: translateX(0);   opacity: 1; }
}
@keyframes tfdjs-slide-back {
    from { transform: translateX(-6%); opacity: 0.6; }
    to   { transform: translateX(0);   opacity: 1; }
}

/* ---- Wiki tab -- detail-as-sheet on mobile ---------------------------- */
/* Base (mobile): sidebar takes full height; the editor only renders when a
   row is open, and renders as a fixed bottom-sheet overlay. The .wiki-tab
   selector scopes this to wiki -- scratchpad shares .pad-editor markup but
   never carries .pad-editor-open, so it is unaffected. */
.pad-back-btn {
    display: none;
}
@media (max-width: 767.98px) {
    .wiki-tab .pad-layout {
        grid-template-rows: 1fr;
        grid-template-columns: 1fr;
    }
    .wiki-tab .pad-sidebar {
        max-height: none;
        border-bottom: none;
    }
    /* The Wiki editor pane is hidden by default; promoted to a fixed sheet
       overlay when wikiTab.activeId stamps .pad-editor-open. */
    .wiki-tab .pad-editor {
        display: none;
    }
    .wiki-tab .pad-editor.pad-editor-open {
        display: flex;
        position: fixed;
        inset: 0;
        z-index: 60;
        background: var(--bg);
        flex-direction: column;
        padding-top: var(--safe-top, 0);
        padding-bottom: var(--safe-bottom, 0);
        animation: wiki-sheet-in 0.18s ease-out;
    }
    .wiki-tab .pad-back-btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 44px;
        min-height: 44px;
        flex-shrink: 0;
    }
}
@keyframes wiki-sheet-in {
    from { transform: translateY(8%); opacity: 0.6; }
    to   { transform: translateY(0);   opacity: 1; }
}

/* ---- Wiki mobile drill-down (OneNote-style, task #1060) --------------- */
/* Desktop renders the indented tree (.pad-list) under the sidebar header.
   The drill-down nav bar + level list are mobile-only: at <768px the tree,
   the sidebar header, and the project-jump dropdown are hidden, and the
   drill surface takes over (the search box stays). */
.wiki-mobile-nav,
.wiki-drill {
    display: none;
}
@media (max-width: 767.98px) {
    .wiki-tab .pad-sidebar-header,
    .wiki-tab .pad-list,
    .wiki-tab .wiki-filter-select,
    .wiki-tab .wiki-add-project-btn {
        display: none;
    }
    .wiki-tab .wiki-mobile-nav { display: flex; }
    .wiki-tab .wiki-drill { display: block; }
}
.wiki-mobile-nav {
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.wiki-mobile-title {
    flex: 1;
    min-width: 0;
    font-size: 18px;
    font-weight: 700;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wiki-drill-back,
.wiki-drill-add { flex-shrink: 0; }
.wiki-drill-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 12px;
    min-height: 52px;
    border-bottom: 1px solid var(--border-soft);
    cursor: pointer;
}
.wiki-drill-row:active { background: var(--bg-elevated); }
.wiki-drill-title {
    flex: 1;
    min-width: 0;
    font-size: 16px;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wiki-drill-count {
    flex-shrink: 0;
    font-size: 14px;
    color: var(--text-muted);
    background: var(--bg-elevated);
    border-radius: 10px;
    padding: 2px 8px;
}
.wiki-drill-chevron {
    flex-shrink: 0;
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
}
.wiki-drill-chevron:active { color: var(--accent); }

/* ---- Tasks (Grid) tab -- card stack on mobile ------------------------- */
/* Base (mobile): hide the 7-column table; render the cards + sort dropdown.
   At >= 1024px the table comes back and the cards/sort are hidden -- the
   table layout does not reshape via CSS alone (different markup, different
   ergonomics), so the two views are alternates rendered into the same
   x-data scope. */
.grid-mobile-sort {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--border);
}
.grid-mobile-sort-label {
    font-size: 14px;
    color: var(--text-muted);
    flex-shrink: 0;
}
.grid-mobile-sort .grid-filter-select {
    flex: 1;
    min-width: 0;
}
.grid-cards {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px 12px;
}
.grid-card {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.grid-card-selected {
    border-color: var(--accent);
    background: var(--accent-dim);
}
.grid-card-head {
    display: flex;
    align-items: flex-start;
    gap: 8px;
}
.grid-card-check {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-top: 2px;
}
.grid-card-title {
    flex: 1;
    min-width: 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--text);
    cursor: pointer;
    word-break: break-word;
}
.grid-card-due {
    font-size: 14px;
    color: var(--text-muted);
    white-space: nowrap;
    flex-shrink: 0;
}
.grid-card-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.grid-chip {
    font-size: 13px;
    padding: 2px 8px;
    border-radius: 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-muted);
    line-height: 1.4;
}
.grid-chip-status {
    text-transform: capitalize;
}
.grid-chip-status[data-status="in_progress"] { color: var(--yellow); border-color: var(--yellow); }
.grid-chip-status[data-status="almost_done"] { color: var(--orange); border-color: var(--orange); }
.grid-chip-status[data-status="next"]        { color: var(--accent); border-color: var(--accent); }
.grid-chip-status[data-status="waiting"]     { color: var(--purple); border-color: var(--purple); }
.grid-chip-status[data-status="backlog"]     { color: var(--text-muted); }
.grid-chip-type { color: var(--text); }
.grid-card-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}
.grid-card-act {
    min-height: 44px;
    min-width: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.grid-card-empty {
    padding: 32px 16px;
    text-align: center;
    color: var(--text-muted);
    font-size: 14px;
}

/* Desktop reverts the toggle: table comes back, cards + sort go away. */
@media (min-width: 1024px) {
    .grid-mobile-sort,
    .grid-cards {
        display: none;
    }
}
/* Mobile + tablet hide the table -- cards are the only renderer below 1024px. */
@media (max-width: 1023.98px) {
    .grid-table-wrap {
        display: none;
    }
}

/* ---- Calendar tab -- compact gutter on mobile -------------------------- */
/* Base (mobile): 40px hour-label gutter (down from 56px), shorter rows. */
.cal-hour-label {
    width: 52px;
    padding: 2px 6px;
    font-size: var(--text-chrome);
}
.cal-events-overlay {
    left: 52px;
}
.cal-hour-row {
    height: 36px;
}

@media (min-width: 768px) { /* --bp-md -- restore desktop calendar */
    .cal-hour-label {
        width: 56px;
        padding: 2px 8px;
    }
    .cal-events-overlay {
        left: 56px;
    }
    .cal-hour-row {
        height: 40px;
    }
}

/* ---- Books + TFDJS -- tighten auto-fit minimum on mobile --------------- */
/* The two auto-fit minmax(220px, 1fr) grids in the codebase (Books form
   grid + TFDJS detail meta) try to keep min 220px per cell. On a 375px
   viewport minus padding that leaves room for one cell only, but the
   minmax can still force horizontal overflow when min-content exceeds
   220px (long account names, long meta values). Drop the floor to a
   single 1fr column on mobile so the grid always fits the viewport. */
.books-form-grid,
.tfdjs-detail-meta {
    grid-template-columns: 1fr;
}

@media (min-width: 768px) { /* --bp-md -- restore auto-fit */
    .books-form-grid,
    .tfdjs-detail-meta {
        grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    }
}
