/* ─────────────────────────────────────────────────────────────────────────────
   LISTS
   The one responsive list system every table uses, plus tabs and modals.

   Part 3 of 11, cut from the 5,142-line app.css. THE ORDER OF THESE
   FILES IS LOAD-BEARING — they are one cascade, split for navigation only, and
   index.php links them in this sequence. Moving one changes which rule wins.
   ───────────────────────────────────────────────────────────────────────────── */
/* ════════════════════════════════════════════════════════════════════════════════
   GLOBAL RESPONSIVE LIST — THE single control for every list's responsive behaviour
   (ledger / income / expense / clients / team / documents / recent-activity; the
   project table mirrors the same tiers with its own pj-* classes). One PRIMARY text
   column anchors the row and TRUNCATES smartly (ellipsis, full text on hover);
   SECONDARY columns drop in staggered tiers (md ≤1240 · lg ≤1100 · sm ≤680) and a
   sub-line carries their text. js/table.js only ASSIGNS the classes — all behaviour
   lives here. To retune a breakpoint or the truncation, edit this block only.
   ════════════════════════════════════════════════════════════════════════════════ */
/* Truncation mechanic — fixed layout (same as the project table): the PRIMARY column
   is a wide flexible share, every cell truncates with an ellipsis. So the title is
   prominent and shows in full when there's room, and ellipsises when the row narrows;
   the secondary columns drop in tiers (below), handing their width back to the title. */
.list-card table { table-layout: fixed; }
.list-card thead th, .list-card tbody td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* COLUMN WIDTHS (project-table principle): the PRIMARY title is the flexible anchor —
   width:auto, it ABSORBS all slack and truncates; every other column has a COMPACT
   fixed width by role, so on resize the secondary columns stay tidy and the title
   grows into the freed space (no ballooning date/figure columns with dead gaps). */
.list-card th.lst-primary, .list-card td.lst-primary { width: auto; min-width: 160px; }
.list-card .lst-col-date { width: 132px; }   /* the date is usually the first cell (carries the 24px card inset) — keep room for a full YYYY-MM-DD */
/* Date cells follow the Recent Activity date treatment — a calm MUTED, tabular
   timestamp (not ink), so the title/figures lead. Applied to every list view. */
.list-card tbody td.lst-col-date { color: var(--text-muted); font-size: 13px; font-variant-numeric: tabular-nums; }
/* FIGURES GET THE WIDTH THE FIGURES ACTUALLY NEED. At 124px this column held 92px of
   content after its padding, and "HKD 118,776.98" measures 120 — so nine of twenty rows
   on a stretch year ellipsised, and an amount that reads "HKD 118,7…" is not a number,
   it is a rumour. Sized to the widest figure these books can produce: the largest single
   posting across all four scenarios is 1,542,100.00, and at tabular-nums a seven-figure
   amount with decimals measures 133px, so 133 + 32 padding + headroom. */
.list-card .lst-col-fig  { width: 168px; }
.list-card .lst-col-meta { width: 144px; }
/* NARROW tag column — badges / one-word values (Type · Team · Status). Half the meta
   width so the crowded ledger hands that space back to Description / Category instead
   of leaving dead gaps around short cells. */
.list-card .lst-col-tag  { width: 104px; }
.list-card thead th:last-child, .list-card tbody td:last-child { width: 52px; }   /* single three-dot overflow menu */
/* The action cell holds a 32px icon button, not text — it must NOT clip (the global
   .list-card td overflow:hidden would crop the three-dot button at the row's end).
   overflow:visible mirrors the project table's .pj-c-act so the menu sits cleanly. */
.lst-act { display: flex; align-items: center; justify-content: flex-end; gap: 8px; white-space: nowrap; overflow: visible; }
.list-card thead th:last-child, .list-card tbody td.lst-act { overflow: visible; }
/* INLINE document CTA (Bill Phase / Receive Payment) — surfaced in the row instead of
   buried in the three-dot menu. A compact pill that sits left of the overflow button. */
.lst-cta { padding: 7px 14px; font-size: 12.5px; font-weight: var(--fw-semibold); border-radius: var(--radius-sm); white-space: nowrap; gap: 5px; }
.lst-cta .material-icons { font-size: 16px; }
/* DOCUMENT list — explicit column widths (order: Type · Doc ID · Date · Amount · Status ·
   Action) so the inline CTA (Bill Phase / Receive Payment) + the menu never overflow into
   the Status, and the Status never truncates. Doc ID (col 2) stays the flexible anchor. */
