/* =============================================================================
   Cabinetry Flow Pro – app.css
   ---------------------------------------------------------------------------
   Minimal overrides on top of MudBlazor's Material Design stylesheet.
   MudBlazor replaces Bootstrap entirely, so Bootstrap-specific classes have
   been removed.
   ============================================================================= */

/* Let MudBlazor's Roboto font cascade; override only if needed */
html, body {
    font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    margin: 0;
    padding: 0;
}

/* Blazor error boundary (kept from default template) */
.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."
}

/* Blazor error banner (bottom of page) */
#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;
}

/* =============================================================================
   LOGIN / SPLASH SCREEN
   Ported from: CFP.UI.Login.dfm
     The Delphi form filled the page with an IWImageFile background
     (DistinctiveHighCountyCab.jpg) and floated the brand labels plus the
     username / password edits on top of it.  Until that artwork is copied into
     wwwroot, a brand-coloured gradient stands in.
   ============================================================================= */
.cfp-login-bg {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: linear-gradient(135deg, #1a237e 0%, #0d47a1 55%, #1565c0 100%);
}

.cfp-login-card {
    width: 100%;
    max-width: 420px;
    border-radius: 10px;
}

/* -----------------------------------------------------------------------------
   SPLASH SCREEN OVERLAY

   Ported from CFP.UI.Splash.pas / ShowSplashScreen.

   In Delphi the splash was a borderless VCL TForm created with TForm.CreateNew,
   holding a single TImage stretched to the whole screen.  It was drawn by
   Windows on the machine that launched ClientFlowPro.exe, BEFORE the IntraWeb
   server was listening and before any browser existed, then torn down after
   SPLASH_DURATION_MS.

   NOTE - why a CSS overlay instead of a second form
     A browser has no equivalent of "a window that exists before the web server
     starts" - by the time anything can be shown, the server has already served
     a page.  So the web port turns the splash into a full-viewport <div> that is
     painted on top of the sign-in card and then removed.  The user-visible
     result is the same (branding for three seconds, then the logon screen); the
     mechanism is completely different.

     position:fixed + inset:0 is the CSS way of saying "cover the whole client
     area", which is what the Delphi version achieved with BoundsRect :=
     Screen.MonitorFromPoint(...).BoundsRect.

     The z-index only has to beat the MudBlazor card (elevation 8); 2000 is well
     clear of MudBlazor's own stacking range for non-modal content.
   ----------------------------------------------------------------------------- */
/* NOTE – no fade-in animation on the splash
     The original used @keyframes cfp-splash-fade (opacity 0 → 1 over 400 ms).
     That looked elegant, but during those 400 ms the overlay was semi-transparent
     and the login card underneath bled through – so you briefly saw the sign-in
     form before the splash covered it.  Darren reported this as "the login screen
     shows just before the splash screen".

     Removing the animation makes the splash opaque from the very first painted
     frame.  The background colour (#0d2b4e) is chosen to match the dark blue
     band in the artwork, so even if the splash PNG has not loaded yet the screen
     is a solid dark blue, not a blank white flash.

     cursor:wait gives the user visual feedback that the app is loading – Delphi
     did not set crHourGlass during its splash, but Darren asked for a busy
     pointer to make it look like something is happening. */
.cfp-splash {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #0d2b4e;
    cursor: wait;
}

/* While the splash div is in the DOM, hide the login card that sits below it.
   This is a pure-CSS sibling rule, so it survives Blazor Server's circuit-connect
   re-render without any flicker.  The Blazor code ALSO hides the card via a
   conditional class (belt-and-braces), but this CSS rule is the one that prevents
   the flash Darren reported: "reappears briefly for a split second then goes back
   to the splash screen".  That flash happened when Blazor replaced the pre-rendered
   static DOM with its interactive DOM – for one frame the splash div was absent
   and the login card was not yet marked hidden by the @code block. */
.cfp-splash ~ .cfp-login-bg {
    opacity: 0;
    visibility: hidden;
}

/* Smooth entrance for the login card when the splash is removed from the DOM.
   The transition fires because the sibling rule above no longer matches, so
   opacity jumps from 0 → 1 over 350 ms.  visibility is toggled instantly (0 s
   delay) so the element becomes focusable the moment it starts fading in. */
.cfp-login-bg {
    transition: opacity 350ms ease-out, visibility 0s;
}

/* object-fit:contain reproduces the Delphi TImage settings Proportional=True +
   Stretch=True: fill as much of the screen as possible without distorting the
   artwork's 3:2 aspect ratio. */
.cfp-splash img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* -----------------------------------------------------------------------------
   APEX / MARKETING LANDING PAGE  (Landing.razor at /landing)

   Shown to visitors who reach the product without a tenant subdomain (apex /
   www / no-tenant hosts).  It cannot use any tenant branding, so it styles the
   SHARED splash art with generic product copy.  The dark-blue gradient matches
   the login background (.cfp-login-bg) so there is no white flash before the
   PNG loads.
   ----------------------------------------------------------------------------- */
.cfp-landing-bg {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: linear-gradient(135deg, #1a237e 0%, #0d47a1 55%, #1565c0 100%);
}

.cfp-landing-card {
    max-width: 960px;
    width: 100%;
    text-align: center;
    color: #ffffff;
}

/* Proportional splash art, capped so it never dwarfs the copy on large screens. */
.cfp-landing-logo {
    display: block;
    width: 100%;
    max-width: 920px;
    height: auto;
    margin: 0 auto 28px auto;
    border-radius: 12px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);
}

.cfp-landing-title {
    font-size: 2rem;
    font-weight: 600;
    margin: 0 0 8px 0;
    line-height: 1.2;
}

.cfp-landing-tagline {
    font-size: 1.1rem;
    font-style: italic;
    opacity: 0.9;
    margin: 0 0 24px 0;
}

.cfp-landing-instruction {
    font-size: 1.05rem;
    margin: 0 0 12px 0;
}

.cfp-landing-example {
    font-family: "Courier New", Courier, monospace;
    font-weight: 600;
    white-space: nowrap;
    background: rgba(255, 255, 255, 0.12);
    padding: 2px 8px;
    border-radius: 6px;
}

.cfp-landing-help {
    font-size: 0.9rem;
    opacity: 0.75;
    margin: 0;
}

/* Utility used by the list-screen button rows (Bootstrap's .gap-2 is gone). */
.gap-2 > * + * { margin-left: 8px; }

/* -----------------------------------------------------------------------------
   Project-Matrix "jump target" highlight.

   Ported from CFP.UI.CabinetrySetEdit.pas / HighlightMatrixTarget, which set the
   target edit box's BorderColor to red and gave it focus so the user could see
   which figure the matrix row they clicked actually feeds.  Delphi had to poke
   the control's properties from Pascal; here a single CSS class does it, and the
   .razor tab just decides whether to apply it.
   ----------------------------------------------------------------------------- */
.cfp-mtx-target .mud-input-outlined-border {
    border-color: #d32f2f !important;
    border-width: 2px !important;
}

/* The red border above is PERSISTENT — it stays for as long as the field is
   flagged as the matrix target, so the cue survives even if the arrival pulse
   finishes while the tab / grid is still loading.  The glow pulse below simply
   adds movement to catch the eye on arrival. */
.cfp-mtx-target {
    border-radius: 4px;
    animation: cfp-mtx-pulse 1.1s ease-in-out 3;
}

@keyframes cfp-mtx-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(211, 47, 47, 0.0); }
    50%      { box-shadow: 0 0 0 4px rgba(211, 47, 47, 0.40); }
}

