/*@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');*/

*,
*::before,
*::after {
    box-sizing: border-box;
}

/* Lock html/body to the dynamic viewport (100dvh) and suppress page-level
   scroll. Two reasons together:
     1. Blazorise's blazorise.css ships `.b-layout.b-layout-root { height: 100vh }`
        and is loaded *after* this stylesheet by baseapp.indexhead.js, so we can't
        win on specificity alone. Even with !important the root is still 100vh
        worth of HTML — the body would still grow with it.
     2. 100vh on mobile is the *large* viewport (URL-bar-hidden height). When the
        URL bar is showing the document is taller than the visible area, so the
        page scrolls by the URL-bar height even when content fits.
   By clamping html/body to 100dvh and adding overflow: hidden, the document can
   never grow past the visible viewport — Blazorise's inner 100vh layout is just
   clipped to the body box. Internal scroll containers (e.g. the stock photos
   page sets `overflow-y: auto` on its own wrapper) are unaffected because they
   live inside the body and scroll themselves. 100vh kept as a fallback for the
   few browsers without dvh support. */
html, body {
    margin: 0 !important;
    padding: 0 !important;
    width: 100%;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
    box-sizing: border-box;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* Belt-and-suspenders for the layout root itself — even with body overflow
   hidden, sizing the root to 100dvh keeps internal `100vh - N` math (e.g. the
   photo-select container) landing inside the visible viewport. */
.b-layout.b-layout-root {
    height: 100vh !important;
    height: 100dvh !important;
}

/* Pages that legitimately need to scroll (e.g. stock-photo grid in either
   orientation) opt-in via their own overflow-y: auto on a bounded container.
   Do NOT set overflow-y on .b-layout-content globally — it brings back the
   unwanted URL-bar scroll on pages that fit. */

h1:focus {
    outline: none;
}

a, .btn-link {
    color: #0071c1;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

/* Sets page needs top padding; Snaps does not (its own CSS handles header clearance) */
.sets-page-content {
    padding-top: 1.1rem;
    /* body { overflow: hidden } suppresses the unwanted URL-bar scroll, so the
       Sets calculator tabs (which are long-form content and routinely exceed
       the viewport) need their own scroll container. 64px = Blazorise bar
       height (32) for both header and footer — MainLayout renders both on
       /sets. dvh tracks the visible viewport on mobile; vh is the fallback. */
    max-height: calc(100vh - 64px);
    max-height: calc(100dvh - 64px);
    overflow-y: auto;
}

/* EventIt's layout already handles fixed header offset via Blazorise LayoutContent.
   The shared snap3DCmp.css adds margin-top assuming no layout offset.
   Apply a small gap to separate the image from the header in EventIt. */
#snap3dviewer {
    margin-top: 6px !important;
}

/* Header gear (settings) button overrides.
   BaseAppLib's ConfigSettings.razor renders the gear as a full-header-height
   Blazorise Button with default Bootstrap .btn padding. Two problems consumer-side:
     1. Horizontal padding (~12px each side) makes the click target span into the
        gap between the gear and the neighbouring reset icon, causing accidental
        clicks on the gear when reaching for reset.
     2. Full HeaderHeight gives the gear a tall visible button outline that doesn't
        match the bare-icon reset right next to it.
   Trim both:
     - padding-left/right: 4px hugs the icon horizontally without spilling into the
       gap.
     - height: auto + line-height: 1 collapses the button to icon size so the gear
       reads visually as an icon, matching the reset.
     - margin-top: 5px aligns the gear's Y with the reset's Y (the reset's wrapping
       Div in HeaderBar.razor uses the same margin-top: 5px from the row's
       align-items: center baseline).
   The 8px margin-top on the 3D toggle's wrapping Div is preserved separately — it
   tracks the toggle's own visual alignment with the gear, not the other way around. */
.settings-button {
    padding-left: 4px !important;
    padding-right: 4px !important;
    height: auto !important;
    line-height: 1 !important;
    margin-top: 5px !important;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

/* Center the static loading spinner (from index.html) */
#main:has(.loading-progress) {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

.loading-progress {
    margin: 0 !important;
}


.action-tile-divider {
}

.event-it-image {
    object-fit: contain;
    width: 80%;
    z-index: 2;
}

.event-it-tile {
}

.event-it-tap-menu {
}

.nav-link {
    padding: 0.5rem 0.5rem;
}

.static-content-message {
    color: burlywood
}

.static-content-is-dirty {
    color: red
}

.static-content-is-current {
    color: blue
}

/* EventIt landing page buttons */
.eventit-app-btn {
    width: 96%;
    max-width: 500px;
    min-height: 80px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    font-size: 1.2rem;
    font-weight: 600;
    border: 2px solid #333;
    border-radius: 12px;
    background-color: #fff;
    color: #333;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    padding: 1.5rem;
}

.eventit-app-btn:hover {
    background-color: #333;
    color: #fff;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
}

.eventit-app-btn:active {
    transform: scale(0.97);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.eventit-app-btn i,
.eventit-app-btn svg {
    font-size: 1.5rem;
}

.eventit-app-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.eventit-app-btn:disabled:hover {
    background-color: #fff;
    color: #333;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.eventit-loading-hint {
    font-size: 0.75rem;
    opacity: 0.7;
}

.eventit-load-error {
    font-size: 0.75rem;
    color: #d47500;
}

/* MaxFit / Space Required mode tabs — 50% taller via padding */
.calculator-mode-tabs .nav-link {
    padding-top: 0.75rem;
    padding-bottom: 0.75rem;
}

/* Area entry row (L / W / = ) — 50% taller via padding */
.area-entry-row {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

/* Print / Export-to-PDF for the Sets Summary and MaxFit reports.
   The "Export PDF" button on SetsReport.razor / MaxSetsReport.razor calls
   window.print(); we route the print output to render just the report card
   (the rest of the app — header, tabs, sidebars, the buttons themselves —
   is irrelevant and noisy in a saved PDF).
   Strategy: visibility-hide everything by default in print mode, then make
   the printable region and its descendants visible again, and absolute-
   position it to the top-left of the printed page so it isn't pushed down
   by the now-invisible-but-still-laid-out chrome above it. */
@media print {
    /* Override the app-shell's overflow:hidden + 100dvh clamp so the printed
       output can grow to whatever number of pages the report needs.
       Without this the print would be clipped to the screen viewport. */
    html, body {
        height: auto !important;
        overflow: visible !important;
    }
    .b-layout.b-layout-root {
        height: auto !important;
        overflow: visible !important;
    }
    .sets-page-content {
        max-height: none !important;
        overflow: visible !important;
        padding-top: 0 !important;
    }

    body * {
        visibility: hidden;
    }
    .report-printable, .report-printable * {
        visibility: visible;
    }
    .report-printable {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        margin: 0 !important;
        padding: 0 !important;
        border: none !important;
        box-shadow: none !important;
        background: white !important;
        color: black !important;
        font-size: 11pt;
        line-height: 1.4;
    }
    /* Buttons (Copy / Export PDF) and the editable title textarea are
       authoring chrome — keep them visible on screen but suppress in the
       PDF. The static title heading (`.report-print-title`) renders in
       their place when printing. */
    .report-no-print {
        display: none !important;
    }
    .report-print-only {
        display: block !important;
    }
    /* Encourage browsers to print background colors and to break sensibly. */
    .report-printable a {
        color: black !important;
        text-decoration: none !important;
    }
}

/* Static title that only appears in printed output — hidden on screen,
   unhidden by the @media print block above. Lives in normal flow so the
   PDF reads as Title → body lines. */
.report-print-only {
    display: none;
}
