/* ============================================================
   Winner Holistic Consultants – Project Tracker
   style.css — Final Consolidated
============================================================ */
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'DM Sans',sans-serif;background:var(--bg);min-height:100vh;color:var(--text)}
input,select,button,textarea{font-family:inherit}
#app{max-width:780px;margin:0 auto;background:var(--bg);min-height:100vh}
/* Wide-content mode — for admin views (Manage Users, Backups, Permissions
   matrix) that don't have a real sidebar but still need full screen width
   for their tables, instead of being capped at the narrow 780px default
   meant for simple stacked forms. */
body.wide-content #app{max-width:none;margin:0}

/* ── LANDING ── */
.landing-hero{
  background:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.05) 0px, rgba(255,255,255,0.05) 1px, transparent 1px, transparent 28px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.05) 0px, rgba(255,255,255,0.05) 1px, transparent 1px, transparent 28px),
    linear-gradient(150deg,var(--sun3) 0%,var(--sun2) 55%,var(--sun1) 120%);
  padding:40px 24px 36px;text-align:center;position:relative;overflow:hidden}
.landing-hero::before{content:'';position:absolute;top:-40px;right:-40px;width:200px;height:200px;border-radius:50%;background:rgba(255,255,255,0.05);pointer-events:none}
.landing-hero::after{content:'';position:absolute;bottom:-60px;left:-40px;width:250px;height:250px;border-radius:50%;background:rgba(255,255,255,0.04);pointer-events:none}
.landing-logo-mark{width:52px;height:52px;border-radius:14px;background:linear-gradient(135deg,var(--gold1),var(--gold2));display:flex;align-items:center;justify-content:center;margin:0 auto 16px;font-size:22px;box-shadow:0 8px 24px rgba(0,0,0,0.25)}
.landing-brand{font-size:30px;letter-spacing:3px;color:var(--gold2);text-transform:uppercase;font-weight:600;margin-bottom:8px;opacity:0.9}
.landing-title{font-family:'DM Sans',sans-serif;font-size:26px;font-weight:700;color:#fff;margin-bottom:6px;line-height:1.2}
.landing-sub{font-size:10px;color:rgba(255,255,255,0.4);margin-bottom:0}
.landing-body{padding:28px 20px;background:#f0f2f5}
.landing-section-label{font-size:10px;letter-spacing:1.5px;text-transform:uppercase;color:#aaa;font-weight:700;margin-bottom:14px;text-align:center}
.role-card{display:flex;align-items:center;gap:14px;padding:16px 18px;border-radius:14px;margin-bottom:10px;cursor:pointer;border:1.5px solid transparent;transition:all 0.2s;text-align:left;width:100%}
.role-card:hover{transform:translateY(-1px);box-shadow:0 8px 24px rgba(0,0,0,0.12)}
.role-card-icon{width:44px;height:44px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0}
.role-card-title{font-size:14px;font-weight:600;margin-bottom:2px}
.role-card-sub{font-size:11px;opacity:0.65}
.role-card-arrow{margin-left:auto;font-size:16px;opacity:0.4;flex-shrink:0}

/* ── HEADER ── */
.hdr{background:linear-gradient(135deg,#0d2137 0%,#1b4068 100%);color:#fff;padding:24px 20px 20px}
.hdr-logo{font-size:10px;letter-spacing:2px;color:#c9a752;text-transform:uppercase;margin-bottom:10px;font-weight:600}
.hdr-title{font-family:'DM Sans',sans-serif;font-size:22px;font-weight:700;line-height:1.2;margin-bottom:4px}
.hdr-sub{font-size:12px;color:rgba(255,255,255,0.6);margin-bottom:14px}
.pills{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:16px}
.pill{background:rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.18);border-radius:20px;padding:3px 11px;font-size:11px;color:rgba(255,255,255,0.8)}
.pill-fb{background:rgba(201,107,0,0.25);border:1px solid rgba(201,107,0,0.4);color:#f0a050;font-weight:500}
.pbar-row{display:flex;justify-content:space-between;font-size:11px;color:rgba(255,255,255,0.5);margin-bottom:5px}
.pbar-bg{background:rgba(255,255,255,0.12);border-radius:10px;height:5px}
.pbar-fill{height:5px;border-radius:10px;background:linear-gradient(90deg,#c9a752,#f0d080);transition:width 0.7s}

/* ── TABS ── */
.topbar{background:#fff;padding:9px 18px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #e5e5e5;flex-wrap:wrap;gap:8px}
/* Wrap instead of horizontal-scroll: modules with a long tab list (Design,
   QS, PMS, etc.) need any overflow tabs to drop to a clean second row
   rather than scroll off-screen behind a hidden scrollbar where users
   could miss them entirely. row-gap gives breathing room between rows;
   flex-wrap + gap keep every tab's alignment consistent whichever row
   it lands on. */
.tabs{background:#fff;display:flex;flex-wrap:wrap;align-items:center;gap:6px 4px;border-bottom:1px solid #e5e5e5;padding:8px 16px}
.tab{padding:8px 14px;font-size:13px;color:#888;cursor:pointer;white-space:nowrap;border-radius:8px;transition:background 0.15s ease,color 0.15s ease}
.tab:hover:not(.on){background:var(--surface-2)}
/* Active tab is a filled, rounded pill in the current theme's accent
   color (var(--sun1)/var(--sun2) — the same pair every accent choice
   already redefines for buttons/highlights, see the [data-accent=...]
   rules below), not an underline — matches how a selected chip/pill
   reads everywhere else in the app. */
.tab.on{background:linear-gradient(135deg,var(--sun1),var(--sun2));color:#fff;font-weight:600}
.body{padding:18px}

/* ── STAGES ── */
.sec-label{font-size:10px;letter-spacing:1.2px;text-transform:uppercase;color:#aaa;font-weight:700;margin-bottom:14px}
.sw{display:flex;gap:13px}
.sl{display:flex;flex-direction:column;align-items:center;width:32px;flex-shrink:0}
.si{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700}
.si-approved{background:#d4f0e3;color:#166a3f}
.si-authority{background:#e8f0fe;color:#1a5276;border:2px solid #5b8dee}
.si-pending{background:#f0f0f0;color:#bbb;border:1px solid #ddd}
.si-not-approved{background:#fde8e8;color:#a32d2d;border:2px solid #e24b4a}
.si-hold{background:#ffe8cc;color:#a04800;border:2px solid #e8a060}
.sline{flex:1;width:2px;background:#e5e5e5;margin:3px 0}
.sline-done{background:#a3d4b8}
.sr{flex:1;padding-bottom:18px}
.sname{font-size:14px;font-weight:500;color:#1a1a1a;margin-bottom:3px}
.stime{font-size:10px;color:#c9a752;font-weight:600;margin-bottom:3px}
.snote{font-size:12px;color:#666;margin-top:5px;line-height:1.5}
.badge{display:inline-block;font-size:10px;font-weight:700;padding:2px 9px;border-radius:10px;margin-top:3px}
.b-approved{background:#d4f0e3;color:#166a3f}
.b-authority{background:#e8f0fe;color:#1a5276}
.b-pending{background:#f0f0f0;color:#999}
.b-not-approved{background:#fde8e8;color:#a32d2d}
.b-hold{background:#ffe8cc;color:#a04800}

/* ── DOCS ── */
.dc{background:#fff;border:1px solid #e5e5e5;border-radius:10px;margin-bottom:10px;overflow:hidden}
.dch{padding:10px 15px;background:#f7f7f7;font-size:12px;font-weight:600;color:#333;display:flex;align-items:center;gap:8px;border-bottom:1px solid #ebebeb}
.dch-fb{background:#fdf0e6}
.dr{display:flex;align-items:center;gap:9px;padding:9px 15px;border-bottom:1px solid #f5f5f5;font-size:12px;color:#333}
.dr:last-child{border-bottom:none}
.dic{width:18px;height:18px;border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;flex-shrink:0}
.dic-received{background:#d4f0e3;color:#166a3f}
.dic-not-received{background:#fde8e8;color:#a32d2d}
.dic-required{background:#fff3cd;color:#856404}
.dic-correction{background:#ffe8cc;color:#a04800}
.dic-na{background:#f0f0f0;color:#aaa;border:1px solid #ddd}
.dtag{margin-left:auto;font-size:10px;font-weight:700;padding:2px 8px;border-radius:8px;white-space:nowrap}
.dt-received{background:#d4f0e3;color:#166a3f}
.dt-not-received{background:#fde8e8;color:#a32d2d}
.dt-required{background:#fff3cd;color:#856404}
.dt-correction{background:#ffe8cc;color:#a04800}
.dt-na{background:#f0f0f0;color:#999}

/* ── MISC ── */
.nb{background:#fff8e6;border:1px solid #e8c96a;border-radius:8px;padding:10px 14px;margin-bottom:12px;font-size:11px;color:#7a5800;line-height:1.7}
.nb-fb{background:#fdf0e6;border:1px solid #e8a060;color:#7a3800}
.footer{text-align:center;padding:14px;font-size:11px;color:var(--text-faint);border-top:1px solid var(--border-soft);background:var(--surface)}

/* ── BUTTONS ── */
.btn{padding:6px 13px;border-radius:8px;font-size:12px;font-weight:500;cursor:pointer;border:none;transition:all 0.15s}
.btn:hover{opacity:0.88;transform:translateY(-1px)}
.btn-gold{background:linear-gradient(135deg,var(--gold1),var(--gold2));color:var(--gold-ink)}
.btn-navy{background:#1a3a5c;color:var(--gold1)}
.btn-out{background:transparent;border:1.5px solid rgba(201,167,82,0.5);color:var(--gold1)}
.btn-red{background:#fde8e8;color:#a32d2d}
.btn-green{background:#d4f0e3;color:#166a3f}
.btn-purple{background:linear-gradient(135deg,#6d28d9,#7c3aed);color:#fff}
.btn-sm{padding:4px 10px;font-size:11px}
.btn-add{width:100%;padding:8px;background:var(--surface-2);border:1px dashed #ccc;border-radius:6px;color:var(--text-muted);font-size:12px;cursor:pointer;margin-top:7px;text-align:center;transition:all 0.15s}
.btn-add:hover{background:#fff8e6;border-color:var(--gold1);color:#a06b00}
.btn-add-prep{border-color:#5b8dee;color:#1a5276}
.btn-add-approval{border-color:var(--gold1);color:#a06b00}
.btn-del{background:none;border:none;color:#e24b4a;cursor:pointer;font-size:15px;padding:2px 6px}
.btn-del-sm{background:#fde8e8;color:#a32d2d;border:none;border-radius:4px;padding:3px 8px;font-size:11px;cursor:pointer}

/* ── BARS ── */
.cbar{background:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.03) 0px, rgba(255,255,255,0.03) 1px, transparent 1px, transparent 22px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.03) 0px, rgba(255,255,255,0.03) 1px, transparent 1px, transparent 22px),
    var(--sun3);
  padding:11px 18px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}
.clabel{font-size:12px;color:var(--gold1);font-weight:600}
.pbar-header{background:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.03) 0px, rgba(255,255,255,0.03) 1px, transparent 1px, transparent 22px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.03) 0px, rgba(255,255,255,0.03) 1px, transparent 1px, transparent 22px),
    linear-gradient(135deg,var(--sun3),var(--sun2));
  padding:11px 18px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}
.pbar-label{font-size:12px;color:#c4b5fd;font-weight:600}

/* ── FORMS ── */
.sbox{background:var(--surface);border:1px solid var(--border);border-top:3px solid var(--sun1);border-radius:10px 10px 12px 12px;padding:16px;margin-bottom:12px;box-shadow:var(--shadow-card)}
.sbox-title{font-size:10px;letter-spacing:1px;text-transform:uppercase;color:var(--text-faint);font-weight:700;margin-bottom:12px}
.sbox-fb{border-color:#e8c090}
.sbox-title-fb{color:#a04800}
.fgrid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
/* Wider row variants — add alongside "fgrid" (e.g. class="fgrid fgrid-3")
   to pack 3 or 4 fields onto one row instead of the default 2. Same
   specificity as the base .fgrid rule, so which one wins at full desktop
   width comes down to source order (these are declared after it, so they
   win there) — the existing responsive rules below (1100px/700px
   breakpoints, .mobile-view) all target ".fgrid" with higher specificity
   or !important, so a 3/4-col row still collapses exactly like every
   other .fgrid on narrower screens. */
.fgrid-3{grid-template-columns:repeat(3,1fr)}
.fgrid-4{grid-template-columns:repeat(4,1fr)}
.fgrid-5{grid-template-columns:repeat(5,1fr)}
.ff{grid-column:1/-1}
.fl{font-size:11px;color:var(--text-muted);margin-bottom:4px;font-weight:600}
.fi{width:100%;padding:8px 11px;border:1.5px solid var(--input-border);border-radius:8px;font-size:13px;color:var(--input-text);background:var(--input-bg);transition:border-color 0.15s}
.fi:focus{outline:none;border-color:var(--gold1);box-shadow:0 0 0 3px rgba(201,167,82,0.1)}
/* "Wrap Text" line-item fields (Excel-style: text wraps within the box and
   the box's own height grows to fit every wrapped line, instead of a
   single-line input that hides overflow off to the side). Used for every
   template/quotation line-item row across Proposals and Templates — see
   _autoGrowFiRow()/_initFiRowAutoGrow() in shared.js, which auto-sizes
   every textarea.fi-row on input and whenever one is inserted into the
   page, so render code just needs to emit the class below and nothing
   else. resize:none + overflow:hidden because the JS keeps the height
   matched to content — a manual resize handle or scrollbar would fight it. */
textarea.fi-row{resize:none;overflow:hidden;white-space:pre-wrap;word-break:break-word;line-height:1.4;min-height:34px;font-family:inherit}
.req-star{color:#e24b4a;font-weight:700;margin-left:1px}
/* Mandatory-field-empty indicators (req-blink-field / req-blink) no
   longer get any special styling here — the required-field asterisk
   (.req-star above) and the submit-time validation message are the
   only indicators now. */

/* PROJECT INFO CUSTOM TITLES */



/* ── STAGE EDITOR ── */
.se{display:flex;gap:7px;align-items:flex-start;padding:9px;border-radius:8px;margin-bottom:6px;background:#f7f7f7;border:1px solid #eee;cursor:grab}
.se.dragging{opacity:0.4}
.se.drag-over{border:2px dashed #c9a752;background:#fff8e6}
.scope-drag-row.scope-row-dragging{opacity:0.4}
.scope-drag-row.scope-row-over{outline:2px dashed #c9a752;outline-offset:-2px;background:#fff8e6}
.scope-drag-handle:active{cursor:grabbing}
.se-selected{border-color:#c9a752;background:#fff8e6}
.se-check{width:16px;height:16px;margin-top:5px;flex-shrink:0;accent-color:#c9a752;cursor:pointer}
.se-drag-handle{font-size:16px;color:#ccc;cursor:grab;padding:2px 4px;flex-shrink:0;margin-top:2px}
.se-reorder{display:flex;flex-direction:column;gap:2px;flex-shrink:0;margin-top:2px}
.se-reorder-btn{width:20px;height:18px;border:1px solid #ddd;background:#fff;border-radius:4px;font-size:9px;color:#888;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;line-height:1}
.se-reorder-btn:hover{border-color:#c9a752;color:#a06b00}
.se-reorder-btn:disabled{opacity:0.3;cursor:not-allowed}
.se-num{width:22px;height:22px;border-radius:50%;background:#0d2137;color:#c9a752;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;flex-shrink:0;margin-top:2px}
.bulk-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;background:#fff8e6;border:1px solid #e8c96a;border-radius:8px;padding:8px 10px;margin-bottom:10px}
.bulk-bar-count{font-size:11px;font-weight:700;color:#a06b00;white-space:nowrap}
.se-body{flex:1;display:flex;flex-direction:column;gap:5px}
.se-r{display:flex;gap:6px;flex-wrap:wrap}
.se-ni{flex:1;min-width:120px;padding:5px 8px;border:1px solid #ddd;border-radius:6px;font-size:13px;color:#222;font-weight:500}
.se-sel{flex:1;min-width:160px;padding:5px 7px;border:1px solid #ddd;border-radius:6px;font-size:12px;color:#222}
.scope-details-fi{width:100%;min-height:60px;padding:6px 8px;border:1px solid #ddd;border-radius:6px;font-size:12px;color:#222;line-height:1.5;resize:vertical;font-family:inherit}
.scope-details-fi:focus{outline:none;border-color:#c9a752}
.se-note{flex:1;padding:5px 8px;border:1px solid #ddd;border-radius:6px;font-size:12px;color:#222}
.se-label{font-size:11px;color:#555;font-weight:500;white-space:nowrap}
.se-appnum-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:4px 0 2px}
.se-appnum-fi{flex:1;min-width:170px;padding:5px 9px;border:1.5px solid #e24b4a;border-radius:6px;font-size:12px;color:#222;background:#fff8f8}
.se-appnum-fi:focus{outline:none;border-color:#c9a752;background:#fff}
.se-appnum-fi::placeholder{color:#bbb}
.se-date-row{display:flex;gap:10px;flex-wrap:wrap;padding:4px 0 2px}
.se-date-field{display:flex;flex-direction:column;gap:3px;flex:1;min-width:140px}
.se-date-fi{padding:5px 8px;border:1px solid #ddd;border-radius:6px;font-size:12px;color:#222}
.se-date-fi:focus{outline:none;border-color:#c9a752}

/* ── DOC EDITOR ── */
.deg{border-radius:8px;padding:10px;margin-bottom:8px;background:#f7f7f7}
.deg-fb{background:#fdf0e6;border:1px solid #e8c090}
.deg-h{display:flex;align-items:center;gap:7px;margin-bottom:8px}
.deg-name{flex:1;padding:5px 8px;border:1px solid #ddd;border-radius:6px;font-size:13px;font-weight:500;color:#222}
.die-r{display:flex;align-items:center;gap:6px;margin-bottom:4px}
.die-n{flex:1;padding:4px 8px;border:1px solid #ddd;border-radius:4px;font-size:12px;color:#222}
.die-sel{padding:4px 7px;border:1px solid #ddd;border-radius:4px;font-size:11px;color:#222}

/* ── LINK BOX ── */
.linkbox{background:#e8f4ff;border:1px solid #b3d4f0;border-radius:8px;padding:12px 14px;margin-bottom:12px}
.linkbox-title{font-size:11px;color:#1a5276;font-weight:600;margin-bottom:6px}
.linkbox-url{font-size:12px;color:#1a5276;word-break:break-all;background:#fff;padding:7px 10px;border-radius:5px;border:1px solid #b3d4f0;margin-bottom:7px;font-family:monospace}
.linkbox-btns{display:flex;gap:7px;flex-wrap:wrap}
[data-theme="dark"] .linkbox{background:#182a42;border-color:#2a4a70}
[data-theme="dark"] .linkbox-title{color:#6aa0d4}
[data-theme="dark"] .linkbox-url{background:var(--surface-2);color:#6aa0d4;border-color:#2a4a70}

/* ── CLIENT VIEW ── */
.login-links{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.login-link-btn{font-size:11px;color:#666;text-decoration:none;padding:4px 11px;border:1px solid #ddd;border-radius:6px;background:#fff;cursor:pointer;white-space:nowrap;transition:border-color 0.15s,color 0.15s}
.login-link-btn:hover{border-color:#c9a752;color:#a06b00}
.s-appnum{font-size:11px;color:#555;margin-top:5px;padding:3px 8px;background:#f0f6ff;border-radius:4px;display:inline-block}
.s-date{font-size:11px;color:#555;margin-top:4px}

/* ── MILESTONE LABEL ── */
.milestone-label{background:#fff;border:1px solid #e5e5e5;border-radius:12px;padding:14px 16px;margin-bottom:14px;display:flex;align-items:center;gap:12px;box-shadow:0 2px 8px rgba(0,0,0,0.06)}
.milestone-icon{font-size:24px;flex-shrink:0}
.milestone-text{flex:1}
.milestone-title{font-size:9px;color:#aaa;text-transform:uppercase;letter-spacing:0.8px;margin-bottom:3px;font-weight:700}
.milestone-value{font-size:13px;font-weight:600;color:#0d2137;line-height:1.3}
.milestone-note{font-size:11px;color:#888;margin-top:2px;font-style:italic}

/* ── MODALS ── */
.overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.55);display:flex;align-items:center;justify-content:center;z-index:9999;padding:16px;backdrop-filter:blur(2px)}
.modal{background:var(--surface);border-radius:16px;padding:24px;width:360px;max-width:100%;box-shadow:0 20px 60px rgba(0,0,0,0.3);color:var(--text)}
.modal h3{font-size:15px;font-weight:600;margin-bottom:5px;color:#1a1a1a}
.modal p{font-size:12px;color:#666;margin-bottom:14px;line-height:1.5}
.modal-btns{display:flex;gap:8px;justify-content:flex-end;margin-top:14px}
.modal-large{width:680px;max-height:85vh;overflow-y:auto}
.modal-large::-webkit-scrollbar{width:4px}
.modal-large::-webkit-scrollbar-thumb{background:#c9a752;border-radius:4px}

/* ── LOGIN ── */
.login-wrap{padding:40px 20px;display:flex;align-items:center;justify-content:center;min-height:400px}
.login-box{background:var(--surface);border-radius:16px;padding:28px;width:320px;box-shadow:0 8px 32px rgba(0,0,0,0.12);color:var(--text)}
.coord-name-box{background:#fff;border-radius:16px;padding:28px;width:340px;box-shadow:0 8px 32px rgba(0,0,0,0.12)}

/* ── LOADING ── */
.loading{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:300px;gap:12px}
.spinner{width:36px;height:36px;border:3px solid #e5e5e5;border-top:3px solid #c9a752;border-radius:50%;animation:spin 0.8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.saved-chip{font-size:11px;background:#d4f0e3;color:#166a3f;padding:3px 10px;border-radius:10px;font-weight:500}
.err-msg{font-size:12px;color:#e24b4a;margin-bottom:10px;padding:8px 12px;background:#fde8e8;border-radius:8px}

/* ── COORD SEARCH ── */
.coord-search-bar{padding:10px 18px;background:#fff;border-bottom:1px solid #e5e5e5;display:flex;gap:8px;flex-wrap:wrap}
.coord-search-input{flex:1;padding:8px 12px;border:1.5px solid #e5e5e5;border-radius:8px;font-size:13px;color:#222}
.coord-search-input:focus{outline:none;border-color:#c9a752}
.coord-filter-sel{padding:7px 10px;border:1.5px solid #e5e5e5;border-radius:8px;font-size:12px;color:#222;background:#fff}
.coord-filter-sel:focus{outline:none;border-color:#c9a752}

/* ── STATUS CHIPS ── */
.status-chip{display:inline-block;font-size:10px;font-weight:600;padding:2px 8px;border-radius:10px}
.chip-active{background:#fff8e6;color:#a06b00}
.chip-done{background:#d4f0e3;color:#166a3f}
.chip-new{background:#f0f0f0;color:#888}
.chip-fb{background:#fde8d8;color:#a04800}
.chip-proposal{background:#ede8fe;color:#4a1fb8}
.chip-allocated{background:#e0f2fe;color:#0369a1}

/* ── PROPOSALS ── */
.alloc-banner{background:#ede8fe;border:1px solid #c4b5fd;border-radius:8px;padding:12px 14px;margin-bottom:12px}
.alloc-banner-title{font-size:11px;color:#4a1fb8;font-weight:700;margin-bottom:4px}
.alloc-banner-body{font-size:12px;color:#5b21b6;line-height:1.6}
.prop-card{background:#fff;border:1px solid #c4b5fd;border-radius:12px;padding:14px 16px;margin-top:10px;box-shadow:0 2px 8px rgba(109,40,217,0.06)}
.prop-card-title{font-size:13px;font-weight:600;color:#2d1b69;margin-bottom:3px}
.prop-card-meta{font-size:11px;color:#888;margin-bottom:6px}
.prop-scope-preview{font-size:12px;color:#555;line-height:1.5;background:#f7f5ff;border-radius:6px;padding:8px 10px;margin-top:6px;max-height:70px;overflow:hidden}
.prop-card-btns{display:flex;gap:7px;margin-top:10px;flex-wrap:wrap}

/* ── PROPOSAL ACTIVITY LOG ── */
.prop-act-row{display:flex;gap:10px;align-items:flex-start;padding:8px 0;border-bottom:1px solid #f0f0f0;font-size:12px}
.prop-act-row:last-child{border-bottom:none}
.prop-act-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;margin-top:4px;background:#c9a752}
.prop-act-body{flex:1;color:#333}
.prop-act-time{font-size:10px;color:#bbb;white-space:nowrap;text-align:right}

/* ── RICH TEXT EDITOR ── */
.rte-wrap{border:1.5px solid #e5e5e5;border-radius:10px;overflow:hidden;background:#fff}
.rte-toolbar{display:flex;flex-wrap:wrap;gap:2px;padding:7px 8px;background:#f7f7f7;border-bottom:1px solid #e5e5e5;align-items:center}
.rte-btn{padding:4px 9px;border:none;background:transparent;border-radius:5px;cursor:pointer;font-size:13px;color:#333;line-height:1;transition:background 0.1s}
.rte-btn:hover{background:#e5e5e5}
.rte-sep{width:1px;background:#ddd;margin:2px 5px;align-self:stretch}
.rte-select{padding:4px 7px;border:1px solid #ddd;border-radius:5px;font-size:12px;color:#333;background:#fff;cursor:pointer}
.rte-color-btn{width:22px;height:22px;border-radius:5px;border:1px solid #ddd;cursor:pointer;padding:0}
.rte-editor{min-height:160px;padding:12px 14px;font-size:13px;color:#222;line-height:1.8;outline:none;overflow-y:auto}
.rte-editor:focus{outline:none}
.rte-editor ul,.rte-editor ol{padding-left:22px}
.rte-editor table{border-collapse:collapse;width:100%;margin:8px 0}
.rte-editor table td,.rte-editor table th{border:1px solid #ddd;padding:6px 10px;font-size:12px}
.rte-editor table th{background:#f7f7f7;font-weight:600}
.rte-editor blockquote{border-left:3px solid #c9a752;padding-left:12px;color:#666;margin:6px 0}

/* ── PROJECT TYPE TAG ── */
.proj-type-tag{display:inline-block;font-size:10px;font-weight:600;padding:2px 8px;border-radius:8px;background:#fff8e6;color:#a06b00;border:1px solid #e8c96a}

/* ── QUOTATION BOX ── */
.quot-box{background:linear-gradient(135deg,#f0f6ff,#e8f4ff);border:1px solid #b3d4f0;border-radius:12px;padding:16px;margin-bottom:12px}
.quot-box-title{font-size:10px;letter-spacing:1px;text-transform:uppercase;color:#1a5276;font-weight:700;margin-bottom:12px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.quot-num-badge{background:#1a5276;color:#fff;font-size:10px;font-weight:700;padding:2px 10px;border-radius:10px}

/* ── REAPPROVAL ── */
.reapp-box{background:linear-gradient(135deg,#fdf0e6,#fde8d8);border:1px solid #e8a060;border-radius:12px;padding:16px;margin-bottom:12px}
.reapp-box-title{font-size:10px;letter-spacing:1px;text-transform:uppercase;color:#a04800;font-weight:700;margin-bottom:12px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.reapp-entry{background:#fff;border:1px solid #e8c090;border-radius:10px;padding:14px;margin-bottom:10px}
.reapp-entry-num{font-size:10px;color:#aaa;margin-bottom:8px;font-weight:600;letter-spacing:0.5px}
.reapp-client-box{background:#fff;border:1px solid #e8a060;border-radius:10px;margin-bottom:10px;overflow:hidden}
.reapp-client-hdr{padding:10px 14px;background:#fdf0e6;font-size:11px;font-weight:600;color:#a04800;display:flex;align-items:center;gap:8px;border-bottom:1px solid #f0d0b0;flex-wrap:wrap}
.reapp-client-body{padding:12px 14px}

/* ── ACTIVITY LOG ── */
.act-row{display:flex;gap:10px;align-items:flex-start;padding:9px 0;border-bottom:1px solid #f5f5f5}
.act-row:last-child{border-bottom:none}
.act-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0;margin-top:3px}
.act-dot-approved{background:#2ecc71}
.act-dot-authority{background:#5b8dee}
.act-dot-hold{background:#e8a060}
.act-dot-rejected{background:#e24b4a}
.act-dot-default{background:#ccc}
.act-body{flex:1}
.act-stage{font-weight:500;color:#1a1a1a;margin-bottom:2px;font-size:12px}
.act-detail{font-size:11px;color:#888;line-height:1.5}
.act-time{font-size:10px;color:#bbb;white-space:nowrap;text-align:right;min-width:65px}

/* ── ADMIN DASHBOARD ── */
.admin-hdr{background:linear-gradient(135deg,#2e1065,#6d28d9);color:#fff;padding:20px}
.admin-title{font-family:'DM Sans',sans-serif;font-size:20px;font-weight:700;margin-bottom:4px}
.admin-sub{font-size:12px;color:rgba(255,255,255,0.6)}
.admin-nav-tabs{display:flex;background:#fff;border-bottom:2px solid #e5e5e5;padding:0 18px;overflow-x:auto}
.admin-nav-tabs::-webkit-scrollbar{display:none}
.admin-nav-tab{padding:13px 18px;font-size:13px;color:#888;cursor:pointer;border-bottom:3px solid transparent;margin-bottom:-2px;white-space:nowrap;font-weight:500;transition:color 0.15s}
.admin-nav-tab.on{color:#0d2137;border-bottom-color:#c9a752;font-weight:600}
.dash-body{padding:16px 18px}

/* ── INTERACTIVE KPI CARDS ── */
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(100px,1fr));gap:10px;margin-bottom:14px}
.kpi-card{background:#fff;border:1.5px solid #e5e5e5;border-radius:12px;padding:14px 12px;text-align:center;cursor:pointer;transition:all 0.2s;user-select:none}
.kpi-card:hover{border-color:#c9a752;transform:translateY(-2px);box-shadow:0 6px 20px rgba(0,0,0,0.08)}
.kpi-card.kpi-active-filter{border-color:#c9a752;background:#fff8e6;box-shadow:0 4px 16px rgba(201,167,82,0.2)}
.kpi-num{font-size:26px;font-weight:700;color:#0d2137;line-height:1}
.kpi-label{font-size:10px;color:#888;text-transform:uppercase;letter-spacing:0.8px;margin-top:5px}
.kpi-click-hint{font-size:9px;color:#c9a752;margin-top:3px;opacity:0}
.kpi-card:hover .kpi-click-hint{opacity:1}
.kpi-active .kpi-num{color:#a06b00}
.kpi-done .kpi-num{color:#166a3f}
.kpi-fb .kpi-num{color:#a04800}
.kpi-warn .kpi-num{color:#e24b4a}
.kpi-proposal .kpi-num{color:#4a1fb8}
.kpi-reapp .kpi-num{color:#a04800}

/* ── Pictorial stat tiles (Coordinator/Account/Proposals dashboards) ── */
.stat-tile{
  background: linear-gradient(160deg, #ffffff, #f7f8fc);
  border: 1px solid #edf0f7;
  border-radius: 14px;
  padding: 14px 8px 12px;
  text-align: center;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(20,20,50,0.05);
  transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}
.stat-tile::before{
  content:""; position:absolute; top:0; left:0; right:0; height:3px;
  background: var(--tile-color, #999);
  opacity:0.85;
}
.stat-tile:hover{
  transform: translateY(-3px);
  box-shadow: 0 10px 22px rgba(20,20,50,0.10);
  border-color: var(--tile-color, #ccc);
}
.stat-tile:active{ transform: translateY(-1px) scale(0.97); }
.stat-tile.stat-tile-on{
  border-color: var(--tile-color, #999);
  background: linear-gradient(160deg, #ffffff, color-mix(in srgb, var(--tile-color, #999) 8%, #ffffff));
  box-shadow: 0 4px 14px rgba(20,20,50,0.10);
}
.stat-tile-icon{
  font-size: 19px; line-height:1; margin-bottom:5px;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.10));
}
.stat-tile-n{ font-size: 20px; font-weight: 800; color: var(--tile-color, #333); line-height: 1.1; }
.stat-tile-l{ font-size: 9px; color: #8a8f9c; text-transform: uppercase; letter-spacing: 0.6px; margin-top: 4px; font-weight: 700; }
@media(max-width:480px){ .stat-tile{ padding:11px 6px 9px } .stat-tile-icon{ font-size:16px } .stat-tile-n{ font-size:17px } }

.dash-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@media(max-width:540px){.dash-row{grid-template-columns:1fr}}
.dash-card{background:var(--surface);border:1px solid var(--border);border-top:3px solid var(--sun1);border-radius:10px 10px 12px 12px;padding:16px;box-shadow:var(--shadow-card);color:var(--text)}
.dash-card-title{font-size:11px;letter-spacing:1px;text-transform:uppercase;color:#aaa;font-weight:700;margin-bottom:12px}
.dash-empty{font-size:12px;color:#bbb;padding:10px 0;text-align:center}
.bar-row{display:flex;align-items:center;gap:10px;margin-bottom:9px;cursor:pointer;border-radius:6px;padding:2px 4px;transition:background 0.15s}
.bar-row:hover{background:#f7f7f7}
.bar-label{font-size:12px;color:#555;width:110px;flex-shrink:0}
.bar-track{flex:1;height:8px;background:#f0f0f0;border-radius:8px;overflow:hidden}
.bar-fill{height:8px;border-radius:8px;transition:width 0.5s}
.bar-done{background:linear-gradient(90deg,#2ecc71,#a3d4b8)}
.bar-active{background:linear-gradient(90deg,#c9a752,#f0d080)}
.bar-new{background:#ddd}
.bar-fb{background:linear-gradient(90deg,#e8a060,#fde8d8)}
.bar-retail{background:linear-gradient(90deg,#5b8dee,#b3d4f0)}
.bar-default{background:linear-gradient(90deg,#aaa,#ddd)}
.bar-proposal{background:linear-gradient(90deg,#7c3aed,#c4b5fd)}
.bar-count{font-size:12px;font-weight:700;color:#333;width:24px;text-align:right}
.coord-table{width:100%}
.coord-thead{display:grid;grid-template-columns:2fr 50px 80px 80px 2fr;gap:8px;font-size:10px;color:#aaa;font-weight:700;text-transform:uppercase;letter-spacing:0.7px;padding:4px 0 8px;border-bottom:1px solid #f0f0f0;margin-bottom:6px}
.coord-row{display:grid;grid-template-columns:2fr 50px 80px 80px 2fr;gap:8px;align-items:center;padding:7px 0;border-bottom:1px solid #f9f9f9;font-size:12px;color:#333;cursor:pointer;border-radius:6px;transition:background 0.15s}
.coord-row:hover{background:#f7f7f7}
.coord-row:last-child{border-bottom:none}
.coord-name{font-weight:500;color:#0d2137}
.attn-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:9px 0;border-bottom:1px solid #f5f5f5;cursor:pointer;border-radius:6px;transition:background 0.15s;padding-left:4px}
.attn-row:hover{background:#f7f7f7}
.attn-row:last-child{border-bottom:none}
.attn-stage{font-size:12px;font-weight:500;color:#333;flex:1;min-width:160px}
.attn-proj{font-size:11px;color:#888;flex:1;min-width:120px}
.pipeline-stage-label{font-size:10px;letter-spacing:1px;text-transform:uppercase;color:#aaa;font-weight:700;margin-bottom:8px}
.pipeline-stage-pills{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:4px}
.pipeline-pill{display:flex;align-items:center;gap:6px;background:#fff;border:1px solid #ddd;border-radius:20px;padding:5px 12px;cursor:pointer;font-size:12px;color:#555;transition:all 0.15s}
.pipeline-pill:hover{border-color:#c9a752;color:#a06b00}
.pipeline-pill-on{background:#0d2137;border-color:#0d2137;color:#c9a752;font-weight:600}
.pp-num{font-size:10px;font-weight:700;opacity:0.6}
.pp-name{font-size:12px}
.pp-badge{background:#e24b4a;color:#fff;font-size:10px;font-weight:700;padding:1px 6px;border-radius:10px}
.pipeline-group{margin-bottom:14px}
.pipeline-group-hdr{display:flex;align-items:center;margin-bottom:8px;padding-bottom:5px;border-bottom:1px dashed #eee}
.pipeline-proj-row{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding:10px 12px;background:#f9f9f9;border-radius:8px;margin-bottom:6px;flex-wrap:wrap;cursor:pointer;transition:background 0.15s}
.pipeline-proj-row:hover{background:#fff8e6}
.search-bar{padding:12px 18px;background:#fff;border-bottom:1px solid #e5e5e5;display:flex;gap:8px;flex-wrap:wrap}
.search-input{flex:1;min-width:160px;padding:8px 12px;border:1.5px solid #e5e5e5;border-radius:8px;font-size:13px;color:#222}
.search-input:focus{outline:none;border-color:#c9a752}
.filter-sel{padding:7px 10px;border:1.5px solid #e5e5e5;border-radius:8px;font-size:12px;color:#222;background:#fff}
.filter-sel:focus{outline:none;border-color:#c9a752}
.proj-table{padding:0 18px 18px}
.proj-row{background:#fff;border:1.5px solid #e5e5e5;border-radius:12px;padding:14px 16px;margin-top:10px;transition:all 0.15s;cursor:pointer}
.proj-row:hover{border-color:#c9a752;box-shadow:0 4px 16px rgba(0,0,0,0.08)}
.proj-row-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;flex-wrap:wrap}
.proj-row-title{font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:3px}
.proj-row-meta{font-size:11px;color:#888}
.proj-row-right{display:flex;flex-direction:column;align-items:flex-end;gap:5px}
.proj-pct{font-size:13px;font-weight:700;color:#0d2137}
.mini-bar-bg{width:80px;height:5px;background:#e5e5e5;border-radius:4px;overflow:hidden}
.mini-bar-fill{height:5px;border-radius:4px;background:linear-gradient(90deg,#c9a752,#f0d080)}
.proj-row-btns{display:flex;gap:6px;margin-top:8px;flex-wrap:wrap}

/* ── PROJECT TYPE CHECKBOXES ── */
.proj-type-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:4px}
.proj-type-option{display:flex;align-items:center;gap:8px;padding:9px 11px;border:1.5px solid #e5e5e5;border-radius:9px;cursor:pointer;background:#fff;transition:all 0.15s}
.proj-type-option:hover{border-color:#c9a752;background:#fffdf5}
.proj-type-option.selected{border-color:#c9a752;background:#fff8e6}
.proj-type-option input[type="checkbox"]{accent-color:#c9a752;width:15px;height:15px;cursor:pointer;flex-shrink:0}
.proj-type-label{font-size:12px;color:#333;font-weight:500;cursor:pointer}

/* ── ADMIN POPUP OVERLAY ── */
.admin-popup-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.55);display:flex;align-items:flex-start;justify-content:center;z-index:9998;padding:20px;overflow-y:auto;backdrop-filter:blur(2px)}
.admin-popup{background:#fff;border-radius:16px;width:100%;max-width:720px;margin:auto;box-shadow:0 20px 60px rgba(0,0,0,0.3);overflow:hidden}
.admin-popup-hdr{background:linear-gradient(135deg,#2e1065,#6d28d9);color:#fff;padding:16px 20px;display:flex;align-items:center;justify-content:space-between}
.admin-popup-title{font-size:14px;font-weight:600;color:#fff}
.admin-popup-sub{font-size:11px;color:rgba(255,255,255,0.6);margin-top:2px}
.admin-popup-close{background:rgba(255,255,255,0.15);border:none;color:#fff;width:30px;height:30px;border-radius:50%;cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.admin-popup-body{padding:16px}
.admin-popup-proj-row{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding:12px 14px;border:1.5px solid #e5e5e5;border-radius:10px;margin-bottom:8px;cursor:pointer;transition:all 0.15s;flex-wrap:wrap}
.admin-popup-proj-row:hover{border-color:#c9a752;background:#fff8e6}
.admin-popup-empty{text-align:center;padding:30px;color:#aaa;font-size:13px}

/* ── PROPOSAL FILTERS ── */
.prop-filters{background:#f7f7f7;border:1px solid #e5e5e5;border-radius:10px;padding:12px;margin-bottom:12px;display:grid;grid-template-columns:1fr 1fr;gap:8px}
.prop-filter-item{display:flex;flex-direction:column;gap:3px}
.prop-filter-label{font-size:10px;font-weight:600;color:#888;text-transform:uppercase;letter-spacing:0.5px}
.prop-filter-input{padding:6px 9px;border:1px solid #ddd;border-radius:6px;font-size:12px;color:#222;background:#fff}
.prop-filter-input:focus{outline:none;border-color:#c9a752}
.scroll-top-btn{position:fixed;bottom:24px;right:18px;width:38px;height:38px;border-radius:50%;background:#c9a752;color:#0d2137;border:none;font-size:20px;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,0.18);display:none;align-items:center;justify-content:center;z-index:998;transition:opacity 0.2s}
.scroll-top-btn.visible{display:flex}


/* ============================================================
   LIGHT THEME styling for the newer components
   (LPO tab, LPO Status cards, activity log, user dashboard).
   The base sheet above is already light; these match it with a
   clean navy/gold accent and soft shadows.
   ============================================================ */

/* ── User management dashboard (auth) ── */
.auth-hdr{background:linear-gradient(160deg,var(--sun1) 0%,var(--sun2) 60%,var(--sun3) 120%);padding:20px 24px;color:#fff;display:flex;justify-content:space-between;align-items:flex-start;gap:14px}
.auth-hdr .hdr-logo{font-size:12px;letter-spacing:2px;color:var(--gold1);text-transform:uppercase;font-weight:600}
.auth-hdr-title{font-family:'DM Sans',sans-serif;font-size:21px;color:#fff;margin-top:4px}
.auth-hdr-sub{font-size:11.5px;color:rgba(255,255,255,0.65);margin-top:2px}
.auth-tabs{display:flex;gap:4px;background:#fff;padding:0 18px;border-bottom:1px solid #e8e8e8}
.auth-tab{padding:13px 18px;font-size:13px;font-weight:600;color:#888;cursor:pointer;border-bottom:2px solid transparent;transition:all 0.15s;user-select:none}
.auth-tab:hover{color:#0d2137}
.auth-tab.on{color:#0d2137;border-bottom-color:var(--sun2)}
.auth-body{max-width:1200px;margin:0 auto;padding:22px 26px 50px}
.auth-success{max-width:860px;margin:14px auto 0;background:#e6f4ec;color:#166a3f;border:1px solid #b8e0c8;border-radius:9px;padding:10px 14px;font-size:13px}
.auth-error{max-width:860px;margin:14px auto 0;background:#fbe9e9;color:#a32d2d;border:1px solid #f0c4c4;border-radius:9px;padding:10px 14px;font-size:13px}
.auth-kpi-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:12px;margin-bottom:20px}
.auth-kpi{background:#fff;border:1px solid #ececec;border-radius:13px;padding:16px 14px;text-align:center;box-shadow:0 2px 10px rgba(13,33,55,0.05)}
.auth-kpi-n{font-size:24px;font-weight:700;color:#0d2137;line-height:1}
.auth-kpi-l{font-size:10.5px;color:#999;margin-top:6px;text-transform:uppercase;letter-spacing:0.5px}
.auth-filter-bar{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:14px}
.auth-user-inactive{opacity:0.6}
.auth-user-avatar{width:44px;height:44px;border-radius:50%;background:linear-gradient(135deg,var(--gold1),var(--gold2));color:var(--gold-ink);display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:700;flex-shrink:0}
.auth-user-name{font-size:15px;font-weight:700;color:#0d2137;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.auth-user-email{font-size:12px;color:#888;display:flex;align-items:center;gap:5px}
.auth-you-badge{background:var(--gold1);color:var(--gold-ink);font-size:10px;font-weight:700;padding:1px 8px;border-radius:8px}
.auth-inactive-badge{background:#fbe9e9;color:#a32d2d;font-size:10px;font-weight:600;padding:1px 8px;border-radius:8px}

/* ── Manage Users modernization — row-item list (super-admin.js renderUserList,
   renderUserRow). Was a card grid; now one full-width bordered row per
   user (.auth-user-list/.auth-user-row below) so a long roster reads as
   a scannable list instead of a wall of boxes. Identity (avatar/name/
   email) anchors the left, the compact meta/chip lines sit underneath
   it, group/status/kebab stay pinned to the row's right edge. All
   per-row edit actions (name/contact/employee ID/teams/companies/apps)
   plus Export/Reset PIN/Deactivate/Delete stay consolidated into one
   "⋮" popover menu per row — see renderUserMenu()/_toggleUserMenu() in
   super-admin.js — instead of a half-dozen separate inline pencil icons and
   buttons competing for attention. ── */
.auth-user-list{border:1px solid #ececec;border-radius:14px;overflow:hidden;background:#fff;box-shadow:0 2px 10px rgba(13,33,55,0.05)}
.auth-user-row{display:flex;gap:14px;align-items:center;padding:12px 16px;border-top:1px solid #f0f0f0;transition:background 0.12s}
.auth-user-row:first-child{border-top:none}
.auth-user-row:hover{background:#fafafd}
.aur-main{flex:1;min-width:0}
.aur-identity{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.aur-meta-line{display:flex;flex-wrap:wrap;gap:4px 14px;font-size:11.5px;color:#666;margin-top:3px}
.aur-chips-line{display:flex;flex-wrap:wrap;align-items:center;gap:5px 8px;margin-top:5px}
.aur-side{flex:none;display:flex;align-items:center;gap:8px;position:relative}
.um-kebab{flex:none;width:30px;height:30px;border-radius:8px;border:1px solid transparent;background:transparent;color:#999;font-size:16px;font-weight:700;cursor:pointer;transition:all 0.12s;line-height:1}
.um-kebab:hover{background:#f2f2f5;color:#333;border-color:#e5e5e5}
.um-icon-link{cursor:pointer;font-size:11px;opacity:0.65;transition:opacity 0.12s}
.um-icon-link:hover{opacity:1}
.um-meta-label{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:0.4px;color:#aaa}
.um-badges-label{font-size:10px;font-weight:700;color:#aaa;text-transform:uppercase;letter-spacing:0.3px;flex:none}
.um-chip{font-size:10px;font-weight:600;padding:2px 8px;border-radius:9px;background:#f5f6fa;color:#444}
.um-chip-muted{font-size:11px;color:#aaa;font-style:italic}
.um-group-select{margin:0;font-size:11px;padding:4px 8px;width:auto;max-width:140px}
.um-status-pill{font-size:10.5px;font-weight:700;padding:3px 10px;border-radius:9px;white-space:nowrap}
.um-status-pill.on{background:#e6f4ec;color:#166a3f}
.um-status-pill.off{background:#fbe9e9;color:#a32d2d}
/* Transparent click-catcher behind the popover — closes the menu on any
   outside click, same convention this app already uses for modal backdrops. */
.user-menu-backdrop{position:fixed;inset:0;z-index:40;background:transparent}
/* position:fixed with top:/left: supplied inline by _toggleUserMenu()'s
   viewport-coordinate calculation (see super-admin.js) — NOT
   position:absolute anchored to the row. An absolute popover here used
   to get silently clipped by .um-table-wrap's overflow-x:auto, which
   per the CSS overflow spec forces overflow-y to "auto" too on that same
   element — invisible with a full roster (always more row-height below
   to render into) but very visible the moment a search narrows the list
   to just the last row or two. Fixed positioning escapes that ancestor
   entirely. top:38px;right:0 below is only the fallback for the rare
   case JS positioning didn't run (e.g. AS.userMenuPos never got set). */
.user-menu-popover{position:fixed;top:38px;right:12px;z-index:50;background:#fff;border:1px solid #e5e5e5;border-radius:12px;box-shadow:0 12px 32px rgba(13,33,55,0.18);min-width:190px;padding:6px;animation:um-pop-in 0.12s ease-out}
@keyframes um-pop-in{from{opacity:0;transform:translateY(-4px) scale(0.97)}to{opacity:1;transform:translateY(0) scale(1)}}
.user-menu-item{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:8px;font-size:12.5px;font-weight:600;color:#333;cursor:pointer;transition:background 0.1s;white-space:nowrap}
.user-menu-item:hover{background:#f2f2f5}
.user-menu-item.danger{color:#a32d2d}
.user-menu-item.danger:hover{background:#fbe9e9}
.user-menu-divider{height:1px;background:#eee;margin:5px 4px}

/* ══ Manage Users v2 — avatars, bulk actions, table view, inline edit ══
   The row list above stays the default ("Cards"); everything here layers
   on top of it. Three additions, all driven from super-admin.js:
     • .aur-avatar / .aur-check — the coloured initial and the bulk-select
       tick that now lead every row. The avatar's colour comes from an
       inline hsl() style computed per name (umAvatarStyle()), so the
       class carries only shape and the palette needs no CSS at all.
     • .um-bulkbar — appears ONLY when something is ticked, so an admin
       who never uses bulk actions never sees it.
     • .um-table — the dense sortable alternative to the cards, for
       rosters long enough that one screen of ten cards stops helping. ── */
.aur-avatar{flex:none;width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:15px;font-family:'Poppins','DM Sans',sans-serif;background:#eef0ff;color:#5b3df5;letter-spacing:0.2px}
.aur-avatar.sm{width:26px;height:26px;font-size:11.5px}
.aur-check{flex:none;width:16px;height:16px;cursor:pointer;accent-color:#5b3df5}
.auth-user-row.aur-selected{background:#f7f5ff;box-shadow:inset 3px 0 0 #5b3df5}
.auth-user-row.aur-selected:hover{background:#f2efff}

/* View switch (Cards / Table) — segmented control in the filter bar */
.um-viewswitch{display:flex;border:1.5px solid var(--input-border);border-radius:9px;overflow:hidden;background:var(--input-bg)}
.um-viewswitch button{border:none;background:transparent;padding:7px 13px;font-size:12px;font-weight:600;color:var(--text-muted);cursor:pointer;transition:background 0.12s,color 0.12s;font-family:inherit}
.um-viewswitch button:hover{background:rgba(91,61,245,0.07);color:var(--text)}
.um-viewswitch button.on{background:#5b3df5;color:#fff}

.um-count-line{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;font-size:11px;color:var(--text-muted);margin-bottom:8px}
.um-selectall{display:flex;align-items:center;gap:6px;cursor:pointer;font-weight:600;user-select:none}
.um-selectall input{width:14px;height:14px;cursor:pointer;accent-color:#5b3df5}

/* Bulk action bar */
.um-bulkbar{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;background:linear-gradient(135deg,#5b3df5,#7c5cff);color:#fff;border-radius:12px;padding:10px 16px;margin-bottom:12px;box-shadow:0 6px 20px rgba(91,61,245,0.28);animation:um-bulk-in 0.16s ease-out}
@keyframes um-bulk-in{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.um-bulkbar.busy{opacity:0.92}
.um-bulk-count{font-size:12.5px;font-weight:600;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.um-bulk-n{background:rgba(255,255,255,0.22);border-radius:8px;padding:2px 9px;font-size:13px;font-weight:700}
.um-bulk-note{font-size:11px;font-weight:500;opacity:0.85}
.um-bulk-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.um-bulk-btn{border:1px solid rgba(255,255,255,0.45);background:rgba(255,255,255,0.14);color:#fff;font-size:12px;font-weight:600;padding:6px 12px;border-radius:8px;cursor:pointer;transition:background 0.12s;font-family:inherit}
.um-bulk-btn:hover:not(:disabled){background:rgba(255,255,255,0.28)}
.um-bulk-btn:disabled{opacity:0.45;cursor:not-allowed}
.um-bulk-btn.ghost{border-color:transparent;background:transparent;text-decoration:underline}
.um-bulk-select{border:1px solid rgba(255,255,255,0.45);background:rgba(255,255,255,0.14);color:#fff;font-size:12px;font-weight:600;padding:6px 10px;border-radius:8px;cursor:pointer;font-family:inherit}
.um-bulk-select option{color:#222;background:#fff}
.um-bulk-progress{font-size:12.5px;font-weight:600;display:flex;align-items:center;gap:8px}
.um-spin{width:13px;height:13px;border:2px solid rgba(255,255,255,0.35);border-top-color:#fff;border-radius:50%;display:inline-block;animation:um-spin 0.7s linear infinite}
@keyframes um-spin{to{transform:rotate(360deg)}}

/* Inline quick-edit — click a value, type, Enter saves / Esc cancels */
.um-inline{cursor:text;border-radius:5px;padding:0 3px;margin:0 -3px;transition:background 0.1s}
.um-inline:hover{background:rgba(91,61,245,0.09)}
.um-inline.strong{font-weight:700}
.um-inline-pen{font-size:9.5px;opacity:0;margin-left:4px;transition:opacity 0.1s}
.um-inline:hover .um-inline-pen{opacity:0.55}
.um-inline-input{font:inherit;font-size:inherit;color:var(--input-text);background:var(--input-bg);border:1.5px solid #5b3df5;border-radius:6px;padding:1px 6px;min-width:110px;max-width:230px;outline:none;box-shadow:0 0 0 3px rgba(91,61,245,0.14)}

/* Dense table view */
.um-table-wrap{border:1px solid #ececec;border-radius:14px;overflow-x:auto;background:#fff;box-shadow:0 2px 10px rgba(13,33,55,0.05)}
.um-table{width:100%;border-collapse:collapse;font-size:12.5px}
.um-table th{text-align:left;font-size:10px;letter-spacing:0.5px;text-transform:uppercase;color:#999;padding:10px 12px;border-bottom:1px solid #ececec;background:#fafafd;white-space:nowrap}
.um-table td{padding:9px 12px;border-bottom:1px solid #f2f2f5;vertical-align:middle;color:#333}
.um-table tbody tr:last-child td{border-bottom:none}
.um-table tbody tr:hover td{background:#fafafd}
.um-table tbody tr.um-tr-sel td{background:#f7f5ff}
.um-table tbody tr.um-tr-inactive td{opacity:0.62}
.um-table input[type=checkbox]{width:15px;height:15px;cursor:pointer;accent-color:#5b3df5}
.um-th{cursor:pointer;user-select:none;transition:color 0.12s}
.um-th:hover{color:#5b3df5}
.um-th.on{color:#5b3df5}
.um-th-arrow{font-size:8px;margin-left:4px}
.um-td-name{display:flex;align-items:center;gap:8px;white-space:nowrap}
.um-td-dim{color:#888;white-space:nowrap}

/* Shared empty state for both views */
.um-empty{text-align:center;padding:44px 20px;background:var(--surface-2);border-radius:14px}
.um-empty-icon{font-size:30px;opacity:0.5;margin-bottom:8px}
.um-empty-title{font-size:14.5px;font-weight:700;color:var(--text);font-family:'Poppins','DM Sans',sans-serif}
.um-empty-sub{font-size:12px;color:var(--text-muted);margin-top:4px}

/* ── LPO tab (inside project editor) ── */
.lpo-kpi{background:#f8f9fb;border:1px solid #e8e8e8;border-radius:11px;padding:12px;text-align:center}
.lpo-kpi-n{font-size:17px;font-weight:700;color:#0d2137}
.lpo-kpi-l{font-size:10px;color:#999;margin-top:4px;text-transform:uppercase;letter-spacing:0.4px}
.lpo-card{background:#fff;border:1px solid #e8e8e8;border-radius:12px;padding:14px;margin-bottom:12px;box-shadow:0 1px 6px rgba(13,33,55,0.04)}
.lpo-card.lpo-credited{border-left:4px solid #27ae60}
.lpo-row{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.lpo-field{flex:1;min-width:120px}
.lpo-foot{display:flex;justify-content:space-between;align-items:center;margin-top:4px}
.lpo-meta{font-size:11px;color:#999}

/* ── LPO Status cards (payments module) ── */
.pay-card{background:#fff;border:1px solid #e8e8e8;border-radius:14px;padding:16px;margin-bottom:12px;box-shadow:0 2px 10px rgba(13,33,55,0.05)}
.pay-card-top{display:flex;gap:12px;align-items:flex-start;margin-bottom:12px}
.pay-title{font-size:15px;font-weight:700;color:#0d2137}
.pay-sub{font-size:11.5px;color:#888;margin-top:2px}
.pay-status{font-size:11px;font-weight:700;padding:3px 11px;border-radius:10px;flex-shrink:0;white-space:nowrap}
.pay-figures{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:10px}
.pay-figures > div{background:#f8f9fb;border:1px solid #eee;border-radius:9px;padding:9px 11px;display:flex;flex-direction:column}
.pay-fl{font-size:9.5px;color:#999;text-transform:uppercase;letter-spacing:0.5px}
.pay-fv{font-size:16px;font-weight:700;color:#0d2137;margin-top:2px}
.pay-fc{font-size:10px;color:#aaa;margin-top:1px}
.pay-bar{height:7px;background:#eef0f3;border-radius:5px;overflow:hidden;margin-bottom:10px}
.pay-bar-fill{height:100%;background:linear-gradient(90deg,#34c77b,#27ae60);border-radius:5px;transition:width 0.3s}
.pay-details{font-size:12px}
.pay-details summary{cursor:pointer;color:#6d28d9;font-size:12px;font-weight:600;padding:4px 0;user-select:none}
.pay-lpo-list{margin-top:8px}
.pay-lpo-row{display:flex;gap:10px;align-items:center;padding:8px 0;border-bottom:1px solid #f0f0f0}
.pay-lpo-row:last-child{border-bottom:none}
.pay-lpo-name{font-size:13px;color:#0d2137;font-weight:600}
.pay-lpo-meta{font-size:10.5px;color:#999;margin-top:2px}
.pay-lpo-amt{font-size:14px;font-weight:700;color:#0d2137}
.pay-lpo-chip{font-size:9.5px;font-weight:700;padding:1px 8px;border-radius:7px;display:inline-block;margin-top:3px}
.pay-card-foot{margin-top:10px;text-align:right}
.pay-open{font-size:11.5px;color:#6d28d9;text-decoration:none;font-weight:600}
.pay-open:hover{text-decoration:underline}

/* Activity log panel: styled dynamically by injectActivityLogStyles() in
   shared.js (dark "Splunk-style" panel, wide layout) — that's the single
   source of truth. An older, narrower, light-themed version used to live
   here too, using class names (.actlog-row/.actlog-dot/.actlog-modpill)
   the current renderer doesn't even use anymore; removed to stop it
   fighting the real styles for width/theme. */

/* ── Date range bar (LPO Status & Summary) ── */
.range-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding:12px 18px;background:#fff;border-bottom:1px solid #eee}
.range-lbl{font-size:11px;color:#888;text-transform:uppercase;letter-spacing:0.5px;font-weight:600}
.range-input{border:1px solid #ddd;border-radius:8px;padding:7px 10px;font-size:12px;font-family:inherit;color:#0d2137}
.range-input:focus{outline:none;border-color:#c9a752}
.range-now{margin-left:auto;font-size:12px;color:#0d2137;font-weight:600;background:#ece4fb;padding:4px 12px;border-radius:8px}

/* ============================================================
   CREATIVE-TIM STYLE — gradient sidebar + modern cards
   Light violet theme. Sidebar is fixed-left; content shifts right.
   ============================================================ */
:root{
  --sb-w: 248px;
  --sb-w-collapsed: 76px;
  color-scheme: light;
  --sun1:#3d6d94;   /* blueprint — default, muted technical blue */
  --sun2:#2a4d6e;   /* mid */
  --sun3:#1a3347;   /* deep blueprint navy */
  --ink:#32325d;    /* primary text (Creative Tim navy-ink) */
  --ink-soft:#8898aa;
  --page:#f4f5f7;

  /* ── Theme system: surfaces/text (light defaults) ── */
  --bg:#f0f2f5; --surface:#ffffff; --surface-2:#f7f7f7; --surface-3:#f5f6fa;
  --text:#1a2740; --text-muted:#6b7280; --text-faint:#9aa0ab;
  --border:#e5e5e5; --border-soft:#eef0f3;
  --input-bg:#ffffff; --input-border:#d6d9e2; --input-text:#222;
  --gold1:#4a8dbf; --gold2:#7bb3d9; --gold-ink:#0a2540;
  --navy:#0d2137;
  --money-color:#166a3f; --highlight-row:#fffde7;
  --shadow-card: 0 1px 4px rgba(0,0,0,0.04);
}
/* ── Dark mode — overrides surfaces/text. Accent hue stays the same
   family across light/dark (brand identity shouldn't flip), but each
   accent gets its own brighter/more-saturated variant here since the
   muted light-mode shades go flat and low-contrast on a dark surface ── */
[data-theme="dark"]{
  color-scheme: dark;
  --bg:#0e1116; --surface:#1e2530; --surface-2:#262e3b; --surface-3:#2c3543;
  --text:#eef1f6; --text-muted:#adb4c2; --text-faint:#767e8c;
  --border:#333c4a; --border-soft:#2a3240;
  --input-bg:#232b38; --input-border:#3f4a5a; --input-text:#eef1f6;
  --page:#0e1116; --ink:#eef1f6; --ink-soft:#adb4c2;
  --money-color:#4fb37f; --highlight-row:#332c14;
  --shadow-card: 0 2px 10px rgba(0,0,0,0.45);
  /* Brightened default (Blueprint) accent for dark mode */
  --sun1:#5a8bb0; --sun2:#3d6d94; --sun3:#2a4d6e;
  --gold1:#5a95c4; --gold2:#8ab8dc; --gold-ink:#0a1c2e;
}
/* ── Default accent — deep blueprint blue, matching architectural/
   technical-drawing reference art rather than a decorative brand color.
   Anyone with an old accent value (ocean/forest/royal/rose/charcoal/
   concrete/steel) still saved in their browser will now just see this
   new default, since those preset names no longer have their own
   override rule.
   Six presets total, each a genuinely distinct, muted hue family —
   navy / teal / neutral-gray / sage-green / wine / terracotta — rather
   than near-duplicates of each other, and toned down from the earlier,
   more saturated version for a calmer, less fluorescent feel. ── */
[data-accent="maroon"]{ --sun1:#8a4a54; --sun2:#6b333d; --sun3:#452027; --gold1:#c9a06a; --gold2:#dbbb8a; --gold-ink:#2b1216; }
[data-accent="sunset"]{ --sun1:#c17b4a; --sun2:#9c5f38; --sun3:#5c3a24; --gold1:#e0b876; --gold2:#eecf9e; --gold-ink:#3d2412; }
[data-accent="slate"]{ --sun1:#7d8a94; --sun2:#5c6670; --sun3:#3d454d; --gold1:#9aa5ac; --gold2:#b8c0c6; --gold-ink:#1f2429; }
/* Patina — the sage-green a copper roof or fitting oxidizes to over
   time; a genuinely different hue family from Slate's neutral gray,
   rather than another blue-gray. */
[data-accent="patina"]{ --sun1:#6b8268; --sun2:#4d614a; --sun3:#333f31; --gold1:#8fa48c; --gold2:#aebcac; --gold-ink:#1a2118; }
/* Cyanotype — named for the actual 19th-century blueprint printing
   process (an iron-based photographic print process that yields a
   distinctly teal-leaning Prussian blue, not a straight navy) — shifted
   further toward teal/cyan here specifically so it reads as clearly
   different from the default Blueprint navy rather than a near-twin. */
[data-accent="cyanotype"]{ --sun1:#3a8a94; --sun2:#2a6570; --sun3:#1a4148; --gold1:#eef8fc; --gold2:#d4ecf7; --gold-ink:#1a4148; }
/* Dark-mode variants — brighter/more saturated so each accent stays
   legible and vivid against the dark surface instead of going flat. */
[data-theme="dark"][data-accent="maroon"]{ --sun1:#ab6a74; --sun2:#8a4a54; --sun3:#6b333d; --gold1:#dbbb8a; --gold2:#ead6b0; --gold-ink:#1a0a0d; }
[data-theme="dark"][data-accent="sunset"]{ --sun1:#d99c6e; --sun2:#c17b4a; --sun3:#9c5f38; --gold1:#eecf9e; --gold2:#f5e2c0; --gold-ink:#2a1810; }
[data-theme="dark"][data-accent="slate"]{ --sun1:#9aa8b3; --sun2:#7d8a94; --sun3:#5c6670; --gold1:#b8c0c6; --gold2:#d0d6da; --gold-ink:#131a20; }
[data-theme="dark"][data-accent="patina"]{ --sun1:#8ba488; --sun2:#6b8268; --sun3:#4d614a; --gold1:#aebcac; --gold2:#c8d2c6; --gold-ink:#10160e; }
[data-theme="dark"][data-accent="cyanotype"]{ --sun1:#5aabb5; --sun2:#3a8a94; --sun3:#2a6570; --gold1:#d4ecf7; --gold2:#eef8fc; --gold-ink:#1a4148; }

/* Page background + content shift — full width beside the sidebar */
body.has-sidebar{background:var(--page)}
body.has-sidebar #app{margin-left:var(--sb-w);max-width:none;min-height:100vh;background:var(--page)}
/* Hub landing stays comfortably centered */
body.has-sidebar #app .portal-wrap{max-width:1280px}

/* Hide the old floating back button when sidebar is present (sidebar replaces it) */
body.has-sidebar .back-portal-btn{display:none}

/* ── Sidebar ── */
.whc-sidebar{position:fixed;top:0;left:0;width:var(--sb-w);height:100vh;z-index:9000;
  background:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.035) 0px, rgba(255,255,255,0.035) 1px, transparent 1px, transparent 26px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.035) 0px, rgba(255,255,255,0.035) 1px, transparent 1px, transparent 26px),
    linear-gradient(160deg,var(--sun1) 0%,var(--sun2) 55%,var(--sun3) 120%);
  display:flex;flex-direction:column;box-shadow:4px 0 24px rgba(0,0,0,0.18);
  font-family:'DM Sans',system-ui,sans-serif}
[data-theme="dark"] .whc-sidebar{
  background:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.02) 0px, rgba(255,255,255,0.02) 1px, transparent 1px, transparent 26px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.02) 0px, rgba(255,255,255,0.02) 1px, transparent 1px, transparent 26px),
    linear-gradient(160deg,var(--sun3) 0%,#080a0e 130%);
  box-shadow:4px 0 24px rgba(0,0,0,0.5)}
.sb-brand{display:flex;align-items:center;gap:11px;padding:22px 20px 18px;border-bottom:1px solid rgba(255,255,255,0.18)}
/* The logo artwork is navy — invisible if placed as-is on the app's
   navy/colored header backgrounds. brightness(0) invert(1) turns the
   (now-transparent) PNG into a clean white silhouette using the same
   asset, no separate white-logo file needed. Used everywhere the logo
   sits on a colored/dark surface (sidebar, headers); left in its
   original navy on light/white surfaces instead. */
.sb-brand-logo{width:100%;display:block;filter:brightness(0) invert(1) drop-shadow(0 1px 3px rgba(0,0,0,0.3));opacity:0.95}
.sb-brand-name{font-size:14px;font-weight:700;color:#fff;line-height:1.1}
.sb-brand-sub{font-size:11px;color:rgba(255,255,255,0.75)}
.sb-nav{flex:1;padding:14px 12px;overflow-y:auto}
.sb-link{display:flex;align-items:center;gap:12px;padding:11px 14px;margin-bottom:4px;border-radius:10px;color:rgba(255,255,255,0.9);text-decoration:none;font-size:13.5px;font-weight:600;transition:all 0.15s}
.sb-link:hover{background:rgba(255,255,255,0.16);color:#fff}
.sb-link.on{background:#fff;color:var(--sun2);box-shadow:0 4px 12px rgba(0,0,0,0.12)}
.sb-ico{font-size:17px;width:22px;text-align:center}
.sb-foot{padding:14px;border-top:1px solid rgba(255,255,255,0.18)}
.sb-user{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.sb-user-avatar{width:36px;height:36px;border-radius:50%;background:rgba(255,255,255,0.25);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:15px}
.sb-user-name{font-size:13px;font-weight:700;color:#fff;line-height:1.1}
.sb-user-role{font-size:11px;color:rgba(255,255,255,0.75);text-transform:capitalize}
.sb-logout{width:100%;padding:9px;border:none;border-radius:9px;background:rgba(255,255,255,0.18);color:#fff;font-size:12px;font-weight:600;cursor:pointer;transition:all 0.15s;display:flex;align-items:center;justify-content:center;gap:8px}
.sb-logout:hover{background:rgba(255,255,255,0.3)}
.sb-foot-btn{width:100%;padding:8px;margin-bottom:8px;border:1.5px solid rgba(255,255,255,0.25);border-radius:9px;background:rgba(255,255,255,0.1);color:#fff;font-size:12px;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px;transition:all 0.15s}
.sb-foot-btn:hover{background:rgba(255,255,255,0.18)}

/* Mobile toggle + backdrop (hidden on desktop) */
.whc-sb-toggle{display:none;position:fixed;top:12px;left:12px;z-index:9500;width:42px;height:42px;border:none;border-radius:11px;background:linear-gradient(135deg,var(--sun1),var(--sun2));color:#fff;font-size:20px;cursor:pointer;box-shadow:0 4px 12px rgba(76,29,149,0.35)}
.whc-sb-backdrop{display:none;position:fixed;inset:0;z-index:8999;background:rgba(50,50,93,0.4)}

/* ── Desktop auto-retract ── the sidebar rests as an icon-only rail
   (no manual toggle, no arrow button, no stored on/off preference) and
   expands automatically the moment the cursor moves onto it, purely via
   `.whc-sidebar:hover`/`:focus-within` — no JS click handler involved.
   It moves the cursor away, it retracts again on its own. #app's own
   margin stays pinned to the RESTING (collapsed) width the whole time —
   the expanded sidebar floats over the page as an overlay (its existing
   box-shadow already gives it the needed depth) instead of reflowing
   the page's content on every hover, which would be distracting. Scoped
   to the desktop media query's complement so it never fights the mobile
   slide-in transform below, which uses the same --sb-w-derived layout
   differently. */
@media(min-width:821px){
  body.has-sidebar #app{margin-left:var(--sb-w-collapsed)}
  .whc-sidebar{width:var(--sb-w-collapsed);overflow-x:hidden;transition:width 0.18s}
  .sb-brand{padding:18px 10px;justify-content:center}
  .sb-link{justify-content:center;padding:11px 0;gap:0}
  .sb-label{display:none}
  .sb-foot{padding:14px 8px}
  .sb-user{justify-content:center}
  .sb-user-info{display:none}
  /* Appearance panel and PWA install prompt need real width to be
     usable — the resting rail just hides the entry points for them
     rather than trying to cram them in; hovering the sidebar open
     brings both straight back. The theme panel additionally stays
     force-hidden at rest regardless of its own open/closed toggle
     state (`:not(:hover)` beats the inline style toggleThemePanel()
     sets), so it can't get "stuck open" spilling out of the rail. */
  .sb-foot-btn .sb-txt,
  .sb-logout .sb-txt{display:none}
  .whc-sidebar:not(:hover):not(:focus-within) #whc-theme-panel{display:none!important}
  #whc-pwa-install-slot{display:none}

  .whc-sidebar:hover,
  .whc-sidebar:focus-within{width:var(--sb-w);overflow-x:visible}
  .whc-sidebar:hover .sb-brand,
  .whc-sidebar:focus-within .sb-brand{padding:22px 20px 18px;justify-content:flex-start}
  .whc-sidebar:hover .sb-link,
  .whc-sidebar:focus-within .sb-link{justify-content:flex-start;padding:11px 14px;gap:12px}
  .whc-sidebar:hover .sb-label,
  .whc-sidebar:focus-within .sb-label{display:inline}
  .whc-sidebar:hover .sb-foot,
  .whc-sidebar:focus-within .sb-foot{padding:14px}
  .whc-sidebar:hover .sb-user,
  .whc-sidebar:focus-within .sb-user{justify-content:flex-start}
  .whc-sidebar:hover .sb-user-info,
  .whc-sidebar:focus-within .sb-user-info{display:block}
  .whc-sidebar:hover .sb-foot-btn .sb-txt,
  .whc-sidebar:hover .sb-logout .sb-txt,
  .whc-sidebar:focus-within .sb-foot-btn .sb-txt,
  .whc-sidebar:focus-within .sb-logout .sb-txt{display:inline}
  .whc-sidebar:hover #whc-pwa-install-slot,
  .whc-sidebar:focus-within #whc-pwa-install-slot{display:block}
}

@media(max-width:820px){
  body.has-sidebar #app{margin-left:0}
  .whc-sidebar{transform:translateX(-100%);transition:transform 0.25s}
  body.sb-open .whc-sidebar{transform:translateX(0)}
  .whc-sb-toggle{display:flex;align-items:center;justify-content:center}
  body.sb-open .whc-sb-backdrop{display:block}
}

/* ── Modern card restyle (orange-accented, soft shadows) ── */
body.has-sidebar .pbar-header,
body.has-sidebar .cbar,
body.has-sidebar .hdr{
  background:var(--surface);color:var(--ink);box-shadow:var(--shadow-card);
  border-bottom:1px solid var(--border-soft)}
body.has-sidebar .pbar-label,
body.has-sidebar .clabel{color:var(--ink);font-weight:700}

/* Stat / sbox / cards get the soft elevated look */
body.has-sidebar .sbox,
body.has-sidebar .dc,
body.has-sidebar .kpi-card,
body.has-sidebar .dash-card,
body.has-sidebar .pay-card,
body.has-sidebar .lpo-card,
body.has-sidebar .prop-card,
body.has-sidebar .auth-user-list,
body.has-sidebar .auth-kpi{
  background:var(--surface);border:none;border-radius:12px;
  box-shadow:var(--shadow-card)}

/* Primary buttons take the sunset gradient */
body.has-sidebar .btn-gold,
body.has-sidebar .btn-purple{
  background:linear-gradient(135deg,var(--sun1),var(--sun2))!important;
  color:#fff!important;border:none!important;box-shadow:0 3px 8px rgba(76,29,149,0.28)}
body.has-sidebar .btn-gold:hover,
body.has-sidebar .btn-purple:hover{filter:brightness(1.05)}

/* Tab accents → sunset */
body.has-sidebar .admin-nav-tab.on,
body.has-sidebar .auth-tab.on{color:var(--sun2);border-bottom-color:var(--sun2)}

/* Section titles */
body.has-sidebar .sbox-title,
body.has-sidebar .sec-label{color:var(--ink)}

/* ── Full-screen layout refinements (with sidebar) ── */
body.has-sidebar .body{padding:22px 26px}
/* .sbox previously capped at 920px "for readability" — removed: it was
   leaving a large empty gap on normal wide monitors for content like
   detail/field-grid views that don't actually need a narrow reading
   width. .sbox-wide remains available as an explicit marker if a
   specific box is meant to always go full width regardless. */

/* Make 2-col form grids collapse gracefully on smaller effective widths */
@media(max-width:1100px){
  body.has-sidebar .fgrid{grid-template-columns:1fr 1fr}
}
@media(max-width:700px){
  body.has-sidebar .fgrid{grid-template-columns:1fr}
}

/* Proposals/Coordinator header bars span the content width cleanly */
body.has-sidebar .pbar-header,
body.has-sidebar .cbar{padding-left:24px;padding-right:24px;border-radius:0}

/* Lists, payment cards, dashboards: allow comfortable wide layout */
/* .prop-card and .pay-card were both previously capped at max-width:1100px.
   .pay-card's cap was removed already (see note below) for the same reason
   .sbox's cap was removed above: the stat-tile row above these cards
   already spans the full content width, so a capped, left-aligned card
   underneath just left a large empty gap on the right on wide monitors
   instead of using the space the header row already claims. .prop-card
   (the Proposals quotations list) has the exact same layout — its own
   stat-tile row (renderStatTiles) already spans full width above it — so
   it gets the same fix here, not left behind. */

/* ============================================================
   MOBILE VIEW — body.mobile-view
   Auto-applied on phones (screen width or UA sniff). Purely a
   responsive layout: single column, bigger tap targets, roomier
   cards. Fully editable — same inputs, buttons and permission
   rules as desktop, nothing hidden or disabled by device.
   ============================================================ */

/* Floating view toggle (always available) */
.whc-view-toggle{position:fixed;bottom:18px;right:16px;z-index:9600;
  border:none;border-radius:22px;padding:10px 16px;font-size:12px;font-weight:700;
  font-family:'DM Sans',sans-serif;cursor:pointer;color:#fff;
  background:linear-gradient(135deg,var(--sun1,#8b5cf6),var(--sun2,#6d28d9));
  box-shadow:0 4px 14px rgba(76,29,149,0.4)}
.whc-view-toggle:hover{filter:brightness(1.05)}

/* ── Mobile: responsive layout only — fully editable ──
   Phones auto-detect into a single-column layout with larger tap
   targets. Inputs and buttons remain fully usable (no read-only). */
/* (Read-only restrictions removed — mobile users can edit like desktop.) */

/* ── Reflow to single column, larger tap targets, roomy cards ── */
.mobile-view #app{margin-left:0!important;max-width:none!important}
.mobile-view .fgrid,
.mobile-view .dash-row,
.mobile-view .proj-type-grid,
.mobile-view .kpi-grid{grid-template-columns:1fr!important}
.mobile-view .pay-figures{grid-template-columns:1fr 1fr!important}
.mobile-view .lpo-row{flex-direction:column!important}
.mobile-view .lpo-field{min-width:100%!important}
.mobile-view .body{padding:14px!important}
.mobile-view .sbox,
.mobile-view .quot-box,
.mobile-view .pay-card,
.mobile-view .prop-card,
.mobile-view .lpo-card{max-width:none!important;border-radius:14px;margin-bottom:12px}

/* Bigger, cleaner text for reading on phones */
.mobile-view .pay-fv{font-size:18px}
.mobile-view .fi,
.mobile-view .fl{font-size:14px}

/* The 4-up totals strips wrap nicely */
.mobile-view [style*="grid-template-columns:repeat(4,1fr)"]{grid-template-columns:1fr 1fr!important}

/* Sidebar still available via the ☰ toggle on mobile (already responsive).
   Hide the desktop sidebar shift. */
.mobile-view.has-sidebar #app{margin-left:0!important}

/* ── Proposals category cards (home page) ── */
.cat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;margin-top:18px}
.cat-card{background:#fff;border-radius:16px;overflow:hidden;box-shadow:0 2px 8px rgba(50,50,93,0.08),0 1px 3px rgba(0,0,0,0.04);transition:transform 0.18s,box-shadow 0.18s;display:flex;flex-direction:column}
.cat-card:hover{transform:translateY(-4px);box-shadow:0 14px 30px rgba(50,50,93,0.16)}
.cat-card-head{height:84px;display:flex;align-items:center;justify-content:space-between;padding:0 18px;position:relative}
.cat-card-ico{font-size:32px;filter:drop-shadow(0 2px 4px rgba(0,0,0,0.2))}
.cat-card-count{font-size:26px;font-weight:800;color:rgba(255,255,255,0.95);text-shadow:0 1px 3px rgba(0,0,0,0.15)}
.cat-card-body{padding:14px 18px 6px}
.cat-card-name{font-size:17px;font-weight:700;color:#32325d}
.cat-card-desc{font-size:12px;color:#8898aa;margin-top:3px;line-height:1.4}
.cat-card-actions{display:flex;gap:8px;padding:12px 18px 16px;margin-top:auto}
.cat-btn{flex:1;padding:9px 0;border:none;border-radius:9px;font-size:12.5px;font-weight:700;cursor:pointer;transition:all 0.15s;font-family:inherit}
.cat-btn-view{background:#f0f2f5;color:#525f7f}
.cat-btn-view:hover{background:#e6e9ef}
.cat-btn-new{color:#fff;box-shadow:0 3px 8px rgba(50,50,93,0.18)}
.cat-btn-new:hover{filter:brightness(1.06)}
@media(max-width:560px){.cat-grid{grid-template-columns:1fr 1fr}}
@media(max-width:380px){.cat-grid{grid-template-columns:1fr}}

/* ============================================================
   ICON POLISH — consistent, crisp iconography (emoji style)
   Pure CSS; doesn't change any markup. Gives section-header
   emoji a subtle styled feel and crisps up functional glyphs.
   ============================================================ */
/* Emoji render a touch larger & vertically centered in headers */
.pbar-label, .sbox-title, .quot-box-title, .hdr-logo, .admin-nav-tab, .auth-tab, .tab{
  font-variant-emoji: emoji;
}
/* Refresh buttons: spin the ↻ on hover for a lively, intentional feel */
button[onclick*="load"], button[onclick*="Refresh"], .actlog-refresh{
  transition:transform 0.3s;
}
button[onclick*="Refresh"]:hover, .actlog-refresh:hover{ transform:rotate(180deg); }

/* Category card icons get a soft glow ring so they feel designed */
.cat-card-ico{
  display:inline-flex;align-items:center;justify-content:center;
  width:46px;height:46px;border-radius:13px;
  background:rgba(255,255,255,0.22);backdrop-filter:blur(3px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.4),0 2px 6px rgba(0,0,0,0.12);
}

/* Sidebar nav icons sit in a subtle rounded slot for consistency */
.sb-ico{
  display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:30px;border-radius:9px;
  background:rgba(255,255,255,0.14);font-size:16px;
  transition:background 0.15s;
}
.sb-link:hover .sb-ico{background:rgba(255,255,255,0.26)}
.sb-link.on .sb-ico{background:rgba(109,40,217,0.14)}

/* Section-header emoji: give them a faint accent chip on key titles */
.sbox-title{display:flex;align-items:center;gap:7px}

/* Status chips & figures already colored; make ✓ / ✕ marks bolder */
.pay-lpo-chip, .status-chip{letter-spacing:0.2px}

/* ── SVG icons inside buttons: clean alignment + subtle motion ── */
.btn svg, .cat-btn svg, .scroll-top-btn svg{vertical-align:-0.15em;margin-right:1px}
.btn:hover svg{transform:none}
/* Refresh SVG spins on button hover */
button:hover svg.spin-on-hover{transform:rotate(180deg);transition:transform 0.4s}
.scroll-top-btn svg{margin-right:0}

/* ── Team Performance cards ── */
.tp-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px;margin-top:14px}
.tp-card{position:relative;background:#fff;border:1px solid #eef0f3;border-radius:14px;padding:16px;box-shadow:0 2px 8px rgba(50,50,93,0.07);transition:transform 0.18s,box-shadow 0.18s}
.tp-card:hover{transform:translateY(-3px);box-shadow:0 12px 26px rgba(50,50,93,0.14)}
.tp-card.tp-top{border:1px solid #ffd9a8;box-shadow:0 4px 16px rgba(109,40,217,0.16)}
.tp-rank{position:absolute;top:12px;right:14px;font-size:20px;font-weight:800;color:#c0c6d0}
.tp-card.tp-top .tp-rank{font-size:22px}
.tp-head{display:flex;align-items:center;gap:12px;margin-bottom:14px;padding-right:30px}
.tp-avatar{width:46px;height:46px;border-radius:50%;color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:17px;flex-shrink:0;box-shadow:0 3px 8px rgba(0,0,0,0.15)}
.tp-namewrap{min-width:0}
.tp-name{font-size:15px;font-weight:700;color:#32325d;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tp-cats{font-size:10.5px;color:#8898aa;margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tp-stats{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin-bottom:12px}
.tp-stat{background:#f7f8fa;border-radius:9px;padding:8px 4px;text-align:center}
.tp-stat-n{font-size:17px;font-weight:700;color:#32325d}
.tp-stat-l{font-size:9px;color:#8898aa;text-transform:uppercase;letter-spacing:0.4px;margin-top:2px}
.tp-net{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:7px}
.tp-net-v{font-size:16px;font-weight:700;color:#166a3f}
.tp-net-share{font-size:11px;color:#8898aa;font-weight:600}
.tp-bar{height:7px;background:#eef0f3;border-radius:5px;overflow:hidden}
.tp-bar-fill{height:100%;border-radius:5px;transition:width 0.4s}
@media(max-width:600px){.tp-grid{grid-template-columns:1fr}}

/* ── Attachment widget ── */
.att-wrap{margin:10px 0;padding:12px 14px;background:var(--surface-2);border:1px dashed var(--border);border-radius:11px}
.att-label{font-size:12px;font-weight:700;color:var(--text-muted);margin-bottom:8px}
.att-upload-btn{width:100%;padding:11px;border:1px solid var(--input-border);border-radius:9px;background:var(--input-bg);color:var(--text-muted);font-size:12.5px;font-weight:600;cursor:pointer;transition:all 0.15s;font-family:inherit}
.att-upload-btn:hover{border-color:#6d28d9;color:#6d28d9;background:var(--surface-3)}
.att-current{display:flex;align-items:center;gap:10px;flex-wrap:wrap;background:var(--input-bg);border:1px solid var(--border);border-radius:9px;padding:9px 12px}
.att-link{flex:1;min-width:0;color:#2563eb;text-decoration:none;font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.att-link:hover{text-decoration:underline}
.att-meta{font-size:11px;color:var(--text-faint)}
.att-replace{border:none;background:var(--surface-3);color:var(--text-muted);border-radius:7px;padding:5px 11px;font-size:11px;font-weight:600;cursor:pointer}
.att-replace:hover{background:var(--surface-2)}
.att-status{font-size:11.5px;margin-top:6px;min-height:14px}
/* Mobile is fully editable like desktop (see shared.js applyViewMode) —
   upload/replace stay visible; whether a user CAN attach/replace is
   decided by the same per-record/per-role logic that renders this
   widget on desktop, not by device. */

/* ── Attachment inline preview ── */
.att-current-preview{display:flex;align-items:flex-start;gap:10px;flex-wrap:wrap}
.att-thumb-wrap{display:inline-flex;flex-direction:column;gap:5px;text-decoration:none;max-width:100%}
.att-thumb{width:130px;height:130px;object-fit:cover;border-radius:11px;border:1px solid #e6e9ef;box-shadow:0 2px 8px rgba(50,50,93,0.1);transition:transform 0.15s,box-shadow 0.15s;background:#fff}
.att-thumb:hover{transform:scale(1.02);box-shadow:0 8px 20px rgba(50,50,93,0.18)}
.att-thumb-lg{width:200px;height:200px}
.att-thumb-cap{font-size:11px;color:#525f7f;font-weight:600;max-width:200px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.att-pdf-card{display:inline-flex;align-items:center;gap:12px;text-decoration:none;background:#fff;border:1px solid #e6e9ef;border-radius:11px;padding:12px 16px;transition:all 0.15s;box-shadow:0 1px 4px rgba(50,50,93,0.06)}
.att-pdf-card:hover{border-color:#6d28d9;box-shadow:0 6px 16px rgba(50,50,93,0.12)}
.att-pdf-ico{font-size:30px;line-height:1}
.att-pdf-info{display:flex;flex-direction:column;min-width:0}
.att-pdf-name{font-size:13.5px;font-weight:700;color:#32325d;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}
.att-pdf-sub{font-size:11px;color:#8898aa;margin-top:2px}

/* ============================================================
   PRIMAVERA SCHEDULE VIEWER — project-engineer/schedule-parser.js
   A plain CSS/HTML bar chart (no canvas/SVG library) drawn from a
   parsed .xer/P6-XML schedule: a sticky name column on the left,
   a horizontally-scrolling timeline on the right. Every bar/marker
   is positioned with a `left`/`width` computed in JS from the
   parsed dates, so this block is purely presentational.
   ============================================================ */
.sched-viewer{margin-top:14px;border:1px solid var(--border,#e6e9ef);border-radius:12px;overflow:hidden}
.sched-toolbar{display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 12px;background:var(--surface-3,#f6f7fb);border-bottom:1px solid var(--border,#e6e9ef)}
.sched-meta{font-size:11.5px;color:var(--text-muted)}
.sched-toggle{display:flex;gap:6px}
.sched-toggle-btn{border:1px solid var(--border,#e6e9ef);background:#fff;border-radius:8px;padding:5px 10px;font-size:11.5px;font-weight:600;cursor:pointer;color:var(--text-muted)}
.sched-toggle-btn.on{background:linear-gradient(135deg,var(--sun1,#8b5cf6),var(--sun2,#6d28d9));color:#fff;border-color:transparent}
.sched-empty{padding:24px;text-align:center;color:var(--text-muted);font-size:12.5px}

.sched-table-wrap{max-height:420px;overflow:auto}
.sched-table thead tr{position:sticky;top:0;z-index:1}
.sched-table tbody tr.sn-row{cursor:default}
.sched-milestone-row td{background:#faf7ff}

.sched-gantt-wrap{background:#fff}
.sched-gantt-scroll{overflow:auto;max-height:460px}
.sched-gantt-header-row,.sched-gantt-row{display:flex;min-width:max-content}
.sched-gantt-header-row{position:sticky;top:0;z-index:3;background:#fff;border-bottom:1px solid var(--border,#e6e9ef)}
.sched-gantt-name{flex:0 0 220px;max-width:220px;position:sticky;left:0;background:#fff;z-index:2;padding:6px 10px;font-size:11.5px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-right:1px solid var(--border,#e6e9ef);display:flex;align-items:center}
.sched-gantt-header-blank{flex:0 0 220px;max-width:220px;position:sticky;left:0;background:#fff;z-index:4;border-right:1px solid var(--border,#e6e9ef)}
.sched-gantt-groupname{font-weight:700;color:#5b3df5;background:#faf7ff}
.sched-gantt-grouprow .sched-gantt-track{background:#faf7ff}
.sched-gantt-track{position:relative;height:30px;flex:0 0 auto;border-bottom:1px solid #f0f1f5}
.sched-gantt-header-track{position:relative;height:26px;flex:0 0 auto}
.sched-gantt-month{position:absolute;top:0;height:100%;border-left:1px solid var(--border,#e6e9ef);font-size:10px;color:var(--text-muted);padding:4px 0 0 4px;white-space:nowrap;box-sizing:border-box}
.sched-gantt-bar{position:absolute;top:6px;height:18px;border-radius:5px;border:1px solid;box-sizing:border-box;overflow:hidden;cursor:default}
.sched-gantt-fill{position:absolute;top:0;left:0;bottom:0;opacity:0.9}
.sched-gantt-milestone{position:absolute;top:7px;width:14px;height:14px;background:#5b3df5;transform:translateX(-7px) rotate(45deg);border-radius:2px;cursor:default}
.sched-gantt-todaymark{position:absolute;top:0;bottom:0;width:0;border-left:1.5px dashed #dc2626;z-index:1;pointer-events:none}

/* ── User management row list (wider layout) — .auth-user-list/
   .auth-user-row live with the rest of the Manage Users rules above;
   this just covers the narrow-screen stack for the row's right-edge
   group/status/kebab cluster, which no longer fits inline on a phone. ── */
@media(max-width:560px){
  .auth-user-row{flex-wrap:wrap;gap:10px;padding:12px 13px}
  .aur-side{flex-basis:100%;justify-content:flex-end;margin-top:8px}
  /* Identity block keeps the avatar + checkbox on one line with the
     name, then meta/chips stack underneath — on a phone the row reads
     as a small card rather than a squeezed desktop row. */
  .aur-main{flex-basis:calc(100% - 76px)}
  .aur-meta-line{gap:2px 10px;font-size:11px}
  .aur-chips-line{gap:4px 6px}
  .um-group-select{max-width:none;flex:1}
  /* The "⋮" menu becomes a bottom sheet: a popover anchored to a row's
     right edge would otherwise open half off-screen on a narrow phone. */
  .user-menu-popover{position:fixed;top:auto;bottom:0;left:0;right:0;border-radius:16px 16px 0 0;min-width:0;padding:10px 10px calc(10px + env(safe-area-inset-bottom));box-shadow:0 -10px 34px rgba(13,33,55,0.26);animation:um-sheet-in 0.16s ease-out}
  .user-menu-backdrop{background:rgba(13,33,55,0.28)}
  .user-menu-item{padding:12px 12px;font-size:14px}
  /* Bulk bar sticks to the bottom of the viewport on a phone so it
     stays reachable while scrolling a long roster. */
  .um-bulkbar{position:sticky;bottom:8px;z-index:30}
  .um-bulk-actions{width:100%}
  .um-bulk-btn,.um-bulk-select{flex:1 1 auto;text-align:center}
  /* Table view horizontal-scrolls rather than crushing eight columns. */
  .um-table{min-width:760px}
}
@keyframes um-sheet-in{from{transform:translateY(100%)}to{transform:none}}

/* ── Typography: stylish Poppins titles + DM Sans body ── */
.landing-title, .hdr-title, .admin-title, .auth-hdr-title, .portal-greet,
.pbar-label, .clabel, .sbox-title, .quot-box-title, .hdr-logo,
.tile-title, .cat-card-name, .pay-title, .tp-name, .sb-brand-name,
.auth-user-name, .pbar-header .pbar-label, h1, h2, h3 {
  font-family: 'Poppins', 'DM Sans', sans-serif !important;
}

/* ── PDF inline preview (added with improved previews) ───────── */
.att-pdf-preview{display:block;max-width:340px}
.att-pdf-preview .att-pdf-frame-wrap{box-shadow:0 2px 8px rgba(50,50,93,0.1)}
@media (max-width:480px){
  .att-pdf-preview{max-width:100%}
  .att-thumb{width:110px;height:110px}
}

/* ============================================================
   DARK MODE — broad catches for the most common inline colors
   used throughout the app's JS-generated content. This can't be a
   perfect 1:1 rewrite of every hardcoded color (there are thousands
   of them across every module), but this covers the overwhelming
   majority: neutral card/surface backgrounds and body/muted text.
   Colorful semantic tints (status badges, warning banners, etc.)
   are deliberately left alone — they still read fine as-is.
============================================================ */
[data-theme="dark"] [style*="background:#fff"],
[data-theme="dark"] [style*="background: #fff"],
[data-theme="dark"] [style*="background:#f7f7f7"],
[data-theme="dark"] [style*="background:#f5f6fa"],
[data-theme="dark"] [style*="background:#f0f0f0"],
[data-theme="dark"] [style*="background:#f3f3f7"],
[data-theme="dark"] [style*="background:#fafafa"],
[data-theme="dark"] [style*="background:#fafafe"],
[data-theme="dark"] [style*="background:#fafbfc"],
[data-theme="dark"] [style*="background:#f7f8fc"],
[data-theme="dark"] [style*="background:#eee"],
[data-theme="dark"] [style*="background:#f4f8ff"],
[data-theme="dark"] [style*="background:#f0f2f5"],
[data-theme="dark"] [style*="background:#eef0f3"],
[data-theme="dark"] [style*="background: #f7f7f7"]{
  background: var(--surface-2) !important;
}
[data-theme="dark"] [style*="background:#eef0ff"],
[data-theme="dark"] [style*="background:#f3f0ff"],
[data-theme="dark"] [style*="background:#f3f1ff"],
[data-theme="dark"] [style*="background:#ede8fe"]{
  background: #262a45 !important;
}
[data-theme="dark"] [style*="color:#888"],
[data-theme="dark"] [style*="color:#999"],
[data-theme="dark"] [style*="color:#aaa"],
[data-theme="dark"] [style*="color:#bbb"],
[data-theme="dark"] [style*="color:#555"],
[data-theme="dark"] [style*="color:#666"]{
  color: var(--text-muted) !important;
}
[data-theme="dark"] [style*="color:#333"],
[data-theme="dark"] [style*="color:#222"],
[data-theme="dark"] [style*="color:#1a2740"],
[data-theme="dark"] [style*="color:#1a5276"],
[data-theme="dark"] [style*="color:#0d2137"],
[data-theme="dark"] [style*="color:#1a3a5c"],
[data-theme="dark"] [style*="color:#1a1a1a"],
[data-theme="dark"] [style*="color:#32325d"]{
  color: var(--text) !important;
}
/* Overall Summary's per-category KPI cards (summary-dashboard.js) put the
   category's tint on the OUTER card as a plain inline background, while
   the "ink" color (category label + Inquiries count) sits on separate
   inner elements — so the generic color:#1a5276 -> var(--text) override
   just above (written for elements whose own background is ALSO
   neutralized above) leaves this card's still-literal light pastel
   background untouched, producing light text on a light card. Scoped fix:
   darken each category's card background to the same dark equivalent
   already used elsewhere for that tint, and give the ink its own paired
   dark color instead of falling through to the generic override. */
[data-theme="dark"] .summary-cat-card.cat-live{ background:#182a42 !important; }
[data-theme="dark"] .summary-cat-card.cat-live .summary-cat-ink{ color:#6aa0d4 !important; }
[data-theme="dark"] .summary-cat-card.cat-fitout{ background:#0f2e20 !important; }
[data-theme="dark"] .summary-cat-card.cat-fitout .summary-cat-ink{ color:#4fb37f !important; }
[data-theme="dark"] .summary-cat-card.cat-id{ background:#3d2f10 !important; }
[data-theme="dark"] .summary-cat-card.cat-id .summary-cat-ink{ color:#d1a050 !important; }
[data-theme="dark"] .summary-cat-card.cat-private{ background:#262a45 !important; }
[data-theme="dark"] .summary-cat-card.cat-private .summary-cat-ink{ color:#a898dd !important; }
/* Stat tiles hardcode a light gradient background regardless of theme —
   fixed here since it's one shared component (renderStatTiles). */
[data-theme="dark"] .stat-tile{
  background: linear-gradient(160deg, var(--surface), var(--surface-2)) !important;
  border-color: var(--border) !important;
}
[data-theme="dark"] .stat-tile-l{ color: var(--text-faint) !important; }
/* The "Total" tile across every module's KPI row uses #0d2137 (near-
   black navy) as its number color — reads fine as "ink" on the tile's
   white light-mode background, but is nearly invisible against the
   dark tile background in dark mode. Every other tile's color is a
   genuinely vivid/saturated status color (orange/green/red/blue) that
   stays legible on dark surfaces without needing an override — this
   one specifically needed it. */
[data-theme="dark"] .stat-tile[style*="--tile-color:#0d2137"] .stat-tile-n{ color: var(--text) !important; }
/* Same problem, different dark navy — used on Account's "Invoice
   Raised" tile. Its luminance is nearly identical to the dark tile
   background, so it also reads as invisible without this override. */
[data-theme="dark"] .stat-tile[style*="--tile-color:#1a3a5c"] .stat-tile-n{ color: var(--text) !important; }
[data-theme="dark"] table thead tr,
[data-theme="dark"] thead tr{ background: var(--surface-2) !important; }
[data-theme="dark"] [style*="border:1px solid #eef0f3"],
[data-theme="dark"] [style*="border-bottom:1px solid #eef0f3"],
[data-theme="dark"] [style*="border:1px solid #e5e5e5"],
[data-theme="dark"] [style*="border-bottom:1px solid #f0f0f3"],
[data-theme="dark"] [style*="border-bottom:1px solid #f2f2f2"]{
  border-color: var(--border) !important;
}

/* ── Status badge PAIRS (background + text together) ──────────
   These MUST be overridden as matched pairs, not independently —
   overriding just one half of a badge's background/text combo left
   the other half untouched, producing light-text-on-light-background
   (or the reverse) that was unreadable in dark mode. Every status
   color map in the app (coordinator/account/proposals status
   dropdowns, document status, etc.) draws from this same small set of
   5 semantic pairs, so this covers all of them at once. Compound
   attribute selectors ([style*="a"][style*="b"]) only match elements
   that have BOTH substrings, so plain text using just one of these
   colors elsewhere is unaffected. */
[data-theme="dark"] [style*="background:#eef0f3"][style*="color:#777"],
[data-theme="dark"] [style*="background:#f0f0f0"][style*="color:#888"]{
  background:#2a2f3a !important; color:#9aa0ab !important; border-color:#3a4250 !important;
}
[data-theme="dark"] [style*="background:#eef4ff"][style*="color:#1a3a5c"],
[data-theme="dark"] [style*="background:#e8f0fe"][style*="color:#1a5276"]{
  background:#182a42 !important; color:#6aa0d4 !important; border-color:#2a4a70 !important;
}
[data-theme="dark"] [style*="background:#fdf3df"][style*="color:#a06b00"],
[data-theme="dark"] [style*="background:#ffe8cc"][style*="color:#a04800"]{
  background:#3d2f10 !important; color:#d1a050 !important; border-color:#5c4818 !important;
}
[data-theme="dark"] [style*="background:#e3f6ee"][style*="color:#166a3f"],
[data-theme="dark"] [style*="background:#d4f0e3"][style*="color:#166a3f"]{
  background:#0f2e20 !important; color:#4fb37f !important; border-color:#1c4a34 !important;
}
[data-theme="dark"] [style*="background:#fde8e8"][style*="color:#a32d2d"],
[data-theme="dark"] [style*="background:#fdecec"][style*="color:#a32d2d"],
[data-theme="dark"] [style*="background:#fdecec"][style*="color:#a33"]{
  background:#3d1515 !important; color:#e07070 !important; border-color:#5c2323 !important;
}
[data-theme="dark"] [style*="color:#a33"]{ color:#e07070 !important; }

/* Warm/orange notice banners — several near-duplicate light tints across
   coordinator/proposals/auth all pairing with the same #a06b00 text */
[data-theme="dark"] [style*="background:#fff7e6"][style*="color:#a06b00"],
[data-theme="dark"] [style*="background:#fff4e5"][style*="color:#a06b00"],
[data-theme="dark"] [style*="background:#fde8d8"][style*="color:#a04800"]{
  background:#3d2f10 !important; color:#d1a050 !important; border-color:#5c4818 !important;
}
/* Standalone versions of the same warm palette — for cases where the
   background and text color live on different elements (e.g. a message
   bubble whose header text is a separate inner element), so the paired
   selector above can't match both conditions on one element at once. */
[data-theme="dark"] [style*="background:#fff7e6"]{ background:#3d2f10 !important; }
[data-theme="dark"] [style*="border:1px solid #ffe1a8"],
[data-theme="dark"] [style*="border-color:#ffe1a8"]{ border-color:#5c4818 !important; }
[data-theme="dark"] [style*="color:#a06b00"]{ color:#d1a050 !important; }
[data-theme="dark"] [style*="background:#fff3e0"][style*="color:#e67e22"]{
  background:#3d2510 !important; color:#d8834a !important; border-color:#5c3a18 !important;
}

/* Blue info tints */
[data-theme="dark"] [style*="background:#e8f4ff"][style*="color:#1a5276"]{
  background:#182a42 !important; color:#6aa0d4 !important; border-color:#2a4a70 !important;
}

/* Purple tints — role badge pairs not covered by the plain surface wash above */
[data-theme="dark"] [style*="background:#eef0fb"][style*="color:#3c3489"],
[data-theme="dark"] [style*="background:#eeedfe"][style*="color:#3c3489"]{
  background:#262a45 !important; color:#a898dd !important; border-color:#3d3a5c !important;
}
[data-theme="dark"] [style*="background:#f3ecfb"][style*="color:#5b2c86"]{
  background:#2a2040 !important; color:#b898d9 !important; border-color:#453560 !important;
}

/* Role-badge pairs (super-admin.js ROLE_BADGE map) not covered by the groups above */
[data-theme="dark"] [style*="background:#faece7"][style*="color:#712b13"]{
  background:#3d1f18 !important; color:#e09070 !important; border-color:#5c3226 !important;
}
[data-theme="dark"] [style*="background:#e7f1fd"][style*="color:#1a4e8a"]{
  background:#182a42 !important; color:#6aa0d4 !important; border-color:#2a4a70 !important;
}
[data-theme="dark"] [style*="background:#faeeda"][style*="color:#633806"]{
  background:#3d2f10 !important; color:#d1a050 !important; border-color:#5c4818 !important;
}
[data-theme="dark"] [style*="background:#e0f0ea"][style*="color:#1c6b4a"]{
  background:#0f2e20 !important; color:#4fb37f !important; border-color:#1c4a34 !important;
}
[data-theme="dark"] .cat-card,
[data-theme="dark"] .proj-row,
[data-theme="dark"] .dash-card{
  background: var(--surface) !important; border-color: var(--border) !important;
}

/* ============================================================
   DARK MODE — class-based component overrides.
   Everything above only fixes elements carrying an inline
   style="" attribute (JS-rendered dynamic content). These
   components hardcode their light colors directly as CSS class
   rules earlier in this file instead, so the [style*="..."]
   catches never touch them — they stayed white/light with dark
   text no matter what theme was selected. This block is what
   was missing: the top tab bar, table/list rows, filter bars,
   and form fields across every module.
============================================================ */
[data-theme="dark"] .topbar,
[data-theme="dark"] .tabs,
[data-theme="dark"] .coord-name-box,
[data-theme="dark"] .coord-search-bar,
[data-theme="dark"] .rte-wrap,
[data-theme="dark"] .reapp-entry,
[data-theme="dark"] .reapp-client-box,
[data-theme="dark"] .admin-nav-tabs,
[data-theme="dark"] .pipeline-pill,
[data-theme="dark"] .search-bar,
[data-theme="dark"] .proj-type-option,
[data-theme="dark"] .admin-popup,
[data-theme="dark"] .auth-tabs,
[data-theme="dark"] .range-bar,
[data-theme="dark"] .milestone-label,
[data-theme="dark"] .linkbox-url,
[data-theme="dark"] .login-link-btn,
[data-theme="dark"] .se-reorder-btn{
  background: var(--surface) !important;
  border-color: var(--border) !important;
  color: var(--text) !important;
}
/* "Sign in with Microsoft" button on the login page - Microsoft's brand
   guidelines keep this button's own white/light background regardless
   of the surrounding app's theme (same reason "Sign in with Google"
   buttons never go dark either), so it deliberately has NO background
   override above. But its inline text color (#333, dark grey - meant to
   read against that light background) was still getting swept up by the
   generic [style*="color:#333"] catch-all a bit above, which forces it
   to var(--text) - near-white in dark mode. White text on a light-grey
   button is how it disappeared. Scoped by class + the original inline
   color so this wins over that catch-all without touching any other
   button that happens to also use #333. */
[data-theme="dark"] .ms-signin-btn[style*="color:#333"]{
  color:#333 !important;
}

[data-theme="dark"] .dch,
[data-theme="dark"] .se,
[data-theme="dark"] .deg,
[data-theme="dark"] .rte-toolbar,
[data-theme="dark"] .prop-filters,
[data-theme="dark"] .lpo-kpi,
[data-theme="dark"] .pipeline-proj-row{
  background: var(--surface-2) !important;
  border-color: var(--border) !important;
}
[data-theme="dark"] .bar-row:hover,
[data-theme="dark"] .coord-row:hover,
[data-theme="dark"] .attn-row:hover{
  background: var(--surface-2) !important;
}
[data-theme="dark"] .landing-body{ background: var(--bg) !important; }

[data-theme="dark"] .dr,
[data-theme="dark"] .sname,
[data-theme="dark"] .milestone-value,
[data-theme="dark"] .modal h3,
[data-theme="dark"] .prop-act-body,
[data-theme="dark"] .rte-btn,
[data-theme="dark"] .rte-editor,
[data-theme="dark"] .act-stage,
[data-theme="dark"] .admin-nav-tab.on,
[data-theme="dark"] .bar-count,
[data-theme="dark"] .coord-row,
[data-theme="dark"] .coord-name,
[data-theme="dark"] .attn-stage,
[data-theme="dark"] .auth-tab.on,
[data-theme="dark"] .pay-lpo-name,
[data-theme="dark"] .pay-lpo-amt,
[data-theme="dark"] .range-input,
[data-theme="dark"] .proj-row-title,
[data-theme="dark"] .proj-type-label,
[data-theme="dark"] .die-n,
[data-theme="dark"] .die-sel,
[data-theme="dark"] .deg-name{
  color: var(--text) !important;
}

[data-theme="dark"] .se-ni,
[data-theme="dark"] .se-sel,
[data-theme="dark"] .scope-details-fi,
[data-theme="dark"] .se-note,
[data-theme="dark"] .se-date-fi,
[data-theme="dark"] .search-input,
[data-theme="dark"] .coord-search-input,
[data-theme="dark"] .filter-sel,
[data-theme="dark"] .prop-filter-input,
[data-theme="dark"] .coord-filter-sel,
[data-theme="dark"] .rte-select{
  background: var(--input-bg) !important;
  border-color: var(--input-border) !important;
  color: var(--input-text) !important;
}
[data-theme="dark"] .se-appnum-fi{
  background: #3d1515 !important;
  color: var(--input-text) !important;
}
[data-theme="dark"] .range-now{
  background: #2a2340 !important;
  color: var(--text) !important;
}

/* ── Proposals list-card text/chips — missed because these are plain
   CSS class rules (not inline styles the earlier catch-all could reach),
   and weren't included in the bulk pass since they live in
   proposals/index.html's own markup rather than a shared .js file ── */
[data-theme="dark"] .prop-card{
  border-color: var(--border) !important;
}
[data-theme="dark"] .prop-card-title{
  color: var(--text) !important;
}
[data-theme="dark"] .prop-card-meta,
[data-theme="dark"] .prop-filter-label,
[data-theme="dark"] .prop-act-time{
  color: var(--text-muted) !important;
}
[data-theme="dark"] .prop-scope-preview{
  background: var(--surface-2) !important;
  color: var(--text-muted) !important;
}
[data-theme="dark"] .chip-active{ background:#3d2f10 !important; color:#d1a050 !important; }
[data-theme="dark"] .chip-done{ background:#0f2e20 !important; color:#4fb37f !important; }
[data-theme="dark"] .chip-new{ background:var(--surface-2) !important; color:var(--text-muted) !important; }
[data-theme="dark"] .chip-fb{ background:#3d2510 !important; color:#d8834a !important; }
[data-theme="dark"] .chip-proposal{ background:#262a45 !important; color:#a898dd !important; }
[data-theme="dark"] .chip-allocated{ background:#182a42 !important; color:#6aa0d4 !important; }

/* ── Remaining app-wide gaps found on a full sweep: plain CSS class
   rules (not inline styles) scattered across every module, most never
   touched because they live in each page's own markup/JS rather than
   a shared file the earlier passes covered. Grouped by what they mean
   so dark mode still reads as "success is green / warning is gold"
   instead of turning everything into flat gray. ── */

/* Muted/caption text */
[data-theme="dark"] .landing-section-label,
[data-theme="dark"] .sec-label,
[data-theme="dark"] .se-label,
[data-theme="dark"] .s-date,
[data-theme="dark"] .milestone-title,
[data-theme="dark"] .milestone-note,
[data-theme="dark"] .reapp-entry-num,
[data-theme="dark"] .act-detail,
[data-theme="dark"] .act-time,
[data-theme="dark"] .kpi-label,
[data-theme="dark"] .dash-card-title,
[data-theme="dark"] .dash-empty,
[data-theme="dark"] .coord-thead,
[data-theme="dark"] .attn-proj,
[data-theme="dark"] .pipeline-stage-label,
[data-theme="dark"] .proj-row-meta,
[data-theme="dark"] .admin-popup-empty,
[data-theme="dark"] .auth-kpi-l,
[data-theme="dark"] .auth-user-email,
[data-theme="dark"] .lpo-kpi-l,
[data-theme="dark"] .lpo-meta,
[data-theme="dark"] .pay-sub,
[data-theme="dark"] .pay-fl,
[data-theme="dark"] .pay-fc,
[data-theme="dark"] .pay-lpo-meta,
[data-theme="dark"] .range-lbl,
[data-theme="dark"] .bar-label{
  color: var(--text-muted) !important;
}

/* Bold heading/value text */
[data-theme="dark"] .admin-nav-tab.on,
[data-theme="dark"] .auth-tab.on,
[data-theme="dark"] .auth-user-name,
[data-theme="dark"] .pay-title{
  color: var(--text) !important;
}
/* .proj-pct (Coordinator/Account project-row progress %) and .pay-fv
   (Payments figure values) both default to #0d2137 in light mode - same
   near-black-navy problem as every other tile above - but BOTH are also
   given a real inline status color at some call sites (milestone-value
   green on .proj-pct, Credited-green/Pending-gold on .pay-fv), which the
   blanket !important rule they used to share with .pay-title/.auth-user-name
   was wiping out. Their existing inline colors already have good contrast
   on the dark surface (checked: #1d9e75, #27ae60, #e3c468 all clear 4.5:1+),
   so no brightened substitute is needed here - just not forcing them to
   white when they have their own color already. */
[data-theme="dark"] .proj-pct{ color: var(--text); }
[data-theme="dark"] .pay-fv{ color: var(--text); }

/* Account module's admin dashboard KPI cards (.kpi-num) — same problem
   again, but with TWO different ways the color gets set: a parent
   modifier class in light-mode CSS (.kpi-active/.kpi-done/.kpi-fb/
   .kpi-warn/.kpi-proposal/.kpi-reapp, each wrapping .kpi-num) AND a
   plain inline style for the couple of tiles account.js colors directly
   (see the `k.c` map in renderAdminDash). The old blanket rule had equal
   CSS specificity to the light-mode modifier-class rules and came later
   in the file, so it silently won and flattened every one of these too.
   Colors reused from the same brightened palette established above/
   elsewhere in this file, so the same status always reads as the same
   color everywhere in the app, dark or light. */
[data-theme="dark"] .kpi-num{ color: var(--text); }
[data-theme="dark"] .kpi-active .kpi-num{ color:#d1a050 !important; }
[data-theme="dark"] .kpi-done .kpi-num{ color:#4fb37f !important; }
[data-theme="dark"] .kpi-fb .kpi-num{ color:#d1a050 !important; }
[data-theme="dark"] .kpi-warn .kpi-num{ color:#e07070 !important; }
[data-theme="dark"] .kpi-proposal .kpi-num{ color:#a898dd !important; }
[data-theme="dark"] .kpi-reapp .kpi-num{ color:#d1a050 !important; }
[data-theme="dark"] .kpi-num[style*="color:#e24b4a"]{ color:#e07070 !important; }
[data-theme="dark"] .kpi-num[style*="color:#0369a1"]{ color:#6aa0d4 !important; }
[data-theme="dark"] .kpi-num[style*="color:#a04800"]{ color:#d1a050 !important; }

/* Green "approved/received/success" pairs */
[data-theme="dark"] .si-approved,
[data-theme="dark"] .b-approved,
[data-theme="dark"] .dic-received,
[data-theme="dark"] .dt-received,
[data-theme="dark"] .saved-chip,
[data-theme="dark"] .btn-green{
  background:#0f2e20 !important; color:#4fb37f !important;
}

/* Neutral "pending/n.a." pairs */
[data-theme="dark"] .si-pending,
[data-theme="dark"] .b-pending,
[data-theme="dark"] .dic-na,
[data-theme="dark"] .dt-na,
[data-theme="dark"] .bar-track{
  background: var(--surface-2) !important; color: var(--text-muted) !important; border-color: var(--border) !important;
}

/* Gold/warm highlight surfaces — notices, drag-over, selected, hover states */
[data-theme="dark"] .nb,
[data-theme="dark"] .btn-add:hover,
[data-theme="dark"] .se.drag-over,
[data-theme="dark"] .scope-drag-row.scope-row-over,
[data-theme="dark"] .se-selected,
[data-theme="dark"] .bulk-bar,
[data-theme="dark"] .proj-type-tag,
[data-theme="dark"] .kpi-card.kpi-active-filter,
[data-theme="dark"] .proj-type-option.selected,
[data-theme="dark"] .admin-popup-proj-row:hover{
  background:#3d2f10 !important; border-color:#5c4818 !important; color:#d1a050 !important;
}

/* Light blue callout */
[data-theme="dark"] .s-appnum{
  background:#182a42 !important; color: var(--text-muted) !important;
}

/* Light purple banner */
[data-theme="dark"] .alloc-banner{
  background:#262a45 !important; border-color:#3d3a5c !important;
}

/* Misc surface */
[data-theme="dark"] .pay-figures > div{
  background: var(--surface-2) !important; border-color: var(--border-soft) !important;
}
[data-theme="dark"] [style*="background:#eef6ff"][style*="color:#1a5fb4"]{
  background:#182a42 !important; color:#6aa0d4 !important;
}
[data-theme="dark"] [style*="background:#f0fdf4"]{
  background:#0f2e20 !important; border-color:#1c4a34 !important;
}

/* ── Manage Users (auth) — dark mode ──
   This page never gets the has-sidebar layout (it's a standalone view,
   not one of the sidebar modules), so none of the body.has-sidebar
   dark-mode overrides elsewhere in this file ever reach it. Needs its
   own complete set here instead of piggybacking on those. */
[data-theme="dark"] .auth-tabs{ background: var(--surface); border-color: var(--border); }
[data-theme="dark"] .auth-tab{ color: var(--text-muted); }
[data-theme="dark"] .auth-tab:hover,
[data-theme="dark"] .auth-tab.on{ color: var(--text); }
[data-theme="dark"] .auth-kpi{ background: var(--surface); border-color: var(--border); }
/* .auth-kpi-n is shared well beyond Manage Users - Dependent Tasks,
   Site Inspection, and every read-only team-viewer page (Design/PE/QS/
   FLS/Structural) all use it for their status-count tiles too, each
   passing its own inline color per tile (green=done, blue=in progress,
   amber=open, red=hold, orange=needs pickup) — see the `tile()` helper
   in each of those files. This base rule only covers the "Total" tile,
   which passes no inline color at all and would otherwise fall back to
   its light-mode default (#0d2137, near-black navy - invisible on a
   dark tile). It must NOT be !important, or it would stomp every other
   tile's inline color too and flatten them all to plain white — that
   was exactly the bug here (every tile number looked identical in dark
   mode, losing the whole point of color-coding them). The specific
   colors below are brightened per-hue equivalents of what light mode
   uses, matching the same brightening this file already does for these
   exact hexes everywhere else (badges, pills, banners) — chosen for
   contrast against the dark tile background (--surface, ~#1e2530),
   not just genuinely different colors from each other. */
[data-theme="dark"] .auth-kpi-n{ color: var(--text); }
[data-theme="dark"] .auth-kpi-n[style*="color:#166a3f"]{ color:#4fb37f !important; } /* green - done/credited/resolved */
[data-theme="dark"] .auth-kpi-n[style*="color:#1a5fb4"]{ color:#6aa0d4 !important; } /* blue - in progress/allocated */
[data-theme="dark"] .auth-kpi-n[style*="color:#a06b00"]{ color:#d1a050 !important; } /* amber - open/pending */
[data-theme="dark"] .auth-kpi-n[style*="color:#a32d2d"]{ color:#e07070 !important; } /* red - hold/attention */
[data-theme="dark"] .auth-kpi-n[style*="color:#e67e22"]{ color:#d8834a !important; } /* orange - unassigned/needs pickup */
[data-theme="dark"] .auth-kpi-l{ color: var(--text-muted); }
/* .lpo-kpi-n (Coordinator's LPO summary tiles) has the identical
   pattern and needed the identical fix — same reasoning as .auth-kpi-n
   above. (.lpo-kpi background/.lpo-kpi-l color are already handled
   elsewhere in this file — only the number's color needed this.) */
[data-theme="dark"] .lpo-kpi-n{ color: var(--text); }
[data-theme="dark"] .lpo-kpi-n[style*="color:#1a5fb4"]{ color:#6aa0d4 !important; } /* blue - % collected */
[data-theme="dark"] .auth-success{ background:#0f2e20; color:#4fb37f; border-color:#1c4a34; }
[data-theme="dark"] .auth-error{ background:#3d1515; color:#e07070; border-color:#5c2323; }
[data-theme="dark"] .auth-user-list{ background: var(--surface); border-color: var(--border); }
[data-theme="dark"] .auth-user-row{ border-color: var(--border-soft); }
[data-theme="dark"] .auth-user-row:hover{ background: var(--surface-2); }
[data-theme="dark"] .auth-user-name{ color: var(--text); }
[data-theme="dark"] .auth-user-email{ color: var(--text-muted); }
[data-theme="dark"] .aur-meta-line{ color: var(--text-muted); }
[data-theme="dark"] .auth-inactive-badge{ background:#3d1515; color:#e07070; }
/* Manage Users v2 — dark pass. The avatar keeps its per-name hsl()
   colour (set inline by umAvatarStyle(), so it can't be overridden
   here and doesn't need to be — light pastel fills read fine against
   the dark row and stay the fastest way to recognise a person). */
[data-theme="dark"] .auth-user-row.aur-selected{ background: rgba(91,61,245,0.16); }
[data-theme="dark"] .auth-user-row.aur-selected:hover{ background: rgba(91,61,245,0.22); }
[data-theme="dark"] .um-table-wrap{ background: var(--surface); border-color: var(--border); }
[data-theme="dark"] .um-table th{ background: var(--surface-2); color: var(--text-faint); border-color: var(--border); }
[data-theme="dark"] .um-table td{ color: var(--text); border-color: var(--border-soft); }
[data-theme="dark"] .um-table tbody tr:hover td{ background: var(--surface-2); }
[data-theme="dark"] .um-table tbody tr.um-tr-sel td{ background: rgba(91,61,245,0.16); }
[data-theme="dark"] .um-td-dim{ color: var(--text-muted); }
[data-theme="dark"] .um-inline:hover{ background: rgba(124,92,255,0.20); }
[data-theme="dark"] .um-empty-title{ color: var(--text); }
/* Manage Users card modernization — dark-mode pass, same classes as the
   light-mode block above (shared/style.css's .um-* rules). */
[data-theme="dark"] .um-kebab{ color: var(--text-muted); }
[data-theme="dark"] .um-kebab:hover{ background: var(--surface-2); color: var(--text); border-color: var(--border); }
[data-theme="dark"] .um-meta-label{ color: var(--text-faint); }
[data-theme="dark"] .um-badges-label{ color: var(--text-faint); }
[data-theme="dark"] .um-chip{ background: var(--surface-3); color: var(--text); }
[data-theme="dark"] .um-chip-muted{ color: var(--text-faint); }
[data-theme="dark"] .um-status-pill.on{ background:#0f2e20; color:#4fb37f; }
[data-theme="dark"] .um-status-pill.off{ background:#3d1515; color:#e07070; }
[data-theme="dark"] .user-menu-popover{ background: var(--surface); border-color: var(--border); box-shadow:0 12px 32px rgba(0,0,0,0.5); }
[data-theme="dark"] .user-menu-item{ color: var(--text); }
[data-theme="dark"] .user-menu-item:hover{ background: var(--surface-2); }
[data-theme="dark"] .user-menu-item.danger{ color:#e07070; }
[data-theme="dark"] .user-menu-item.danger:hover{ background:#3d1515; }
[data-theme="dark"] .user-menu-divider{ background: var(--border-soft); }

/* ── ServiceNow-style compact request list table ──
   Used by Dependent Tasks and Account's queues. */
.sn-table{width:100%;border-collapse:collapse;font-size:12.5px}
.sn-table thead tr{background:var(--surface-3);border-bottom:1px solid var(--border)}
.sn-table th{text-align:left;padding:8px 10px;font-size:10.5px;font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.3px;white-space:nowrap}
.sn-table tbody tr.sn-row{border-bottom:1px solid var(--border-soft);cursor:pointer;transition:background 0.1s}
.sn-table tbody tr.sn-row:hover{background:var(--surface-2)}
.sn-table td{padding:9px 10px;vertical-align:middle;white-space:nowrap}
.sn-table td.sn-desc{font-weight:600;color:var(--text);white-space:normal;min-width:180px}
.sn-table td.sn-muted{color:var(--text-muted)}
.sn-table td.sn-num{font-family:'SF Mono',Consolas,Menlo,monospace;font-size:11px;font-weight:700;color:#5b3df5}
.sn-table td.sn-overdue{color:#a32d2d;font-weight:700}
.sn-pill{display:inline-block;font-size:10.5px;font-weight:600;padding:2px 9px;border-radius:9px;white-space:nowrap}
@media(max-width:820px){
  .sn-table{font-size:11.5px}
  .sn-table th, .sn-table td{padding:7px 8px}
}

/* ── Toast notifications — replaces plain browser alert() for
   save/submit confirmations across the app. See shared.js showToast(). ── */
#whc-toast-wrap{position:fixed;top:22px;left:50%;transform:translateX(-50%);z-index:99999;display:flex;flex-direction:column;gap:10px;align-items:center;pointer-events:none}
.whc-toast{pointer-events:auto;display:flex;align-items:center;gap:11px;min-width:260px;max-width:min(520px,86vw);padding:13px 20px 13px 16px;border-radius:12px;background:var(--surface);border:1px solid var(--border);box-shadow:0 10px 32px rgba(13,33,55,0.22),0 2px 8px rgba(13,33,55,0.10);opacity:0;transform:translateY(-14px) scale(0.97);transition:opacity 0.28s cubic-bezier(.22,1,.36,1),transform 0.28s cubic-bezier(.22,1,.36,1)}
.whc-toast.show{opacity:1;transform:translateY(0) scale(1)}
.whc-toast.hide{opacity:0;transform:translateY(-10px) scale(0.97)}
.whc-toast-icon{flex:0 0 auto;width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;color:#fff;animation:whc-toast-pop 0.4s cubic-bezier(.34,1.56,.64,1) 0.05s both}
.whc-toast-msg{font-size:13px;font-weight:600;color:var(--text);line-height:1.45}
.whc-toast-bar{position:absolute;left:0;bottom:0;height:3px;border-radius:0 0 12px 12px;animation:whc-toast-shrink linear forwards}
.whc-toast{position:relative;overflow:hidden}
.whc-toast-success .whc-toast-icon{background:linear-gradient(135deg,#22a86b,#166a3f)}
.whc-toast-success .whc-toast-bar{background:linear-gradient(90deg,#22a86b,#166a3f)}
.whc-toast-error .whc-toast-icon{background:linear-gradient(135deg,#e0554f,#a32d2d)}
.whc-toast-error .whc-toast-bar{background:linear-gradient(90deg,#e0554f,#a32d2d)}
.whc-toast-info .whc-toast-icon{background:linear-gradient(135deg,#7b8fd9,#5b3df5)}
.whc-toast-info .whc-toast-bar{background:linear-gradient(90deg,#7b8fd9,#5b3df5)}
@keyframes whc-toast-pop{0%{transform:scale(0.4);opacity:0}60%{transform:scale(1.15)}100%{transform:scale(1);opacity:1}}
@keyframes whc-toast-shrink{from{width:100%}to{width:0%}}
@media(max-width:600px){
  #whc-toast-wrap{top:12px;width:94vw}
  .whc-toast{width:100%;min-width:0}
}

/* ── Modern confirm/prompt dialogs — replace the plain browser
   confirm()/prompt() popups app-wide. See shared.js whcConfirm()/
   whcPrompt(). Same overlay+card language as .overlay/.modal but its
   own classes/z-index, since it's injected straight onto document.body
   independent of any module's own modal state (it can legitimately be
   asked to show up ON TOP of an already-open custom modal, e.g.
   "delete this row" confirmed from inside a detail editor). ── */
.whc-confirm-overlay{position:fixed;inset:0;z-index:99999;display:flex;align-items:center;justify-content:center;padding:16px;
  background:rgba(13,20,30,0.5);backdrop-filter:blur(2px);
  opacity:0;transition:opacity 0.2s cubic-bezier(.22,1,.36,1)}
.whc-confirm-overlay.show{opacity:1}
.whc-confirm-overlay.hide{opacity:0}
.whc-confirm-box{background:var(--surface);color:var(--text);border-radius:16px;padding:26px 24px 22px;width:380px;max-width:100%;
  box-shadow:0 20px 60px rgba(0,0,0,0.32),0 4px 16px rgba(0,0,0,0.14);
  transform:translateY(10px) scale(0.96);transition:transform 0.24s cubic-bezier(.22,1,.36,1)}
.whc-confirm-overlay.show .whc-confirm-box{transform:translateY(0) scale(1)}
.whc-confirm-icon{width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-size:18px;font-weight:700;color:#fff;margin-bottom:12px}
.whc-confirm-icon-info{background:linear-gradient(135deg,var(--sun1,#8b5cf6),var(--sun2,#6d28d9))}
.whc-confirm-icon-danger{background:linear-gradient(135deg,#e0554f,#a32d2d)}
.whc-confirm-title{font-size:15px;font-weight:700;color:var(--text);margin-bottom:6px}
.whc-confirm-msg{font-size:13px;color:var(--text-muted);line-height:1.55}
.whc-confirm-input{margin-top:14px;width:100%}
.whc-confirm-btns{display:flex;justify-content:flex-end;gap:9px;margin-top:20px}
.whc-confirm-btn{border:none;border-radius:10px;padding:9px 18px;font-size:13px;font-weight:600;cursor:pointer;
  font-family:'DM Sans',sans-serif;transition:filter 0.15s,background 0.15s}
.whc-confirm-btn-cancel{background:var(--surface-3,#eef0f3);color:var(--text)}
.whc-confirm-btn-cancel:hover{filter:brightness(0.96)}
.whc-confirm-btn-ok{background:linear-gradient(135deg,var(--sun1,#8b5cf6),var(--sun2,#6d28d9));color:#fff;box-shadow:0 3px 8px rgba(76,29,149,0.28)}
.whc-confirm-btn-danger{background:linear-gradient(135deg,#e0554f,#a32d2d);color:#fff;box-shadow:0 3px 8px rgba(163,45,45,0.28)}
.whc-confirm-btn-ok:hover,.whc-confirm-btn-danger:hover{filter:brightness(1.06)}
@media(max-width:480px){
  .whc-confirm-box{width:100%}
}

/* ══════════════════════════════════════════════════════════════
   Site inspection on phones & tablets
   ──────────────────────────────────────────────────────────────
   Inspectors fill these screens standing in the unit, one-handed,
   on a phone — not at a desk. Everything below is scoped to
   max-width:820px (tablet portrait and down), so DESKTOP RENDERS
   EXACTLY AS BEFORE: no rule here applies above that width.

   The hooks these rules attach to (.si-sheet, .si-req-grid,
   .si-detail-grid, .si-snag-wrap/.sn-snag, .sn-cards, .si-search-bar,
   .si-photo-btn) are plain class names added to existing markup in
   coordinator.js, shared.js and site-inspection.js — no layout logic
   moved into JavaScript.
   ══════════════════════════════════════════════════════════════ */
@media(max-width:820px){

  /* 1. Inputs at 16px. Any smaller and iOS Safari zooms the page in
        the moment a field is focused, leaving the inspector pinched
        into a corner of a form they then have to scroll back out of.
        16px is the documented threshold — this is the single most
        important rule in this block. The !important is deliberate:
        many of these fields carry an inline font-size (11–13px) set
        for the desktop table layout, and inline styles otherwise win. */
  .si-sheet .fi,
  .si-snag-wrap .fi,
  .si-search-bar .fi{
    font-size:16px !important;
    padding:11px 12px !important;
    min-height:44px;
  }
  .si-sheet textarea.fi,
  .si-snag-wrap textarea.fi{ min-height:70px }

  /* 2. Tap targets. 44px is the smallest reliably-hittable control
        with a thumb; several of these were 14–20px tall. */
  .si-sheet .btn,
  .si-snag-wrap .btn,
  .si-sheet select.fi{ min-height:44px; font-size:14px }
  .si-sheet input[type="checkbox"],
  .si-snag-wrap input[type="checkbox"]{ width:22px; height:22px }

  /* 3. The request/detail modal becomes a full-height sheet rather
        than a floating card with wasted margin on every side. */
  .overlay:has(.si-sheet){ padding:0; align-items:flex-end }
  .modal.si-sheet{
    width:100% !important; max-width:100% !important;
    max-height:100vh !important; height:100vh;
    border-radius:0; padding:18px 16px calc(18px + env(safe-area-inset-bottom));
  }

  /* 4. Group / Visit Date / Visit Time were three columns sharing
        ~330px — about 100px each, which makes the native date and
        time pickers unusable. Stack them. */
  .si-req-grid{ grid-template-columns:1fr !important }
  .si-detail-grid{ grid-template-columns:1fr !important }

  /* 5. Submit/Cancel pinned to the bottom of the sheet, so raising a
        request never requires scrolling to the end of the form to
        find the button. */
  .si-sheet .si-sheet-actions{
    position:sticky; bottom:0; z-index:2;
    margin:14px -16px calc(-18px - env(safe-area-inset-bottom));
    padding:12px 16px calc(12px + env(safe-area-inset-bottom));
    background:var(--surface);
    border-top:1px solid var(--border);
  }

  /* 6. The snag list is a 10-column table. On a phone that means
        typing an issue into a cell that is half off-screen. Each row
        becomes a card, each cell labelled from its data-label. */
  .si-snag-wrap{ overflow-x:visible !important }
  .sn-snag thead{ display:none }
  .sn-snag, .sn-snag tbody, .sn-snag tr, .sn-snag td{ display:block; width:auto }
  .sn-snag tr{
    border:1px solid var(--border); border-radius:12px;
    padding:12px 12px 6px; margin-bottom:12px; background:var(--surface);
    position:relative;
  }
  .sn-snag td{
    white-space:normal !important;
    padding:6px 0 !important;
    border:none;
  }
  .sn-snag td::before{
    content:attr(data-label);
    display:block;
    font-size:10px; font-weight:700; letter-spacing:0.3px;
    text-transform:uppercase; color:var(--text-muted);
    margin-bottom:3px;
  }
  .sn-snag td[data-label=""]::before{ content:none }
  /* Inputs sized for the desktop columns (100/140/80px) go full width */
  .sn-snag td .fi{ width:100% !important }
  /* Item number as a corner badge rather than its own labelled row */
  .sn-snag td.sn-snag-idx{
    position:absolute; top:10px; right:12px;
    padding:0 !important; font-weight:700; color:var(--text-muted); font-size:12px;
  }
  .sn-snag td.sn-snag-idx::before{ content:"#" }
  .sn-snag td.sn-snag-del{ text-align:right }

  /* 7. Same card treatment for the inspection list, so picking the
        right inspection doesn't need sideways scrolling either. */
  .sn-cards thead{ display:none }
  .sn-cards, .sn-cards tbody, .sn-cards tr, .sn-cards td{ display:block; width:auto }
  .sn-cards tr.sn-row{
    border:1px solid var(--border); border-radius:12px;
    padding:12px 14px; margin-bottom:10px; background:var(--surface);
  }
  .sn-cards td{
    white-space:normal !important;
    padding:3px 0 !important; border:none;
    display:flex; justify-content:space-between; gap:12px; align-items:baseline;
  }
  .sn-cards td::before{
    content:attr(data-label);
    flex:0 0 auto;
    font-size:10px; font-weight:700; letter-spacing:0.3px;
    text-transform:uppercase; color:var(--text-muted);
  }
  /* Number and item read as the card's heading, not as labelled rows */
  .sn-cards td.sn-num, .sn-cards td.sn-desc{ display:block }
  .sn-cards td.sn-num::before, .sn-cards td.sn-desc::before{ content:none }
  .sn-cards td.sn-desc{ font-size:14px; margin-bottom:4px }

  /* 8. Search fields: the 180px/200px minimums overflow a 360px
        screen when sitting side by side. One per line. */
  .si-search-bar{ flex-direction:column; align-items:stretch }
  .si-search-bar .fi{ width:100% !important; min-width:0 !important }

  /* 9. Photo buttons were 9px text in a 1px-padded box. */
  .si-photo-btn{
    font-size:13px !important;
    padding:9px 14px !important;
    min-height:40px; margin-top:6px;
  }
  .si-sheet .att-upload-btn{ min-height:44px; font-size:14px }
}

/* Phones specifically: the checklist nests Main > Sub > Equipment,
   each indented 24px. Three levels costs 72px of a 360px screen
   before any content. Tighten the indent and keep the left rules as
   the visual cue for depth instead. */
@media(max-width:560px){
  .si-sheet [style*="margin:8px 0 0 24px"],
  .si-sheet [style*="margin:6px 0 0 24px"],
  .si-sheet [style*="margin:10px 0 0 24px"]{
    margin-left:10px !important;
    border-left:2px solid var(--border-soft);
    padding-left:8px;
  }
}