/* -----------------------------------------------------------------------------
   EDIT-SCREEN ACTION BAR  (used by Components/Shared/EditActionBar.razor)

   Ported from the btnSave / btnCancel pair that Delphi anchored to the bottom
   edge of every edit frame with akBottom.  Because a Delphi frame was exactly
   as tall as the browser window, those buttons were ALWAYS on screen.

   A Blazor page is a tall scrolling document instead, so buttons placed in the
   title row scrolled out of sight the moment the user started filling in the
   lower half of a long form - which is exactly the "Save button is not visible"
   problem this fixes.  position:sticky pins the bar to the bottom edge of the
   viewport while the form scrolls behind it.
   ----------------------------------------------------------------------------- */
.cfp-action-bar {
    position: sticky;
    bottom: 0;
    z-index: 5;                       /* above the form, below MudBlazor popovers */
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 24px;
    padding: 12px 16px;
    background-color: #ffffff;
    border-top: 1px solid #e0e0e0;
    /* Lift the bar off the content behind it so it reads as a separate strip. */
    box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.08);
}

/* -----------------------------------------------------------------------------
   GRID TITLE

   Delphi put a TIWLabel directly above every TIWGrid (lblAreas, lblSets,
   lblCosts, ...) so you could always tell what a grid was showing.  Those
   captions were lost in the first pass of the port; this class restores them
   with one consistent look instead of a hand-rolled MudText style per page.
   ----------------------------------------------------------------------------- */
