/* ============================================================
   Kodi Mobile — design system
   Carried over from the Kodi Sheets app on purpose, so this looks like
   the same product, not a different one. Trimmed down to only what
   this first screen slice (login/signup + Overview) actually needs;
   more gets added here as more screens get built in Phase 3.
   ============================================================ */
:root{
  --bg:#FAF9F7; --surface:#FFFFFF; --surface-2:#F4F2EF; --line:#E8E4DE;
  --ink:#221F1D; --ink-2:#5C5651; --ink-3:#8A837C;
  --green:#0E8F5B; --green-bg:#E7F4EE; --green-dark:#0B6E45;
  --amber:#B87309; --amber-bg:#FCF3E4;
  --red:#C63D3D;  --red-bg:#FAEBEB;
  --blue:#2B6CB0; --blue-bg:#EAF1F9;
  --r:14px; --r-sm:10px;
  --sh:0 1px 2px rgba(34,31,29,.05), 0 1px 3px rgba(34,31,29,.04);
  --sh-lg:0 4px 16px rgba(34,31,29,.10);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--ink);
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  font-size:15px; line-height:1.5; -webkit-font-smoothing:antialiased;
  min-height:100vh;
}
h1,h2,h3,h4{margin:0;font-weight:650;letter-spacing:-.015em}
button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
a{color:var(--ink);text-decoration:none}

