/* =============================================================================
   nn-theme.css — application-wide values from the nn-wp port
   -----------------------------------------------------------------------------
   Loaded on every page (layouts/includes/header.blade.php). Its companions —
   nn-sidebar.css, nn-card-section.css, nn-table.css — are all scoped to one
   component; this is the file for the handful of things that are not.

   ⚠ LOADED EVERYWHERE IS NOT THE SAME AS APPLYING EVERYWHERE. The page ground
   below is scoped to `body.nn-mm-page` because it shipped unscoped and turned the
   background of every screen in the application grey. Check what a rule in here
   will reach before adding one: the file's audience is the whole app.

   WHY NOT app.scss, which is where global styles belong. Because app.scss is
   compiled to public/css/app.css by Laravel Mix, and the build DOES NOT RUN in
   this worktree: `npx mix` fails on a missing node_modules/dt1-core (the
   DataTables v1 alias). An edit to the SCSS would therefore have been a silent
   no-op — the source would say one thing and every browser would keep seeing the
   old app.css. Worse, the failed run had already written five compiled assets
   (nnc-core.css, four bundles and mix-manifest.json) before it errored, which
   had to be reverted.

   So: hand-written, straight into public/css, cache-busted by filemtime() on the
   tag — the same arrangement as ngen.css beside it and as the three component
   stylesheets. If the build is ever fixed, the right move is to fold this into
   app.scss and delete both this file and its <link>.
   ============================================================================= */

/* THE PAGE GROUND: #f5f5f5, CSS's `whitesmoke` — ON THE COMPOSED PAGES ONLY.

   Sampled from the colour swatch this was asked for rather than guessed — every
   one of that image's 416 pixels is #f5f5f5. It matters, because the first
   attempt used #e6e7e8 on the reasoning that "the same light grey" meant the
   palette token this port keeps restating (nn-wp's --ast-global-color-5, the card
   borders / grid stripes / nav hover). It is a visibly darker grey and it was the
   wrong one.

   #f5f5f5 is already the application's own page-furniture grey: `.footer` uses it
   (app.scss) and so does the maintenance screens' filter bar
   (datatable-page-styles). NOT an Astra palette token and not a ported value —
   nn-wp sets no page background of its own, it inherits Astra's.

   THE FOOTER IS NOT AFFECTED, contrary to what this note said a commit ago. I
   wrote that it would now blend into the page because `.footer` also declares
   #f5f5f5 — but it carried Bootstrap's `bg-dark`, whose
   `background-color: #343a40 !important` beat it, so that #f5f5f5 had never
   applied to anything. The footer is styled outright below.

   Bootstrap Reboot sets `body { background-color: #fff }` in nnc-core.css, which
   loads before this, so plain source order carries it — no !important, and no
   specificity games.

   DARK MODE IS UNAFFECTED: `body.darkmode` in app.css sets its own ground with
   !important, so it still wins. Checked rather than assumed.

   ⚠ SCOPED TO `.nn-mm-page`, AND IT WAS NOT AT FIRST. This was a bare `body`
   rule in a file loaded on every page, so the grey appeared across the whole
   application — every existing screen, not just the ones built against it. The
   cards, the sidebar and the section rules were designed on this ground; nothing
   else in the app was, and a global change of the page background was never the
   intent.

   The class comes from `@section('body-class', 'nn-mm-page')` in
   menu/page.blade.php, through the `body-class` hook on layouts/app.blade.php.
   Server-rendered on purpose: adding the class with script after load means a
   visible flash of white before the grey lands. Anything else that wants this
   ground says the same section — it is the one thing a descendant cannot style
   for itself. */
body.nn-mm-page {
    background-color: #f5f5f5;
}

/* -----------------------------------------------------------------------------
   THE FOOTER IS FIXED TO THE SCREEN
   -----------------------------------------------------------------------------
   Bottom of the VIEWPORT, always visible, never scrolled away. It replaces a
   sticky footer (flex column on body, <main> taking the slack) that sat at the
   bottom of the PAGE — those three rules are gone with it, and body is back to
   plain block flow.

   ⚠ IT IS A STACKING CONTEXT, AND NOTHING PAGE-WIDE MAY LIVE INSIDE IT. This
   note used to say the opposite — that a positioned element with `z-index: auto`
   does not establish one, so the ajax loader, error alert and search modal could
   go on living inside the <footer> where footer.blade.php has always put them.

   That rule is true of `relative` and `absolute`. IT IS NOT TRUE OF `fixed`: a
   fixed-position element always establishes a stacking context, whatever its
   z-index. Making this footer fixed therefore trapped every one of those
   descendants at the footer's own level — and Bootstrap appends `.modal-backdrop`
   to the BODY at z-index 1040, outside the trap, so the backdrop painted OVER a
   modal that was inside it. Searching for a container that does not exist put the
   error modal behind its own overlay with the page unclickable behind that. The
   loader's 1100 was trapped by the same thing, which is precisely what leaving the
   z-index off was meant to avoid.

   The fix is where those elements live, not what z-index they carry: they are
   siblings of the footer now (see footer.blade.php), back in the root stacking
   context where their numbers mean what they say. Nothing page-wide goes back
   inside this element.

   Still no z-index here, now for a smaller reason: it does not need one. It is
   the last thing in the body and paints above the page content in tree order. The
   one thing that could have painted over it was the grids' sticky table header at
   `z-index: 2`; `.nn-panel` is a stacking context of its own (see
   menu/page.blade.php) so that 2 stays inside its panel.

   --nn-footer-h IS MEASURED, not assumed. The value below is a fallback for
   before the script runs; footer.blade.php measures the real height and writes it
   to :root, because the footer is a two-column Bootstrap grid that stacks on
   narrow screens and its right-hand cell is filled in by the analytics script. A
   hardcoded reserve would be wrong at some width or after some render, and this
   session has already had three hardcoded offsets turn out wrong.
   ----------------------------------------------------------------------------- */