.cfp-grid-title {
    font-size: 1rem;
    font-weight: 600;
    color: #1a237e;
    margin-bottom: 6px;
}

/* -----------------------------------------------------------------------------
   GRID HEADER ROW  (.cfp-grid-header)

   Delphi reference
     Every grid in the Delphi app painted its own header.  In each
     grdXxxRenderCell handler the first line was the same test:

         if ARow = 0 then
         begin
           ACell.BackgroundColor := clWebLIGHTBLUE;
           ACell.Font.Style      := [fsBold];
         end;

     ...repeated in CFP.UI.ProjectAreaList.pas (grdAreasRenderCell,
     grdCostsRenderCell), CFP.UI.CabinetrySetList.pas, CFP.UI.CustomerList.pas,
     CFP.UI.ProjectList.pas and the six grids inside
     CFP.UI.CabinetrySetEdit.pas.

   NOTE – why one CSS class replaces a dozen RenderCell handlers
     IntraWeb had no stylesheet story, so "colour the header" meant writing the
     same three lines of Pascal for every single grid.  In Blazor the header is
     just a <tr> of <th> elements, so ONE class does the whole application and
     each MudDataGrid opts in with a single attribute:

         <MudDataGrid HeaderClass="cfp-grid-header" ... >

     The colour is the same #ADD8E6 (clWebLIGHTBLUE) that
     CfpTheme.GridHeaderColor already applies inline to the hand-built
     MudSimpleTable summaries (Area Cost Summary, Project Cost Summary), so the
     two kinds of table now match.

   NOTE – why the selectors are so specific
     MudBlazor's own rules (.mud-table-head .mud-table-cell) set a background
     and colour on every header cell, and they win on specificity against a
     bare ".cfp-grid-header".  Naming the cell inside the class - and adding
     !important - is what actually makes the colour stick.  This is the CSS
     equivalent of Delphi's "the last assignment to ACell.BackgroundColor wins".
   ----------------------------------------------------------------------------- */
.cfp-grid-header,
.cfp-grid-header th,
.cfp-grid-header .mud-table-cell,
tr.cfp-grid-header > th {
    background-color: #add8e6 !important;   /* clWebLIGHTBLUE */
    color: #1a237e !important;              /* brand indigo, readable on light blue */
    font-weight: 600 !important;
}

/* The sort arrow / column-options button inherits the header text colour so it
   does not disappear against the light blue. */
.cfp-grid-header .mud-button-root,
.cfp-grid-header .mud-icon-root {
    color: #1a237e !important;
}

