/* ==========================================================================
   ef-layout.css
   Page-level layout rules for the classic EasyFreight layout (_Layout.cshtml).

   Loaded LAST in the <head> so it wins over screen.css on equal specificity.
   screen.css is a 43KB legacy blob (CSS reset + grid framework + EasyFreight
   overrides in one file) and already declares html,body{height:100%} twice, so
   layout corrections live here instead of being buried in it.

   Added 2026-08-25 for Ken's footer feedback:
     "The footer moves up the page to be under wherever the grid or other
      controls are. Look at getting it locked to the bottom of the page and
      move the version number into the same center area as the rest of the
      footer."
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Sticky footer
   --------------------------------------------------------------------------
   The problem this solves: screen.css sets html,body{height:100%}. That sizes
   the body BOX to one viewport; it does not stretch the body's CHILDREN. So on
   any page whose content was shorter than the window, the footer sat directly
   under the content, halfway up the screen.

   The fix is the standard flex-column sticky footer:

     - body becomes a vertical flex container.
     - min-height (NOT height) means "at least one viewport tall, grow if the
       content needs more". height:100% would cap the body at one viewport and
       let longer content spill out of it.
     - #ef-body-container (the div wrapping @RenderBody) gets flex: 1 0 auto,
       i.e. "grow to absorb any leftover space, but never shrink". Growing is
       what pushes the footer down on a short page; refusing to shrink is what
       stops a long page (Booking/Index, Routing/Index) from being squashed.
     - margin-top:auto on the footer is a belt-and-braces backstop: in a flex
       column an auto margin absorbs all remaining free space, so the footer
       still lands on the bottom edge even if a page suppresses the container's
       growth.

   This is why position:fixed is NOT used. A fixed footer is an overlay -- it
   would float on top of the bottom rows of the full-height AG Grid pages. See
   session journal 2026-08-24 section 5d, where exactly that footer was rejected
   during the Grid-Update merge for this reason.

   NOTE on making body a flex container: flex items ignore `float`. The direct
   children of body in _Layout.cshtml are #headermargin, #headernavcontainer, an
   inline <style>, #nav, #ef-body-container and footer -- none of which are
   floated. The legacy `float:left` on .column / .span-* lives INSIDE
   #ef-body-container and is unaffected.

   Fallback if the legacy floats ever misbehave: delete the `body` rule below
   and use `body > footer { position: sticky; top: 100vh; }` instead. That parks
   the footer at the bottom of the viewport when there is room and scrolls
   normally when there is not, without changing how anything else lays out.
   -------------------------------------------------------------------------- */

html {
    height: 100%;
}

body {
    /* height:auto is a deliberate override. screen.css line 577 declares
       html,body{height:100%}, which would CAP this flex container at exactly one
       viewport -- so on a long page the content would spill out of the box and
       margin-top:auto would park the footer at the bottom of that 100vh box,
       i.e. floating in the middle of the page on top of the content. Because
       ef-layout.css is linked after screen.css and the selectors have equal
       specificity, this wins. */
    height: auto;
    min-height: 100%;
    display: flex;
    flex-direction: column;
}

/* The header bars keep their natural height and are never compressed. */
body > #headermargin,
body > #headernavcontainer,
body > #nav {
    flex-shrink: 0;
}

/* Wrapper around @RenderBody. Grows to fill, never shrinks -- see section 1.
   The grid pages override the shrink half of this; see section 3. */
body > #ef-body-container {
    flex: 1 0 auto;
}


/* --------------------------------------------------------------------------
   2. Footer
   --------------------------------------------------------------------------
   Positioning and alignment moved here out of the inline style="" attribute on
   the <footer> element. Inline styles beat stylesheet rules regardless of
   specificity, so leaving them there would have forced every future tweak to
   use !important.
   -------------------------------------------------------------------------- */

body > footer {
    margin-top: auto;   /* backstop -- see section 1 */
    flex-shrink: 0;     /* never let the footer be squashed to nothing */
    text-align: center;
    padding: 6px 0;
}

