/* ==========================================================================
   NexusSheet — central bottom-sheet styles for PublicPortal (.nexus-sheet)

   ONE stylesheet for the map bottom-sheet chrome, replacing the three copies:
     - map-info-sheet.css (.pp-info-sheet)                     -> .nexus-sheet--dismiss
     - public-portal-responsive.css .infotool-sheet           -> .nexus-sheet--snap
     - public-portal-responsive.css .searchtool-sheet         -> .nexus-sheet--snap

   Paired with nexus-sheet.js (window.NexusSheet). Two shell variants share the same
   chrome (grip, header, body label/value list, pager) so both LOOK identical:

     .nexus-sheet--dismiss : body-level sheet, translateY open/close + backdrop
                          (map-click info). Hidden >=768px (desktop uses the OL popup).
     .nexus-sheet--snap    : morphs the sidebar host into a peek/half/full snap sheet
                          (InfoTool / SearchTool). Mobile PublicPortal only.

   NOTE: This file is inert until consumers adopt the classes (Phase 2+). Adding it
   changes nothing on its own — no existing element carries a .nexus-sheet* class yet.
   ========================================================================== */

/* ==========================================================================
   Shared chrome — applies inside either shell (and inside the desktop OL popup).
   ========================================================================== */

/* Grip handle */
.nexus-sheet__grip {
    width: 42px;
    height: 5px;
    border-radius: 3px;
    background: #c4ccd6;
    margin: 8px auto 6px;
    cursor: grab;
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
}

/* Close (×) button — dismiss shell. Plain glyph normally; on hover a soft round highlight
   (like InfoTool) instead of an underline. */
/* ==========================================================================
   THE 44px ROUND TARGET — one definition for every circular control in the sheet shell.

   S6 raised the pager and the dismiss close to the 44px touch minimum, which made three controls that
   had drifted apart identical again in their box: the dismiss close, the pager button (in both its
   markups) and the snap header's close. The duplication detector reported it immediately - 8 shared
   declarations between the pager and the card action, 6 between each of the others.

   So the box lives here once and each control keeps only its own chrome: the pager is a bordered white
   button, the closes are borderless glyphs. Adding a round control means adding its selector here, not
   repeating six lines.

   OUTSIDE the mobile media query on purpose, even though the snap header close is only styled inside it:
   that selector requires `.nexus-sheet--snap`, which mount() adds only on the mobile PublicPortal
   surface, so it cannot match on desktop regardless of where this sits.

   NOT extended to `.nexus-card-action` (nexus-content.css). That file is deliberately self-sufficient -
   a tool may adopt its content classes without loading this shell file at all (the three-shell rule) -
   so it carries its own copy of the box by design. That is a stated invariant, not an oversight.
   ========================================================================== */
