/* Global styles — Bootstrap 5.3's data-bs-theme already handles most dark-mode work. */

body {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* Navbar logo — crisp edges at small sizes, slight dark-mode brighten so
   the mark stays legible on the tertiary-bg navbar. */
.navbar-logo {
    object-fit: contain;
    image-rendering: -webkit-optimize-contrast;
}
[data-bs-theme="dark"] .navbar-logo {
    /* Dark linework on dark nav → invert so the mark stays legible. */
    filter: invert(1) brightness(0.95);
}

main {
    flex: 1;
}

/* Skip-to-content link — visible only when focused. Keyboard users hit Tab
   once on page load and get a jump link to the main content. */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0.5rem;
    z-index: 10000;
    padding: 0.5rem 1rem;
    background: var(--bs-primary);
    color: #fff;
    text-decoration: none;
    border-radius: 0.25rem;
}
.skip-link:focus {
    left: 0.5rem;
}

/* Stronger focus ring that works on both themes. Bootstrap's default is
   per-component; this adds a consistent fallback for anything interactive. */
:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
    border-radius: 2px;
}

.calculator-card {
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    color: inherit;
}

.calculator-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--bs-box-shadow);
}

/* Make Chart.js canvases honour theme. */
[data-bs-theme="dark"] canvas {
    filter: brightness(0.95);
}

/* Reserve vertical space for Chart.js canvases so the chart.js library
   instantiating late doesn't push content down (Lighthouse CLS win). */
canvas {
    max-width: 100%;
    min-height: 240px;
}

/* Permalink copy-button affordance */
.copy-flash {
    transition: background-color 0.3s ease;
}
.copy-flash.flashed {
    background-color: var(--bs-success-bg-subtle);
}

/* -----------------------------------------------------------------------
   Hover-or-click dropdown (custom, replaces Bootstrap's data-bs-toggle).
   - On hover-capable devices: CSS shows the menu on hover/focus.
   - On touch devices: JS in app.js toggles an .open class on first tap.
   No more internal state conflict between CSS hover and Bootstrap clicks.
   ----------------------------------------------------------------------- */

[data-hover-dropdown] > .dropdown-menu {
    margin-top: 0;
}

/* Touch / JS-driven: .open class is added by app.js on tap. */
[data-hover-dropdown].open > .dropdown-menu {
    display: block;
}

@media (hover: hover) and (pointer: fine) {
    [data-hover-dropdown]:hover > .dropdown-menu,
    [data-hover-dropdown]:focus-within > .dropdown-menu {
        display: block;
    }
    [data-hover-dropdown] > .dropdown-toggle::after {
        transition: transform 0.15s;
    }
    [data-hover-dropdown]:hover > .dropdown-toggle::after,
    [data-hover-dropdown]:focus-within > .dropdown-toggle::after {
        transform: rotate(180deg);
    }
}

/* -----------------------------------------------------------------------
   Ad slots (Layout B). Placeholder styling — swap with real ad code when
   integrating AdSense. See BACKLOG.md.
   ----------------------------------------------------------------------- */

/* Reserve outer-wrapper space so CLS stays at 0 even after we swap the
   placeholder for real AdSense markup. Sizes match Layout B. */
.ad-slot {
    position: relative;
}
.ad-slot-sidebar { min-height: 600px; }
.ad-slot-leaderboard { min-height: 90px; }

/* In production, the dashed-border "Advertisement / 300×600" placeholder
   is hidden so AdSense reviewers (and users while ads aren't sold) don't
   see fake ad-like elements. Outer .ad-slot wrappers still reserve space
   (CLS guard) so when real <ins> markup swaps in later, layout is stable.
   To re-enable during local layout work, toggle .cp-show-placeholders on
   <body>. */
