/* =====================================================================
   iOS 26 "Liquid Glass" mobile tab bar
   ---------------------------------------------------------------------
   Restyles #mobile-bottom-menu (app/Views/layout/index.php) into a
   floating, translucent tab bar that reads as the native iOS 26 toolbar:

     - a glass capsule inset from the screen edges, sitting above the
       home-indicator safe area
     - every tab is `flex: 1 1 0`, so N tabs always share the width
       evenly no matter how many the workspace ends up rendering
     - icon + label stacked, active tab tinted and capsuled
     - the bar condenses (labels out, height down) while the page scrolls
       down and expands again on scroll up, like iOS 26

   Scoped to `.nz-bb26` / `body.nz-bb26-on`, both added by
   assets/js/bottombar-ios26.js, so nothing here can leak onto the
   ticket details bar (#details-view-bottom-menu) or the desktop chrome.

   Dark mode is NIZU's body.color-1E202D theme, not prefers-color-scheme.
   ===================================================================== */

.nz-bb26 {
    /* geometry */
    --bb26-gutter: 10px;
    --bb26-h: 58px;
    /* on a wide phone the capsule centres instead of stretching edge to edge,
       the way an iPadOS 26 floating tab bar does */
    --bb26-max: 460px;
    /* an icon-only bar (the ticket details section jumps) needs less room */
    --bb26-h-plain: 48px;
    --bb26-h-condensed: 44px;
    --bb26-radius: 27px;
    --bb26-icon: 25px;
    --bb26-label: 10px;

    /* motion — the iOS spring */
    --bb26-ease: cubic-bezier(0.32, 0.72, 0, 1);
    --bb26-dur: 380ms;

    /* material */
    --bb26-glass: rgba(252, 252, 254, 0.8);
    --bb26-blur: saturate(190%) blur(30px);
    --bb26-stroke: rgba(255, 255, 255, 0.55);
    --bb26-hairline: rgba(60, 60, 67, 0.12);
    --bb26-shadow: 0 8px 30px rgba(0, 0, 0, 0.13), 0 1px 2px rgba(0, 0, 0, 0.07);

    /* ink */
    --bb26-ink: rgba(60, 60, 67, 0.62);
    --bb26-accent: #007aff;
    --bb26-accent-soft: rgba(0, 122, 255, 0.1);
}

/* ------------------------------------------------------------- the bar --- */

nav.mobile-bottom-menu.nz-bb26 {
    /* neutralise the classic opaque bar */
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    z-index: 99;

    left: 0;
    right: 0;
    bottom: 0;
    padding: 0 var(--bb26-gutter);
    padding-bottom: calc(var(--bb26-gutter) + env(safe-area-inset-bottom, 0px));
    pointer-events: none;
    /* only the capsule takes taps, not the gutter */
}

.nz-bb26 .nz-bb26-row {
    pointer-events: auto;
    max-width: var(--bb26-max);
    margin-inline: auto;
    display: flex !important;
    align-items: stretch;
    justify-content: space-between !important;
    gap: 0;
    padding: 0 !important;
    min-height: var(--bb26-h-plain);
    border-radius: var(--bb26-radius);
    background: var(--bb26-glass);
    -webkit-backdrop-filter: var(--bb26-blur);
    backdrop-filter: var(--bb26-blur);
    box-shadow: var(--bb26-shadow), inset 0 0 0 0.5px var(--bb26-stroke);
    transition: min-height var(--bb26-dur) var(--bb26-ease),
        background var(--bb26-dur) var(--bb26-ease),
        margin-bottom 260ms var(--bb26-ease),
        opacity 180ms var(--bb26-ease);

    /* NO `overflow: hidden` here. The classic bar carries `will-change:
       transform`, which makes it the containing block for its `position:
       fixed` descendants — so clipping the row also clips the quick-add and
       page-actions sheets, which then open invisibly. The children are inset
       well inside the capsule, so nothing needs clipping anyway. */
}

/* a faint specular top edge — the "liquid" in liquid glass */
.nz-bb26 .nz-bb26-row::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(to bottom, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0) 45%);
    pointer-events: none;
}

.nz-bb26 .nz-bb26-row {
    position: relative;
}