/* -----------------------------------------------------------------------------
   FIXED GRID HEIGHT

   Delphi reference
     Each TIWGrid had a fixed Height in the .dfm and simply scrolled when the
     dataset held more rows than fitted.  Grids never grew, never collapsed.

   NOTE – Height="..." on MudDataGrid vs this class
     MudDataGrid's Height parameter already produces a scrolling body, and that
     is what every grid in this app now uses (CfpTheme.GridHeight = 440px, about
     ten Dense rows plus the header).  The rules below only tidy up the result:

       * keep the scrolled body from collapsing to nothing when a grid is empty,
         so an empty grid is still the same size as a full one - exactly like a
         fixed-Height TIWGrid showing "no rows";
       * make sure the sticky header sits ABOVE the scrolling rows (z-index),
         otherwise rows scroll over the top of the captions.
   ----------------------------------------------------------------------------- */
.mud-table-container {
    /* Stops a 0-row grid from shrinking to a sliver. */
    min-height: 0;
}

.mud-table-sticky-header thead th {
    position: sticky;
    top: 0;
    z-index: 2;
}



/* -----------------------------------------------------------------------------
   FIXED-HEIGHT SIMPLE TABLES  (.cfp-fixed-table)

   Delphi reference
     The cost-summary panels on CFP.UI.CabinetrySetList.pas (grdCosts,
     grdAccessories, grdHardware, grdLumber, grdGdsm) and the Area Cost
     Summary on CFP.UI.ProjectAreaList.pas were ordinary TIWGrids with a
     fixed Height in the .dfm, exactly like every other grid on the form.

   NOTE – why these need their own class
     Those five/six summaries are rendered with MudSimpleTable, not
     MudDataGrid.  MudSimpleTable has NO Height parameter, so the 440 px
     that CfpTheme.GridHeight gives every MudDataGrid was silently skipped
     and the summaries sized themselves to their content.  That is what made
     them look wrong next to the fixed grids above.

     The height itself is still supplied inline from CfpTheme.GridHeight so
     there is exactly ONE place that decides how tall a grid is.  This class
     only supplies the scrolling behaviour:

       * MudBlazor gives .mud-table-container "overflow-x:auto; max-height:100%",
         so it needs an explicit height plus overflow-y before it will scroll
         vertically inside the 440 px box;
       * the header is pinned so it behaves like the FixedHeader="true" grids.
   ----------------------------------------------------------------------------- */
.cfp-fixed-table .mud-table-container {
    height: 100%;
    overflow-y: auto;
}

.cfp-fixed-table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background-color: #add8e6; /* clWebLIGHTBLUE - same as .cfp-grid-header */
}

/* -----------------------------------------------------------------------------
   GRID HEAD BLOCK  (.cfp-grid-head)

   Delphi reference
     On the Delphi forms every grid's caption label sat at a hard-coded Top
     in the .dfm, so two grids placed side by side always started at the same
     Y coordinate - the designer guaranteed it.

   The problem this solves
     In Blazor the two columns of a side-by-side row are independent flow
     layouts.  The LEFT column above a grid holds just a caption; the RIGHT
     column (a change-history panel) holds a caption AND a "Show change
     history" tick-box.  The tick-box is about 34 px tall, so the right-hand
     grid started 34 px LOWER than the grid beside it and the two header rows
     did not line up.

   NOTE – why a fixed min-height and not flexbox
     There is no CSS way to say "make these two sibling blocks in different
     grid columns the same height" without a shared flex/grid container, and
     MudGrid does not give us one at that level.  Reserving the same vertical
     space in both columns is the reliable fix: the caption-only column gets
     the same block height as the caption-plus-tick-box column, so both grids
     start at exactly the same Y.

     72 px = caption (16 px text, ~24 px line box, + 6 px margin) plus a Dense
     MudCheckBox row (~34 px), rounded up so a wrapped two-line caption still
     fits without pushing the grid down.
   ----------------------------------------------------------------------------- */