#app{min-height:100vh;display:flex;flex-direction:column}
.topbar{
  position:sticky;top:0;z-index:40;background:var(--ink);color:#fff;
  display:flex;align-items:center;gap:12px;padding:12px 16px;
}
.topbar .brand{font-weight:700;font-size:16px;letter-spacing:-.02em;flex:1;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.iconbtn{background:#ffffff1a;border:0;color:#fff;width:34px;height:34px;border-radius:9px;
  display:grid;place-items:center;cursor:pointer;font-size:15px;flex:none}
.iconbtn:active{background:#ffffff33}
.topbadge{position:absolute;top:-5px;right:-5px;min-width:16px;height:16px;padding:0 4px;
  border-radius:99px;background:var(--red);color:#fff;font-size:10px;font-weight:700;
  line-height:16px;text-align:center;box-shadow:0 0 0 2px var(--ink,#1a1a1a)}

main{flex:1;padding:16px 16px 96px;max-width:560px;width:100%;margin:0 auto}

/* bottom nav */
.tabbar{
  position:fixed;bottom:0;left:0;right:0;z-index:40;background:var(--surface);
  border-top:1px solid var(--line);display:flex;padding:6px 4px 8px;
  padding-bottom:calc(8px + env(safe-area-inset-bottom));
}
.tabbar button{
  flex:1;background:none;border:0;padding:6px 2px;display:flex;flex-direction:column;
  align-items:center;gap:3px;color:var(--ink-3);font-size:10.5px;font-weight:600;cursor:pointer;
  border-radius:10px;
}
.tabbar button .ic{font-size:18px;line-height:1}
.tabbar button.on{color:var(--ink)}

/* lists */
.list{list-style:none;margin:0;padding:0}
.row{display:flex;align-items:center;gap:12px;padding:14px 16px;
  border-bottom:1px solid var(--line);cursor:pointer;background:var(--surface)}
.row:last-child{border-bottom:0}
.row:active{background:var(--surface-2)}
.row .main{flex:1;min-width:0}
.row .t1{font-weight:600;font-size:14.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row .t2{font-size:12.5px;color:var(--ink-2);margin-top:2px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.av{width:38px;height:38px;border-radius:11px;background:var(--surface-2);display:grid;
  place-items:center;font-weight:700;font-size:13px;color:var(--ink-2);flex:none}
.card-h{padding:14px 16px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
.card-h h3{font-size:14px;flex:1}
.card-b.tight{padding:0}
.sec-title{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;
  color:var(--ink-3);margin:22px 0 10px}
.rowflex{display:flex;gap:10px;align-items:center}
.rowflex.wrap{flex-wrap:wrap}
.spacer{flex:1}
.btn.sm{padding:8px 12px;font-size:13px;min-height:36px;border-radius:9px}
.btn.ghost{background:var(--surface);color:var(--ink);border:1px solid var(--line)}
.btn.soft-red{background:var(--red-bg);color:var(--red)}

/* KPI grid - numbers lead, labels follow - carried over verbatim from the
   Sheets app's dashboard so the two look like the same product. */
.kpis{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
.kpi{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:14px;box-shadow:var(--sh)}
.kpi .lab{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:6px}
.kpi .val{font-size:24px;font-weight:700;letter-spacing:-.03em;line-height:1.1}
.kpi .sub{font-size:12px;color:var(--ink-2);margin-top:4px}
.kpi.danger{background:var(--red-bg);border-color:#F0D5D5}
.kpi.danger .val{color:var(--red)}
.kpi.good .val{color:var(--green)}

/* Value-only accent colors (plain white card, just a colored figure) -
   for tiles where the number itself should stand out but the tile
   isn't flagging a problem the way .danger's red background does. */
.kpi.txt-green .val{color:var(--green)}
.kpi.txt-red .val{color:var(--red)}

/* Houses + Occupancy combined into one Overview tile (per direct
   feedback) - two mini stat columns, Houses on the left and Occupancy
   pushed to the far right of the tile, each with its own occupied/
   empty count directly underneath it instead of one shared subtitle. */
.kpi-split{display:flex;justify-content:space-between}
.kpi-split .val{font-size:20px}
.kpi-split .kpi-right{text-align:right}

/* Overview's tiles link through to their underlying report/page (per
   direct feedback) - a plain tap, no confirmation step, same as every
   other "tap a summary to drill into its detail" spot already in the
   app (the "Who to follow up" list, the Reports menu itself). */
#ovKpis .kpi{cursor:pointer}
#ovKpis .kpi:active{background:var(--surface-2)}
#ovKpis .kpi.danger:active{background:#F5DEDE}

/* privacy mask - see privacyOn_/setPrivacy_ in app.js. Blurs money figures
   on the Overview screen only, without touching layout. */
body.privacy-on .mny{filter:blur(7px);user-select:none}

/* the privacy toggle icon - a plain eye, with a line drawn across it in CSS
   when amounts are hidden. */
.eye-ic{position:relative;display:inline-block}
.eye-ic.off::after{content:'';position:absolute;left:-3px;right:-3px;top:50%;
  height:2px;background:currentColor;transform:rotate(-40deg);border-radius:2px}

/* segmented control - This month / This year */
.seg{display:flex;background:var(--surface-2);border-radius:11px;padding:3px;gap:2px;
  overflow-x:auto;-webkit-overflow-scrolling:touch}
.seg button{flex:1;background:none;border:0;padding:9px 12px;border-radius:9px;
  font-size:12.5px;font-weight:650;color:var(--ink-2);cursor:pointer;white-space:nowrap}
.seg button.on{background:var(--surface);color:var(--ink);box-shadow:var(--sh)}

/* modal / sheet */
.mask{position:fixed;inset:0;background:rgba(34,31,29,.42);z-index:60;display:flex;
  align-items:flex-end;justify-content:center;backdrop-filter:blur(2px)}
.sheet{background:var(--surface);width:100%;max-width:600px;max-height:92vh;overflow:auto;
  border-radius:20px 20px 0 0;box-shadow:var(--sh-lg);animation:up .22s ease}
@keyframes up{from{transform:translateY(24px);opacity:.6}to{transform:none;opacity:1}}
.sheet-h{position:sticky;top:0;background:var(--surface);border-bottom:1px solid var(--line);
  padding:16px;display:flex;align-items:center;gap:12px;z-index:2}
.sheet-h h3{flex:1;font-size:16px}
.sheet-b{padding:16px;padding-bottom:calc(20px + env(safe-area-inset-bottom))}
.empty{text-align:center;padding:30px 16px;color:var(--ink-3)}
.empty .ic{font-size:32px;margin-bottom:8px}
.empty .t1{font-weight:600;color:var(--ink-2);margin-bottom:4px}

.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--sh);overflow:hidden}
.card + .card{margin-top:12px}
.card-b{padding:16px}

.pill{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:700;
  padding:3px 8px;border-radius:99px;letter-spacing:.02em;white-space:nowrap;text-transform:uppercase}
.pill.ok{background:var(--green-bg);color:var(--green)}
.pill.warn{background:var(--amber-bg);color:var(--amber)}
.pill.bad{background:var(--red-bg);color:var(--red)}

.balpill{display:inline-flex;align-items:center;font-size:13.5px;font-weight:700;
  padding:6px 12px;border-radius:99px;white-space:nowrap}
.balpill.owe{background:var(--red-bg);color:var(--red)}
.balpill.credit{background:var(--green-bg);color:var(--green)}
.balpill.paid{background:var(--surface-2);color:var(--ink-2)}

.small{font-size:12.5px;color:var(--ink-2)}
.tiny{font-size:11.5px;color:var(--ink-3)}
.center{text-align:center}
.mt{margin-top:12px} .mb{margin-bottom:12px}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;
  background:var(--ink);color:#fff;border:0;border-radius:var(--r-sm);
  padding:12px 16px;font-weight:650;font-size:14px;cursor:pointer;min-height:44px}
.btn:active{opacity:.85}
.btn[disabled]{opacity:.45;cursor:not-allowed}
.btn.wide{width:100%}

.linkbtn{background:none;border:0;color:var(--ink-2);font-size:13px;font-weight:650;
  cursor:pointer;padding:6px;text-decoration:underline}
.linkbtn.back{text-decoration:none;display:inline-flex;align-items:center;gap:2px;
  margin-bottom:14px;color:var(--ink-2)}

.choicecard{display:flex;align-items:center;gap:12px;width:100%;text-align:left;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--sh);padding:14px;cursor:pointer;font:inherit;color:var(--ink)}
.choicecard + .choicecard{margin-top:10px}
.choicecard:active{background:var(--surface-2)}
.choicecard-ic{width:40px;height:40px;border-radius:11px;background:var(--surface-2);
  display:grid;place-items:center;font-size:19px;flex:none}
.choicecard-txt{flex:1;min-width:0}
.choicecard-t1{font-weight:700;font-size:14.5px}
.choicecard-t2{font-size:12.5px;color:var(--ink-2);margin-top:2px;line-height:1.35}
.choicecard-arrow{font-size:22px;color:var(--ink-3);flex:none}

.bufnote{color:var(--red);font-weight:700}
.examplebox{background:var(--surface-2);border-radius:var(--r-sm);padding:12px;margin-bottom:14px}

.field{margin-bottom:14px;text-align:left}
.field label{display:block;font-size:12px;font-weight:700;color:var(--ink-2);
  margin-bottom:6px;letter-spacing:.01em}
.field input{
  width:100%;padding:12px 13px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--surface);outline:none;font-size:15px}
.field input:focus{border-color:var(--ink);box-shadow:0 0 0 3px rgba(34,31,29,.07)}
.field textarea{width:100%;padding:12px 13px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--surface);outline:none;font-size:15px;resize:vertical;min-height:90px}
.field textarea:focus{border-color:var(--ink);box-shadow:0 0 0 3px rgba(34,31,29,.07)}
.field label.chk{display:flex;align-items:center;gap:8px;font-weight:600;color:var(--ink);
  cursor:pointer;margin-bottom:0}
.field label.chk input{width:auto}

.err{background:var(--red-bg);color:#8E2C2C;padding:11px 13px;border-radius:var(--r-sm);
  font-size:13px;margin-bottom:14px;text-align:left}
.ok-msg{background:var(--green-bg);color:#0B6E45;padding:11px 13px;border-radius:var(--r-sm);
  font-size:13px;margin-bottom:14px;text-align:left}

/* grid-template-columns:100% pins the (only) column to the container's
   own width - without it, an auto-sized grid track takes a child's
   max-width into account when sizing itself, so a wide .auth-card (like
   the tenant portal's 440px one) could inflate the track past the
   viewport and force the whole page to scroll sideways, even though
   width:100% on the card looks like it should have prevented that. */
.auth{min-height:100vh;display:grid;grid-template-columns:100%;place-items:center;padding:24px;background:var(--bg);overflow-x:hidden}
.auth-card{width:100%;max-width:380px;background:var(--surface);border:1px solid var(--line);
  border-radius:18px;padding:28px 24px;box-shadow:var(--sh-lg);text-align:center}
.auth-logo{width:56px;height:56px;border-radius:15px;background:var(--ink);color:#fff;
  display:grid;place-items:center;font-weight:700;font-size:22px;margin:0 auto 16px}
.auth h2{text-align:center;font-size:20px;margin-bottom:4px}
.auth .sub{text-align:center;color:var(--ink-3);font-size:13px;margin-bottom:22px}

.skel{background:linear-gradient(90deg,var(--surface-2) 25%,#EDEAE5 37%,var(--surface-2) 63%);
  background-size:400% 100%;animation:sk 1.4s ease infinite;border-radius:var(--r-sm);
  height:16px;margin:8px 0}
@keyframes sk{0%{background-position:100% 50%}100%{background-position:0 50%}}

/* ------------------------------------------------------------------
   Print / "Download as PDF" - #printArea sits outside #app, hidden
   at all times on screen. When a receipt, invoice, statement, or
   report is printed, JS fills it with a clean, plain document and
   calls window.print() - the browser's own print dialog offers
   "Save as PDF" as a destination, which is the whole mechanism, no
   PDF library needed. @media print then hides the live app entirely
   and shows only this, so what prints is just the document, not the
   phone-sized app chrome around it. */
#printArea{display:none}

/* "Account history" table on the tenant page - a real running-balance
   statement (Date/Detail/Charge/Paid/Balance), on-screen, dark-theme
   version of the same idea the print statement uses. */
table.ahist{width:100%;border-collapse:collapse;font-size:12.5px}
table.ahist th{position:sticky;top:0;background:var(--surface);text-align:left;
  font-size:10.5px;text-transform:uppercase;letter-spacing:.02em;color:var(--ink-3);
  padding:8px 6px;border-bottom:1px solid var(--line)}
table.ahist td{padding:8px 6px;border-bottom:1px solid var(--line);vertical-align:top;
  overflow-wrap:break-word}
table.ahist tr:last-child td{border-bottom:0}
/* Details carries the most text (entry type, reference, description,
   Reverse/Edit links) so it should end up the widest column - but the
   Date/Charge/Paid/Balance cells are deliberately white-space:nowrap
   (see loadTenantLedger) so a date or amount never wraps mid-value.
   table-layout:fixed with hard percentages fought that: it forced
   those nowrap cells into a narrower box than their content actually
   needed, which overflowed the table on a phone-width screen (found
   via screenshot testing - the Balance column was getting visibly
   clipped). Plain auto layout lets the browser give every nowrap
   column exactly the width its content needs first, then hands the
   rest to Details - these numbers are just a relative hint on top of
   that, not a hard cap. */
table.ahist th:nth-child(1),table.ahist td:nth-child(1){width:14%}
table.ahist th:nth-child(2),table.ahist td:nth-child(2){width:40%}
table.ahist th:nth-child(3),table.ahist td:nth-child(3){width:16%}
table.ahist th:nth-child(4),table.ahist td:nth-child(4){width:14%}
table.ahist th:nth-child(5),table.ahist td:nth-child(5){width:16%}
/* Every printed document (receipt/invoice/statement/report) shares
   this look: a full-bleed green band across the top of the page
   (business identity + document title/meta), then a plain white body
   below it - no card, no floating border, so it fills the printed
   page edge to edge instead of looking like a shrunk-down card
   stranded in the middle of an A4 sheet (direct feedback after the
   first attempt at this got that wrong). */
.pdoc{background:#fff;font-family:inherit;color:#111}
.pdoc-topband{width:100%;background:var(--green);color:#fff;padding:26px 44px;
  display:flex;justify-content:space-between;align-items:flex-start;gap:16px}
.pdoc-biz{font-weight:800;font-size:19px;letter-spacing:-.01em}
.pdoc-contact{font-size:12px;color:#E4F5EC;margin-top:5px}
.pdoc-contact div{line-height:1.5}
.pdoc-meta{text-align:right;flex:none}
.pdoc-meta>div{font-size:12.5px;color:#E4F5EC;margin-top:4px}
.pdoc-doctype{font-size:11.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  color:#fff!important;margin-top:0!important}
/* A clear rule right under the green header band, on every printed
   document - per direct feedback, separating "who this is from" from
   the document body needed a harder line than the band's own edge.
   Solid dark, same weight as the receipt's own Thank You divider
   below, not another shade of green (too close to the band itself to
   actually read as a line). */
.pdoc-rule{height:3px;background:#111}

.pdoc-body{padding:30px 40px 36px}
.pdoc-sub{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink-3);margin:0 0 5px}
.pdoc-from{font-weight:800;font-size:16px;margin-bottom:16px}

/* Amount-in-figures-and-words box, used on receipts. */
.pdoc-amountbox{background:var(--green-bg);border:1px solid #CFE8DB;border-radius:12px;
  padding:22px 20px;margin:6px 0 20px;text-align:center}
.pdoc-amt{font-size:34px;font-weight:800;color:var(--green-dark);letter-spacing:-.01em}
.pdoc-amt-words{font-size:13px;font-weight:700;color:var(--ink-2);margin-top:8px;font-style:italic}

.pdoc table{width:100%;border-collapse:collapse;font-size:13.5px;margin:14px 0 4px}
.pdoc thead th{text-align:left;font-size:10.5px;font-weight:800;text-transform:uppercase;
  letter-spacing:.04em;color:var(--ink-3);padding:0 10px 10px 0;border-bottom:2px solid #111}
.pdoc td{border-bottom:1.5px solid #111;padding:10px 10px 10px 0}
.pdoc tr:last-child td{border-bottom:0}
.pdoc tr.total td{border-top:2px solid #111;border-bottom:0;font-weight:800;padding-top:12px}

/* A single highlighted total (e.g. Net on the Income & expenses
   report), set apart from the table instead of buried as one more row. */
.pdoc-highlight{background:var(--green-bg);border:1px solid #CFE8DB;border-radius:12px;
  padding:18px 20px;margin-top:20px;display:flex;justify-content:space-between;align-items:center}
.pdoc-highlight.negative{background:var(--red-bg);border-color:#F0D5D5}
.pdoc-highlight-label{font-size:13px;font-weight:700;color:var(--ink-2)}
.pdoc-highlight-value{font-size:22px;font-weight:800;color:var(--green-dark)}
.pdoc-highlight.negative .pdoc-highlight-value{color:var(--red)}

/* Three at-a-glance stat blocks (Income/Expenses/Net) above a report's
   table, mirroring the same KPI cards already shown on screen. */
.pdoc-stats{display:flex;gap:12px;margin:0 0 22px}
.pdoc-stat{flex:1;border-radius:10px;padding:13px 14px 12px;border:1px solid var(--line)}
.pdoc-stat-lab{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-3)}
.pdoc-stat-val{font-size:17px;font-weight:800;margin-top:5px;letter-spacing:-.01em}
.pdoc-stat-sub{font-size:10px;color:var(--ink-2);margin-top:2px}
.pdoc-stat.income{background:var(--green-bg);border-color:#CFE8DB}
.pdoc-stat.income .pdoc-stat-val{color:var(--green-dark)}
.pdoc-stat.expense{background:var(--surface-2)}
.pdoc-stat.net{background:var(--green-bg);border-color:#CFE8DB}
.pdoc-stat.net .pdoc-stat-val{color:var(--green-dark)}
.pdoc-stat.net.negative{background:var(--red-bg);border-color:#F0D5D5}
.pdoc-stat.net.negative .pdoc-stat-val{color:var(--red)}

/* Bold "Thank You" closing, receipts only. */
.pdoc-thankyou{text-align:center;margin-top:26px;padding-top:20px;border-top:2px solid #111}
.pdoc-thankyou-h{font-weight:800;font-size:16px;color:var(--green-dark)}
.pdoc-thankyou-p{font-size:12.5px;color:var(--ink-2);margin-top:5px}

.pdoc-note{color:var(--ink-2);font-size:11.5px;margin-top:18px}
.pdoc-footnote{color:var(--ink-3);font-size:10.5px;text-align:center;margin-top:18px;line-height:1.5}
.pdoc-actions{margin-top:20px}
@media print{
  body *{visibility:hidden}
  #printArea, #printArea *{visibility:visible}
  #printArea{display:block;position:absolute;left:0;top:0;width:100%}
  .pdoc-actions{display:none}
}

/* ============================================================
   Item #12 from the v0.32 feature list: a real desktop/PC layout,
   without touching a single mobile rule above - everything here is
   gated behind this one min-width query, so nothing below 900px
   (every phone, and this is exactly the width every existing
   Playwright test runs at) is affected in any way.

   The one thing that actually looks "wrong" on a wide monitor is the
   bottom tab bar - a full-width fixed strip along the bottom edge
   reads as a phone app stretched sideways, not a desktop site. The
   fix here is purely structural CSS, no JS/DOM changes: the exact
   same .tabbar element (still built once, in renderShell()) becomes
   a fixed left-hand sidebar instead of a fixed bottom bar - its
   buttons already lay out icon-over-label in a column, which maps
   onto a vertical sidebar item without changing a single button's
   markup. main/.topbar then just get enough left offset to clear it,
   and the content column gets a bit more breathing room since a
   desktop screen has it to spare. */
@media (min-width: 900px){
  .topbar{padding-left:104px}
  /* Per direct feedback on the first pass: a flat margin-left:104px
     left the content column stranded against the sidebar with a huge
     dead gap on the right on genuinely wide monitors (a fixed
     960px-wide column on a 1920px screen leaves ~850px unused on one
     side only). margin-left now grows with the viewport once it's
     wide enough that true centering (relative to the space right of
     the sidebar) would push it past the minimum 104px offset needed
     to clear the sidebar - so it stays put on a normal laptop screen
     (~1280-1440px, where this still resolves to 104px, unchanged from
     before) and visibly centers itself on a large monitor instead of
     hugging the left edge. */
  main{
    max-width:1400px;
    margin-left:max(104px, calc((100vw - 1400px) / 2));
    margin-right:auto;
    padding:24px 32px 32px;
  }
  .tabbar{
    top:0;bottom:0;left:0;right:auto;width:88px;z-index:40;
    flex-direction:column;justify-content:flex-start;align-items:stretch;
    gap:6px;padding:20px 8px;border-top:0;border-right:1px solid var(--line);
  }
  .tabbar button{flex:none;padding:10px 2px;border-radius:var(--r-sm)}
  .tabbar button.on{background:var(--surface-2)}
}
