/* ════════════════════════════════════════════════════════════════
   A NAM INVOICE — PHONE / iOS HARDENING (customer app + public site)

   The same set of fixes the admin panel already carries, kept in one
   file so every page inherits them instead of each page solving (or
   forgetting) them on its own.

   Loaded after each page's own <style>, so equal-specificity rules win.
   ════════════════════════════════════════════════════════════════ */

/* Safari inflates text on rotation unless this is set. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* ── iOS auto-zoom ────────────────────────────────────────────────
   Safari zooms the whole page in when a focused field has text under
   16px, and never zooms back out — the "everything got huge" effect.
   The pointer query covers iPads (1024px wide, where a width rule
   would miss); the width query covers phones.                        */
@media (hover: none) and (pointer: coarse), (max-width: 1023px) {
    input, select, textarea,
    .form-group input, .form-group select, .form-group textarea,
    .search-bar input, .filter-bar input, .filter-bar select,
    .item-desc, .item-qty, .item-price {
        font-size: 16px !important;
    }
    input, select, textarea { min-height: 44px; }
    input[type="checkbox"], input[type="radio"] { min-height: 0; }
}

/* ── Wide tables must scroll, not clip ───────────────────────────── */
.table-wrap, .tbl-wrap, .table-scroll, .table-container,
.table-responsive, .items-table-wrap, .data-table-wrap {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
}

/* ── Full-height surfaces track the visible viewport ─────────────── */
body { min-height: 100vh; min-height: 100dvh; }
.sidebar { height: 100vh; height: 100dvh; }

/* ── Notch and home indicator ────────────────────────────────────── */
.top-bar, .header, .app-header {
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
}
.content-container, .app-content, .main-content > .container {
    padding-left: max(14px, env(safe-area-inset-left));
    padding-right: max(14px, env(safe-area-inset-right));
}
.bottom-nav, .app-bottom-nav {
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* ── Nothing may push the page wider than the screen ─────────────── */
img, video, canvas, svg, iframe { max-width: 100%; height: auto; }
pre, code { white-space: pre-wrap; word-break: break-word; }

/* Grid and flex children default to min-width:auto and refuse to shrink
   below their content; one nowrap button is enough to widen the whole
   track past the screen. */
.stats-grid > *, .quick-grid > *, .panels-two > *, .panels-three > *,
.cards-grid > *, .doc-grid > *, .summary-grid > *, .form-row > *,
.pricing-grid > *, .rep-grid > *, .mstats > *, .filter-bar > *,
.row-item > *, .list-row > * {
    min-width: 0;
}

@media (max-width: 520px) {
    /* Long unbroken strings — emails, invoice numbers, references — set a
       min-content width wider than the card. `anywhere` also shrinks
       min-content, which is what actually stops the sideways scroll. */
    .card, .card *, .stat-card, .stat-card *, .panel, .panel *,
    .inv-card, .inv-card *, .doc-card, .doc-card *,
    .summary-card, .summary-card *, .pricing-card, .pricing-card *,
    td, th {
        overflow-wrap: anywhere;
    }

    /* Pixel column minimums are wider than a small phone's content area. */
    .stats-grid, .summary-grid, .cards-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    }
    .form-row, .pricing-grid, .doc-grid, .rep-grid, .plans-grid {
        grid-template-columns: minmax(0, 1fr) !important;
    }

    /* Search rows stack rather than forcing the page wider. */
    .search-bar, .search-bar form, .filter-bar, .bulk-actions,
    .cycle-switch {
        flex-wrap: wrap;
    }
    .search-bar input, .search-bar select,
    .filter-bar input, .filter-bar select {
        flex: 1 1 100%;
        min-width: 0;
    }

    /* Comfortable tap targets without stretching the layout. */
    .btn-mini, .btn-sm, .action-btn, .icon-btn {
        min-height: 34px;
        display: inline-flex;
        align-items: center;
    }
}

/* iPhone SE and other genuinely narrow screens. */
@media (max-width: 360px) {
    .stats-grid, .summary-grid, .cards-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    }
    .hero-figures { grid-template-columns: minmax(0, 1fr) !important; }

    /* The header row is the tightest part of the layout once the theme
       switch is docked into it — let it shrink rather than push the page
       a couple of pixels wider than the screen. */
    .top-bar > *, .header > * { min-width: 0; }
    .top-right { gap: 6px; flex-shrink: 1; }
    .theme-toggle {
        width: 34px; height: 34px; flex: 0 0 34px; font-size: 14px;
    }
}

