/* Tax CRM — clean back-office styling, navy + gold like the tax brand. */
:root { --navy:#14304d; --gold:#c9a227; --bg:#f4f5f7; --card:#fff; --line:#dde1e6; --txt:#1c2430; --mut:#67707d; --ok:#177245; --bad:#b3261e; }
* { box-sizing: border-box; }
body { margin:0; font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; background:var(--bg); color:var(--txt); }
a { color:var(--navy); }
.topbar { background:var(--navy); color:#fff; display:flex; justify-content:space-between; align-items:center; padding:10px 18px; flex-wrap:wrap; gap:8px; }
.topbar .brand { font-weight:700; font-size:18px; }
.topbar .brand span { color:var(--gold); }
.topbar nav { display:flex; gap:14px; align-items:center; }
.topbar nav a { color:#dbe4ee; text-decoration:none; padding:4px 8px; border-radius:6px; }
.topbar nav a.on { background:rgba(255,255,255,.15); color:#fff; }
/* Two-row owner top bar (owner's ruling, 2026-11-02 evening; built
   2026-11-03): the owner bar stacks two rows — row 1 is the brand
   with ⚙️ Settings, the 🔔 bell and Sign out at the right; row 2 is
   ⚡ Quick Actions first, then Dashboard · Clients · Calendar ·
   Payments · Marketing. Scoped to .ownerbar: the portal top bar
   shares .topbar but carries no .ownerbar and stays one row. */
.topbar.ownerbar { flex-direction:column; align-items:stretch; }
.topbar.ownerbar .barrow1 { display:flex; justify-content:space-between; align-items:center; gap:8px; }
/* Marketing header/footer image previews in the Marketing tab. */
.mktimgprev { max-width:300px; max-height:110px; display:block; border:1px solid #dde1e6; border-radius:8px; margin-top:4px; }
.linkbtn { background:none; border:none; color:#dbe4ee; cursor:pointer; font-size:14px; padding:4px; }
main { max-width:1100px; margin:0 auto; padding:18px; }
h2 { margin:8px 0 14px; } h3 { margin:6px 0 10px; } h4 { margin:10px 0 6px; }
.card { background:var(--card); border:1px solid var(--line); border-radius:10px; padding:14px 16px; margin:12px 0; }
.card.alert { border-left:4px solid var(--gold); }
.grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:10px; }
.grid2 { display:grid; grid-template-columns:repeat(auto-fit,minmax(320px,1fr)); gap:14px; }
label { display:block; font-size:13px; color:var(--mut); margin:4px 0; }
input, select, textarea { width:100%; padding:8px; border:1px solid var(--line); border-radius:7px; font-size:14px; margin-top:3px; background:#fff; color:var(--txt); }
textarea { resize:vertical; }
.btn { background:#eef1f5; border:1px solid var(--line); padding:8px 14px; border-radius:8px; cursor:pointer; font-size:14px; display:inline-block; }
.btn.primary { background:var(--navy); color:#fff; border-color:var(--navy); }
.btn.danger { background:#fbeae8; color:var(--bad); border-color:#eec9c5; }
.btn.small { padding:4px 9px; font-size:13px; }
.row { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin:8px 0; }
.rowline { display:flex; justify-content:space-between; align-items:center; gap:10px; padding:6px 0; border-bottom:1px solid var(--line); }
.rowline:last-child { border-bottom:none; }
table { width:100%; border-collapse:collapse; background:var(--card); border:1px solid var(--line); border-radius:10px; overflow:hidden; margin:10px 0; }
th, td { text-align:left; padding:8px 10px; border-bottom:1px solid var(--line); font-size:14px; vertical-align:top; }
th { background:#eef1f5; }
/* Wide tables slide sideways inside their own strip (.tscroll) —
   owner ruling 2026-11-01: on his phone the client page Documents
   table was wider than the screen, the whole page ended up cut off
   on both sides and stuck sideways. Every owner table is emitted
   inside a .tscroll wrapper. The wrapper is a plain full-width
   block, so desktop layout is untouched (when the table fits, the
   auto overflow shows no scrollbar and nothing moves); when a
   table is wider than its strip, the TABLE slides inside the strip
   and the page itself never exceeds the viewport because of it.
   overflow-x:auto also makes the wrapper contain the table's
   min-content width, so it can never widen an ancestor. */
.tscroll { max-width:100%; overflow-x:auto; -webkit-overflow-scrolling:touch; }
.pill { font-size:12px; padding:2px 9px; border-radius:99px; background:#e8ecf1; white-space:nowrap; }
.pill.lead { background:#fdf3d7; } .pill.customer, .pill.received { background:#dcf2e5; color:var(--ok); }
.pill.needed { background:#fbeae8; color:var(--bad); } .pill.waived { background:#e8ecf1; color:var(--mut); }
.pill.stage { background:#e2e9f5; } .pill.fee.paid { background:#dcf2e5; color:var(--ok); } .pill.fee.partial { background:#fdf3d7; } .pill.fee.unpaid { background:#fbeae8; color:var(--bad); }
.stats { display:flex; gap:10px; flex-wrap:wrap; }
.stat { background:var(--card); border:1px solid var(--line); border-radius:10px; padding:10px 14px; min-width:104px; text-align:center; }
.statn { font-size:22px; font-weight:700; } .statl { font-size:12px; color:var(--mut); }
.note { border-bottom:1px solid var(--line); padding:7px 0; font-size:14px; }
.muted { color:var(--mut); } .small { font-size:12px; } .err { color:var(--bad); } .ok { color:var(--ok); font-weight:600; }
.hidden { display:none; }
.loginwrap { min-height:100vh; display:flex; align-items:center; justify-content:center; padding:16px; }
.logincard { background:var(--card); border:1px solid var(--line); border-radius:14px; padding:26px; max-width:380px; width:100%; }
.logincard h1 { font-size:22px; margin:0 0 4px; } .logincard h1 span { color:var(--gold); }
.logincard .btn { width:100%; margin-top:10px; }
.uploadbtn { position:relative; overflow:hidden; cursor:pointer; }
.signdoc { border:1px dashed var(--gold); border-radius:10px; padding:14px; margin-top:12px; }
.docbody { white-space:pre-wrap; background:#fafbfc; border:1px solid var(--line); border-radius:8px; padding:12px; max-height:260px; overflow:auto; font-size:14px; }
.sigfont { font-family:"Segoe Script", "Brush Script MT", cursive; font-size:20px; }
label.check { display:flex; gap:8px; align-items:flex-start; color:var(--txt); font-size:14px; }
label.check input { width:auto; margin-top:2px; }
/* Quick Actions launcher */
.btn.qa { background:var(--gold); border-color:var(--gold); color:#1c2430; font-weight:700; }
.qamodal { position:fixed; inset:0; z-index:60; background:rgba(20,32,48,.55); display:flex; align-items:flex-start; justify-content:center; padding:42px 14px; overflow:auto; }
.qacard { background:var(--card); border-radius:12px; padding:16px 18px; width:100%; max-width:580px; box-shadow:0 14px 44px rgba(0,0,0,.35); }
.qacard h3 { margin:2px 0; }
.qagrid { display:grid; grid-template-columns:repeat(auto-fit,minmax(165px,1fr)); gap:8px; margin:8px 0; }
.btn.qaact { text-align:left; padding:10px 12px; background:#fff; }
.btn.qaact:hover { border-color:var(--gold); }
.btn.qaclient { display:block; width:100%; text-align:left; margin:4px 0; background:#fff; }
.primed { outline:3px solid var(--gold); outline-offset:1px; }
/* Client portal tabs + chat (bubble is WhatsApp-style: round, green,
   fixed at the bottom corner; the panel opens above it). Main gets
   extra bottom padding so page content can always scroll clear of
   the bubble — it never sits on top of the sign pad or uploads. */
main.portalmain { padding-bottom:110px; }
.ptabs { display:flex; gap:2px; margin:10px 0 4px; border-bottom:2px solid var(--line); overflow-x:auto; }
.ptab { background:none; border:none; border-bottom:3px solid transparent; margin-bottom:-2px; padding:9px 12px; font-size:15px; cursor:pointer; color:var(--mut); white-space:nowrap; font-family:inherit; }
.ptab.on { color:var(--navy); border-bottom-color:var(--gold); font-weight:700; }
.ptabpanel[hidden] { display:none; }
.tabbadge { background:var(--bad); color:#fff; font-size:11px; font-weight:700; border-radius:99px; padding:1px 6px; vertical-align:2px; }
.chatbubblebtn { position:fixed; right:18px; bottom:18px; width:56px; height:56px; border-radius:50%; background:#25d366; border:none; box-shadow:0 4px 16px rgba(0,0,0,.32); cursor:pointer; z-index:70; display:flex; align-items:center; justify-content:center; padding:0; }
.chatbubblebtn svg { width:30px; height:30px; fill:#fff; }
.chatbadge { position:absolute; top:-4px; right:-4px; background:var(--bad); color:#fff; font-size:12px; font-weight:700; min-width:20px; height:20px; border-radius:99px; display:flex; align-items:center; justify-content:center; padding:0 5px; }
.chatpanel { position:fixed; right:12px; bottom:86px; width:min(360px, calc(100vw - 24px)); max-height:min(72vh, 580px); background:var(--card); border:1px solid var(--line); border-radius:14px; box-shadow:0 14px 44px rgba(0,0,0,.32); z-index:71; display:flex; flex-direction:column; overflow:hidden; }
.chatpanel[hidden] { display:none; }
.chathead { background:var(--navy); color:#fff; padding:10px 14px; display:flex; justify-content:space-between; align-items:center; }
.chathead .linkbtn { color:#fff; font-size:16px; }
.chatthread { padding:10px; overflow-y:auto; }
.chatthread.tabthread { max-height:52vh; padding:4px 0; }
.chatcomposer { display:flex; gap:6px; padding:8px; border-top:1px solid var(--line); align-items:center; }
.chatpanel .chatcomposer { background:var(--card); }
.chatcomposer input { flex:1; margin-top:0; }
.chatcomposer .btn { white-space:nowrap; }
.chatpanel .err { margin:0 10px 6px; }
.chatrow { display:flex; margin:6px 0; }
.chatrow.me { justify-content:flex-end; }
.chatbubble { background:#eef1f5; border-radius:12px; padding:8px 11px; max-width:85%; white-space:pre-wrap; word-break:break-word; font-size:14px; }
.chatbubble.me { background:#dcf2e5; }
.chatmeta { font-size:11px; color:var(--mut); margin-bottom:2px; }
/* Owner Inbox — conversation thread: the thread scrolls INSIDE its
   own box, with its own scrollbar on the side, instead of stretching
   the whole client page as the conversation grows. The composer
   (subject + body + Send email) sits below the box, outside the
   scrolling region, and stays put while the owner reads back.
   viewClientDetail scrolls the box to the bottom on every render, so
   a conversation always opens at the latest message. Owner shell
   only — the portal chat panel and Messages tab keep their own
   .chatthread rules above, untouched. */
.msgthread { max-height:360px; overflow-y:auto; padding-right:6px; }
/* Dashboard Client activity (2026-11-02 evening): the feed scrolls
   INSIDE its card, the same pattern as .msgthread above — the card
   header stays put and the Dashboard never stretches no matter
   how much client activity piles up. */
.actfeed { max-height:360px; overflow-y:auto; padding-right:6px; }
/* Charge card dialog (2026-11-02 evening): a centered overlay for
   the in-office card entry. The card fields themselves are
   Stripe's iframe inside #charge_el — nothing card-shaped is
   styled (or readable) by this app. */
.modalwrap { position:fixed; inset:0; background:rgba(20,18,15,.55); display:flex; align-items:center; justify-content:center; z-index:60; padding:1rem; }
.modalcard { background:#fff; border-radius:14px; padding:1.4rem; max-width:440px; width:100%; box-shadow:0 8px 32px rgba(0,0,0,.25); }
#charge_el { border:1px solid #d8d2c4; border-radius:10px; padding:.8rem; background:#fff; }
/* Owner top bar at phone width: even split into the two rows of
   the 2026-11-03 layout, each row's controls add up wider than a
   ~360px screen, and an unwrapped row pushes its last control
   (Sign out on row 1) off the right edge. Narrow screens only:
   row 1 WRAPS (the utility controls drop under the brand) and both
   navs wrap within the bar's width, so every control stays on
   screen and tappable with no horizontal page scroll. Scoped to
   .ownerbar — the portal top bar shares .topbar but carries no
   .ownerbar. */
@media (max-width: 640px) {
  .topbar.ownerbar { padding:10px 12px; }
  .topbar.ownerbar .barrow1 { flex-wrap:wrap; }
  .topbar.ownerbar nav { min-width:0; flex-wrap:wrap; gap:6px 10px; }
  .topbar.ownerbar nav a, .topbar.ownerbar nav .linkbtn, .topbar.ownerbar nav .btn { white-space:nowrap; }
}
/* Same narrow width, companion to .tscroll above: let long cell
   text wrap inside its cell instead of demanding width — the
   dual-signing Status lines ("Client: ✓ Name · 11/1/2026,
   5:27:53 PM · Spouse: ✓ Name · …") are the worst case. Ordinary
   text wraps at its spaces as always; overflow-wrap:break-word
   only breaks a token that otherwise could not fit at all (long
   emails, file names), so other columns keep their shape and the
   strip has less distance to slide. Phone widths only — desktop
   cells render exactly as before. */
@media (max-width: 640px) {
  .tscroll td { overflow-wrap:break-word; }
}
/* Phase 2 appointments: picked slot in the portal/public pickers,
   and the calendar's editor rows. */
.slotbtn.on { background:var(--navy); color:#fff; border-color:var(--navy); }
.svcrow label, .avrow label { margin:0; }
.avrow b { min-width:110px; }
/* Document-request picker (owner's final ruling 2026-11-01
   18:51, "One dropdown instead of folders"): one select with an
   <optgroup> per return type and a pick-to-add to-send list. It
   needs no rule of its own — the select is a plain form control
   and the list rows are .rowline. (The folder picker's
   .dcfold-head rule left with the folders it styled.) */
/* Document list category folders (owner's ruling 2026-11-01: the
   client page's documents sit in three folded folders — To sign,
   Shared with client, Requested from client — with Internal as a
   plain block after them): the folder header is a clickable
   .rowline; only the cursor is new — the fold itself is the same
   .hidden class toggle the app uses everywhere. */
.docfold-head { cursor:pointer; }
/* Preview as client (owner ruling 2026-11-01): the read-only
   portal preview carries a gold strip naming the client, so the
   owner can never mistake the preview tab for his own back office
   or for a live client session. */
.previewbar { background:var(--gold); color:#1c2430; font-weight:600; padding:9px 18px; display:flex; justify-content:space-between; align-items:center; gap:10px; flex-wrap:wrap; }
.previewbar .btn { background:#fff; border-color:#a8861d; }
/* 2026-11-02 (task links + owner notifications + Documents form
   split): the bell's unread badge mirrors the portal's .tabbadge;
   a Dashboard .statlink wraps a .stat pill without changing its
   look; portal summary task links read as actions; the split
   Documents form's per-job blocks separate with a hairline and a
   heading — the .card around them is unchanged. */
.ntfbadge { background:var(--bad); color:#fff; font-size:11px; font-weight:700; border-radius:99px; padding:1px 6px; margin-left:4px; vertical-align:2px; }
.statlink { display:block; text-decoration:none; color:inherit; }
.tasklink { font-weight:600; }
.docblock { border-top:1px solid var(--line); padding-top:10px; margin-top:14px; }
.docblock h4 { margin-top:2px; }
/* Folds (2026-11-03 styling package, owner's ruling): a fold
   header — caret, section title, one-line state summary — stays
   on screen; the .fold-body under it carries the section's
   working content and starts hidden. The toggle is the same
   .hidden class idiom as the document folders above; the
   summary on the closed line is the information, the entry
   area is what folds away. Used by the Settings sections, the
   Dashboard Client activity card and the Calendar Recent list. */
.fold-head { display:flex; align-items:center; gap:8px; cursor:pointer; border-bottom:1px solid var(--line); padding-bottom:6px; }
.fold-head h3 { margin:0; }
.fold-caret { color:var(--gold); font-weight:700; font-size:13px; }
.foldsum { margin-left:auto; text-align:right; white-space:nowrap; }
.fold-body { padding-top:10px; }
.actgroup-head { border-bottom:1px solid var(--line); }
.recentgroup-head { border-bottom:1px solid var(--line); }
/* Dashboard polish (2026-11-03 styling package): the owner
   Dashboard reads in the brand's navy + gold — cards get a soft
   shadow and a little more air, section titles sit in navy over
   a gold hairline, the stage stats take a gold cap and navy
   numbers. Scoped to .dash (a wrapper only viewDashboard emits):
   every other view renders exactly as before. */
.dash h2 { color:var(--navy); }
.dash .card { border-radius:12px; box-shadow:0 1px 4px rgba(20,48,77,.09); padding:16px 18px; }
.dash .card > h3 { color:var(--navy); border-bottom:2px solid var(--gold); padding-bottom:5px; }
.dash .fold-head { border-bottom:2px solid var(--gold); padding-bottom:5px; }
.dash .fold-head h3 { color:var(--navy); }
.dash .stat { border-top:3px solid var(--gold); box-shadow:0 1px 3px rgba(20,48,77,.07); }
.dash .statn { color:var(--navy); }