.cfp-grid-head {
    min-height: 72px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
}

/* The tick-box carries its own padding; strip the extra top margin so the
   caption + tick-box pair fits the 72 px block predictably. */
.cfp-grid-head .mud-input-control {
    margin-top: 0;
}


/* =============================================================================
   CONTRACT / INVOICE IMAGE PLACEHOLDERS
   -----------------------------------------------------------------------------
   When no contract logo or thank-you graphic has been uploaded, the Contract
   and Invoice pages show a dashed "Company Logo" / "Thank You Graphic" box so
   the user can see where the image will land.  Those boxes are guidance for the
   screen only — a printed page or the QuestPDF output must show NOTHING in that
   spot (no empty box, no reserved space).  This rule hides every placeholder in
   print; the real <img> (rendered only when an image exists) is unaffected and
   still prints.
   ============================================================================= */
@media print {
    .cfp-image-placeholder { display: none !important; }
}

/* =============================================================================
   PUNCH LIST – INLINE STATUS DROPDOWN
   -----------------------------------------------------------------------------
   Ensure the popover (dropdown menu) for the inline status MudSelect in the
   punch list grid is wide enough to display all status labels without clipping.
   ============================================================================= */
.punch-status-popover {
    min-width: 140px !important;
}



/* =============================================================================
   PUNCH LIST CHECKLIST  (touch-friendly alternate view)
   -----------------------------------------------------------------------------
   The Punch List Checklist (PmPunchChecklistDialog) is designed for field use
   on a phone or tablet as well as the desktop.  Each punch item is a large,
   whole-card touch target so it can be checked/unchecked with a fingertip.

     .punch-checklist          wrapper around all rows
     .punch-checklist-row      one tappable card (>=56px comfortable touch size)
     .punch-checklist-locked   a Closed item — shown checked, dimmed, not tappable
   ============================================================================= */
.punch-checklist {
    display: flex;
    flex-direction: column;
}

.punch-checklist-row {
    min-height: 56px;
    display: flex;
    align-items: center;
    transition: background-color 0.12s ease-in-out;
    user-select: none;
}

.punch-checklist-row:not(.punch-checklist-locked):hover {
    background-color: #f0f7ff; /* subtle hover for pointer devices */
}

.punch-checklist-row:not(.punch-checklist-locked):active {
    background-color: #e3f0ff; /* touch feedback */
}

.punch-checklist-locked {
    opacity: 0.6;
    cursor: default;
}



/* =============================================================================
   PROJECT NOTES  (.cfp-note-*)  — Project Management Notes page (/pm/notes)
   ---------------------------------------------------------------------------
   Each project note renders as a card in a newest-first list.  The header row
   carries the date/time + author on the left and the Edit control on the right;
   it wraps on narrow (phone) widths so the author and the button never collide.
   The note text preserves the author's line breaks and wraps long words so a
   pasted URL can never overflow the card on a phone.
   ============================================================================= */
.cfp-note-card {
    border-left: 3px solid #1a237e; /* matches the PM heading accent */
}

.cfp-note-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 4px 12px;
}

.cfp-note-meta {
    color: #1a237e;
}

.cfp-note-author {
    font-weight: 600;
}

.cfp-note-text {
    white-space: pre-wrap;   /* keep the author's line breaks */
    overflow-wrap: anywhere; /* never overflow on a long unbroken string */
}




/* =========================================================================
   PROJECT OVERVIEW  (PmOverview.razor)
   Screen + Print styles — Phase 1
   Palette sampled from the approved print mock-ups:
     · section band navy   #1c5280
     · column-header steel #d4dfe9 (text #14344f)
     · zebra shading       #eef2f7
     · grid borders        #c9d3de
     · serif headings      Georgia / Times
   ========================================================================= */

