/*
 * Wider content area on large screens. Bootstrap's default .container caps at
 * 1140-1320px, which was too narrow for the app's wide data tables.
 */
@media (min-width: 1200px) {
    .container {
        max-width: 1600px;
    }
}

/*
 * Reserve page-level vertical scrollbar space up front, in browsers that
 * support it. Without this, a page whose content grows just past viewport
 * height suddenly needs an outer scrollbar that some browsers/OSes draw as
 * an overlay on top of content near the right edge instead of reserving
 * space for it -- clipping whatever sits there (see .table-scroll-pane
 * below for the same problem, one level in).
 */
html {
    scrollbar-gutter: stable;
}

/*
 * Data tables: don't wrap short columns (dates, amounts, statuses) just
 * because the table as a whole is wide — scroll horizontally instead (see
 * .table-responsive on each table). Free-text columns keep their own
 * truncate-with-tooltip wrapper, which isn't affected by this.
 */
.table td,
.table th {
    white-space: nowrap;
}

/* Slightly denser text on tables opted into Bootstrap's .table-sm padding. */
.table-sm {
    font-size: 0.875rem;
}

/*
 * Bounded-height, both-axis scrolling table with a frozen header — for
 * tables too tall to fit on screen even after pagination (e.g. Actual
 * Transactions, Expected Transactions). Keeps the horizontal scrollbar
 * reachable at the bottom of a viewport-sized box instead of after however
 * many rows the page has, and keeps column headers visible while scrolling
 * down within that box. thead's `top` offset per row is set by public/js/
 * app.js (stackStickyTheadRows()), not hardcoded here, since a table with a
 * filter row below its header row needs that row pinned below the header's
 * own height, not at the same top:0. .action-menu's panel is `position:
 * fixed` (below) specifically so it is safe to use inside this even though
 * overflow:auto would otherwise clip an absolutely-positioned one.
 */
.table-scroll-pane {
    max-height: 70vh;
    overflow: auto;
    /* scrollbar-gutter reserves real space in Chrome/Firefox. Safari does
       not support scrollbar-gutter at all, and its overlay scrollbar
       (macOS default) draws on top of content right at this pane's true
       edge -- confirmed clipping the last column in testing. Styling
       ::-webkit-scrollbar below is the fix for that: defining it makes
       WebKit switch this element from "overlay" to a classic, always-
       space-reserving scrollbar at exactly the width declared, instead of
       floating on top of content. */
    scrollbar-gutter: stable;
}
.table-scroll-pane::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}
.table-scroll-pane::-webkit-scrollbar-track {
    background: transparent;
}
.table-scroll-pane::-webkit-scrollbar-thumb {
    background-color: rgba(0, 0, 0, .25);
    border-radius: 6px;
}
.table-scroll-pane::-webkit-scrollbar-thumb:hover {
    background-color: rgba(0, 0, 0, .4);
}
.table-scroll-pane table {
    margin-bottom: 0;
}
.table-scroll-pane thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background-color: #fff;
}

/*
 * A second, top-anchored horizontal scrollbar for a .table-scroll-pane
 * table that is both wide and tall -- without it, reaching the pane's own
 * (bottom) scrollbar to scroll sideways means scrolling all the way down
 * first. public/js/app.js sizes the inner spacer div to the table's actual
 * content width, pins this element's own width to the pane's real
 * (currently-measured) one, and mirrors scrollLeft between this and the
 * pane below it. Purely a scrollbar-shaped affordance -- 1px tall, nothing
 * visible inside. No scrollbar-gutter here -- deliberately: it was an
 * attempt to reserve space matching the pane's real vertical scrollbar
 * without measuring it, and was never guaranteed to reserve the exact same
 * amount (the pane's own scrollbar is customized via ::-webkit-scrollbar
 * below); app.js now pins the width directly instead.
 */
.table-scroll-top {
    overflow-x: auto;
    overflow-y: hidden;
}
.table-scroll-top > div {
    height: 1px;
}

/*
 * Shared "..." row-action dropdown, used on every list page.
 */
.action-menu {
    position: relative;
    display: inline-block;
}
/*
 * Fixed, not absolute -- so the panel is never clipped by a .table-scroll-pane
 * (or any other overflow:auto) ancestor. Its top/right are meaningless until
 * public/js/app.js computes them from the trigger button's own position; the
 * far-off-screen default here is just so nothing flashes at 0,0 before that
 * first runs. Opens/closes via the .show class (click-driven, see app.js) --
 * not :hover/:focus-within, which broke as soon as this became fixed-
 * positioned: any gap between "over the button" and "over the (now
 * possibly-relocated) panel" loses hover and closes it before it is reachable.
 */
.action-menu-panel {
    display: none;
    position: fixed;
    top: -9999px;
    right: -9999px;
    z-index: 20;
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: .375rem;
    box-shadow: 0 .25rem .5rem rgba(0, 0, 0, .1);
    padding: .25rem;
    min-width: 10rem;
}
.action-menu-panel.show {
    display: block;
}
.action-menu-panel a,
.action-menu-panel button {
    display: block;
    width: 100%;
    text-align: left;
    padding: .25rem .5rem;
    border: 0;
    background: none;
    font-size: .875rem;
    text-decoration: none;
    color: #212529;
    border-radius: .25rem;
    white-space: nowrap;
}
.action-menu-panel a:hover,
.action-menu-panel button:hover {
    background: #f8f9fa;
}