/* ------------------------------------------------------- equal columns --- */

/* Whatever the app injects — an <a>, a <div id="mobile-quick-add-button">,
   the chat button — becomes one equal-width column. This is the rule that
   keeps N tabs balanced without JS measuring anything. */
.nz-bb26 .nz-bb26-row > .nz-bb26-tab {
    flex: 1 1 0 !important;
    min-width: 0;
    display: flex;
    align-items: stretch;
    justify-content: center;
    position: relative;

    /* The tab's own horizontal padding must be zero. `flex-basis: 0` is a
       BORDER-box length here, so it clamps up to the item's own padding —
       leaving each tab `equal share + its own padding` wide. The app's
       `.menu-item` ships 20px of side padding, which is exactly why the raw
       bar came out at 62/58/98/98px instead of four equal columns. Padding
       lives on .nz-bb26-hit (vertical only) instead. */
    padding: 0 !important;
    margin: 0 !important;
    border: 0 !important;
}

/* a tab the JS has ruled out (a duplicate of one we already show) */
.nz-bb26 .nz-bb26-row > .nz-bb26-tab.nz-bb26-void {
    display: none !important;
}

/* the tappable surface inside a column */
.nz-bb26 .nz-bb26-hit {
    flex: 1 1 auto;
    min-width: 0;
    display: flex !important;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    /* vertical only — see the note on .nz-bb26-tab: side padding here would
       unbalance a tab that is its own hit surface (the drawer toggle) */
    padding: 6px 0 !important;
    margin: 0 !important;
    border: 0 !important;
    background: none !important;
    color: var(--bb26-ink) !important;
    text-decoration: none !important;
    -webkit-tap-highlight-color: transparent;
    cursor: pointer;
    transition: color 200ms var(--bb26-ease), transform 220ms var(--bb26-ease);
}

.nz-bb26 .nz-bb26-hit::after {
    display: none !important;
}

/* icon */
.nz-bb26 .nz-bb26-ico {
    display: flex;
    align-items: center;
    justify-content: center;
    height: var(--bb26-icon);
    font-size: calc(var(--bb26-icon) - 2px);
    line-height: 1;
    /* FA glyphs sit on the baseline; the fixed-height flex box above keeps the
       ink optically centred across the very different shapes in the bar
       (grid, ellipsis, speech bubble, plus) */
    transition: transform 260ms var(--bb26-ease), color 200ms var(--bb26-ease);
}

.nz-bb26 .nz-bb26-ico i {
    display: block;
    line-height: 1;
}

.nz-bb26 .nz-bb26-ico svg,
.nz-bb26 .nz-bb26-ico .icon {
    width: calc(var(--bb26-icon) - 3px) !important;
    height: calc(var(--bb26-icon) - 3px) !important;
    stroke-width: 1.8;
}

/* label */
.nz-bb26 .nz-bb26-lbl {
    display: block;
    max-width: 100%;
    font-size: var(--bb26-label);
    font-weight: 500;
    letter-spacing: -0.01em;
    line-height: 1.1;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    opacity: 1;
    max-height: 14px;
    transition: opacity 220ms var(--bb26-ease), max-height var(--bb26-dur) var(--bb26-ease);
}

/* ------------------------------------------------------------- states --- */

/* `:active` is the fallback; `.is-pressed` is driven straight off the touch
   events so the press lands with the finger, not after the tap delay */
.nz-bb26 .nz-bb26-hit:active,
.nz-bb26 .nz-bb26-hit.is-pressed {
    transform: scale(0.9);
    transition-duration: 90ms;
}

.nz-bb26 .nz-bb26-tab.is-active .nz-bb26-hit,
.nz-bb26 .nz-bb26-hit.is-active {
    color: var(--bb26-accent) !important;
}

.nz-bb26 .nz-bb26-tab.is-active .nz-bb26-ico {
    transform: translateY(-1px) scale(1.06);
}

/* The selection capsule is ONE element that slides between tabs rather than a
   per-tab box that pops in and out — the same idea as assets/js/ios26-tabs.js
   uses for `.nav-tabs`, but the geometry is trivial here because every tab is
   the same width. Placed by syncGlider() in bottombar-ios26.js. */