/* Modals must never exceed the screen or trap content off-canvas. */
.modal .modal-box, .modal .modal-content, .modal-box, .modal-content {
    max-width: min(96vw, 920px);
    max-height: 92vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

/* ════════════════════════════════════════════════════════════════
   SHARED COMPONENTS
   Used by more than one page, so they live here once instead of
   being copied into each page's <style>.
   ════════════════════════════════════════════════════════════════ */

/* ── Monthly / yearly billing switch ──────────────────────────── */
.cycle-switch{
    display:inline-flex; align-items:center; gap:4px; padding:4px; margin-bottom:24px;
    background:var(--glass-bg,rgba(255,255,255,.06));
    border:1px solid var(--glass-border,rgba(255,255,255,.12));
    border-radius:100px; max-width:100%; flex-wrap:wrap;
}
.cycle-opt{
    display:inline-flex; align-items:center; gap:8px;
    padding:9px 18px; border-radius:100px; text-decoration:none;
    font-size:13px; font-weight:600; color:var(--text-muted);
    transition:background .2s,color .2s; white-space:nowrap;
}
.cycle-opt:hover{ color:var(--text-primary); }
.cycle-opt.on{
    background:linear-gradient(135deg,var(--accent),var(--accent2));
    color:#fff; box-shadow:0 4px 14px rgba(45,156,219,.32);
}
.cycle-save{
    font-size:10px; font-weight:700; padding:3px 8px; border-radius:100px;
    background:rgba(56,217,169,.18); color:var(--accent2); white-space:nowrap;
}
.cycle-opt.on .cycle-save{ background:rgba(255,255,255,.22); color:#fff; }

/* ── Yearly price note under a plan price ─────────────────────── */
.price-note{ margin-bottom:18px; display:flex; flex-direction:column; align-items:center; gap:6px; }
.price-note .was{ font-size:14px; color:var(--text-faint); text-decoration:line-through; }
.price-note .save-pill{
    display:inline-block; padding:4px 12px; border-radius:100px;
    font-size:11px; font-weight:700;
    background:rgba(56,217,169,.16); color:var(--accent2);
    border:1px solid rgba(56,217,169,.3);
}
.price-note small{ font-size:11px; color:var(--text-muted); }

/* ── Brand block (top of every sidebar) ───────────────────────────
   Replaces the old placeholder: a rounded square holding a generic
   chart icon with the site name spelled out beneath it. The real
   wordmark is wide (roughly 2.2:1), so it gets a wide, boxless slot
   instead of being squeezed into a 66px square.                      */
.brand-block{
    display:flex; flex-direction:column; align-items:center; gap:8px;
    padding:4px 6px; text-decoration:none; color:inherit;
    transition:opacity .2s, transform .2s;
}
.brand-block:hover{ opacity:.85; transform:translateY(-1px); }
.brand-logo{
    display:block;
    width:auto;
    max-width:min(186px, 100%);
    max-height:74px;              /* never taller than the header allows */
    height:auto;
    object-fit:contain;
    margin:0 auto;
}
.brand-fallback{
    font-size:15px; font-weight:800; letter-spacing:-.2px;
    color:var(--accent,#2D9CDB); text-align:center;
}
.brand-sub{
    font-size:9.5px; font-weight:700; letter-spacing:2.2px;
    text-transform:uppercase; color:var(--text-muted,#9fb4d0);
    text-align:center;
}

/* The wordmark is mid-blue, which reads well on white but can sink into a
   navy sidebar — lift it slightly in dark mode so it stays crisp. */
:root[data-theme='dark'] .brand-logo{
    filter:brightness(1.18) saturate(1.05);
}

/* The old square/icon presentation is retired wherever the brand block is
   used; hide any leftovers so nothing double-renders during rollout. */
.brand-block + .logo-wrap,
.sidebar-header .logo-wrap:empty{ display:none; }

@media (max-width:1023px){
    .brand-logo{ max-width:min(172px, 100%); max-height:64px; }
}

/* ════════════════════════════════════════════════════════════════
   SAVE / ACTION TOAST  ("Invoice saved", "Quotation updated", …)

   There used to be several of these. The document pages each carried
   their own `.toast`, hard-coded dark navy at `bottom:24px` — which on
   the light theme painted a dark slab over the page, and on a phone sat
   exactly where the bottom navigation is. pwa-init.js carried a third
   that built `.toast-notification` markup styled only in mobile-app.css,
   a stylesheet no page loads, so those confirmations rendered as bare
   text at the foot of the document.

   This is the only definition now; partials/theme.php holds the only
   matching script. It is deliberately NOT called `.toast` — the public
   Updates page uses that name for a stacked list inside its own
   container, and a `position:fixed` rule would collapse the stack.
   ════════════════════════════════════════════════════════════════ */
.app-toast{
    position: fixed;
    right: 18px;
    left: auto;
    /* clear of the home indicator on iOS */
    bottom: calc(24px + env(safe-area-inset-bottom, 0px));
    /* above the bottom nav (300) and the document modals (2000) */
    z-index: 4200;

    display: none;
    max-width: min(380px, calc(100vw - 36px));
    padding: 15px 20px;

    background: #FFFFFF;
    color: var(--text-primary, #0B2545);
    border: 1px solid var(--glass-border, rgba(19,52,90,.12));
    border-left: 4px solid var(--accent, #2D9CDB);
    border-radius: 14px;

    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.45;
    text-align: left;
    box-shadow: 0 14px 44px rgba(30,80,140,.20), 0 2px 8px rgba(30,80,140,.10);

    animation: appToastIn .3s cubic-bezier(.2,.9,.3,1.15) both;
}

/* Status disc + tick. Drawn with a mask so it needs no icon font — these
   pages do load Font Awesome, but the confirmation should not depend on
   a webfont having arrived. Inline-block rather than flex because the
   script shows the toast with an inline `display:block`, which would
   beat any layout mode set here. */
.app-toast::before{
    content: '';
    display: inline-block;
    vertical-align: -5px;
    width: 21px; height: 21px;
    margin-right: 11px;
    border-radius: 50%;
    background: var(--accent, #2D9CDB);
    -webkit-mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/%3E%3C/svg%3E") center / 14px no-repeat;
            mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/%3E%3C/svg%3E") center / 14px no-repeat;
}

.app-toast.success{ border-left-color: #34B96F; }
.app-toast.success::before{ background: #34B96F; }

.app-toast.error{ border-left-color: #C62828; }
.app-toast.error::before{
    background: #C62828;
    -webkit-mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.4 17.6 5 12 10.6 6.4 5 5 6.4 10.6 12 5 17.6 6.4 19 12 13.4 17.6 19 19 17.6 13.4 12z'/%3E%3C/svg%3E") center / 13px no-repeat;
            mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.4 17.6 5 12 10.6 6.4 5 5 6.4 10.6 12 5 17.6 6.4 19 12 13.4 17.6 19 19 17.6 13.4 12z'/%3E%3C/svg%3E") center / 13px no-repeat;
}

@keyframes appToastIn{
    from{ opacity: 0; transform: translateY(18px) scale(.96); }
    to  { opacity: 1; transform: none; }
}

/* Dark theme — a white slab would be just as wrong the other way round.
   Three border sides only: `border-color` would repaint the left edge
   too and wipe out the success/error accent stripe. */
:root[data-theme='dark'] .app-toast{
    background: #0C1E3A;
    color: #F0F4FF;
    border-top-color: rgba(255,255,255,.14);
    border-right-color: rgba(255,255,255,.14);
    border-bottom-color: rgba(255,255,255,.14);
    box-shadow: 0 16px 48px rgba(0,0,0,.55);
}

/* Phones: sit above the bottom navigation and span the width, so a long
   confirmation stays one or two lines instead of a tall narrow column. */
@media (max-width: 1023px){
    .app-toast{
        left: 14px;
        right: 14px;
        max-width: none;
        bottom: calc(86px + env(safe-area-inset-bottom, 0px));
    }
}

/* ════════════════════════════════════════════════════════════════
   PHONE BOTTOM NAVIGATION  (markup: app/inc/bottomnav.php)

   Eight pages declared their own version of this and eleven declared
   none, so the phone menu vanished as soon as you left the document
   pages. Declaring it here means a page gets the bar simply by
   including the partial — it no longer has to remember the CSS too.

   Pages that still carry their own identical `.bottom-nav` block are
   harmless: this file loads last and the rules agree.
   ════════════════════════════════════════════════════════════════ */
:root{ --bottomnav-h: 62px; }

.bottom-nav{
    display: none;
    position: fixed;
    bottom: 0; left: 0; right: 0;
    height: calc(var(--bottomnav-h) + env(safe-area-inset-bottom, 0px));
    align-items: stretch;
    background: rgba(4,10,22,.98);
    border-top: 1px solid var(--glass-border, rgba(255,255,255,.12));
    backdrop-filter: blur(32px);
    -webkit-backdrop-filter: blur(32px);
    z-index: 300;
}
@media (max-width: 767px){ .bottom-nav{ display: flex; } }

/* `.bn-item` on some pages, a bare <a> on others — accept both. */
.bottom-nav .bn-item,
.bottom-nav > a{
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 0 2px;
    /* keep the labels clear of the iOS home indicator */
    padding-bottom: env(safe-area-inset-bottom, 0px);
    text-decoration: none;
    background: none;
    border: 0;
    font: inherit;
    font-size: 9px;
    font-weight: 600;
    color: var(--text-faint, rgba(160,185,220,.45));
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.bottom-nav .bn-item i,
.bottom-nav > a i{ font-size: 19px; }

.bottom-nav .bn-item span,
.bottom-nav > a span{
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bottom-nav .bn-item.active,
.bottom-nav > a.active{ color: var(--accent, #2D9CDB); }

/* The bar is fixed, so the page must reserve room or its last row hides
   underneath it. Pages that already pad their own wrapper keep whichever
   value is larger. */
@media (max-width: 767px){
    .content-wrap, .app-content, .content-container, .main-content > .container{
        padding-bottom: calc(var(--bottomnav-h) + 22px + env(safe-area-inset-bottom, 0px));
    }
}

/* The toast sits above this bar; keep the two breakpoints in step. */
@media (max-width: 767px){
    .app-toast{
        bottom: calc(var(--bottomnav-h) + 24px + env(safe-area-inset-bottom, 0px));
    }
}

/* ════════════════════════════════════════════════════════════════
   TOP-BAR ACTIONS — notification bell + dropdown
   (markup: app/inc/topbar-actions.php)

   Eight pages declared this and eleven had nothing on the right of the
   top bar at all, so whether you could reach your notifications depended
   on which page you were standing on. Declaring it here means including
   the partial is enough.

   The pages that still carry their own copy agree with these rules, and
   this file loads last, so nothing changes for them.
   ════════════════════════════════════════════════════════════════ */
.tb-right, .top-right{ display:flex; align-items:center; gap:10px; margin-left:auto; }

.notif-btn{
    position:relative; width:38px; height:38px; flex:0 0 38px;
    background:var(--glass-bg, rgba(255,255,255,.06));
    border:1px solid var(--glass-border, rgba(19,52,90,.12));
    border-radius:var(--radius-sm, 10px);
    display:flex; align-items:center; justify-content:center;
    text-decoration:none; cursor:pointer; transition:background .2s, border-color .2s;
}
.notif-btn:hover{ background:rgba(45,156,219,.12); border-color:rgba(45,156,219,.35); }
.notif-btn i{ font-size:17px; color:var(--text-muted); }
.notif-btn:hover i{ color:var(--accent); }

.notif-badge{
    position:absolute; top:-5px; right:-5px;
    background:#ef4444; color:#fff; border-radius:50%;
    min-width:18px; height:18px; padding:0 4px;
    font-size:10px; font-weight:700;
    display:flex; align-items:center; justify-content:center;
    border:2px solid var(--navy, #07152B);
}

.notification-dropdown{
    position:absolute; top:48px; right:0;
    width:340px; max-width:calc(100vw - 20px);
    background:linear-gradient(145deg,#0C1E3A,#07152B);
    border:1px solid var(--glass-border, rgba(255,255,255,.12));
    border-radius:var(--radius-lg, 22px);
    box-shadow:var(--shadow-float, 0 18px 50px rgba(0,0,0,.45));
    z-index:1200; display:none; overflow:hidden; text-align:left; cursor:default;
}
.notification-dropdown.active{ display:block; }

.notification-header{
    padding:15px 18px; border-bottom:1px solid var(--glass-border, rgba(255,255,255,.12));
    display:flex; justify-content:space-between; align-items:center; gap:10px;
}
.notification-header h4{
    font-size:14px; font-weight:600; margin:0;
    display:flex; align-items:center; gap:8px; color:var(--text-primary);
}
.mark-all-read{
    font-size:11px; color:var(--accent2, #38D9A9); cursor:pointer;
    padding:4px 10px; border-radius:20px; white-space:nowrap;
    background:rgba(56,217,169,.1); border:1px solid rgba(56,217,169,.2);
}
.mark-all-read:hover{ background:rgba(56,217,169,.2); }

.notification-list{ max-height:380px; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.notification-item{
    padding:12px 18px; display:flex; gap:12px; cursor:pointer;
    border-bottom:1px solid rgba(255,255,255,.05);
    border-left:3px solid transparent; text-align:left;
}
.notification-item:hover{ background:rgba(45,156,219,.08); }
.notification-item.unread{ background:rgba(45,156,219,.06); border-left-color:var(--accent2, #38D9A9); }
.notification-icon{
    width:32px; height:32px; flex:0 0 32px; border-radius:10px;
    background:rgba(45,156,219,.15);
    display:flex; align-items:center; justify-content:center;
}
.notification-icon i{ font-size:14px; color:var(--accent2, #38D9A9); }
.notification-content{ flex:1; min-width:0; }
.notification-title{ font-size:12px; font-weight:600; margin-bottom:3px; color:var(--text-primary); }
.notification-text, .notification-message{
    font-size:11px; color:var(--text-muted); line-height:1.4;
    overflow:hidden; text-overflow:ellipsis;
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
}
.notification-time{ font-size:9px; color:var(--text-faint); margin-top:4px; display:flex; align-items:center; gap:4px; }
.unread-dot{ width:6px; height:6px; border-radius:50%; display:inline-block; background:var(--accent2, #38D9A9); }
.empty-notifications{ padding:36px 20px; text-align:center; color:var(--text-faint); }
.empty-notifications i{ font-size:36px; margin-bottom:10px; opacity:.3; display:block; }
.notification-footer{
    display:block; padding:12px; text-align:center;
    font-size:12px; font-weight:600; text-decoration:none;
    color:var(--accent, #2D9CDB);
    border-top:1px solid var(--glass-border, rgba(255,255,255,.12));
}
.notification-footer:hover{ background:rgba(45,156,219,.08); }

/* Light theme: the panel is drawn dark-first, like the rest of the app. */
:root:not([data-theme='dark']) .notification-dropdown{
    background:#FFFFFF;
    border-color:rgba(19,52,90,.12);
    box-shadow:0 18px 50px rgba(30,80,140,.18);
}
:root:not([data-theme='dark']) .notification-item{ border-bottom-color:rgba(19,52,90,.07); }
:root:not([data-theme='dark']) .notif-badge{ border-color:#FFFFFF; }

/* On a phone the panel would run off the right edge of a 38px button. */
@media (max-width: 520px){
    .notification-dropdown{
        position:fixed;
        top:64px; right:12px; left:12px;
        width:auto; max-width:none;
    }
}

/* ════════════════════════════════════════════════════════════════
   SIDEBAR FOOTER — Home / Logout

   The sidebar is a fixed, full-height flex column that scrolls as one
   piece. With the Business Suite entries switched on, its content runs
   past 1000px, so on a normal laptop (720–800px of viewport) the footer
   sat below the fold and Logout could only be reached by scrolling the
   whole menu to its end. Most pages also never styled these two links,
   so the button was a bare 73x20 inline text link.

   Only the nav list scrolls now; the footer is pinned to the bottom of
   the sidebar and is always in view.
   ════════════════════════════════════════════════════════════════ */
.sidebar{
    display: flex;
    flex-direction: column;
    overflow: hidden;              /* the nav does the scrolling, not this */
}
.sidebar .sidebar-nav{
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    /* Flex children refuse to shrink below their content without this, which
       would push the footer straight back off the bottom. */
    min-height: 0;
}
.sidebar .sidebar-footer{
    flex: 0 0 auto;
    display: flex;
    gap: 8px;
    padding: 12px 14px;
    padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--glass-border, rgba(19,52,90,.12));
}
.sidebar .sidebar-footer a{
    flex: 1 1 0;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;              /* comfortable touch target */
    padding: 10px 8px;
    border: 1px solid var(--glass-border, rgba(19,52,90,.12));
    border-radius: 10px;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    color: var(--text-muted, #14406B);
    transition: background .2s, border-color .2s, color .2s;
}
.sidebar .sidebar-footer a:hover{
    color: var(--text-primary, #0B2545);
    border-color: var(--glass-bright, rgba(19,52,90,.18));
    background: rgba(125,155,195,.10);
}
.sidebar .sidebar-footer a.logout,
.sidebar .sidebar-footer a.logout i{ color: #E5484D; }
.sidebar .sidebar-footer a.logout{ border-color: rgba(229,72,77,.30); }
.sidebar .sidebar-footer a.logout:hover{
    background: rgba(229,72,77,.12);
    border-color: rgba(229,72,77,.45);
    color: #E5484D;
}