/*
 * Dashboard widget drag-and-drop reordering (Edit mode only,
 * app/Views/home/index.php) -- same dragging-opacity convention as the
 * accounts list's own tr.dragging (accounts/index.php has its own copy of
 * this rule scoped to <tr>; this one is scoped to the widget wrapper divs).
 */
[data-widget-id] {
    cursor: move;
}
[data-widget-id].dragging {
    opacity: .4;
}

/*
 * Account provider icons (App\Support\AccountProviderIcon) -- fixed size
 * everywhere they appear (Account providers list, Accounts list, dashboard
 * "Provision accounts"/"Last statement loaded per account" widgets) so a
 * provider's real icon and the generic fallback glyph line up identically.
 */
.provider-icon-img,
.provider-icon-fallback {
    width: 20px;
    height: 20px;
    margin-right: .4rem;
    vertical-align: -.35em;
}
.provider-icon-img {
    object-fit: contain;
}
.provider-icon-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    color: #6c757d;
}

/*
 * Expected-transaction calendar (BM-010 §4, app/Views/calendar/index.php,
 * public/js/calendar.js). A continuous, scrollable run of Monday-first week
 * rows -- weeks are added above/below as the user scrolls, not one month at
 * a time, so month boundaries are marked by a tinted background on every
 * other month instead of separate month grids.
 */
.cal {
    border: 1px solid #dee2e6;
    border-radius: .375rem;
    background: #fff;
}
.cal-weekdays,
.cal-week {
    display: grid;
    grid-template-columns: 2.2rem repeat(7, minmax(0, 1fr));
}
.cal-weekdays {
    border-bottom: 1px solid #dee2e6;
    font-size: .85rem;
    color: #495057;
    text-align: right;
}
.cal-weekdays > div {
    padding: .35rem .5rem;
}
.cal-weekend {
    background: rgba(0, 0, 0, .03);
}
.cal-scroll {
    height: calc(100vh - 260px);
    min-height: 360px;
    overflow-y: auto;
    position: relative;
}
.cal-week {
    min-height: 7.5rem;
    border-bottom: 1px solid #e9ecef;
}
.cal-weeknum {
    font-size: .7rem;
    color: #adb5bd;
    padding: .25rem 0 0 .3rem;
}
.cal-day {
    border-left: 1px solid #e9ecef;
    padding: .2rem .3rem;
    min-width: 0;
    cursor: pointer;
}
.cal-day.cal-month-odd {
    background: #f8f9fa;
}
.cal-day.cal-weekend {
    background: rgba(0, 0, 0, .035);
}
.cal-day.cal-month-odd.cal-weekend {
    background: rgba(0, 0, 0, .05);
}
.cal-day.cal-today .cal-daynum span {
    background: #0d6efd;
    color: #fff;
    border-radius: 999px;
    padding: 0 .4rem;
}
.cal-daynum {
    text-align: right;
    font-size: .85rem;
    color: #212529;
    margin-bottom: .15rem;
}
.cal-daynum-first {
    font-weight: 600;
}
.cal-chip {
    display: block;
    font-size: .72rem;
    line-height: 1.25rem;
    padding: 0 .35rem;
    margin-bottom: 2px;
    border-radius: .2rem;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    text-decoration: none;
}
.cal-chip-expense {
    background: #f8d7da;
    color: #842029;
}
.cal-chip-revenue {
    background: #d1e7dd;
    color: #0f5132;
}
.cal-chip:hover {
    filter: brightness(.95);
}
/*
 * A matched actual transaction (BM-010 §9): the same hue as its expected
 * counterpart but solid, with a check mark -- distinguishable without relying
 * on colour alone.
 */
.cal-chip-actual::before {
    content: "\2713\00a0";
}
.cal-chip-actual.cal-chip-expense {
    background: #dc3545;
    color: #fff;
}
.cal-chip-actual.cal-chip-revenue {
    background: #198754;
    color: #fff;
}
.cal-more {
    font-size: .7rem;
    color: #6c757d;
    padding: 0 .35rem;
}

/*
 * Narrow screens (BM-010 §4.3): a chip collapses to a small coloured dot
 * (its text hidden), and tapping the day opens that day's list -- which is
 * also what makes room for a future icon (§4.4) instead of a label.
 */
@media (max-width: 575.98px) {
    .cal-week {
        grid-template-columns: 1.4rem repeat(7, minmax(0, 1fr));
        min-height: 4.5rem;
    }
    .cal-weekdays {
        grid-template-columns: 1.4rem repeat(7, minmax(0, 1fr));
        font-size: .7rem;
    }
    .cal-weekdays > div {
        padding: .3rem .15rem;
    }
    .cal-chip {
        display: inline-block;
        width: .6rem;
        height: .6rem;
        line-height: 0;
        padding: 0;
        margin: 0 2px 2px 0;
        border-radius: 50%;
        text-indent: -9999px;
    }
    /* Expected = hollow ring, matched actual = solid dot. */
    .cal-chip {
        box-sizing: border-box;
        border: 2px solid transparent;
    }
    .cal-chip::before {
        content: none !important;
    }
    .cal-chip-expense {
        background: transparent;
        border-color: #dc3545;
    }
    .cal-chip-revenue {
        background: transparent;
        border-color: #198754;
    }
    .cal-chip-actual.cal-chip-expense {
        background: #dc3545;
    }
    .cal-chip-actual.cal-chip-revenue {
        background: #198754;
    }
    .cal-more {
        display: none;
    }
}