.nexus-sheet__close,
.nexus-sheet__pager-btn,
body.public-portal .info-tool-nav > em,
body.public-portal .turbosidebar.nexus-sheet--snap .turbosidebar-header .turbosidebar-close {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* The DISMISS shell's close. The desktop popup's closer further down stays 36px on purpose: it is a
   mouse target, and 44px there is simply oversized. "Touch minimum" is not "make everything bigger". */
.nexus-sheet__close {
    position: absolute;
    top: 18px; /* on the TITLE row, nudged up + right */
    right: 16px;
    border: 0;
    background: transparent;
    color: #6a7280;
    font-size: 26px;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: background .15s, color .15s;
    z-index: 2;
}

    .nexus-sheet__close:hover {
        background: #f2f4f7;
        color: #1a2030;
        text-decoration: none;
    }

/* Map-click DESKTOP popup close — plain × like the InfoTool desktop close (not the heavy "✖"). */
.nexus-popup .ol-popup-closer {
    top: 8px; /* on the TITLE row, nudged up + right */
    right: 14px;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    color: #6a7280;
    text-decoration: none;
    transition: background .15s, color .15s;
}

    /* Hover: a soft round highlight (like InfoTool), no underline under the ×. */
    .nexus-popup .ol-popup-closer:hover {
        background: #f2f4f7;
        color: #1a2030;
        text-decoration: none;
    }

    .nexus-popup .ol-popup-closer:after {
        content: "\00d7"; /* × */
        font-size: 24px;
    }

/* ---- Content: title + a Bootstrap table turned into a clean label/value list ---- */
.nexus-sheet__body br {
    display: none; /* generators emit a stray <br> before the heading */
}

.nexus-sheet__body h4,
.nexus-sheet__body h3 {
    font-size: 16px;
    font-weight: 700;
    text-align: left !important; /* beats a generator's .text-center (which is !important) */
    color: #1a2030;
    margin: 2px 0 12px 0;
    padding: 0 44px 12px 0; /* right PADDING clears the X, but the border-bottom still spans full width */
    border-bottom: 1px solid #e6e9ef;
}

/* Bootstrap table -> stacked label/value list: small uppercase label ON TOP, value
   below (both left-aligned), hairline separators. Chosen unified look — long values
   wrap cleanly on a narrow sheet instead of being squeezed to the right. */
.nexus-sheet__body table,
.nexus-sheet__body tbody,
.nexus-sheet__body tr,
.nexus-sheet__body th,
.nexus-sheet__body td {
    display: block;
    width: 100%;
    border: 0 !important;
}

.nexus-sheet__body table {
    margin: 0;
}

.nexus-sheet__body tr {
    background: transparent !important; /* kill zebra striping */
}

.nexus-sheet__body th {
    padding: 11px 0 0;
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: #6a7280;
    font-weight: 600;
    text-align: left;
}

.nexus-sheet__body td {
    padding: 2px 0 11px;
    font-size: 14px;
    font-weight: 600;
    color: #1a2030;
    text-align: left;
    word-break: break-word;
    border-bottom: 1px solid #eef1f5 !important;
}

    .nexus-sheet__body tr:last-child td {
        border-bottom: 0 !important;
    }

.nexus-sheet__body a {
    color: #1e5fd0;
    word-break: break-all;
}

/* ---- Feature pager  ‹  N / total  ›  — circle chevron buttons + counter ---- */
.nexus-sheet__pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 0 12px;
    margin: 0 0 4px;
    border-bottom: 1px solid #eef1f5;
}

/* TWO MARKUP SHAPES, ONE SET OF DECLARATIONS.
   `.nexus-sheet__pager-btn` is an empty <button> and belongs to markup this file's portal owns outright
   (PublicPortal/Views/Tourism/Index.cshtml). InfoTool cannot use it: that component also renders on 7
   IntranetPortal views whose layout never loads this file, so its arrows must stay portal-neutral Font
   Awesome <em>s — see the comment at InfoTool/Default.cshtml's pager row for what happened when they didn't.
   So the <em>s are named alongside each selector instead, behind `body.public-portal` (the surface flag, not
   the app-wide mode flag). Adding a shape means extending these selector lists — never copying the block. */
/* The pager's own chrome only — a bordered white button. Its 44px round box comes from the shared target
   rule above; S6 raised it from 40px, which was under the touch minimum for a control that gets pressed
   repeatedly while reading through results. */