.nz-bb26 .nz-bb26-glider {
    position: absolute;
    top: 7px;
    bottom: 7px;
    left: 0;
    width: 0;
    border-radius: 17px;
    background: var(--bb26-accent-soft);
    opacity: 0;
    pointer-events: none;
    z-index: 0;
    transition: transform var(--bb26-dur) var(--bb26-ease),
        width var(--bb26-dur) var(--bb26-ease),
        opacity 220ms var(--bb26-ease),
        top var(--bb26-dur) var(--bb26-ease),
        bottom var(--bb26-dur) var(--bb26-ease);
}

.nz-bb26 .nz-bb26-glider.is-on {
    opacity: 1;
}

/* the first placement must not fly in from the left edge */
.nz-bb26 .nz-bb26-glider.no-anim {
    transition: none !important;
}

/* the tabs paint above the capsule */
.nz-bb26 .nz-bb26-row > .nz-bb26-tab {
    z-index: 1;
}

/* --------------------------------------------------- keyboard avoidance --- */

/* An on-screen keyboard shrinks the visual viewport but not the layout one, so
   a bottom-anchored bar lands on top of the field being typed into. Get out of
   the way entirely, the way iOS does.

   Moved with a negative margin rather than a transform ON PURPOSE: a transform
   here would make the row the containing block for the `position: fixed`
   sheets inside it, and on the bar itself it would collide with the
   slide-in/out classes general_helper.js puts on this element for the mobile
   details pages. */
.nz-bb26.is-keyboard .nz-bb26-row {
    margin-bottom: -160px;
    opacity: 0;
    pointer-events: none;
}

/* ------------------------------------------------------ condensed state --- */

.nz-bb26.nz-bb26-labelled .nz-bb26-row {
    min-height: var(--bb26-h);
}

/* too many tabs for the screen: drop the labels rather than truncate them,
   the way iOS does. Must sit after the .nz-bb26-labelled rule above. */
.nz-bb26.nz-bb26-tight .nz-bb26-row {
    min-height: var(--bb26-h-plain);
}

.nz-bb26.nz-bb26-tight .nz-bb26-lbl {
    display: none;
}

.nz-bb26.is-condensed .nz-bb26-row {
    min-height: var(--bb26-h-condensed);
}

.nz-bb26.is-condensed .nz-bb26-lbl {
    opacity: 0;
    max-height: 0;
}

.nz-bb26.is-condensed .nz-bb26-glider {
    top: 5px;
    bottom: 5px;
}

/* ------------------------------------------------------------- badges --- */

/* The chat tab's unread pill. Left alone, the app replaces the whole icon with
   the raw number, which looks nothing like a tab bar. */
.nz-bb26 .nz-bb26-badge {
    position: absolute;
    top: 4px;
    /* logical, so the badge lands on the correct side of the icon in RTL
       (this app ships assets/css/rtl.css for Arabic/Hebrew workspaces) */
    inset-inline-start: 50%;
    margin-inline-start: 3px;
    min-width: 17px;
    height: 17px;
    padding: 0 5px;
    font-size: 10px;
    font-weight: 600;
    line-height: 17px;
    text-align: center;
    color: #fff;
    background: #ff3b30;
    border-radius: 9px;
    box-shadow: 0 0 0 1.5px var(--bb26-glass);
}

.nz-bb26 .nz-bb26-badge.is-dot {
    min-width: 9px;
    width: 9px;
    height: 9px;
    padding: 0;
    top: 7px;
    border-radius: 50%;
}

.nz-bb26.is-condensed .nz-bb26-badge,
.nz-bb26.nz-bb26-tight .nz-bb26-badge {
    top: 2px;
}


.nz-bb26 .nz-bb26-hit .badge,
.nz-bb26 .nz-bb26-hit .unread-message-count {
    position: absolute;
    top: 3px;
    left: 50%;
    margin-left: 4px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    font-size: 9px;
    line-height: 16px;
    border-radius: 8px;
    text-align: center;
}

/* --------------------------------------------------------- popup menus --- */