/* --- Serif family used for the on-screen project heading --- */
.overview-project-heading {
    font-family: Georgia, "Times New Roman", Times, serif;
}

/* --- Project heading ("PRJ-… — Name") --- */
.overview-project-heading {
    font-size: 1.7rem;
    font-weight: 700;
    color: #14263d;
    margin: 0 0 .75rem 0;
    line-height: 1.15;
}

/* --- Two-column responsive layout (summary + punch/note) --- */
.overview-two-col {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    align-items: flex-start;
}
.overview-summary-cols .overview-col {
    flex: 1 1 320px;
    min-width: 280px;
}
.overview-punchnote-cols .overview-col-main {
    flex: 1 1 60%;
    min-width: 340px;
}
.overview-punchnote-cols .overview-col-side {
    flex: 1 1 30%;
    min-width: 260px;
}

/* --- Info table (Customer / Status / Install Date etc.) --- */
.overview-info-table {
    border-collapse: collapse;
    width: 100%;
}
.overview-info-table td {
    padding: 3px 8px 3px 0;
    vertical-align: top;
    font-size: .9rem;
    color: #212121;
}
.overview-label {
    font-weight: 700;
    white-space: nowrap;
    min-width: 165px;
    color: #37474f;
}

/* --- Section heading bands (navy) --- */
.overview-section-head {
    background-color: #1c5280;
    color: #fff;
    padding: 7px 12px;
    font-weight: 700;
    font-size: .9rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    margin: 0;
    line-height: 1.2;
}

/* --- Overview data tables --- */
.overview-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .85rem;
}
.overview-table thead th {
    background-color: #d4dfe9;
    color: #14344f;
    padding: 6px 8px;
    font-weight: 700;
    text-align: left;
    border: 1px solid #c9d3de;
    white-space: nowrap;
}
.overview-table tbody td {
    padding: 5px 8px;
    border: 1px solid #dbe2ea;
    vertical-align: top;
    color: #212121;
}
.overview-table tbody tr:nth-child(even) {
    background-color: #eef2f7;
}
.overview-total-row td {
    background-color: #d4dfe9 !important;
    border-top: 2px solid #1c5280;
    color: #14344f;
    font-weight: 700;
}

/* --- Right-aligned numeric helper --- */
.overview-table .text-right,
.text-right { text-align: right; }

/* --- Punch table numeric columns --- */
.overview-punch-table th:nth-child(n+3),
.overview-punch-table td:nth-child(n+3) {
    text-align: right;
    width: 68px;
}

/* --- Most Recent Note card --- */
.overview-note-card {
    border: 1px solid #c9d3de;
    border-top: none;
    padding: 12px 14px;
    background: #f4f7fb;
    min-height: 80px;
}
.overview-note-meta {
    font-size: .85rem;
    font-weight: 700;
    color: #14344f;
    margin-bottom: 8px;
}
.overview-note-body {
    font-size: .88rem;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    color: #212121;
    line-height: 1.4;
}

/* --- Cabinetry Globals sub-label (when multiple sets) --- */
.overview-globals-set-label {
    font-weight: 700;
    font-size: .9rem;
    color: #14344f;
    padding: 8px 0 2px;
    border-bottom: 1px solid #c9d3de;
    margin-bottom: 0;
}
.overview-globals-table {
    margin-bottom: 10px;
}

/* --- Empty-state note --- */
.overview-empty-note {
    font-size: .88rem;
    color: #666;
    padding: 8px 12px;
}

/* --- Section spacing --- */
.overview-summary       { margin-top: .5rem; }
.overview-tabs-section  { margin-bottom: 2rem; }

/* =========================================================================
   PRINT-ONLY  vs  SCREEN-ONLY  visibility toggles
   ========================================================================= */
.overview-screen-only { display: block; }

/* Screen-side spacing for the two-column blocks */
.overview-punchnote-cols { margin-top: 1.25rem; }