.nexus-sheet__pager-btn,
body.public-portal .info-tool-nav > em {
    min-width: 44px;
    padding: 0;
    border: 1.5px solid #c4ccd6;
    background: #fff;
    color: #1e5fd0;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    transition: border-color .15s, background .15s, opacity .15s;
}

    /* The <em> carries Bootstrap's `.mr-2`, which the IntranetPortal look needs and which would otherwise
       pull the trailing arrow 8px off the edge of this `space-between` row. `.mr-2` is `!important`, so
       beating it requires one too. Scoped to the <em> so Tourism's buttons are not touched at all. */
    body.public-portal .info-tool-nav > em {
        margin-right: 0 !important;
    }

    .nexus-sheet__pager-btn::before,
    body.public-portal .info-tool-nav > em::before {
        /* Fully specified `font`, so it overrides Font Awesome's family/weight and `.fa-2x`'s size, and
           `font-style: normal` because <em> is italic by default and would slant the chevron. */
        font: 700 22px/1 Arial, "Segoe UI", sans-serif;
        font-style: normal;
    }

    .nexus-sheet__pager-btn--prev::before,
    body.public-portal .info-tool-nav > .infoToolPrevLeft::before {
        content: "\2039"; /* ‹  — beats Font Awesome's own \f359 on specificity */
    }

    .nexus-sheet__pager-btn--next::before,
    body.public-portal .info-tool-nav > .infoToolNextRight::before {
        content: "\203A"; /* › */
    }

    .nexus-sheet__pager-btn:hover:not(:disabled),
    body.public-portal .info-tool-nav > em:hover {
        border-color: #1e5fd0;
        background: #f5f8ff;
    }

    .nexus-sheet__pager-btn:focus-visible {
        outline: 2px solid #1e5fd0;
        outline-offset: 2px;
    }

    /* <em> cannot be :disabled — InfoTool hides an unavailable arrow with .hide() instead, so there is
       deliberately no <em> counterpart here. */
    .nexus-sheet__pager-btn:disabled {
        opacity: .35;
        cursor: default;
    }

.nexus-sheet__pager-count,
body.public-portal #map-info-tool-counter {
    font-size: 15px;
    font-weight: 600;
    color: #8a929e;
    letter-spacing: 4px;
    font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   DISMISS shell — body-level sheet (map-click info: Tourism/Street/Education).
   ========================================================================== */
.nexus-sheet--dismiss {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0; /* left:0 + right:0 on <body> => always full width */
    transform: translateY(100%);
    transition: transform .28s cubic-bezier(.4, 0, .2, 1);
    max-height: 82vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    background: #fff;
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -8px 30px rgba(16, 24, 40, .22);
    padding: 6px 18px 22px;
    z-index: 1200;
}

    .nexus-sheet--dismiss.is-open {
        transform: translateY(0);
    }

    /* Peek: minimised to an ~84px handle strip at the bottom (grip + × + title show). The map above
       is uncovered — the JS drops the backdrop at peek — so it stays tappable, exactly like the
       InfoTool snap sheet at peek. Drag up / tap to expand; drag down again to close. */
    .nexus-sheet--dismiss.is-open.is-peek {
        transform: translateY(calc(100% - 84px));
    }

/* During a grip/swipe drag the JS sets an inline transform; kill the animation so it tracks the finger. */
.nexus-sheet--dismiss.nexus-sheet-dragging {
    transition: none;
}

.nexus-sheet__backdrop {
    position: fixed;
    inset: 0;
    background: rgba(16, 24, 40, .28);
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s;
    z-index: 1199;
}

    .nexus-sheet__backdrop.is-open {
        opacity: 1;
        pointer-events: auto;
    }

@media (prefers-reduced-motion: reduce) {
    .nexus-sheet--dismiss {
        transition: none;
    }
}

/* Desktop: the anchored OL popup is used instead — never show the dismiss sheet or backdrop. */
@media (min-width: 768px) and (min-height: 501px) {
    .nexus-sheet--dismiss,
    .nexus-sheet__backdrop {
        display: none !important;
    }
}

/* ==========================================================================
   SNAP shell — morph the sidebar host into a bottom sheet (InfoTool/SearchTool).
   Mobile PublicPortal only, mirroring the current .infotool-sheet / .searchtool-sheet.
   ========================================================================== */