.ad-slot-placeholder {
    display: none;
}
.cp-show-placeholders .ad-slot-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    border: 1px dashed var(--bs-border-color);
    border-radius: 0.375rem;
    background: var(--bs-body-bg);
    color: var(--bs-secondary-color);
    padding: 1rem;
    text-align: center;
}
.ad-slot-placeholder .smaller {
    font-size: 0.75rem;
    opacity: 0.7;
}

/* Sidebar skyscraper — sticky so it stays visible while you scroll the
   results / amortization schedule. */
.ad-slot-sidebar .ad-slot-placeholder {
    position: sticky;
    top: 1rem;
    min-height: 600px;
    width: 300px;
    margin-left: auto;
}

/* Leaderboard — centered 728×90 below content. */
.ad-slot-leaderboard .ad-slot-placeholder {
    width: 728px;
    height: 90px;
    margin: 0 auto;
}

/* Mobile sticky anchor — fixed at bottom, behind nav-ish chrome.
   Hidden by default (see .ad-slot-placeholder rule above); only shown when
   a real ad is present or the placeholder is explicitly re-enabled. */
.ad-slot-mobile {
    display: none;
}
.cp-show-placeholders .ad-slot-mobile {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    height: 50px;
    background: var(--bs-body-bg);
    border-top: 1px solid var(--bs-border-color);
    z-index: 1030;
    display: flex;
    align-items: center;
    justify-content: center;
}
.ad-slot-mobile .ad-slot-placeholder {
    width: 320px;
    height: 50px;
    border: none;
    flex-direction: row;
    gap: 0.5rem;
    padding: 0;
}
.ad-slot-mobile .ad-slot-close {
    position: absolute;
    top: 2px;
    right: 4px;
    width: 24px;
    height: 24px;
    line-height: 22px;
    padding: 0;
    background: transparent;
    border: none;
    color: var(--bs-secondary-color);
    font-size: 1.25rem;
    cursor: pointer;
}
.ad-slot-mobile.dismissed {
    display: none !important;
}

/* Pad bottom of body on mobile so the sticky ad doesn't cover the footer. */
@media (max-width: 767.98px) {
    body {
        padding-bottom: 56px;
    }
}

/* Print: produce a clean, PDF-quality result page. Hides nav/ads/buttons,
   forces white background, reserves letter-size margins, and adds page-break
   hints so amortization tables don't split rows across pages. */
@page {
    size: letter;
    margin: 0.6in;
}
@media print {
    nav, footer, .no-print, .navbar, button,
    .ad-slot, .ad-slot-mobile, aside, .skip-link { display: none !important; }

    html, body {
        background: #fff !important;
        color: #000 !important;
    }
    .container, main.container {
        max-width: 100% !important;
        padding: 0 !important;
        margin: 0 !important;
    }

    /* Expose the page URL under the h1/h2 title so a printout is traceable
       back to the live calculator. The ::after content is populated by JS
       on page load (see app.js — setPrintURL). */
    h1, h2 { break-after: avoid; }
    h1::after, h2:first-of-type::after {
        content: attr(data-print-url);
        display: block;
        font-size: 9pt;
        font-weight: normal;
        color: #555;
        margin-top: 0.1rem;
    }

    /* Card bodies carry a tinted background on-screen; flatten for print. */
    .card, .card-body, .bg-body-tertiary, .bg-body-secondary {
        background: #fff !important;
        border: 1px solid #ddd !important;
        box-shadow: none !important;
    }

    /* Tables: shrink, avoid mid-row page breaks, repeat headers per page. */
    .table { font-size: 10pt; page-break-inside: auto; }
    .table thead { display: table-header-group; }
    .table tr { page-break-inside: avoid; }

    /* Charts: keep on one page, don't split between pages. */
    canvas, .chart-container { break-inside: avoid; max-width: 100% !important; }

    /* Strip decorative link underlines and color in print. */
    a, a:link, a:visited { color: #000 !important; text-decoration: none !important; }
    a[href]:after { content: "" !important; }

    /* Keep result card blocks together. */
    .card { break-inside: avoid; }
}