/* the quick-add / page-actions sheets float above the capsule */
.nz-bb26 .dropdown-menu {
    position: fixed !important;
    transform: none !important;
    inset: auto !important;
    left: var(--bb26-gutter) !important;
    right: var(--bb26-gutter) !important;
    width: auto !important;
    max-width: var(--bb26-max) !important;
    margin-inline: auto !important;
    bottom: calc(var(--bb26-h) + var(--bb26-gutter) * 2 + env(safe-area-inset-bottom, 0px)) !important;
    border: 0 !important;
    border-radius: 18px !important;
    padding: 6px !important;
    background: var(--bb26-glass) !important;
    -webkit-backdrop-filter: var(--bb26-blur);
    backdrop-filter: var(--bb26-blur);
    box-shadow: var(--bb26-shadow), inset 0 0 0 0.5px var(--bb26-stroke) !important;
}

/* long sheets scroll instead of running off the top of the screen */
.nz-bb26 .dropdown-menu.show {
    max-height: calc(100vh - var(--bb26-h) - 120px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    animation: nzbb26-sheet 320ms var(--bb26-ease);
}

@keyframes nzbb26-sheet {
    from {
        opacity: 0;
        transform: translateY(14px) scale(0.97);
    }

    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.nz-bb26 .dropdown-menu .dropdown-item {
    border-radius: 12px !important;
    padding: 12px 14px !important;
    font-size: 15px;
    position: relative;
}

/* iOS grouped-list hairlines: inset, and never after the last row. Two
   selectors because the app builds these sheets two different ways —
   quick_add.php stacks every anchor inside ONE <li>, while
   convertTabButtonsToDropdownOnMobileView wraps each one in its own <div>. */
.nz-bb26 .dropdown-menu .dropdown-item:not(:last-child)::after,
.nz-bb26 .dropdown-menu > li:not(:last-child) > .dropdown-item::after,
.nz-bb26 .dropdown-menu > div:not(:last-child) > .dropdown-item::after {
    content: "";
    position: absolute;
    inset-inline-start: 14px;
    inset-inline-end: 0;
    bottom: 0;
    height: 0.5px;
    background: var(--bb26-hairline);
}

.nz-bb26 .dropdown-menu .dropdown-item:active {
    background: var(--bb26-accent-soft) !important;
}

/* ------------------------------------------------------- page clearance --- */

/* Scoped to the breakpoint where the bar actually exists. Bootstrap's
   `d-sm-none` hides it from 576px up, so without this the rule reserved 76px at
   the bottom of every DESKTOP page for a bar that is not there. */
@media (max-width: 575.98px) {
    body.nz-bb26-on .scrollable-page {
        margin-bottom: calc(var(--nz-bb26-clear, 76px) + env(safe-area-inset-bottom, 0px)) !important;
    }
}

/* ---------------------------------------------------------- dark theme --- */

body.color-1E202D .nz-bb26 {
    --bb26-glass: rgba(30, 32, 45, 0.8);
    --bb26-stroke: rgba(255, 255, 255, 0.1);
    --bb26-hairline: rgba(255, 255, 255, 0.1);
    --bb26-shadow: 0 8px 30px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.4);
    --bb26-ink: rgba(235, 235, 245, 0.6);
    --bb26-accent: #0a84ff;
    --bb26-accent-soft: rgba(10, 132, 255, 0.2);
}

body.color-1E202D .nz-bb26 .nz-bb26-row::before {
    background: linear-gradient(to bottom, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0) 45%);
}

body.color-1E202D .nz-bb26 .nz-bb26-hit {
    color: var(--bb26-ink) !important;
}

body.color-1E202D .nz-bb26 .nz-bb26-tab.is-active .nz-bb26-hit {
    color: var(--bb26-accent) !important;
}

/* the runtime theme paints .menu-item colours with !important; re-win them */
body.color-1E202D .nz-bb26 .menu-item,
body.color-1E202D .nz-bb26 #mobile-function-button {
    color: var(--bb26-ink) !important;
}

/* --------------------------------------------------------- reduced motion --- */

@media (prefers-reduced-motion: reduce) {

    .nz-bb26 *,
    .nz-bb26 *::before {
        transition-duration: 1ms !important;
        animation-duration: 1ms !important;
    }
}