#table-project-docs th:nth-child(1), #table-project-docs td:nth-child(1) { width: 90px; }    /* Type */
#table-project-docs th:nth-child(3), #table-project-docs td:nth-child(3) { width: 126px; }   /* Date Issued */
#table-project-docs th:nth-child(4), #table-project-docs td:nth-child(4) { width: 168px; }   /* Amount — same seven-figure sizing as .lst-col-fig */
#table-project-docs th:nth-child(5), #table-project-docs td:nth-child(5) { width: 154px; }   /* Status */
#table-project-docs thead th:last-child, #table-project-docs tbody td:last-child { width: 224px; }  /* Action: CTA + menu */
/* PRIMARY cell typography — the row's title, matched to the project list's .pj-tbl-name
   (14px semibold ink) so every list shares the same title hierarchy over its sub-line. */
.lst-primary-text { display: block; min-width: 0; font-size: 14px; font-weight: var(--fw-semibold); color: var(--text-main); letter-spacing: 0.02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lst-sub { display: none; font-size: 12px; color: var(--text-muted); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 1240px) { .lst-hide-md { display: none; } }
@media (max-width: 1100px) {
    .lst-hide-lg { display: none; }
    .lst-sub { display: block; }
}
@media (max-width: 680px) { .lst-hide-sm { display: none; } }
/* Load-More — a sibling BELOW the table (not a colspan row, which would resurrect the
   hidden columns under table-layout:fixed). Centered, calm. */
.lst-more { display: flex; justify-content: center; padding: 22px 0 6px; }
/* Row hover — a calm scanning aid, matching the project list's interaction. */
.list-card tbody tr:hover td { background: var(--bg-hover); }

/* ════════════════════════════════════════════════════════════════════════════════
   HEADLINE TAB SWITCHER (.seg-tabs) — sits where the page title was on the merged
   Transactions (All · Income · Expense) and People (Clients · Team) pages. Plain
   underline tabs at the title's scale: active = ink + underline, the rest muted.
   (NOT the pill toggle — the brief asks for an underlined active headline.)
   ════════════════════════════════════════════════════════════════════════════════ */
.seg-tabs { display: inline-flex; align-items: baseline; gap: 22px; flex-wrap: wrap; }
.seg-tab {
    border: none; background: none; padding: 0 1px 5px; cursor: pointer; font-family: inherit;
    font-size: var(--text-xl); font-weight: var(--fw-bold); letter-spacing: var(--tracking-display);
    line-height: var(--leading-tight); color: var(--text-muted); opacity: 0.5;
    border-bottom: 2.5px solid transparent;
    transition: color 0.16s ease, opacity 0.16s ease, border-color 0.16s ease;
}
.seg-tab:hover { opacity: 0.85; color: var(--text-main); }
.seg-tab.active { color: var(--text-main); opacity: 1; border-bottom-color: var(--text-main); }
@media (max-width: 680px) { .seg-tab { font-size: 26px; } .seg-tabs { gap: 16px; } }

/* The merged pages toggle their tab bodies; only the active one shows. */
.tx-pane.hidden { display: none; }

/* SETTINGS nav = icon only (the gear), still a normal nav pill cell. */
.top-nav-link.top-nav-icon { display: inline-flex; align-items: center; justify-content: center; }
.top-nav-link.top-nav-icon .material-icons { font-size: 19px; line-height: 1; }

/* Sortable header — a fixed-width caret slot so toggling the sort NEVER reflows the
   header (no jump). Inactive = faint unfold_more; active = ink up/down arrow. */
.th-sortable { cursor: pointer; }
.th-cell { display: inline-flex; align-items: center; gap: 5px; vertical-align: middle; }
th.text-right .th-cell { flex-direction: row-reverse; }   /* number right, caret to its left */
.th-caret { font-size: 13px; line-height: 1; width: 14px; flex: 0 0 14px; text-align: center; color: var(--text-muted); opacity: 0.32; transition: opacity 0.15s ease, color 0.15s ease; }
.th-caret.is-active { opacity: 1; color: var(--text-main); }
.th-sortable:hover .th-caret { opacity: 0.7; }

tr:hover td {
    background-color: var(--bg-hover);
}

.table-actions {
    display: flex;
    gap: 6px;
    justify-content: flex-end;
}

.action-btn {
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6px;
    border-radius: var(--radius-sm);
    transition: 0.2s;
}

.action-btn:hover {
    background: var(--divider);
    color: var(--text-main);
}

.table-link {
    color: var(--text-main);
    text-decoration: none;
    font-weight: var(--font-bold);
    transition: 0.2s;
    border-bottom: 1px solid transparent;
}

.table-link:hover {
    border-color: var(--text-main);
}

/* DOCUMENT REFERENCE LINK — a quote/invoice/receipt number handle: ink tabular
   figures, UNDERLINE only (no trailing glyph), left-aligned as normal inline text.
   Used globally wherever a doc reference renders (ledger refs, doc IDs). */
.table-link-mono {
    color: var(--text-main); text-align: left;
    font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums; letter-spacing: 0.01em;
    text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px;
    text-decoration-color: var(--divider-strong);
    transition: color 0.16s ease, text-decoration-color 0.16s ease;
}
.table-link-mono:hover { color: var(--theme-text, var(--text-main)); text-decoration-color: currentColor; }

.tabs-container {
    display: inline-flex;
    background: var(--bg-main);
    padding: 6px;
    border-radius: var(--radius-lg);
    border: 1px solid var(--divider);
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.05);
    gap: 8px;
    align-items: center;
}