:root {
    --nn-footer-h: 2.75rem;
}

body {
    /* Reserve the strip the fixed footer covers, so the last line of a page is
       never hidden behind it. */
    padding-bottom: var(--nn-footer-h);
}

/* Bare mode has no fixed footer to clear — footer.blade.php drops the classes, so
   the element stays in normal flow and the reserve would just be dead space. */
body.nn-bare {
    padding-bottom: 0;
}

body > footer.footer {
    position: fixed;
    right: 0;
    bottom: 0;
    left: 0;
}

/* nn-wp's .customer-dashboard-footer, ported: the sidebar blue, white text,
   0.9rem Roboto Condensed, and a hairline top border in white at 10%.

   Its layout is NOT copied. nn-wp centres its footer's contents because it holds
   an attribution and a button; ours is a Bootstrap grid with the copyright left
   and the analytics readout right, which reads fine and is not what was asked to
   change. Colour, font and metrics only.

   `body > footer.footer`, NOT a bare `.footer`, and that is not belt-and-braces.
   app.scss declares its footer rules NESTED INSIDE `body { … }`, so they compile
   to `body .footer` — specificity (0,1,1), which quietly out-specifies a bare
   `.footer` (0,1,0) no matter which file loads last. A first attempt at this
   block used the bare selector and lost `background-color` and `line-height` to
   app.css while `font-family` came through, because app.css happens not to
   declare that one. Only resolving the cascade showed it; reading the two files
   would not have, since the nesting is invisible in the SCSS.

   `line-height: normal` and `min-height: 0` undo `line-height: 60px` /
   `min-height: 60px` there, which existed to centre a single line inside a 60px
   bar. With nn-wp's padding doing the spacing, 60px would leave the text floating
   in a bar two and a half times taller than it needs. */
body > footer.footer {
    padding: 0.75rem 1rem;
    background-color: #324b6b;
    color: #fff;
    font-family: 'Roboto Condensed', sans-serif;
    font-size: 0.9rem;
    line-height: normal;
    min-height: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
}

/* !important, and unavoidable. app.scss has `body p { color: #666 !important }`,
   which no specificity beats — and #666 on this blue is barely legible. It was
   barely legible on the #343a40 the footer used to be, too. */
body > footer.footer p {
    color: rgba(255, 255, 255, 0.85) !important;
    margin-bottom: 0;
}

body > footer.footer a {
    color: #fff;
    text-decoration: underline;
}

/* -----------------------------------------------------------------------------
   THE PAGE MUST NEVER SCROLL SIDEWAYS
   -----------------------------------------------------------------------------
   Wide content belongs to whatever contains it — a table scrolls inside its
   panel, not by dragging the whole document along.

   `min-width: 0` IS THE FIX, and it is not obvious why. A flex item defaults to
   `min-width: auto`, which resolves to its content-based minimum — and in CSS
   `min-width` BEATS `max-width`. So `#nn-body-r`, and the `.col-md-*` panel
   columns inside it, would refuse to shrink below the widest thing they contain
   no matter what percentage cap they carry. One nowrap table is enough: its
   min-content width propagates up the whole chain and the document grows to fit.
   Zeroing the automatic minimum lets each box honour its cap and hands the
   overflow to the scroll container inside it.

   WHAT NOT TO DO: `overflow-x: hidden` (or clip) on html/body. It looks like the
   direct fix and it would work, but it makes the page a scroll container, and
   `position: sticky` resolves against the nearest scroll container rather than
   the viewport — so it would silently unstick the left sidebar and the grids'
   sticky headers. Fix the cause, not the symptom.
   ----------------------------------------------------------------------------- */
#nn-body-r {
    min-width: 0;
}

/* -----------------------------------------------------------------------------
   THE ALERT BANNER
   -----------------------------------------------------------------------------
   It is relocated into the content column at parse time (see the layouts), so it
   spans the band the sections render in rather than sitting above the whole row
   and pushing the left nav down. All that is needed here is a gap beneath it, so
   it does not butt against the first card.

   Nothing sets its width: it is a block in a Bootstrap column and fills it, which
   is exactly the span asked for.
   ----------------------------------------------------------------------------- */
#nn-body-r > #alert-system {
    margin-bottom: 0.5rem;
}