@media screen and (max-width: 767.98px),
       screen and (max-height: 500px) and (orientation: landscape) {

    /* Container = the bottom sheet: bottom-anchored, snap height, rounded top. */
    body.public-portal .turbosidebar.nexus-sheet--snap {
        top: auto;
        bottom: 0;
        height: 54vh;
        width: 100%;
        background: transparent;
        border-radius: 16px 16px 0 0;
        box-shadow: 0 -6px 22px rgba(0, 0, 0, 0.22);
        transition: height .25s ease;
    }

    /* FALLBACK ONLY. nexus-sheet.js resolves every snap to an INLINE px height against the host box
       (#map), which wins over these rules. They stay as the no-JS / pre-snap() safety net, so a JS
       failure degrades to a bounded sheet instead of height:auto covering the whole map. Do NOT treat
       these as the source of truth and do not add per-tool overrides here — per-tool peek heights belong
       in each consumer's `snaps` config. `vh` resolves against the LARGE viewport on mobile browsers,
       which is exactly the mismatch the inline px height exists to avoid. */
    body.public-portal .turbosidebar.nexus-sheet--snap.snap-peek { height: 84px; }
    body.public-portal .turbosidebar.nexus-sheet--snap.snap-half { height: 54vh; }
    body.public-portal .turbosidebar.nexus-sheet--snap.snap-full { height: 88vh; }

    /* During a drag the JS sets an inline height; kill the animation so it tracks the finger. */
    body.public-portal .turbosidebar.nexus-sheet--snap.nexus-sheet-dragging { transition: none; }

    /* Hide the tool strip while the sheet is open (closing the tool brings it back). */
    body.public-portal .turbosidebar.nexus-sheet--snap > .turbosidebar-tabs {
        display: none;
    }

    /* §10 пр. 6 (owner decision, 31.08.2026): while the sheet is PARKED at peek the strip comes
       back, floating just above the band on the right — switching tools is one tap instead of
       X-then-tap. Only at peek: at half/full the sheet owns the width and covers the map anyway.
       `bottom: calc(100% + 8px)` rides the host, so every per-tool peek height (66/84/96/124) is
       handled without knowing it. The <ul> goes static and block: the vendor keeps BOTH the strip
       and the list absolutely positioned with height:100% (and S28's landscape column-wrap flexes
       against that 100%), which would collapse or double-column against `height: auto` here.
       Ten 44px items outgrow a short-landscape screen, so the strip scrolls within 60vh. */
    body.public-portal .turbosidebar.nexus-sheet--snap.snap-peek {
        /* The vendor host is overflow:hidden, which would CLIP the strip riding above the band —
           both visually and for hit-testing (taps would fall through to the map canvas). Visible
           only at peek: the band is pure chrome there (its content scroll is already killed below),
           so nothing else can leak out. */
        overflow: visible;
    }

    body.public-portal .turbosidebar.nexus-sheet--snap.snap-peek > .turbosidebar-tabs {
        display: block;
        top: auto;
        bottom: calc(100% + 8px);
        right: 0;
        left: auto;
        width: 44px;
        height: auto;
        max-height: 60vh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        border-radius: 8px 0 0 8px;
    }

    body.public-portal .turbosidebar.nexus-sheet--snap.snap-peek > .turbosidebar-tabs > ul {
        position: static;
        display: block;
        width: 44px;
        height: auto;
    }

    /* Content fills the sheet full-width (strip is gone). */
    body.public-portal .turbosidebar.nexus-sheet--snap .turbosidebar-content {
        left: 0;
        right: 0;
        border-radius: 16px 16px 0 0;
        background-color: #fff;
        overscroll-behavior: contain;
    }

    /* At PEEK the visible band is (near enough) all sticky chrome — grip plus, for tools that pin one, the
       pane header. A vertical swipe there would scroll the content BEHIND that chrome with nothing visibly
       moving, which reads as a dead sheet. Kill the scroll at peek; every other snap keeps it. */
    body.public-portal .turbosidebar.nexus-sheet--snap.snap-peek .turbosidebar-content {
        overflow-y: hidden;
    }

    /* S7 — the vendor pane padding is `10px 20px`, and the header's negative top margin cancels only the
       TOP half. The surviving 10px adds to scrollHeight, so an exactly-budgeted peek becomes scrollable
       with its content pressed against the rounded bottom edge. Only at peek: every other snap wants it. */
    body.public-portal .turbosidebar.nexus-sheet--snap.snap-peek .turbosidebar-pane {
        padding-bottom: 0;
    }

    /* A tap anywhere on a peeked sheet expands it (nexus-sheet.js, tapToExpand), so show that it is a
       target rather than a dead strip. */
    body.public-portal .turbosidebar.nexus-sheet--snap.snap-peek {
        cursor: pointer;
    }

    /* ======================================================================
       S4 — HEADER CHROME, shared. Before this it lived only in the per-tool blocks, so a newly converted
       pane inherited the vendor bar instead: 40px, dark #3a3f51, white text, negative margins, and — via
       `.turbosidebar-right .turbosidebar-close { left: 0 }` — its close X pinned to the LEFT.

       `top` is part of the contract, not decoration (S16): every pane already gets
       `.turbosidebar-header { position: sticky; top: 0 }` from public-portal-responsive.css, and with a
       22px grip sitting above it inside the same scrollport, `top: 0` would let the header slide UNDER the
       grip (z-index 5) the moment the content scrolls. The offset is published as a custom property so
       consumers that pin a second row can stack on it instead of hand-summing pixels.
       ====================================================================== */
    body.public-portal .turbosidebar.nexus-sheet--snap {
        --nexus-sheet-grip-h: 22px;
        --nexus-sheet-header-h: 44px;
    }

    body.public-portal .turbosidebar.nexus-sheet--snap .turbosidebar-header {
        position: sticky;
        top: var(--nexus-sheet-grip-h);
        z-index: 3;
        height: var(--nexus-sheet-header-h);
        line-height: var(--nexus-sheet-header-h);
        /* 44px each side reserves the close lane symmetrically, so a centred title never collides with the
           X regardless of how long the localised string is. 44 is the existing tool-strip inset, not a new
           number. */
        padding: 0 44px;
        background-color: #fff;
        color: #2b2f3d;
        text-align: center !important;
        border-bottom: 1px solid #e3e7ef;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* Vendor pins this left for a right-hand sidebar; in a sheet it belongs on the right. Position only —
       the 44x44 round box comes from the shared target rule at the top of this file. */
    body.public-portal .turbosidebar.nexus-sheet--snap .turbosidebar-header .turbosidebar-close {
        left: auto;
        right: 8px;
        top: 50%;
        transform: translateY(-50%);
        color: #6a7280;
        transition: background .15s, color .15s;
    }

        body.public-portal .turbosidebar.nexus-sheet--snap .turbosidebar-header .turbosidebar-close:hover {
            background: #f2f4f7;
            color: #1a2030;
        }

    /* Anything a consumer pins BELOW the header stacks on the published offset instead of a magic sum. */
    body.public-portal .turbosidebar.nexus-sheet--snap [data-nexus-pin] {
        position: sticky;
        top: calc(var(--nexus-sheet-grip-h) + var(--nexus-sheet-header-h));
        z-index: 2;
        background: #fff;
    }

    /* Grip sits pinned at the very top of the scrolling content. */
    body.public-portal .turbosidebar.nexus-sheet--snap .nexus-sheet__grip {
        position: sticky;
        top: 0;
        z-index: 5;
        flex: none;
        /* MUST be explicit: the base .nexus-sheet__grip rule (used by the body-level dismiss shell) sets
           width: 42px, and without overriding it here the shared grip renders as a 42px pill floating over
           a transparent host instead of a full-bleed drag strip. The per-tool grips it replaces were block
           elements with no width, so this is what keeps them interchangeable. */
        width: 100%;
        height: 22px;
        margin: 0 auto;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #fff;
        border-radius: 16px 16px 0 0;
    }
    /* Draw the handle bar via ::before so the sticky row keeps a white backing. */
    body.public-portal .turbosidebar.nexus-sheet--snap .nexus-sheet__grip::before {
        content: "";
        width: 40px;
        height: 5px;
        border-radius: 3px;
        background: #c4ccd6;
    }
}