/* Version number. Previously position:absolute; right:14px, which pulled it out
   of the centered text flow and pinned it to the right edge. Now a plain inline
   span, so it sits on the same centered line as the copyright. */
.ef-footer-version {
    color: #999;
    margin-left: 8px;
}


/* --------------------------------------------------------------------------
   3. Full-height page content (the four AG Grid pages)
   --------------------------------------------------------------------------
   Shipments/Index, Claims/Index, Booking/Pending and Booking/Quotes each used
   to size their content block with `height: calc(100vh - 160px)`. That 160px
   was a hand-tuned guess at the header stack (measured: 29px #headermargin +
   61px #headernavcontainer + ~67px #nav = ~157px), which left ~3px for the
   footer and pushed it off the bottom of a body with overflow:hidden.

   Those views now add .ef-viewport-page to their page-content div instead.
   Because body is a flex column, the chain below lets the browser compute the
   grid's height from the real rendered heights of the header bars and footer --
   no magic number to re-tune when the header changes.

   min-height:0 is REQUIRED, not cosmetic. A flex item defaults to
   min-height:auto, which refuses to shrink below its own content's size, so the
   grid would still push past the bottom of the screen without it. This is the
   single most common way a flex-based grid layout goes wrong.
   -------------------------------------------------------------------------- */

/* The grid views set ViewBag.BodyClass = "ef-viewport-lock", which _Layout.cshtml
   renders onto <body>. That replaces the old per-page
   `html, body { overflow: hidden; height: 100%; }` rule.

   height:100% (with html{height:100%} above) pins the body to exactly one
   viewport, and overflow:hidden means the page itself never scrolls -- the grid
   scrolls internally instead. */
body.ef-viewport-lock {
    height: 100%;
    overflow: hidden;
}

/* On these pages the RenderBody wrapper must also be a flex column, so the
   chain body -> #ef-body-container -> .ef-viewport-page can flex together.
   Note this re-enables shrinking (flex: 1 1 auto) which section 1 switched off.
   That is correct here and only here: these pages deliberately clip to the
   viewport. */
body.ef-viewport-lock > #ef-body-container {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

/* Everything else the grid views put in the body wrapper -- the toolbar partial,
   inline <script> blocks -- keeps its natural height. Without this, flex would
   distribute shrinkage across all the siblings and squeeze the toolbar. */
body.ef-viewport-lock > #ef-body-container > *:not(.ef-viewport-page) {
    flex-shrink: 0;
}

/* Goes on the page-content div itself, replacing height: calc(100vh - 160px). */
.ef-viewport-page {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}


/* ==========================================================================
   5. Modal dialog stacking
   ==========================================================================
   jQuery UI puts .ui-widget-overlay at z-index 100 and .ui-dialog just above
   it. That is below two things this application already stacks higher:

       #pending-col-chooser-menu   z-index 2000   (Pending.cshtml)
       #quotes-col-chooser-menu    z-index 2000   (Quotes.cshtml)

   Left at the jQuery UI defaults, a column chooser left open when a modal
   dialog opens floats ON TOP of the overlay and stays clickable -- so a
   "blocking" confirmation would have a hole in it. The delete confirmation on
   Booking/Pending depends on the overlay actually covering everything.

   These live here rather than in a view because jquery-ui.css is loaded by
   _Layout for every page, so every modal dialog in the application needs the
   same stacking, not just Pending.

   ONE rule, on .ui-front, deliberately. jQuery UI puts .ui-front on every
   widget it stacks -- dialogs, their overlays, autocomplete menus, datepickers
   -- and its own _moveToTop() then bumps an opening dialog above any visible
   .ui-front sibling. Raising the whole layer therefore preserves every
   widget's relative order for free, and the dialog still lands above its own
   overlay without being named here. Raising only .ui-dialog would strand a
   datepicker or autocomplete opened INSIDE a dialog behind it. */
.ui-front {
    z-index: 3000;
}