.tab-btn {
    padding: 10px 24px;
    border-radius: var(--radius-md);
    border: none;
    font-size: 14px;
    font-weight: 600;
    transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
    margin: 0;
    cursor: pointer;
}

.tab-active {
    background: var(--bg-card);
    color: var(--text-main);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

html[data-theme='light'] .tab-active {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.tab-inactive {
    background: transparent;
    color: var(--text-muted);
}

.tab-inactive:hover {
    color: var(--text-main);
    background: var(--active-theme-bg);
}

.dropdown {
    position: relative;
    display: inline-block;
}

.dropdown-content {
    display: none;
    position: absolute;
    right: 0;
    min-width: 140px;
    z-index: 1000;
    border-radius: var(--radius-sm);
    padding: var(--space-1);
    /* glass material supplied by the unified .liquid-surface group below */
}

.dropdown-content a {
    color: var(--text-main);
    padding: var(--space-2) var(--space-3);
    text-decoration: none;
    display: block;
    font-size: var(--text-base);
    font-weight: var(--font-bold);
    border-radius: var(--radius-sm);
    transition: 0.2s;
}

.dropdown-content a:hover {
    background-color: var(--bg-hover);
    color: var(--text-main);
}

.dropdown:hover .dropdown-content {
    display: block;
}

/* ROW OVERFLOW MENU — three-dot button + a fixed-positioned popover (opened by
   window.toggleRowMenu, which escapes any ancestor overflow clipping). Reuses the
   .dropdown-content glass styling. */
.row-menu { display: inline-block; position: relative; }
.row-menu-btn { width: 32px; height: 32px; opacity: 0.55; transition: opacity 0.15s ease, background 0.15s ease; }
.row-menu-btn .material-icons { font-size: 18px; }
tr:hover .row-menu-btn,
.row-menu:hover .row-menu-btn,
.row-menu-open .row-menu-btn { opacity: 1; }

.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(8, 8, 11, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    /* flat: plain dim scrim, no frosted-glass refraction */
}

/* Modal — liquid glass; material comes from the unified .liquid-surface
   group below. Layout only here. */
.modal-card {
    position: relative;
    width: 100%;
    max-width: 480px;
    padding: 32px 40px;
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
    max-height: 90vh;
}

.modal-card.transaction-modal {
    max-width: 680px;
}

.modal-card-large {
    max-width: 840px;
    width: 90%;
    padding: 40px;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 24px;
    padding-bottom: 16px;
}

.modal-header h3 {
    margin: 0;
    font-weight: var(--fw-bold);
    font-size: 22px;
    letter-spacing: -0.01em;
}

.close-btn {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    padding: 4px;
    cursor: pointer;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: 0.2s ease;
}

.close-btn:hover {
    color: var(--text-main);
    transform: rotate(90deg);
}

.form-grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin-bottom: 16px;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 16px;
}

/* Inside a 2-col grid the grid's own gap handles spacing — no per-field margin
   (replaces the inline style="margin-bottom: 0;" that was on every gridded field). */
.form-grid-2 > .form-group { margin-bottom: 0; }

.form-label {
    font-size: 11px;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: var(--fw-medium);
    letter-spacing: var(--tracking-caps);
}

.pill-group {
    position: relative;          /* anchors the sliding .pill-glider */
    display: flex;
    background: var(--bg-main);
    padding: 4px;
    border-radius: var(--radius-pill);
    gap: 2px;
}

/* segmented option pill — chassis comes from the SHARED RECIPES filter-pill
   group (end of file); the ink-inverted active is only the no-JS fallback:
   with the glider running (.has-glider) the glass capsule carries the pill
   and the active item keeps ink TEXT on a transparent fill (main-view style) */
.btn-pill {
    position: relative;          /* sit above the glider */
    z-index: 1;
    flex: 1;
    padding: 8px 12px;
    background: transparent;
    color: var(--text-muted);
    font-size: 13px;
    text-align: center;
}

.btn-pill:hover {
    color: var(--text-main);
}

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

input[type="number"] {
    -moz-appearance: textfield;
}

.amount-wrapper {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
}

/* currency code = quiet caption beside the hero figure (figure-unit pattern);
   .cur-code lets the display-currency sweep relabel it */
.amount-currency {
    font-size: 13px;
    color: var(--text-muted);
    position: absolute;
    left: 0;
    font-weight: var(--fw-semibold);
    letter-spacing: var(--tracking-caps);
    text-transform: uppercase;
}

.input-amount-huge {
    font-size: 48px;
    font-weight: var(--fw-bold);
    color: var(--text-main);
    background: transparent;
    border: none;
    border-bottom: 2px solid var(--divider-strong);
    border-radius: 0;
    padding: 8px 0;
    margin-bottom: 8px;
    text-align: center;
    box-shadow: none;
    width: 100%;
    font-variant-numeric: tabular-nums;
    font-family: var(--font-sans);
}

.input-amount-huge:focus {
    outline: none;
    border-bottom-color: var(--theme-color);
}

.modal-input {
    width: 100%;
    padding: 14px 16px;
    margin-bottom: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-size: var(--text-base);
    font-family: inherit;
    font-weight: var(--fw-semibold);   /* a filled-in value is DATA — 600 like every data value */
    background: var(--bg-main);
    color: var(--text-main);
    transition: all 0.2s;
    appearance: none;
}

.modal-input::placeholder, .modal-input-lg::placeholder {
    color: var(--text-muted);
    font-weight: var(--fw-medium);     /* prompts sit back like labels */
}

/* Inside the modal card, radius = affordance — unchanged as an idea, but the
   value moves from --radius-pill to the control primitive. These rules reached
   for a 999px capsule back when --radius-sm was 8px and a true pill was the only
   way to say "control"; --radius-control now says it at 18px. On a 44px field
   the two are within 4px of each other, and the capped value is the better one:
   the textarea below no longer needs a special case to avoid bulging, so all
   three fields are one geometry instead of two. */
.modal-card .modal-input, .modal-card .modal-input-lg { border-radius: var(--radius-sm); padding: 13px 22px; }
.modal-card textarea.modal-input { border-radius: var(--radius-sm); }
.modal-card .btn { border-radius: var(--radius-sm); }   /* buttons follow — AI card actions, Record, Remove… */

/* Focus = "a 1px ring REPLACES the fill" (the reference's exact wording): the
   resting grey fill lifts to paper and a single hairline ring appears. The old
   4px halo was a glow, which is a different idea — it added a soft mass around
   the field instead of drawing its edge. One token, both themes. */
.modal-input:focus {
    outline: none;
    background: var(--bg-card);
    border-color: var(--theme-color);
    box-shadow: var(--ring-focus);
}

.modal-input-lg {
    width: 100%;
    padding: 16px 20px;
    margin-bottom: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-size: 17px;                   /* name tier (.pj-name): 17px / 600 */
    font-family: inherit;
    font-weight: var(--fw-semibold);
    background: var(--bg-main);
    color: var(--text-main);
    transition: all 0.2s;
    appearance: none;
}

.modal-input-lg:focus {
    outline: none;
    background: var(--bg-card);
    border-color: var(--theme-color);
    box-shadow: var(--ring-focus);
}

select.modal-input,
select.modal-input-lg {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A1A1AA' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 16px;
    padding-right: 40px;
    cursor: pointer;
}

#modal-form-body {
    overflow-y: auto;
    flex: 1;
    margin-bottom: var(--space-4);
    padding-right: var(--space-2);
}

#modal-form-body::-webkit-scrollbar {
    width: 4px;
}

#modal-form-body::-webkit-scrollbar-thumb {
    background: var(--divider-strong);
    border-radius: 4px;
}

/* The full-width save button is the clearest case for the CAPPED pill: at 999px
   and 54px tall it drew a 27px lozenge, a different corner from every other
   button on the same screen. 18px holds. Size and tracking join the ladder too —
   one button size, and body tracking at zero. */
.btn-save-full {
    border-radius: var(--radius-sm) !important;
    padding: 16px 24px !important;
    font-size: var(--text-base) !important;
    font-weight: var(--font-bold) !important;
    margin-top: 16px;
    width: 100%;
    letter-spacing: var(--tracking-normal);
}
