  :root{
    --ink:#1C2B33;
    --ink-2:#2B3D46;
    --paper:#F7F3EC;
    --paper-2:#EFE9DD;
    --card:#FFFDF9;
    --peso:#2F6F4E;
    --peso-soft:#E4EFE7;
    --amber:#C97A2B;
    --amber-soft:#F6E9D8;
    --gold:#D4A017;
    --rust:#B23A2E;
    --rust-soft:#F5DEDB;
    --blue:#3B5BDB;
    --blue-soft:#E7EBFB;
    --violet:#7C3AED;
    --violet-soft:#EFE7FC;
    --slate:#7C8B90;
    --line:#DCD4C2;
    --radius:14px;
    --safe-b: env(safe-area-inset-bottom, 0px);
    --safe-t: env(safe-area-inset-top, 0px);
    font-size:20px;
  }
  *{box-sizing:border-box; -webkit-tap-highlight-color:transparent;}
  html,body{margin:0; padding:0; height:100%; overscroll-behavior-y:contain;}
  body{
    background:var(--paper);
    color:var(--ink);
    font-family:'Inter',system-ui,sans-serif;
    line-height:1.45;
    overscroll-behavior-y:contain;
    -webkit-font-smoothing:antialiased;
  }
  .num, .peso-amt{font-family:'JetBrains Mono',monospace;}
  h1,h2,h3,.display{font-family:'Space Grotesk',system-ui,sans-serif;}
  button{font-family:inherit;}
  #app{
    max-width:480px;
    margin:0 auto;
    min-height:100vh;
    background:var(--paper);
    display:flex;
    flex-direction:column;
    position:relative;
  }

  /* ---------- HEADER ---------- */
  header.topbar{
    position:sticky; top:0; z-index:20;
    background:var(--ink);
    color:var(--paper);
    padding:calc(18px + var(--safe-t)) 20px 18px;
    display:flex; align-items:center; gap:12px;
    border-bottom:3px solid var(--amber);
  }
  header.topbar .back-btn{
    background:none; border:none; color:var(--paper);
    font-size:28px; padding:5px 8px 5px 0; cursor:pointer; line-height:1;
    visibility:hidden;
  }
  header.topbar .back-btn.show{visibility:visible;}
  header.topbar h1{
    font-size:1.05rem; margin:0; font-weight:600; flex:1;
    letter-spacing:.2px;
  }
  header.topbar .icon-btn{
    background:none; border:1px solid rgba(247,243,236,.35); color:var(--paper);
    border-radius:10px; width:45px; height:45px; font-size:20px;
    cursor:pointer; display:flex; align-items:center; justify-content:center;
  }

  /* ---------- MAIN / VIEWS ---------- */
  main{flex:1; padding:20px 20px calc(120px + var(--safe-b));}
  .view{display:none;}
  .view.active{display:block; animation:fadein .18s ease;}
  @keyframes fadein{from{opacity:0; transform:translateY(4px);} to{opacity:1; transform:translateY(0);}}

  .section-label{
    font-size:.72rem; text-transform:uppercase; letter-spacing:.09em;
    color:var(--slate); font-weight:600; margin:28px 0 12px;
  }
  .section-label:first-child{margin-top:0;}

  /* ---------- STAT CARDS (dashboard) ---------- */
  .stat-grid{display:grid; grid-template-columns:1fr 1fr; gap:12px;}
  .stat-card{
    background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
    padding:18px;
  }
  .stat-card .val{font-size:1.5rem; font-weight:700; font-family:'JetBrains Mono',monospace;}
  .stat-card .lbl{font-size:.75rem; color:var(--slate); margin-top:2px;}
  .stat-card.wide{grid-column:1/-1; display:flex; justify-content:space-between; align-items:center;}
  .stat-card.warn .val{color:var(--rust);}
  .stat-card.ok .val{color:var(--peso);}

  /* ---------- LIST CARDS ---------- */
  .card-list{display:flex; flex-direction:column; gap:10px;}
  .ou-cols{display:grid; grid-template-columns:1fr 1fr; gap:14px; align-items:start;}
  .ou-col .section-label{margin-bottom:10px;}
  .ou-group-label{
    background:var(--paper-2); border:1px solid var(--line); border-radius:12px;
    padding:11px 14px; margin:14px 0 8px; display:flex; align-items:center; justify-content:space-between;
    cursor:pointer; user-select:none; transition:transform .1s ease, background .15s ease;
  }
  .ou-group-label:active{transform:scale(.985);}
  .ou-group-label:hover{background:var(--line);}
  .ou-group-label .ou-group-name{font-size:.86rem; font-weight:700; color:var(--ink);}
  .ou-group-label .ou-count{font-size:.76rem; font-weight:600; color:var(--slate); margin-left:6px;}
  .ou-group-label:first-child{margin-top:0;}
  .ou-group-label .ou-chevron{color:var(--slate); font-size:.8rem; transition:transform .15s ease;}
  .ou-group-label.collapsed .ou-chevron{transform:rotate(-90deg);}
  .ou-group-body{display:flex; flex-direction:column; gap:8px;}
  .ou-group-body.collapsed{display:none;}
  /* Roster cards run in two columns, so keep them tighter than the regular
     row-card used elsewhere (location detail, overdue list, etc). */
  /* Roster cards: everything sits on ONE line — unit + tenant/status on the
     left, badge + amount + stamp on the right — so a property with many
     units reads as a dense single-line-per-unit list instead of a stack of
     tall multi-line cards. */
  .ou-col .row-card{
    flex-direction:row; align-items:center;
    padding:9px 12px; gap:8px; border-radius:12px;
  }
  .ou-col .rc-main{
    display:flex; align-items:baseline; gap:6px;
    flex:1; min-width:0;
  }
  .ou-col .rc-title{font-size:.84rem; flex-shrink:0;}
  .ou-col .rc-sub{
    font-size:.76rem; margin-top:0;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  .ou-col .rc-right{
    display:flex; align-items:center; gap:7px; flex-shrink:0; margin-left:auto;
  }
  .ou-col .rc-amt{font-size:.8rem; margin-left:0;}
  .ou-col .badge-months{font-size:.58rem; padding:1px 6px; margin:0;}
  .ou-col .stamp.small{
    width:24px; height:24px; font-size:.3rem; margin:0; flex-shrink:0;
  }
  /* Narrow columns (mobile, two-up) need an even tighter row-card still. */
  @media (max-width:640px){
    .ou-col .row-card{padding:8px 9px; gap:6px;}
    .ou-col .rc-main{gap:4px;}
    .ou-col .rc-right{gap:5px;}
    .ou-col .stamp.small{width:20px; height:20px; font-size:.26rem;}
    .ou-col .rc-title{font-size:.76rem;}
    .ou-col .rc-sub{font-size:.66rem;}
    .ou-col .rc-amt{font-size:.72rem;}
    .ou-col .badge-months{font-size:.52rem; padding:1px 5px;}
  }
  .row-card{
    background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
    padding:16px 18px; display:flex; align-items:center; gap:15px; cursor:pointer;
    transition:transform .1s ease;
  }
  .row-card:active{transform:scale(.985);}
  #aiChatLog.card-list{gap:16px;}
  #aiChatLog .row-card{padding:20px 18px; cursor:default;}
  #aiChatLog .row-card:active{transform:none;}
  .agent-reply-title{font-weight:700; font-size:.98rem; margin-bottom:6px;}
  .agent-block{margin-bottom:6px;}
  .agent-block:last-child{margin-bottom:0;}
  .ai-avatar{
    width:30px; height:30px; border-radius:50%; flex-shrink:0;
    object-fit:cover; margin-top:2px;
  }
  /* ---- AI Assistant chat bubbles — assistant on the left (with avatar),
     admin's own messages on the right, messenger/WhatsApp-style, so who
     said what is obvious from position alone without needing a label. ---- */
  #aiChatLog.card-list{gap:14px;}
  .ai-msg-row{display:flex; align-items:flex-start; gap:8px;}
  .ai-msg-row.me{justify-content:flex-end;}
  .ai-msg-row.them{justify-content:flex-start;}
  .ai-msg-bubble{
    max-width:92%; padding:12px 16px; border-radius:16px; font-size:.88rem;
    line-height:1.35; word-break:break-word; white-space:pre-wrap;
  }
  .ai-msg-bubble.me{background:var(--peso); color:#fff; border-bottom-right-radius:4px;}
  .ai-msg-bubble.them{background:var(--card); color:var(--ink); border:1px solid var(--line); border-bottom-left-radius:4px;}
  .ai-msg-bubble .agent-reply-title{color:inherit;}
  .row-card .rc-main{flex:1; min-width:0;}
  .row-card .rc-title{font-weight:600; font-size:.96rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .row-card .rc-sub{font-size:.78rem; color:var(--slate); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .row-card .rc-amt{font-family:'JetBrains Mono',monospace; font-weight:600; font-size:.9rem; text-align:right; white-space:nowrap;}
  .row-card .rc-chevron{color:var(--slate); font-size:1.1rem;}
  /* Two-line unit card (location detail's unit list): line 1 is the unit
     label with its overdue badge at the right edge, line 2 is the tenant
     name with the amount at the right edge — so the whole card reads in
     exactly two lines next to the stamp, instead of title/sub/badge each
     getting their own line with the amount floating separately. */
  .row-card .rc-line{display:flex; align-items:center; justify-content:space-between; gap:10px;}
  .row-card .rc-line + .rc-line{margin-top:3px;}
  .row-card .rc-line .rc-title{flex:1; min-width:0;}
  .row-card .rc-line .rc-sub{flex:1; min-width:0; margin-top:0;}
  .row-card .rc-line .badge-months{margin-top:0; flex-shrink:0;}
  .row-card .rc-line .rc-amt{flex-shrink:0;}

  /* ---------- PAYMENTS LIST — dense bordered table, not cards ----------
     Deliberately its own thing rather than reusing .row-card: a table
     needs consistent columns across rows (status/tenant/unit/charge/
     method/date/amount) so everything lines up, and a much shorter row
     height than the card list gives elsewhere so an admin scanning many
     payments can see more of them at once without scrolling. Horizontal
     scroll (min-width on rows, overflow-x on the container) keeps the
     columns from getting unreadably squished on narrow screens instead
     of wrapping/stacking. */
  .pm-table{
    border:1px solid var(--line); border-radius:var(--radius);
    overflow-x:auto; overflow-y:hidden; background:var(--card);
  }
  .pm-row{
    display:grid; grid-template-columns:72px 1.3fr 1.2fr 1.3fr 96px 100px 100px;
    align-items:center; gap:10px; min-width:720px;
    padding:8px 16px; border-bottom:1px solid var(--line);
    cursor:pointer; transition:background .1s ease;
  }
  .pm-row:last-child{border-bottom:none;}
  .pm-row:hover{background:var(--paper-2);}
  .pm-row.pm-head{
    cursor:default; background:var(--paper-2); padding:9px 16px;
    font-size:.66rem; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--slate);
  }
  .pm-row.pm-head:hover{background:var(--paper-2);}
  .pm-cell{
    font-size:.82rem; color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  .pm-row.pm-head .pm-cell{overflow:visible;}
  .pm-cell.pm-tenant{font-weight:600;}
  .pm-cell.pm-amount{
    font-family:'JetBrains Mono',monospace; font-weight:600; text-align:right;
  }
  .pm-chip{
    display:inline-block; font-size:.6rem; font-weight:700; text-transform:uppercase;
    letter-spacing:.03em; padding:3px 8px; border-radius:99px; white-space:nowrap;
  }
  .pm-chip.paid{background:var(--peso-soft); color:var(--peso);}
  .pm-chip.late{background:var(--rust-soft); color:var(--rust);}
  .pm-chip.partial{background:var(--amber-soft); color:var(--amber);}
  .pm-break{display:none;}

  .chip{
    display:inline-block; font-size:.66rem; font-weight:700; text-transform:uppercase;
    letter-spacing:.04em; padding:4px 10px; border-radius:99px; white-space:nowrap;
  }
  .chip.occupied{background:var(--peso-soft); color:var(--peso);}
  .chip.vacant{background:var(--paper-2); color:var(--slate);}
  .chip.maintenance{background:var(--amber-soft); color:var(--amber);}

  /* ---------- PAYMENT TAG CHIPS (which balance a payment applies to) ---------- */
  .tagchip-row{display:flex; gap:10px; flex-wrap:wrap; margin:2px 0 18px;}
  .tagchip{
    flex:1; min-width:84px; text-align:center; cursor:pointer; user-select:none;
    font-size:.82rem; font-weight:600; padding:10px 12px; border-radius:10px;
    border:1px solid var(--line); background:var(--card); color:var(--slate);
    transition:transform .1s ease;
  }
  .tagchip:active{transform:scale(.97);}
  .tagchip.active{background:var(--peso-soft); color:var(--peso); border-color:var(--peso);}

  /* ---------- STAMP (signature element) ---------- */
  .stamp{
    --c:var(--peso);
    display:inline-flex; align-items:center; justify-content:center;
    width:54px; height:54px; border-radius:50%;
    border:2px dashed var(--c); color:var(--c);
    font-family:'Space Grotesk',sans-serif; font-weight:700; font-size:.6rem;
    letter-spacing:.03em; text-transform:uppercase; text-align:center;
    transform:rotate(-8deg); flex-shrink:0; line-height:1.05;
    background:color-mix(in srgb, var(--c) 6%, transparent);
  }
  .stamp.overdue{--c:var(--rust);}
  .stamp.due{--c:var(--amber);}
  .stamp.small{width:38px; height:38px; font-size:.5rem; border-width:1.5px;}
  .stamp.filled{
    border-style:solid; background:var(--c); color:#fff;
    box-shadow:0 3px 8px color-mix(in srgb, var(--c) 45%, transparent);
  }
  /* 3+ consecutive months overdue on rent — a step past the ordinary
     "overdue" stamp: solid fill instead of dashed outline, same rust hue,
     so it reads as more urgent without introducing a new color. */
  .stamp.critical{--c:var(--rust); border-style:solid; background:var(--c); color:#fff; box-shadow:0 3px 8px color-mix(in srgb, var(--c) 45%, transparent);}

  /* ---------- OVERDUE-MONTHS BADGE (consecutive months behind on rent) ---------- */
  .badge-months{
    display:inline-block; font-size:.64rem; font-weight:700; text-transform:uppercase;
    letter-spacing:.03em; padding:2px 9px; border-radius:99px; white-space:nowrap;
    margin-top:4px;
  }
  .badge-months.due{background:var(--amber-soft); color:var(--amber);}
  .badge-months.overdue{background:var(--rust-soft); color:var(--rust);}
  .badge-months.critical{background:var(--rust); color:#fff;}

  /* ---------- EMPTY STATE ---------- */
  .empty{
    text-align:center; padding:45px 25px; color:var(--slate);
    border:1.5px dashed var(--line); border-radius:var(--radius);
  }
  .empty .e-icon{font-size:1.8rem; margin-bottom:8px;}
  .empty p{margin:5px 0; font-size:.86rem;}

  /* ---------- BUTTONS ---------- */
  .btn{
    display:inline-flex; align-items:center; justify-content:center; gap:8px;
    border:none; border-radius:11px; padding:15px 20px; font-weight:600;
    font-size:.9rem; cursor:pointer; width:100%;
  }
  .btn-primary{background:var(--ink); color:var(--paper);}
  .btn-accent{background:var(--peso); color:#fff;}
  .btn-outline{background:transparent; color:var(--ink); border:1.5px solid var(--line);}
  .btn-danger{background:transparent; color:var(--rust); border:1.5px solid var(--rust-soft);}
  .btn-sm{padding:11px 15px; font-size:.8rem; width:auto;}
  .share-btn{
    flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:5px; padding:11px 5px 9px; border:1.5px solid var(--line); border-radius:11px;
    background:var(--card); cursor:pointer; color:var(--ink); font-size:.62rem;
    font-weight:600; letter-spacing:.01em;
  }
  .share-btn:active{background:var(--paper-2);}
  .share-btn svg{width:20px; height:20px;}
  .fab{
    position:fixed; right:calc(50% - 240px + 18px); bottom:calc(150px + var(--safe-b));
    z-index:25; width:54px; height:54px; border-radius:50%;
    background:var(--amber); color:#fff; border:none; font-size:1.6rem;
    box-shadow:0 6px 16px rgba(28,43,51,.28); cursor:pointer;
  }
  @media (max-width:480px){ .fab{ right:18px; } }

  /* RIA launcher: a global floating chat button, present on every screen
     (unlike the quick-add fab above, which only shows on a couple of
     views) — sits in the fab's original resting spot; quick-add gets
     bumped up 66px so the two stack instead of overlapping on the views
     where both appear. */
  .fab-ria{
    position:fixed; right:calc(50% - 240px + 18px); bottom:calc(84px + var(--safe-b));
    z-index:25; width:54px; height:54px; border-radius:50%;
    background:var(--ink); color:#fff; border:none; font-size:1.5rem;
    box-shadow:0 6px 16px rgba(28,43,51,.28); cursor:pointer;
    display:flex; align-items:center; justify-content:center;
  }
  @media (max-width:480px){ .fab-ria{ right:18px; } }

  /* RIA desktop widget: a small non-modal chat window docked at the
     bottom-right corner, the way Facebook/X's site chat widgets behave —
     floats over the page instead of a dark-backdrop modal, so the rest of
     the app stays usable while it's open. Desktop-only (toggled via JS at
     the same >=860px breakpoint the sidebar layout uses); phones keep the
     original full sheet from openAiAssistantSheet(), since there isn't
     room for a floating box alongside the app on a small screen. Shares
     the aiChatContext-driven ids with the mobile sheet so renderAiChatLog/
     sendAiChatMessage work unmodified against whichever surface is open. */
  .ria-panel{
    position:fixed; right:102px; bottom:32px; z-index:26;
    width:360px; max-width:calc(100vw - 64px);
    height:520px; max-height:calc(100vh - 150px);
    background:var(--paper); border-radius:16px;
    box-shadow:0 12px 40px rgba(28,43,51,.28);
    display:none; flex-direction:column; overflow:hidden;
    border:1px solid var(--line);
    animation:sheetup .18s ease;
  }
  .ria-panel.show{display:flex;}
  .ria-panel-head{
    display:flex; align-items:center; justify-content:space-between;
    padding:10px 16px; border-bottom:1px solid var(--line); flex:none;
  }
  .ria-panel-head h2{font-size:1rem; margin:0;}
  .ria-panel-close{
    width:28px; height:28px; border-radius:50%; border:1px solid var(--line);
    background:var(--paper-2); color:var(--ink); font-size:14px; cursor:pointer;
    display:flex; align-items:center; justify-content:center; flex:none;
  }
  .ria-panel-body{flex:1; min-height:0; padding:18px 20px 0;}
  .ria-panel-footer{padding:14px 20px 16px; border-top:1px solid var(--line); flex:none;}
  /* The mobile sheet's #aiChatLog-specific gap/padding rules (above, near
     .ai-msg-bubble) don't reach this panel — different id — so it was
     falling back to the plain .card-list gap and reading cramped. Give it
     its own spacing: a bit more room between bubbles, and slightly smaller
     type since the panel itself is narrower than the phone sheet. */
  #riaChatLog.card-list{gap:10px; height:100%; overflow-y:auto; padding-bottom:18px;}
  #riaChatLog .ai-msg-bubble{font-size:.74rem; line-height:1.5; padding:13px 16px; max-width:94%;}
  /* Admin's typing box in the desktop panel specifically — no border/focus
     ring, just the background fill, so it reads as part of the panel
     rather than a separate boxed field. Scoped to this id only; the
     mobile sheet's textarea keeps its usual bordered look. */
  #riaChatInput{border:none; outline:none;}
  /* Safety net: if the window is resized down past the breakpoint while
     the panel happens to be open, don't leave a floating box stranded on
     a phone-width layout. */
  @media (max-width:859.98px){ .ria-panel{ display:none !important; } }

  /* ---------- BOTTOM NAV ---------- */
  nav.bottomnav{
    position:fixed; left:0; right:0; bottom:0; z-index:20;
    max-width:480px; margin:0 auto;
    background:var(--ink); display:flex;
    padding-bottom:var(--safe-b);
    border-top:3px solid var(--amber);
  }
  nav.bottomnav button{
    flex:1; background:none; border:none; color:rgba(247,243,236,.55);
    padding:12px 5px 11px; display:flex; flex-direction:column; align-items:center; gap:4px;
    font-size:.7rem; font-weight:600; letter-spacing:.02em; cursor:pointer;
  }
  nav.bottomnav button .ic{font-size:1.15rem;}
  nav.bottomnav button.active{color:var(--paper);}
  nav.bottomnav button.active .ic{color:var(--amber);}

  /* ---------- SHEET / MODAL ---------- */
  .sheet-backdrop{
    position:fixed; inset:0; background:rgba(28,43,51,.5); z-index:40;
    display:none; align-items:flex-end; justify-content:center;
  }
  .sheet-backdrop.show{display:flex;}
  .sheet{
    background:var(--paper); width:100%; max-width:480px;
    border-radius:20px 20px 0 0; padding:10px 25px calc(25px + var(--safe-b));
    max-height:88dvh; overflow-y:auto; animation:sheetup .22s ease;
    position:relative;
  }
  /* Wider variant for sheets that show a full document page (lease
     contract preview/sign) rather than a short form — the default 480px
     cap reads fine for forms but is needlessly cramped for a document on
     a real desktop screen. Only widens once there's actually room; stays
     identical to .sheet on phones. */
  @media (min-width:700px){
    .sheet.sheet-wide{max-width:960px;}
    /* On a real desktop screen a bottom-anchored sheet reads oddly for the
       wide variant specifically (a document/table naturally wants to be
       read centered, not pinned to the bottom edge) — so once a sheet is
       both wide AND on a wide-enough viewport, center it vertically and
       round all four corners like a normal dialog instead. Regular
       (non-wide) sheets, and everything on phones, are untouched — they
       still behave as a bottom sheet as before. */
    .sheet-backdrop:has(.sheet-wide){align-items:center; padding:30px 0;}
    .sheet-backdrop:has(.sheet-wide) .sheet-wide{border-radius:20px; max-height:82dvh;}
  }
  /* The 4-column pricing grid (Pro/Business highlight lists especially)
     needs more per-card width than the general document sheet does, or
     highlight text wraps 3+ lines deep and pushes the cards past the
     82vh cap above — widen just the pricing sheet specifically once
     there's room for it. */
  @media (min-width:1180px){
    .sheet.sheet-wide:has(.pricing-grid){max-width:1180px;}
  }
  @media (min-width:1440px){
    .sheet.sheet-wide:has(.pricing-grid){max-width:1360px;}
  }
  @keyframes sheetup{from{transform:translateY(24px); opacity:.4;} to{transform:translateY(0); opacity:1;}}

  /* ---- AI Assistant "thinking" indicator: three dots bouncing in
     sequence, same row-card shell as a reply so it doesn't jump around
     when the real answer replaces it. ---- */
  .ai-thinking-dots{ display:inline-flex; align-items:center; gap:4px; height:18px; }
  .ai-thinking-dots span{
    width:7px; height:7px; border-radius:50%; background:var(--slate,#8a8578);
    opacity:.4; animation:aiThinkingBounce 1.1s ease-in-out infinite;
  }
  .ai-thinking-dots span:nth-child(2){ animation-delay:.15s; }
  .ai-thinking-dots span:nth-child(3){ animation-delay:.3s; }
  @keyframes aiThinkingBounce{
    0%, 60%, 100%{ transform:translateY(0); opacity:.4; }
    30%{ transform:translateY(-4px); opacity:1; }
  }
  .sheet-grab{width:36px; height:4px; background:var(--line); border-radius:99px; margin:10px auto 18px;}
  .sheet-close{
    position:absolute; top:14px; right:16px; width:40px; height:40px; border-radius:50%;
    background:var(--paper-2); border:1px solid var(--line); color:var(--ink);
    font-size:19px; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center;
  }
  /* Maximize/minimize toggle for sheets that opt in (e.g. the AI Assistant
     chat) — desktop-only (see the >=860px block below), since on a phone
     the sheet is already close to full-width and there's no bigger state
     worth expanding into. Hidden by default here; the desktop media query
     switches it to flex. */
  .sheet-max-btn{
    display:none; position:absolute; top:14px; right:64px; width:40px; height:40px; border-radius:50%;
    background:var(--paper-2); border:1px solid var(--line); color:var(--ink);
    font-size:16px; line-height:1; cursor:pointer; align-items:center; justify-content:center;
  }
  .sheet h2{font-size:1.05rem; margin:0 0 18px; padding-right:48px;}
  .field{margin-bottom:16px;}
  .field label{display:block; font-size:.75rem; font-weight:600; color:var(--slate); margin-bottom:6px; text-transform:uppercase; letter-spacing:.03em;}
  .field input, .field select, .field textarea{
    width:100%; border:1.5px solid var(--line); border-radius:10px; padding:14px 15px;
    font-size:.95rem; font-family:inherit; background:var(--card); color:var(--ink);
  }
  .field textarea{resize:vertical; min-height:60px;}
  .field-deduction input{background:var(--amber-soft);}
  .field-row{display:flex; gap:12px;}
  .field-row .field{flex:1;}
  .sheet-actions{display:flex; gap:12px; margin-top:22px;}
  .sheet-actions .btn{flex:1;}
  .auth-loading-bar{height:3px; width:100%; background:var(--paper-2); border-radius:2px; overflow:hidden; margin-top:12px; display:none;}
  .auth-loading-bar.show{display:block;}
  .auth-loading-bar-fill{height:100%; width:0%; background:var(--peso); border-radius:2px;}

  /* ---------- SEARCH SHEET ---------- */
  .search-input-wrap{
    display:flex; align-items:center; gap:10px; background:var(--card);
    border:1.5px solid var(--line); border-radius:12px; padding:12px 15px; margin-bottom:18px;
  }
  .search-input-wrap input{border:none; outline:none; background:none; flex:1; font-size:.95rem; color:var(--ink);}

  /* ---------- DETAIL HEADER ---------- */
  .detail-hero{
    background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
    padding:20px; margin-bottom:22px;
  }
  .detail-hero .dh-title{font-size:1.1rem; font-weight:700;}
  .detail-hero .dh-sub{font-size:.82rem; color:var(--slate); margin-top:4px;}
  .kv-grid{display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-top:15px;}
  .kv{background:var(--paper-2); border-radius:9px; padding:10px 12px;}
  .kv .k{font-size:.66rem; text-transform:uppercase; color:var(--slate); letter-spacing:.03em;}
  .kv .v{font-family:'JetBrains Mono',monospace; font-weight:600; font-size:.86rem; margin-top:2px;}
  /* Tenant header row: name/phone on the left, the total-owed card (with
     its months-overdue badge inline next to the amount) on the right, so
     they share one row instead of the badge and the owed card each taking
     their own full-width line underneath the name. */
  .th-header{display:flex; align-items:flex-start; justify-content:space-between; gap:12px;}
  .th-header .kv.owed-card{background:var(--rust-soft); flex-shrink:0; min-width:180px; cursor:pointer;}
  .th-header .kv.owed-card .v-row{display:flex; align-items:center; justify-content:space-between; gap:8px; margin-top:2px;}
  .th-header .kv.owed-card .v-row .v{margin-top:0; font-size:.92rem;}
  .th-header .kv.owed-card .v-row .badge-months{margin-top:0;}
  .th-header .badge-months{margin-top:0; flex-shrink:0;}

  /* ---------- Compact data table (e.g. Payment summary's recent list) ---------- */
  .table-wrap{overflow-x:auto; border:1px solid var(--line); border-radius:12px;}
  table.summary-table{width:100%; border-collapse:collapse; font-size:.78rem; white-space:nowrap;}
  table.summary-table th{
    text-align:left; font-size:.64rem; text-transform:uppercase; letter-spacing:.03em;
    color:var(--slate); font-weight:600; padding:10px 12px; background:var(--paper-2);
    position:sticky; top:0;
  }
  table.summary-table td{padding:11px 12px; border-top:1px solid var(--line); font-family:'JetBrains Mono',monospace;}
  table.summary-table td:last-child, table.summary-table th:last-child{text-align:right;}
  table.summary-table tbody tr{cursor:pointer;}
  table.summary-table tbody tr:active{background:var(--paper-2);}

  .toast{
    position:fixed; left:50%; bottom:calc(100px + var(--safe-b)); transform:translateX(-50%);
    background:var(--ink); color:var(--paper); padding:12px 22px; border-radius:99px;
    font-size:.82rem; font-weight:500; z-index:60; opacity:0; pointer-events:none;
    transition:opacity .2s ease, bottom .2s ease;
  }
  .toast.show{opacity:1; bottom:calc(112px + var(--safe-b));}

  .update-banner, .install-banner{
    position:fixed; left:12px; right:12px; top:calc(12px + var(--safe-t));
    background:var(--ink); color:var(--paper); border-radius:12px;
    padding:15px 18px; display:none; align-items:center; justify-content:space-between;
    gap:15px; font-size:.82rem; z-index:70; box-shadow:0 6px 20px rgba(0,0,0,.2);
  }
  .update-banner.show, .install-banner.show{display:flex;}
  .update-banner button, .install-banner button{
    background:var(--paper); color:var(--ink); border:none; border-radius:8px;
    padding:8px 15px; font-weight:600; font-size:.78rem; flex-shrink:0;
  }
  .install-banner .ib-text{display:flex; align-items:center; gap:10px; min-width:0;}
  .install-banner .ib-icon{
    width:36px; height:36px; border-radius:9px; flex-shrink:0;
    background-size:cover; background-position:center;
  }
  .install-banner .ib-copy{min-width:0;}
  .install-banner .ib-copy strong{display:block; font-size:.84rem;}
  .install-banner .ib-copy span{display:block; font-size:.72rem; color:rgba(247,243,236,.7); margin-top:1px;}
  .install-banner .ib-actions{display:flex; align-items:center; gap:6px; flex-shrink:0;}
  .install-banner .ib-dismiss{
    background:none; color:rgba(247,243,236,.6); border:none;
    font-size:1.1rem; padding:4px 6px; cursor:pointer; line-height:1;
  }

  .divider{height:1px; background:var(--line); margin:20px 0;}
  .muted{color:var(--slate); font-size:.82rem;}

  /* ------------------------------ ADMIN GATE -------------------------------
     Full-screen sign-in shown before the admin dashboard is reachable at all.
     Mirrors the tenant portal's login card visually. Hidden the moment
     onCloudAuthStateChanged resolves to a signed-in user; stays up (showing
     either a brief "checking" state or the login/signup form) otherwise. */
  #adminGate{
    position:fixed; inset:0; z-index:200; background:var(--paper);
    display:flex; align-items:center; justify-content:center;
    padding:30px 25px calc(30px + var(--safe-b)) 25px;
  }
  .admin-gate-card{width:100%; max-width:360px;}
  .admin-gate-icon{
    display:block; margin:0 auto 14px; width:88px; height:88px;
    border-radius:22px; mix-blend-mode:multiply;
  }
  .admin-gate-logo{
    font-family:'Space Grotesk', sans-serif; font-weight:700; font-size:1.5rem;
    text-align:center; margin-bottom:28px; color:var(--ink);
  }
  a.settings-link, .settings-item{
    display:flex; align-items:center; justify-content:space-between;
    background:var(--card); border:1px solid var(--line); border-radius:12px;
    padding:16px 18px; margin-bottom:10px; cursor:pointer;
  }
  .settings-item .si-title{font-weight:600; font-size:.88rem;}
  .settings-item .si-sub{font-size:.75rem; color:var(--slate); margin-top:2px;}
  /* Plan-gated settings row (e.g. rent due reminders below Pro) — dims the
     title slightly and tints the sub text so "included on Pro and up"
     reads as an upsell, not an error. */
  .settings-item.locked{opacity:.85;}
  .settings-item.locked .si-sub{color:var(--peso);}
  .badge-dot{width:8px; height:8px; border-radius:50%; background:var(--slate); flex-shrink:0;}
  .badge-dot.on{background:var(--peso);}
  .settings-edit-btn{
    display:flex; align-items:center; justify-content:center; gap:6px;
    background:var(--ink); color:var(--paper); font-size:.78rem; font-weight:600;
    padding:11px 18px; border-radius:10px; min-height:38px; flex-shrink:0;
  }
  /* Plan usage sheet — one row per limit (properties/units/AI credits) */
  .plan-usage-row{margin-bottom:16px;}
  .plan-usage-row .pu-label{
    display:flex; justify-content:space-between; font-size:.8rem; font-weight:600;
    color:var(--ink); margin-bottom:6px;
  }
  .plan-usage-row .pu-label .pu-count{color:var(--slate); font-weight:600;}
  .plan-usage-track{
    background:var(--paper-2); border:1px solid var(--line); border-radius:999px;
    height:8px; overflow:hidden;
  }
  .plan-usage-fill{height:100%; background:var(--peso); border-radius:999px; transition:width .2s ease;}
  .plan-usage-fill.near-limit{background:var(--rust);}
  .plan-tier-badge{
    display:inline-block; background:var(--peso-soft); color:var(--peso); font-size:.78rem;
    font-weight:700; padding:4px 12px; border-radius:999px; text-transform:capitalize;
  }
  /* Choose-your-plan screen — hero header + accent-coded tier cards */
  .pricing-hero{text-align:center; margin-bottom:24px;}
  .pricing-hero-badge{
    display:inline-flex; align-items:center; gap:6px; background:var(--paper-2);
    border:1px solid var(--line); color:var(--ink); font-size:.72rem; font-weight:600;
    padding:6px 14px; border-radius:999px; margin-bottom:14px;
  }
  .pricing-hero h2{font-size:1.4rem; margin:0 0 8px; padding-right:0; line-height:1.25;}
  .pricing-hero p{font-size:.82rem; color:var(--slate); margin:0;}
  .pricing-grid{display:grid; grid-template-columns:1fr; gap:16px;}
  @media (min-width:700px){
    .pricing-grid{grid-template-columns:repeat(2, 1fr);}
  }
  @media (min-width:1180px){
    .pricing-grid{grid-template-columns:repeat(4, 1fr);}
  }
  /* Narrow/Android mobile: swap the stacked grid for a horizontal
     swipe carousel — one card at a time (with a peek of the next),
     scroll-snap gives native swipe feel with no JS gesture handling
     needed. Dots below show position; JS only handles which dot is
     active and the initial scroll position. */
  @media (max-width:699px){
    .pricing-grid{
      display:flex; grid-template-columns:none; overflow-x:auto; gap:14px;
      scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch;
      padding:16px 28px 10px 4px; margin:0 -4px; scrollbar-width:none;
    }
    .pricing-grid::-webkit-scrollbar{display:none;}
    .pricing-grid .plan-card{flex:0 0 84%; scroll-snap-align:center; scroll-snap-stop:always;}
  }
  .pricing-dots{display:none; justify-content:center; gap:6px; margin-top:14px;}
  @media (max-width:699px){
    .pricing-dots{display:flex;}
  }
  .pricing-dots .dot{
    width:7px; height:7px; border-radius:50%; background:var(--line);
    transition:background .15s ease, width .15s ease;
  }
  .pricing-dots .dot.active{background:var(--ink); width:18px; border-radius:4px;}
  .plan-card{
    position:relative; background:var(--card); border:1.5px solid var(--line); border-radius:16px;
    padding:22px 20px 20px; display:flex; flex-direction:column;
  }
  .plan-card.current{border-color:var(--peso);}
  .plan-card.accent-green.popular{
    border-color:var(--peso); box-shadow:0 0 0 3px var(--peso-soft);
  }
  .plan-card .pc-popular-tag{
    position:absolute; top:-13px; left:50%; transform:translateX(-50%);
    background:var(--peso); color:#fff; font-size:.68rem; font-weight:700;
    padding:5px 14px; border-radius:999px; white-space:nowrap; letter-spacing:.02em;
  }
  .plan-card .pc-icon{
    width:52px; height:52px; border-radius:50%; display:flex; align-items:center;
    justify-content:center; font-size:1.5rem; margin-bottom:14px;
  }
  .plan-card.accent-green .pc-icon{background:var(--peso-soft);}
  .plan-card.accent-blue .pc-icon{background:var(--blue-soft);}
  .plan-card.accent-purple .pc-icon{background:var(--violet-soft);}
  .plan-card .pc-name{
    font-weight:700; font-size:.78rem; letter-spacing:.06em; text-transform:uppercase; margin-bottom:8px;
  }
  .plan-card .pc-name-badge{
    display:inline-block; font-weight:600; font-size:.66rem; letter-spacing:normal; text-transform:none;
    background:var(--md-card, #f1f5f9); color:var(--slate); padding:2px 8px; border-radius:999px;
    vertical-align:middle; margin-left:4px;
  }
  .plan-card.accent-green .pc-name{color:var(--peso);}
  .plan-card.accent-blue .pc-name{color:var(--blue);}
  .plan-card.accent-purple .pc-name{color:var(--violet);}
  .plan-card .pc-price{font-size:1.7rem; font-weight:700; color:var(--ink); font-family:'Space Grotesk',sans-serif;}
  .plan-card .pc-price .pc-price-unit{font-size:.85rem; font-weight:600; color:var(--slate); margin-left:2px;}
  .plan-card .pc-price-note{font-size:.76rem; color:var(--slate); margin:4px 0 14px;}
  .plan-card .pc-tagline{font-size:.78rem; color:var(--slate); line-height:1.5; margin-bottom:16px; min-height:38px;}
  .plan-card .pc-specs-box{
    background:var(--paper-2); border-radius:12px; padding:14px 16px; margin-bottom:16px;
  }
  .plan-card.accent-green .pc-specs-box{background:var(--peso-soft);}
  .plan-card.accent-blue .pc-specs-box{background:var(--blue-soft);}
  .plan-card.accent-purple .pc-specs-box{background:var(--violet-soft);}
  .pc-spec-row{
    display:flex; align-items:center; gap:8px; font-size:.8rem; font-weight:600; color:var(--ink);
    padding:5px 0;
  }
  .pc-spec-row .pc-check{flex-shrink:0; font-size:.85rem;}
  .plan-card.accent-green .pc-check{color:var(--peso);}
  .plan-card.accent-blue .pc-check{color:var(--blue);}
  .plan-card.accent-purple .pc-check{color:var(--violet);}
  .pc-everything-note{font-size:.78rem; font-weight:700; color:var(--ink); margin:2px 0 4px;}
  .pc-extra-list{list-style:none; margin:0; padding:0 0 0 4px;}
  .pc-extra-list li{
    font-size:.78rem; color:var(--ink); padding:3px 0 3px 16px; position:relative;
  }
  .pc-extra-list li::before{
    content:'•'; position:absolute; left:0; font-weight:700;
  }
  .plan-card.accent-purple .pc-extra-list li::before{color:var(--violet);}
  .plan-card .pc-footer{margin-top:auto;}
  .plan-card .pc-current-tag{
    display:block; text-align:center; font-size:.75rem; font-weight:700; color:var(--peso);
    text-transform:uppercase; letter-spacing:.04em; padding:12px; border:1.5px dashed var(--peso);
    border-radius:10px;
  }
  .plan-card .pc-btn{
    width:100%; color:#fff; font-size:.85rem; font-weight:700;
    padding:13px; border-radius:10px; text-align:center; cursor:pointer; border:none;
  }
  .plan-card.accent-green .pc-btn{background:var(--peso);}
  .plan-card.accent-blue .pc-btn{background:var(--blue);}
  .plan-card.accent-purple .pc-btn{background:var(--violet);}
  .plan-card .pc-btn.pc-btn-outline{background:transparent; color:var(--ink); border:1.5px solid var(--line);}
  .plan-card .pc-btn[disabled]{opacity:.5; cursor:not-allowed;}
  .plan-card .pc-btn-note{text-align:center; font-size:.72rem; color:var(--slate); margin-top:8px;}
  .pricing-trust-bar{
    display:grid; grid-template-columns:1fr; gap:14px; margin-top:26px; padding:18px;
    background:var(--paper-2); border-radius:14px;
  }
  @media (min-width:700px){
    .pricing-trust-bar{grid-template-columns:repeat(2, 1fr);}
  }
  @media (min-width:1080px){
    .pricing-trust-bar{grid-template-columns:repeat(4, 1fr);}
  }
  .pricing-trust-item{display:flex; align-items:flex-start; gap:10px;}
  .pricing-trust-item .pt-icon{font-size:1.1rem; flex-shrink:0; margin-top:1px;}
  .pricing-trust-item .pt-title{font-size:.78rem; font-weight:700; color:var(--ink);}
  .pricing-trust-item .pt-sub{font-size:.72rem; color:var(--slate); margin-top:1px;}
  .pricing-footnote{text-align:center; font-size:.72rem; color:var(--slate); margin-top:16px;}
  .doc-slot{
    flex:1; min-width:150px; background:var(--paper-2); border:1.5px dashed var(--line);
    border-radius:12px; padding:15px; display:flex; flex-direction:column;
    align-items:flex-start; gap:8px; font-size:.78rem;
  }
  .doc-slot.has-file{border-style:solid; background:var(--card);}
  .doc-slot .doc-icon{font-size:1.3rem;}
  .doc-slot .doc-label{font-weight:600;}
  .doc-slot .doc-name{color:var(--slate); font-size:.72rem; word-break:break-all;}
  .doc-slot .doc-actions{display:flex; gap:8px; margin-top:2px; flex-wrap:wrap;}
  .doc-slot .doc-actions a, .doc-slot .doc-actions button{font-size:.72rem; padding:8px 12px; min-height:0;}

  /* ---------- Payment-proof review thumbnails (admin) ---------- */
  .proof-thumb-row{display:flex; gap:12px; margin-top:10px; flex-wrap:wrap;}
  .proof-thumb-wrap{display:flex; flex-direction:column; align-items:center; gap:4px;}
  .proof-thumb{
    width:60px; height:60px; border-radius:10px; object-fit:cover;
    border:1px solid var(--line); cursor:zoom-in; background:var(--paper-2);
  }
  .proof-thumb-label{font-size:.62rem; color:var(--slate); text-align:center;}
  .proof-file-chip{
    display:flex; align-items:center; gap:8px; font-size:.72rem; padding:10px 15px;
    border:1px solid var(--line); border-radius:10px; background:var(--paper-2);
    cursor:pointer; text-decoration:none; color:inherit;
  }
  .proof-missing{
    display:flex; align-items:center; gap:8px; font-size:.72rem; font-weight:600; color:var(--rust);
    background:var(--rust-soft); padding:9px 14px; border-radius:10px; margin-top:10px; width:100%;
  }
  .img-lightbox-backdrop{
    position:fixed; inset:0; background:rgba(0,0,0,.85); display:none;
    align-items:center; justify-content:center; z-index:999; padding:35px; cursor:zoom-out;
  }
  .img-lightbox-backdrop.show{display:flex;}
  .img-lightbox-backdrop img{max-width:100%; max-height:100%; border-radius:10px; box-shadow:0 10px 40px rgba(0,0,0,.5); cursor:default;}
  .img-lightbox-close{
    position:absolute; top:18px; right:18px; width:38px; height:38px; border-radius:50%;
    background:rgba(255,255,255,.15); color:#fff; border:none; font-size:1.1rem; cursor:pointer;
  }

  /* ---------- TENANT PORTAL ---------- */
  #tenantPortal{
    max-width:480px; margin:0 auto; min-height:100vh; background:var(--paper);
    display:flex; flex-direction:column;
  }
  /* Desktop-only sidebar (see @media min-width:860px below for the actual
     layout) — hidden on mobile, where navigation stays card-based. */
  .portal-sidenav{ display:none; }
  .sidebar-brand, .sidebar-foot, .sidebar-user, .sidebar-sync, .sidebar-help{ display:none; }
  .stat-card .sc-icon, .stat-card .sc-link{ display:none; }
  .portal-balance-card{
    background:var(--ink); color:var(--paper); border-radius:var(--radius);
    padding:25px; margin-bottom:20px;
  }
  .portal-balance-card .pb-label{font-size:.72rem; text-transform:uppercase; letter-spacing:.06em; color:rgba(247,243,236,.65);}
  .portal-balance-card .pb-amt{font-family:'JetBrains Mono',monospace; font-weight:700; font-size:2rem; margin-top:5px;}
  .portal-balance-card .pb-sub{font-size:.8rem; color:rgba(247,243,236,.75); margin-top:5px;}
  .portal-balance-card.clear{background:var(--peso);}
  .portal-balance-card.overdue{background:var(--rust);}
  .portal-actions{display:flex; gap:12px; margin-bottom:25px;}
  .portal-actions .btn{flex:1;}
  .portal-status-chip{font-size:.66rem; font-weight:700; text-transform:uppercase; letter-spacing:.04em; padding:4px 11px; border-radius:99px;}
  .portal-status-chip.pending{background:var(--amber-soft); color:var(--amber);}
  .portal-status-chip.approved{background:var(--peso-soft); color:var(--peso);}
  .portal-status-chip.rejected{background:var(--rust-soft); color:var(--rust);}
  .portal-tabs{display:flex; gap:8px; margin-bottom:20px; background:var(--paper-2); border-radius:12px; padding:5px;}
  .portal-tabs button{flex:1; border:none; background:none; padding:11px 5px; border-radius:9px; font-size:.8rem; font-weight:600; color:var(--slate); cursor:pointer;}
  .portal-tabs button.active{background:var(--card); color:var(--ink); box-shadow:0 1px 3px rgba(0,0,0,.08);}

  /* ---------- MESSAGES (admin<->tenant chat) — shared by both the admin
     thread sheet and the tenant portal's message view. */
  .msg-thread{
    display:flex; flex-direction:column; gap:10px; max-height:52vh; overflow-y:auto;
    padding:2px 2px 8px; margin-bottom:15px;
  }
  .msg-row{display:flex; align-items:flex-end; gap:8px;}
  .msg-row.me{justify-content:flex-end;}
  .msg-row.them{justify-content:flex-start;}
  .msg-avatar{
    width:30px; height:30px; border-radius:50%; flex-shrink:0;
    display:flex; align-items:center; justify-content:center;
    font-size:.7rem; font-weight:700; background:var(--peso-soft); color:var(--peso);
  }
  .msg-avatar-me{background:var(--peso); color:#fff;}
  .msg-bubble{
    display:inline-block; width:fit-content; max-width:calc(78% - 30px); padding:10px 15px 8px; border-radius:14px; font-size:.88rem; line-height:1.28;
    word-break:break-word; white-space:pre-wrap;
  }
  .msg-bubble .m-time{display:block; font-size:.62rem; line-height:1.1; opacity:.65; margin-top:4px; letter-spacing:.02em;}
  .msg-bubble.me{background:var(--peso); color:#fff; border-bottom-right-radius:4px;}
  .msg-bubble.them{background:var(--paper-2); color:var(--ink); border-bottom-left-radius:4px;}
  .msg-input-row{display:flex; gap:10px; align-items:flex-end;}
  .msg-input-row textarea, .msg-input-row input[type="text"]{
    flex:1; resize:none; min-height:47px; max-height:110px; height:47px; overflow-y:hidden;
    border:1.5px solid var(--line); line-height:1.3;
    border-radius:12px; padding:12px 15px; font-size:.8375rem; font-family:inherit;
    background:var(--card); color:var(--ink);
  }
  /* AI Assistant's input specifically starts taller than the compact
     one-line message inputs elsewhere — makes the "click here to type"
     target obvious at a glance, while still auto-growing further (up to
     its own higher cap) as the admin types a longer question. */
  .msg-input-row textarea.ai-chat-textarea{ min-height:72px; height:72px; max-height:160px; }
  .msg-input-row button{
    flex-shrink:0; width:42px; height:42px; border-radius:50%; border:none;
    background:var(--peso); color:#fff; font-size:1.05rem; cursor:pointer;
  }
  .msg-input-row button:disabled{ opacity:.5; cursor:default; }
  .msg-unread-badge{
    display:inline-flex; align-items:center; justify-content:center; min-width:18px; height:18px;
    padding:0 6px; border-radius:99px; background:var(--rust); color:#fff;
    font-size:.66rem; font-weight:700; margin-left:8px;
  }

  /* ---------- Lease contract print view ---------- */
  #contractView{
    display:none;
    max-width:480px; margin:0 auto; min-height:100vh;
    background:var(--paper); flex-direction:column;
  }
  /* .contract-doc is shared by: the admin print view (#contractDoc), the
     admin's read-only tenant-documents sheet, and the tenant portal's
     sign-the-contract preview — so wording/layout always match. Each
     context sets its own padding/scroll box around it. */
  .contract-doc{
    font-family:'Times New Roman', Georgia, serif;
    font-size:.92rem; line-height:1.55; color:#111;
  }
  #contractDoc{ padding:1in; }
  .contract-doc h1{
    font-family:inherit; text-align:center; font-size:1.15rem;
    letter-spacing:.04em; margin:0 0 22px; text-transform:uppercase;
  }
  .contract-doc p{margin:0 0 18px;}
  .contract-doc p.cd-indent{text-indent:0.5in;}
  .contract-doc .cd-witnesseth{text-align:center; font-weight:700; margin:22px 0;}
  .contract-doc .cd-clause{display:flex; gap:10px; margin:0 0 18px;}
  .contract-doc .cd-clause .cd-num{flex-shrink:0;}
  .contract-doc .cd-page + .cd-page{ margin-top:30px; padding-top:30px; border-top:1px dashed var(--line); }
  .contract-doc .cd-page-label{ text-align:center; font-size:.7rem; color:var(--slate); text-transform:uppercase; letter-spacing:.06em; margin-bottom:20px; }
  .contract-doc .cd-sig-row{display:flex; gap:30px; margin-top:55px;}
  .contract-doc .cd-sig{flex:1; text-align:center;}
  .contract-doc .cd-sig .cd-sig-imgwrap{height:52px; display:flex; align-items:flex-end; justify-content:center;}
  .contract-doc .cd-sig .cd-sig-img{max-height:50px; max-width:100%; object-fit:contain;}
  .contract-doc .cd-sig .cd-sig-line{border-top:1px solid #111; margin-top:50px; padding-top:5px; font-weight:700;}
  .contract-doc .cd-sig .cd-sig-imgwrap + .cd-sig-line{margin-top:2px;}
  .contract-doc .cd-sig .cd-sig-role{font-size:.8rem;}
  .contract-doc .cd-witness-hdr{text-align:center; font-weight:700; margin:45px 0 30px; text-transform:uppercase;}
  .contract-doc .cd-witness-row{display:flex; gap:30px;}
  .contract-doc .cd-witness{flex:1; text-align:center;}
  .contract-doc .cd-witness .cd-sig-line{border-top:1px solid #111; margin-top:50px; padding-top:5px; font-size:.8rem; font-weight:700;}

  /* Read-only scroll box used to preview the contract inside a sheet
     (admin's tenant-documents view, tenant portal sign flow). */
  .cd-preview-box{
    border:1px solid var(--line); border-radius:12px; background:#fff;
    padding:20px; max-height:320px; overflow-y:auto; margin-top:8px;
  }

  /* ---------- Digital signature pad (tenant portal) ---------- */
  .sigpad-wrap{ position:relative; border:1px solid var(--line); border-radius:12px; background:#fff; margin-top:10px; overflow:hidden; }
  .sigpad-canvas{ width:100%; height:160px; display:block; touch-action:none; }
  .sigpad-hint{ position:absolute; left:14px; right:14px; bottom:30px; border-top:1px dashed var(--line); font-size:.7rem; color:var(--slate); text-align:center; padding-top:4px; pointer-events:none; }

  /* ---------- Reports (monthly/annual) print view ---------- */
  #reportView{
    display:none;
    max-width:900px; margin:0 auto; min-height:100vh;
    background:var(--paper); flex-direction:column;
  }
  #reportDoc{ padding:26px 22px 60px; }
  .report-doc h1{ font-size:1.15rem; margin:0 0 2px; }
  .report-doc .rd-sub{ color:var(--slate); font-size:.82rem; margin:0 0 22px; }
  .report-doc .rd-cards{
    display:grid; grid-template-columns:repeat(auto-fit,minmax(140px,1fr));
    gap:10px; margin-bottom:24px;
  }
  .report-doc .rd-card{
    border:1px solid var(--line); border-radius:12px; background:var(--card);
    padding:12px 14px;
  }
  .report-doc .rd-card .rd-card-label{ font-size:.7rem; color:var(--slate); text-transform:uppercase; letter-spacing:.04em; margin-bottom:4px; }
  .report-doc .rd-card .rd-card-value{ font-size:1.05rem; font-weight:700; font-family:'JetBrains Mono',monospace; }
  .report-doc .rd-section-title{ font-size:.78rem; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--slate); margin:26px 0 10px; }
  .report-doc table{ width:100%; border-collapse:collapse; font-size:.82rem; }
  .report-doc th, .report-doc td{ text-align:left; padding:8px 10px; border-bottom:1px solid var(--line); }
  .report-doc th{ color:var(--slate); font-weight:600; font-size:.72rem; text-transform:uppercase; letter-spacing:.03em; }
  .report-doc td.rd-num, .report-doc th.rd-num{ text-align:right; font-family:'JetBrains Mono',monospace; }
  .report-doc tfoot td{ font-weight:700; border-top:2px solid var(--ink); border-bottom:none; }

  /* ==========================================================
     DESKTOP / WIDE LAYOUT (>=860px)
     Mobile markup is untouched below this breakpoint — same
     header/main/nav/fab elements, just re-laid-out with grid.
     Sidebar replaces bottom nav; content gets a comfortable
     reading width instead of stretching edge-to-edge.
     ========================================================== */
  @media (min-width:860px){
    body{ background:var(--paper-2); }
    #app{
      max-width:none; min-height:100vh;
      display:grid;
      grid-template-columns:236px minmax(0,1fr);
      grid-template-rows:auto 1fr;
      grid-template-areas:"sidebar header" "sidebar main";
    }

    /* ---- sidebar (was bottomnav) ---- */
    nav.bottomnav{
      grid-area:sidebar; position:sticky; top:0; height:100vh;
      flex-direction:column; align-items:stretch; justify-content:flex-start;
      gap:2px; padding:28px 15px; border-top:none; border-right:1px solid var(--line);
      overflow-y:auto;
    }
    nav.bottomnav::before{
      content:"UpaPro"; font-family:'Space Grotesk',system-ui,sans-serif;
      font-size:1.05rem; font-weight:700; color:var(--paper);
      padding:0 12px 22px;
    }
    nav.bottomnav button{
      flex:none; flex-direction:row; justify-content:flex-start; align-items:center;
      gap:15px; padding:14px 15px; border-radius:10px; font-size:.85rem;
      text-align:left;
    }
    nav.bottomnav button:hover{ background:rgba(247,243,236,.06); }
    nav.bottomnav button.active{ background:var(--amber); color:var(--ink); }
    nav.bottomnav button.active .ic{ color:var(--ink); }
    nav.bottomnav button .ic{ font-size:1.1rem; }

    /* ---- header spans only the content column ---- */
    header.topbar{ grid-area:header; }

    /* ---- main content: readable column, not edge-to-edge ---- */
    main{
      grid-area:main; padding:35px 40px 70px;
      max-width:820px; width:100%; margin:0 auto; overflow-y:auto;
    }
    /* The dashboard is a wide multi-panel layout (chart + income summary +
       quick actions + activity feed), not a reading column like
       Settings/forms — the 820px cap above squeezed all of that into a
       narrow centered strip. Widen it only while Dashboard is the active
       view. */
    main:has(#view-dashboard.active){ max-width:1400px; }
    main:has(#view-payments.active){ max-width:1100px; }

    /* more breathing room + columns now that width allows it */
    .stat-grid{ grid-template-columns:repeat(4,1fr); gap:15px; }
    .stat-card.wide{ grid-column:1/-1; }

    /* card lists: let rows flow into two columns where it's a
       browsing list (properties/units/overdue), keep single
       column where order matters (payment history, search, etc.) */
    #dashOverdue, #locList, #unitList, #overdueFull{
      display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr));
      gap:12px;
    }

    .fab{ right:32px; bottom:98px; }
    .fab-ria{ right:32px; bottom:32px; }

    /* ---- Lease contract: styled document-page view, not the mobile
       edge-to-edge column. A tan gutter frames a centered white "page"
       with its own header bar, so it reads like a real print preview. ---- */
    #contractView{
      max-width:none; background:var(--paper-2);
      padding:50px 30px 80px; align-items:center;
    }
    #contractView header.topbar{
      max-width:960px; width:100%; margin:0 auto;
      border-radius:14px 14px 0 0; position:static;
    }
    #contractDoc{
      max-width:960px; width:100%; margin:0 auto;
      background:var(--card); padding:80px 110px;
      border-radius:0 0 14px 14px;
      box-shadow:0 12px 32px rgba(28,43,51,.14);
    }

    /* ---- sheet maximize/minimize toggle (AI Assistant chat) ---- */
    .sheet-max-btn{ display:flex; }
    .sheet-backdrop:has(.sheet-maximized){ align-items:center; padding:30px 0; }
    .sheet-backdrop:has(.sheet-maximized) .sheet-maximized{
      width:92vw; max-width:900px; max-height:88vh; height:82vh;
      border-radius:20px; display:flex; flex-direction:column;
    }
    .sheet-maximized #aiChatLog{ flex:1; max-height:none !important; }

    /* ---- Tenant portal: same left-sidebar treatment as the admin app,
       under its own selectors (#tenantPortal / .portal-sidenav) so it
       can't collide with #app's grid or the admin nav's click handlers. ---- */
    #tenantPortal{
      max-width:none; min-height:100vh;
      display:grid;
      grid-template-columns:236px minmax(0,1fr);
      grid-template-rows:auto 1fr;
      grid-template-areas:"sidebar header" "sidebar main";
    }
    .portal-sidenav{
      display:flex;
      grid-area:sidebar; position:sticky; top:0; height:100vh;
      flex-direction:column; align-items:stretch; justify-content:flex-start;
      gap:2px; padding:28px 15px; border-top:none; border-right:1px solid var(--line);
      overflow-y:auto; background:var(--ink);
    }
    .portal-sidenav::before{
      content:"UpaPro"; font-family:'Space Grotesk',system-ui,sans-serif;
      font-size:1.05rem; font-weight:700; color:var(--paper);
      padding:0 12px 22px;
    }
    .portal-sidenav button{
      flex:none; flex-direction:row; justify-content:flex-start; align-items:center;
      gap:15px; padding:14px 15px; border-radius:10px; font-size:.85rem;
      text-align:left; background:none; border:none; color:rgba(247,243,236,.55); cursor:pointer;
    }
    .portal-sidenav button:hover{ background:rgba(247,243,236,.06); }
    .portal-sidenav button.active{ background:var(--amber); color:var(--ink); }
    .portal-sidenav button.active .ic{ color:var(--ink); }
    .portal-sidenav button .ic{ font-size:1.1rem; }

    /* ================= MODERN DESKTOP ADMIN THEME =================
       Scoped entirely to this ≥860px block and to new classes/ids —
       nothing here touches mobile layout or the tenant portal. Colors
       are local custom properties (--md-*) instead of overwriting
       :root, so the cream/amber mobile theme is untouched. */
    body{ --md-bg:#F5F6FA; --md-card:#FFFFFF; --md-line:#EBEDF3; --md-text:#1B2430;
      --md-sub:#8A93A6; --md-blue:#4F6EF7; --md-blue-soft:#E9EDFF; --md-green:#1FAA59;
      --md-green-soft:#E4F7EC; --md-purple:#7B61FF; --md-purple-soft:#EFEAFF;
      --md-sidebar:#101A26; background:var(--md-bg);
    }
    main{ background:var(--md-bg); }
    header.topbar{ background:var(--md-card); color:var(--md-text); border-bottom:1px solid var(--md-line); }
    header.topbar h1{ color:var(--md-text); }
    header.topbar .back-btn{ color:var(--md-text); }
    header.topbar .icon-btn{ color:var(--md-text); border-color:var(--md-line); }

    /* ---- sidebar: dark navy, real brand block, user card ---- */
    nav.bottomnav{ background:var(--md-sidebar); padding:22px 14px; gap:3px; }
    nav.bottomnav::before{ content:none; }
    .sidebar-brand{ display:flex; align-items:center; gap:10px; padding:2px 10px 24px; }
    .sidebar-brand .sb-mark{ width:34px; height:34px; border-radius:9px; background:var(--gold); overflow:hidden;
      display:flex; align-items:center; justify-content:center; flex:none; }
    .sidebar-brand .sb-word{ font-family:'Space Grotesk',system-ui,sans-serif; font-weight:700;
      font-size:1.05rem; color:#fff; }
    .sidebar-brand .sb-word b{ color:var(--gold); font-weight:700; }
    nav.bottomnav button{ color:rgba(255,255,255,.6); }
    nav.bottomnav button:hover{ background:rgba(255,255,255,.06); color:#fff; }
    nav.bottomnav button.active{ background:var(--gold); color:#1B2430; }
    nav.bottomnav button.active .ic{ color:#1B2430; }
    .sidebar-foot{ display:flex; flex-direction:column; margin-top:auto; padding-top:14px; }
    .sidebar-user{ display:flex; align-items:center; gap:10px; padding:12px 10px;
      border-top:1px solid rgba(255,255,255,.1); }
    .sidebar-user .su-avatar{ width:34px; height:34px; border-radius:50%; background:var(--md-blue);
      color:#fff; font-weight:700; font-size:.85rem; display:flex; align-items:center;
      justify-content:center; flex:none; }
    .sidebar-user .su-name{ font-size:.82rem; font-weight:600; color:#fff; }
    .sidebar-user .su-role{ font-size:.7rem; color:rgba(255,255,255,.5); }
    .sidebar-sync{ display:flex; align-items:center; gap:8px; padding:10px 10px 16px;
      font-size:.72rem; color:rgba(255,255,255,.5); }
    .sidebar-sync .ss-dot{ width:7px; height:7px; border-radius:50%; background:var(--slate); flex:none; }
    .sidebar-sync.on .ss-dot{ background:var(--md-green); }
    nav.bottomnav button.sidebar-help{ display:flex; align-items:center; gap:10px; padding:12px 10px;
      font-size:.8rem; color:rgba(255,255,255,.55); text-decoration:none; cursor:pointer;
      border-top:1px solid rgba(255,255,255,.1); background:none; border-left:none; border-right:none; border-bottom:none; width:100%; text-align:left; font-family:inherit; flex:none; }
    nav.bottomnav button.sidebar-help:hover{ background:rgba(255,255,255,.06); color:#fff; }

    /* ---- greeting header ---- */
    #dashOverviewLabel{ display:none; }
    .dm-greet-row{ display:flex; align-items:flex-start; justify-content:space-between; gap:16px; margin-bottom:26px; }
    .dm-greet-title{ margin:0 0 4px; font-size:1.6rem; color:var(--md-text); }
    .dm-greet-sub{ margin:0; color:var(--md-sub); font-size:.88rem; }
    .dm-greet-actions{ display:flex; align-items:center; gap:12px; flex:none; }
    .dm-bell-wrap{ position:relative; }
    .dm-bell{ position:relative; width:40px; height:40px; border-radius:10px; border:1px solid var(--md-line);
      background:var(--md-card); color:var(--md-text); display:flex; align-items:center; justify-content:center; cursor:pointer; }
    .dm-bell-badge{ position:absolute; top:-5px; right:-5px; background:var(--rust); color:#fff;
      font-size:.62rem; font-weight:700; min-width:16px; height:16px; border-radius:8px;
      display:flex; align-items:center; justify-content:center; padding:0 3px; }
    .dm-notif-panel{ position:absolute; top:48px; right:0; width:340px; max-width:88vw; background:#fff;
      border:1px solid var(--md-line); border-radius:14px; box-shadow:0 14px 34px rgba(0,0,0,.16); z-index:60;
      display:none; overflow:hidden; }
    .dm-notif-panel.open{ display:block; }
    .dm-notif-head{ display:flex; align-items:center; justify-content:space-between; padding:12px 14px;
      border-bottom:1px solid var(--md-line); }
    .dm-notif-head span{ font-weight:700; font-size:.86rem; color:var(--md-text); }
    .dm-notif-list{ max-height:360px; overflow-y:auto; }
    .dm-notif-item{ display:flex; gap:10px; padding:11px 14px; border-bottom:1px solid var(--md-line);
      cursor:pointer; align-items:flex-start; }
    .dm-notif-item:last-child{ border-bottom:none; }
    .dm-notif-item:hover{ background:var(--md-card); }
    .dm-notif-icon{ width:34px; height:34px; border-radius:50%; background:var(--md-card); display:flex;
      align-items:center; justify-content:center; flex:none; font-size:1rem; }
    .dm-notif-title{ font-size:.82rem; font-weight:600; color:var(--md-text); }
    .dm-notif-sub{ font-size:.74rem; color:var(--md-sub); margin-top:1px; }
    .dm-notif-time{ font-size:.68rem; color:var(--md-sub); white-space:nowrap; margin-left:auto; flex:none; padding-top:2px; }
    .dm-notif-empty{ padding:28px 14px; text-align:center; color:var(--md-sub); font-size:.82rem; }
    .dm-notif-item.read{ opacity:.55; }
    .dm-notif-item.read:hover{ opacity:.8; }
    .dm-notif-divider{ padding:8px 14px 4px; font-size:.68rem; font-weight:700; letter-spacing:.03em;
      text-transform:uppercase; color:var(--md-sub); }
    .dm-date-pill{ background:var(--md-card); border:1px solid var(--md-line); border-radius:10px;
      padding:9px 14px; font-size:.8rem; font-weight:600; color:var(--md-text); }

    /* ---- modern stat cards ---- */
    .stat-grid{ grid-template-columns:repeat(4,1fr); }
    .stat-card{ background:var(--md-card); border-color:var(--md-line); padding:18px; border-radius:16px; }
    .stat-card .sc-icon{ width:38px; height:38px; border-radius:10px; display:flex; align-items:center;
      justify-content:center; margin-bottom:14px; font-size:1.05rem; }
    .stat-card .sc-icon.blue{ background:var(--md-blue-soft); color:var(--md-blue); }
    .stat-card .sc-icon.green{ background:var(--md-green-soft); color:var(--md-green); }
    .stat-card .sc-icon.purple{ background:var(--md-purple-soft); color:var(--md-purple); }
    .stat-card .val{ color:var(--md-text); font-size:1.4rem; }
    .stat-card .lbl{ color:var(--md-sub); }
    .stat-card .sc-link{ display:block; margin-top:12px; font-size:.76rem; font-weight:600;
      color:var(--md-blue); text-decoration:none; }
    .stat-card.ok .sc-link{ color:var(--md-green); }
    .stat-card.wide{ display:none; } /* superseded by .dm-overdue-banner on desktop */

    /* ---- overdue banner ---- */
    .dm-overdue-banner{ display:flex !important; align-items:center; justify-content:space-between;
      background:var(--rust-soft); border:1px solid #F3C9C3; border-radius:16px; padding:18px 22px; margin:16px 0 22px; }
    .dm-overdue-banner.clear{ background:var(--md-green-soft); border-color:#BFE7CE; }
    .dm-ob-left{ display:flex; align-items:center; gap:14px; }
    .dm-ob-icon{ width:42px; height:42px; border-radius:50%; background:#fff; color:var(--rust);
      display:flex; align-items:center; justify-content:center; flex:none; }
    .dm-overdue-banner.clear .dm-ob-icon{ color:var(--md-green); }
    .dm-ob-label{ font-size:.78rem; color:var(--md-sub); }
    .dm-ob-val{ font-size:1.15rem; font-weight:700; color:var(--rust); }
    .dm-overdue-banner.clear .dm-ob-val{ color:var(--md-green); }
    .dm-ob-btn{ background:#fff; border:1px solid var(--md-line); color:var(--rust); font-weight:600;
      font-size:.8rem; padding:10px 16px; border-radius:10px; cursor:pointer; }

    /* ---- two-column body ---- */
    .dm-cols{ display:grid; grid-template-columns:minmax(0,1fr) 300px; gap:18px; align-items:start; }
    .dm-row2{ display:grid; grid-template-columns:1.5fr 1fr; gap:18px; margin-bottom:18px; }
    .dm-panel{ background:var(--md-card); border:1px solid var(--md-line); border-radius:16px;
      padding:20px; margin-bottom:18px; }
    .dm-col-right .dm-panel:last-child, .dm-col-left .dm-panel:last-child{ margin-bottom:0; }
    .dm-panel-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; }
    .dm-panel-head h3{ margin:0; font-size:.92rem; color:var(--md-text); }
    .dm-view-all-link{ font-size:.76rem; font-weight:600; color:var(--md-blue); text-decoration:none; }
    .dm-block-link{ display:block; text-align:center; margin-top:12px; padding-top:12px; border-top:1px solid var(--md-line); }

    /* due-soon list, restyled as flat rows instead of grid tiles */
    .dm-col-left #dashOverdue{ display:flex; flex-direction:column; gap:0; }
    .dm-col-left #dashOverdue .row-card{ border:none; border-radius:0; border-bottom:1px solid var(--md-line);
      padding:9px 0; background:none; }
    .dm-col-left #dashOverdue .row-card:last-child{ border-bottom:none; padding-bottom:0; }
    .dm-col-left #dashOverdue .empty{ padding:10px 0; }

    /* recent activity */
    .dm-activity-row{ display:flex; align-items:flex-start; gap:10px; padding:9px 0; }
    .dm-activity-row .ar-icon{ width:30px; height:30px; border-radius:8px; flex:none; display:flex;
      align-items:center; justify-content:center; font-size:.85rem; background:var(--md-blue-soft); }
    .dm-activity-row .ar-title{ font-size:.8rem; font-weight:600; color:var(--md-text); }
    .dm-activity-row .ar-sub{ font-size:.72rem; color:var(--md-sub); }
    .dm-activity-row .ar-time{ font-size:.68rem; color:var(--md-sub); flex:none; margin-left:auto; white-space:nowrap; }

    /* collection chart (plain inline HTML/CSS, no chart lib dependency) */
    .dm-chart-period{ display:inline-flex; align-items:center; gap:6px; font-size:.74rem; font-weight:600;
      color:var(--md-text); background:var(--md-card); border:1px solid var(--md-line); border-radius:8px;
      padding:6px 10px; }
    .dm-chart-period svg{ width:12px; height:12px; flex:none; }
    .dm-chart-grid{ display:grid; grid-template-columns:auto 1fr; grid-template-rows:150px auto;
      column-gap:10px; row-gap:6px; }
    .dm-chart-axis{ grid-column:1; grid-row:1; display:flex; flex-direction:column; justify-content:space-between;
      align-items:flex-end; height:150px; }
    .dm-chart-axis span{ font-size:.62rem; color:var(--md-sub); line-height:1; }
    .dm-chart-bars{ grid-column:2; grid-row:1; display:flex; align-items:flex-end; gap:6px; height:150px; position:relative; }
    .dm-chart-bars .cb-col{ flex:1; display:flex; align-items:flex-end; justify-content:center; height:100%; position:relative; }
    .dm-chart-bars .cb-barwrap{ width:100%; display:flex; align-items:flex-end; justify-content:center; gap:5px; height:100%; }
    .dm-chart-bars .cb-bar{ width:18px; border-radius:4px 4px 0 0; background:var(--md-line); position:relative; }
    .dm-chart-bars .cb-bar.collected{ background:var(--md-green); }
    .dm-chart-bars .cb-bar.collected.current::after{
      content:attr(data-val); position:absolute; top:-30px; left:50%; transform:translateX(-50%);
      background:var(--md-text); color:#fff; font-size:.68rem; font-weight:600; white-space:nowrap;
      padding:4px 8px; border-radius:6px; }
    .dm-chart-months{ grid-column:2; grid-row:2; display:flex; gap:6px; }
    .dm-chart-months span{ flex:1; text-align:center; font-size:.62rem; color:var(--md-sub); }
    .dm-chart-legend{ display:flex; justify-content:center; gap:16px; margin-top:14px; font-size:.72rem; color:var(--md-sub); }
    .dm-chart-legend span{ display:inline-flex; align-items:center; gap:6px; }
    .dm-chart-legend i{ width:8px; height:8px; border-radius:50%; display:inline-block; }

    /* income summary */
    .dm-income-row{ display:flex; align-items:center; justify-content:space-between; padding:9px 0;
      border-bottom:1px solid var(--md-line); font-size:.82rem; }
    .dm-income-row:last-of-type{ border-bottom:none; }
    .dm-income-row .ir-lbl{ display:flex; align-items:center; gap:8px; color:var(--md-sub); }
    .dm-income-row .ir-lbl i{ width:8px; height:8px; border-radius:50%; display:inline-block; }
    .dm-income-row .ir-val{ font-weight:700; color:var(--md-text); font-family:'JetBrains Mono',monospace; }
    .dm-income-note{ background:var(--md-green-soft); color:#1c7a41; border-radius:10px; padding:10px 12px;
      font-size:.76rem; margin-top:12px; }
  }

  /* Hide desktop-only dashboard elements on mobile (below 860px) — they're
     always in the DOM (renderDashboard populates them regardless of
     viewport) so the mobile view just needs to not show them. */
  @media (max-width:859.98px){
    .dm-greet-row, .dm-overdue-banner, .dm-cols{ display:none !important; }

    /* Payments table → compact rows on phones, no horizontal scroll/clipping.
       The grid columns from desktop don't fit a phone screen, so rows switch
       to a wrapping flex layout instead: line 1 is status + tenant + method
       + amount, line 2 is the date paid (right-aligned under the amount),
       line 3 is unit/property · charge/period. Same DOM/JS output as
       desktop — only the visual order (via `order`) and layout mode change
       here, so there's one render path for both. */
    .pm-table{ overflow-x:hidden; overflow-y:visible; }
    .pm-row.pm-head{ display:none; } /* column headers don't fit a phone row */
    .pm-row{
      display:flex; flex-wrap:wrap; align-items:center; min-width:0;
      column-gap:8px; row-gap:2px; padding:10px 14px;
    }
    .pm-cell{ font-size:.74rem; color:var(--slate); white-space:normal; overflow:visible; text-overflow:clip; }
    .pm-status{ order:1; flex:none; }
    .pm-tenant{ order:2; flex:1 1 auto; min-width:0; font-size:.86rem; font-weight:600; color:var(--ink);
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .pm-method{ order:3; flex:none; }
    .pm-amount{ order:4; flex:none; font-size:.82rem; }
    .pm-date{ order:5; flex:1 1 100%; text-align:right; }
    .pm-break{ display:block; flex:1 1 100%; height:0; order:6; }
    .pm-unit{ order:7; color:var(--ink); font-weight:600; }
    .pm-charge{ order:8; }
    .pm-charge::before{ content:"·"; margin-right:8px; }
  }

  @media print{
    @page{ size: letter; margin:1in; }
    #app, #tenantPortal, .sheet-backdrop, .toast, .update-banner, #imgLightboxBackdrop, .no-print{
      display:none !important;
    }
    #contractView{ display:block !important; max-width:none; padding:0; background:#fff; }
    #contractDoc{ padding:0; max-width:none; margin:0; box-shadow:none; border-radius:0; background:#fff; }
    #contractDoc .cd-page + .cd-page{ margin-top:0; padding-top:0; border-top:none; page-break-before:always; }
    #contractDoc .cd-page-label{ display:none; }
    #reportView{ display:block !important; max-width:none; padding:0; background:#fff; }
    #reportDoc{ padding:0; }
    .report-doc .rd-card{ break-inside:avoid; }
    .report-doc tr{ break-inside:avoid; }
    body{ background:#fff; }
  }
