/* Finance Tracker web styles. Served content-hashed (whitenoise manifest) —
   any edit here changes the URL, which is also the escape hatch for clients
   that cached a bad copy. */
:root{
  --bg:#faf9f5; --surface:#ffffff; --surface-alt:#f4f2ec; --track:#eceae2;
  --text:#1a1a18; --text-2:#56554f; --text-3:#8a887f; --border:#e3e1d8;
  --accent:#2a78d6; --accent-ink:#fff; --danger:#d6455a; --good:#2aa775;
  --shadow:0 1px 2px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.05);
}
@media (prefers-color-scheme: dark){
  :root{ --bg:#1f1e1c; --surface:#262522; --surface-alt:#2c2b27; --track:#383732;
    --text:#f3f1ea; --text-2:#c0bfb5; --text-3:#8a887f; --border:#3a3933;
    --accent:#3987e5; --shadow:0 1px 2px rgba(0,0,0,.2), 0 4px 16px rgba(0,0,0,.3);}
}
*{box-sizing:border-box;}
body{margin:0; background:var(--bg); color:var(--text);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  line-height:1.5; padding:24px 16px;}
body.no-scroll{overflow:hidden;}
a{color:var(--accent); text-decoration:none;}
a:hover{text-decoration:underline;}
.wrap{max-width:860px; margin:0 auto;}
.wrap.wide{max-width:1180px;}

/* Header */
.topbar{display:flex; justify-content:space-between; align-items:flex-start; gap:12px; margin-bottom:20px; flex-wrap:wrap;}
.topbar.dash-topbar{align-items:center;}
.topbar-title{min-width:0;}
.topbar-actions{display:flex; align-items:center; gap:8px;}
h1{font-size:22px; font-weight:600; margin:0 0 4px;}
h2{font-size:17px; font-weight:600; margin:24px 0 10px;}
.sub{color:var(--text-2); font-size:14px; margin:0;}
.logout-form{margin:0;}

/* Month navigator: prev arrow / clickable date label / next arrow, one row
   sitting in the top bar, aligned with the action buttons on the right. */
.month-nav{display:flex; align-items:center; gap:10px;}
.dash-month-btn{background:transparent; border:none; padding:0; margin:0; font-size:20px; font-weight:600;
  font-variant-numeric:tabular-nums; color:inherit; cursor:pointer; display:inline-flex; align-items:center; gap:5px;}
.dash-month-btn:hover{color:var(--accent);}
.dash-month-btn .ti{font-size:15px; color:var(--text-3);}
.month-nav-arrow{width:34px; height:34px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:var(--surface); border:0.5px solid var(--border); color:var(--text-2); font-size:16px; box-shadow:var(--shadow); flex:0 0 auto;}
.month-nav-arrow:hover{background:var(--surface-alt); color:var(--text); text-decoration:none;}
.month-nav-arrow.disabled{opacity:.3; cursor:default; pointer-events:none;}

/* Summary cards */
.cards{display:flex; gap:12px; margin-bottom:8px; flex-wrap:wrap;}
.card{background:var(--surface-alt); border-radius:10px; padding:14px 16px; flex:1; min-width:150px;}
.card .label{font-size:13px; color:var(--text-2);}
.card .val{font-size:24px; font-weight:600; margin-top:2px; font-variant-numeric:tabular-nums;}
.card .val.pos{color:var(--good);}
.card .val.neg{color:var(--danger);}
/* Second-currency companions: the small parenthesized conversion next to an
   amount (.amt2, inline) or under a summary-card number (.val-sub, block). */
.val-sub{font-size:12px; color:var(--text-3); margin-top:2px; font-variant-numeric:tabular-nums;}
.amt2{font-size:11px; font-weight:500; color:var(--text-3); white-space:nowrap;}

/* Email-confirmation status next to the settings email field. */
.warn-tag{font-size:11px; font-weight:600; color:var(--danger); margin-left:8px; white-space:nowrap;}
.verified-tag{font-size:11px; font-weight:600; color:var(--good); margin-left:8px; white-space:nowrap;}
.field-warn{display:flex; align-items:center; gap:6px; margin-top:6px; font-size:12px;
  color:var(--danger); background:color-mix(in srgb, var(--danger) 9%, transparent);
  border:0.5px solid color-mix(in srgb, var(--danger) 30%, transparent);
  border-radius:8px; padding:7px 10px;}
.field-warn a{color:var(--danger); font-weight:600;}
a.card{display:block; color:inherit; text-decoration:none;}
.card-toggle{border:2px solid transparent; cursor:pointer;}
.card-toggle:hover{text-decoration:none; filter:brightness(1.04);}
.card-toggle.active{border-color:var(--accent);}
.card-edit{color:var(--text-3); margin-left:5px; font-size:12px;}
.card-edit:hover{color:var(--accent); text-decoration:none;}
.tx-amt.pos{color:var(--good);}
.cat-tx td.amt.pos, td.amt.pos{color:var(--good);}

/* Two-column dashboard: categories block (left) + recent transactions (right) */
.dash{display:grid; grid-template-columns:minmax(0,1fr) 340px; gap:16px; align-items:start; margin:16px 0;}
.side-col{min-width:0;}
.side-col h2{margin-top:0;}
.side-col .row-between{margin-bottom:10px;}

/* Chart + category accordion */
.chart-card{background:var(--surface); border:0.5px solid var(--border); border-radius:12px;
  padding:20px; margin:16px 0; box-shadow:var(--shadow); display:flex; gap:24px; align-items:flex-start;}
.dash > .chart-card{margin:0;}
.pie-side{flex:0 0 320px; max-width:320px;}
.chart-canvas-wrap{position:relative; width:100%; aspect-ratio:1/1;}
.cat-side{flex:1; min-width:260px;}
.empty{color:var(--text-3); font-size:14px; padding:20px 0; text-align:center; margin:0;}

/* Daily spending chart (under the pie) */
.daily-card{margin-top:16px;}
.daily-title{font-size:12.5px; color:var(--text-2); margin-bottom:6px;}
.daily-wrap{position:relative; width:100%; height:170px;}

/* Sort switch above the category list */
.sort-row{display:flex; align-items:center; justify-content:space-between; gap:10px; margin:0 0 10px; padding:0 2px;}
.sort-label{font-size:13px; color:var(--text-2);}
.seg{display:inline-flex; border:0.5px solid var(--border); border-radius:8px; overflow:hidden; background:var(--surface);}
.seg-btn{font-family:inherit; font-size:12.5px; padding:6px 12px; border:none; background:transparent; color:var(--text-2); cursor:pointer; display:inline-block; text-decoration:none;}
.seg-btn:hover{text-decoration:none;}
.seg-btn + .seg-btn{border-left:0.5px solid var(--border);}
.seg-btn.active{background:var(--accent); color:var(--accent-ink);}

.cat-acc{border-bottom:0.5px solid var(--border);}
.cat-acc:last-child{border-bottom:none;}
.cat-head{width:100%; display:flex; align-items:center; gap:10px; background:transparent; border:none;
  color:var(--text); cursor:pointer; padding:10px 4px; font-family:inherit; text-align:left; border-radius:8px;}
.cat-head:hover{background:var(--surface-alt);}
.legend-dot{width:11px; height:11px; border-radius:3px; flex:0 0 auto;}
.chead-icon{font-size:17px; color:var(--text-2); width:20px; text-align:center; flex:0 0 auto;}
.legend-name{flex:1; min-width:0; font-size:14px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.legend-val{font-size:12.5px; color:var(--text-2); font-variant-numeric:tabular-nums; white-space:nowrap; flex:0 0 auto;}
.chev{font-size:16px; color:var(--text-3); transition:transform .15s; flex:0 0 auto;}
.cat-head[aria-expanded="true"] .chev{transform:rotate(180deg);}
.cat-panel{padding:2px 0 10px 30px;}
.cat-tx{width:100%; border-collapse:collapse; table-layout:fixed;}
.cat-tx tr{cursor:pointer;}
.cat-tx td{padding:7px 0; font-size:13px; border-top:0.5px solid var(--border);}
.cat-tx tr:first-child td{border-top:none;}
.cat-tx tr:hover td{color:var(--accent);}
.cat-tx td.date{color:var(--text-2); white-space:nowrap; width:80px; padding-right:12px;}
.cat-tx td.merch{padding-right:12px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.cat-tx td.amt{text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap; width:95px;}
/* The fixed 95px amount column can't fit "֏350,000 (€835.84)" on one line —
   stack the second-currency companion under the main amount instead of
   letting it spill past the panel edge. */
.cat-tx td.amt .amt2{display:block; margin-top:1px;}

/* Transaction list */
.tx-list{border:0.5px solid var(--border); border-radius:12px; overflow:hidden; background:var(--surface); box-shadow:var(--shadow);}
.tx{display:flex; align-items:center; gap:12px; padding:12px 16px; border-top:0.5px solid var(--border); cursor:pointer;}
.tx:first-child{border-top:none;}
.tx:hover{background:var(--surface-alt);}
.tx .icon{font-size:18px; color:var(--text-2); width:34px; height:34px; border-radius:9px;
  background:var(--surface-alt); display:flex; align-items:center; justify-content:center; flex:0 0 auto;}
.tx:hover .icon{background:var(--bg);}
.tx-body{flex:1; min-width:0;}
/* display:block is load-bearing: overflow/text-overflow do nothing on an
   inline span, so without it long names paint right over the amount. */
.tx-name{display:block; font-weight:600; font-size:14px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.tx-meta{font-size:12px; color:var(--text-3); display:flex; gap:8px; flex-wrap:wrap;}
.tx-right{display:flex; align-items:center; gap:10px; flex:0 0 auto;}
.tx-amt{font-weight:600; font-variant-numeric:tabular-nums; white-space:nowrap;}
.tx-edit{color:var(--text-3); font-size:16px;}
.tag{font-size:11px; padding:1px 7px; border-radius:20px; background:var(--surface-alt); color:var(--text-2);}

/* Date-group separator — a plain label between .review-cards, or a
   divider line when it sits inside a bordered .tx-list. */
.tx-date-sep{padding:14px 4px 6px; font-size:11px; font-weight:600; text-transform:uppercase;
  letter-spacing:.03em; color:var(--text-3);}
.tx-date-sep:first-child{padding-top:0;}
.tx-list .tx-date-sep{padding-left:16px; padding-right:16px; border-top:0.5px solid var(--border); margin-top:2px;}
.tx-list .tx-date-sep:first-child{border-top:none; margin-top:0; padding-top:14px;}
.tx-list .tx-date-sep + .tx{border-top:none;}

/* Review other transactions */
.review-card{background:var(--surface); border:0.5px solid var(--border); border-radius:12px;
  padding:14px 16px; margin-bottom:10px; box-shadow:var(--shadow); display:flex; align-items:center; gap:14px; flex-wrap:wrap;}
.review-info{flex:1; min-width:160px;}
.review-actions{display:flex; gap:8px; flex-wrap:wrap;}

/* Buttons */
.btn{display:inline-flex; align-items:center; gap:7px; font-size:14px; font-family:inherit;
  padding:9px 16px; border-radius:9px; border:0.5px solid var(--border); background:var(--surface);
  color:var(--text); cursor:pointer; white-space:nowrap;}
.btn:hover{background:var(--surface-alt); text-decoration:none;}
.btn.primary{background:var(--accent); color:var(--accent-ink); border-color:transparent;}
.btn.primary:hover{filter:brightness(1.05);}
.btn.danger{background:var(--danger); color:#fff; border-color:transparent;}
.btn.block{width:100%; justify-content:center;}
.btn.icon-btn{padding:9px 11px; color:var(--text-2);}

/* Add dropdown */
.dropdown{position:relative;}
.menu{position:absolute; right:0; top:calc(100% + 6px); background:var(--surface);
  border:0.5px solid var(--border); border-radius:12px; box-shadow:var(--shadow);
  min-width:230px; padding:6px; z-index:30; display:none;}
.menu.open{display:block;}
.menu a{display:flex; gap:11px; align-items:flex-start; padding:10px 12px; border-radius:9px; color:var(--text);}
.menu a:hover{background:var(--surface-alt); text-decoration:none;}
.menu a .icon{font-size:19px; color:var(--accent); width:22px; text-align:center; margin-top:1px;}
.menu a .mt{font-size:14px; font-weight:600;}
.menu a .md{font-size:12px; color:var(--text-3);}

/* Forms */
.panel{background:var(--surface); border:0.5px solid var(--border); border-radius:12px;
  padding:20px; box-shadow:var(--shadow); margin-top:8px;}
.formrow{margin-bottom:14px;}
.formrow label{display:block; font-size:13px; color:var(--text-2); margin-bottom:5px; font-weight:500;}
.field, .login-card input{width:100%; font-family:inherit; font-size:15px; color:var(--text); background:var(--bg);
  border:0.5px solid var(--border); border-radius:9px; padding:10px 12px; box-sizing:border-box;}
.field:focus, .login-card input:focus{outline:none; border-color:var(--accent);}
textarea.field{resize:vertical;}
select.field{
  -webkit-appearance:none; appearance:none;
  background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a887f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 12px center; background-size:16px;
  padding-right:36px;
}
.help{font-size:12px; color:var(--text-3); margin-top:4px;}
.errlist{color:var(--danger); font-size:12px; margin:4px 0 0; padding-left:16px;}
.actions{display:flex; gap:10px; margin-top:18px; align-items:center; flex-wrap:wrap;}
.receipt-preview{max-width:100%; border-radius:10px; border:0.5px solid var(--border); margin:0 0 12px;}
.muted{color:var(--text-3); font-size:13px;}
.row-between{display:flex; justify-content:space-between; align-items:center; gap:10px;}
.pager{display:flex; gap:10px; justify-content:center; margin-top:14px; font-size:14px;}

/* SMS auto-import setup (settings page) */
.copyrow{display:flex; gap:8px; align-items:center;}
.copyrow .field{flex:1; min-width:0; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13px;}
.setup-steps{font-size:14px; color:var(--text-2); padding-left:20px; margin:12px 0 0;}
.setup-steps li{margin-bottom:8px;}

/* Messages */
.msg{display:flex; align-items:center; gap:10px; padding:11px 14px; border-radius:10px; margin-bottom:10px; font-size:14px; border:0.5px solid var(--border);}
.msg > span{flex:1; min-width:0;}
.msg-close{flex:0 0 auto; background:none; border:none; cursor:pointer; color:inherit; opacity:.55;
  font-size:20px; line-height:1; padding:0 2px; border-radius:6px;}
.msg-close:hover{opacity:1;}
.msg.success{background:rgba(42,167,117,.12); border-color:rgba(42,167,117,.4);}
.msg.error{background:rgba(214,69,90,.12); border-color:rgba(214,69,90,.4);}
.msg.warning{background:rgba(224,168,0,.14); border-color:rgba(224,168,0,.4);}
.msg.info{background:rgba(42,120,214,.10); border-color:rgba(42,120,214,.35);}

/* Reconcile / review */
.review-banner{display:flex; align-items:center; gap:10px; margin:14px 0 0; padding:12px 16px;
  background:rgba(224,168,0,.12); border:0.5px solid rgba(224,168,0,.45); border-radius:12px; color:var(--text); font-size:14px;}
.review-banner:hover{text-decoration:none; background:rgba(224,168,0,.18);}
.review-banner > span{flex:1;}
.review-banner .ti-alert-triangle{color:#d89a00; font-size:19px;}
.dup-card{background:var(--surface); border:0.5px solid var(--border); border-radius:12px; padding:16px; margin-bottom:12px; box-shadow:var(--shadow);}
.dup-pair{display:flex; align-items:stretch; gap:12px;}
.dup-side{flex:1; min-width:0; background:var(--surface-alt); border-radius:10px; padding:12px 14px;}
.dup-tag{font-size:11px; text-transform:uppercase; letter-spacing:.03em; color:var(--text-3); margin-bottom:4px;}
.dup-name{font-weight:600; font-size:15px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.dup-meta{font-size:12px; color:var(--text-3); margin-top:2px;}
.dup-amt{font-size:18px; font-weight:600; font-variant-numeric:tabular-nums; margin-top:8px;}
.dup-vs{display:flex; align-items:center; color:var(--text-3); font-size:18px; flex:0 0 auto;}
.dup-actions{display:flex; gap:10px; margin-top:12px; flex-wrap:wrap;}
.dup-actions form{margin:0;}

/* Budgets / limits */
.review-banner.over{background:rgba(214,69,90,.12); border-color:rgba(214,69,90,.45);}
.review-banner.over .ti-alert-triangle{color:var(--danger);}
.budget-row{padding:14px 2px; border-top:0.5px solid var(--border);}
.budget-row:first-child{border-top:none;}
.budget-head{display:flex; justify-content:space-between; align-items:baseline; gap:10px;}
.budget-name{font-weight:600; font-size:15px;}
.budget-name .ti{color:var(--text-2); margin-right:4px;}
.budget-spent{font-variant-numeric:tabular-nums; white-space:nowrap;}
.budget-row .track{height:7px; background:var(--track); border-radius:4px; margin:8px 0 6px; overflow:hidden;}
.budget-row .fill{display:block; height:100%; background:var(--accent); border-radius:4px;}
.budget-row.near .fill{background:#e0a800;}
.budget-row.over .fill{background:var(--danger);}
.budget-meta{font-size:12px; margin-bottom:8px;}
.badge{font-size:11px; padding:2px 8px; border-radius:20px;}
.badge.near{background:rgba(224,168,0,.16); color:#b58a00;}
.badge.over{background:rgba(214,69,90,.16); color:var(--danger);}
.budget-input label{display:block; font-size:12px; color:var(--text-3); margin-bottom:4px;}
.budget-input .field{max-width:220px;}

/* Modal */
.modal-overlay{position:fixed; inset:0; background:rgba(0,0,0,.5); display:flex; align-items:flex-start;
  justify-content:center; padding:24px 14px; z-index:50; overflow:auto;}
.modal-overlay[hidden]{display:none;}
.modal{position:relative; background:var(--surface); border:0.5px solid var(--border); border-radius:14px;
  box-shadow:var(--shadow); width:min(560px,100%); padding:22px; margin:auto;}
.modal.large{width:min(720px,100%);}
.modal-x{position:absolute; top:8px; right:12px; background:transparent; border:none; color:var(--text-3);
  font-size:26px; line-height:1; cursor:pointer; padding:4px 8px;}
.modal-x:hover{color:var(--text);}
.modal-title{margin:0 0 14px; font-size:18px;}
.modal-actions .btn.danger{margin-left:auto;}
.modal-actions form{margin:0;}

/* Transaction history modal — a chart with two independent switches (metric
   on the left, time unit on the right) above the same-name transaction list. */
.history-controls{display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; margin-bottom:14px;}
.history-chart-wrap{position:relative; width:100%; height:220px; margin-bottom:4px;}

/* Below the "not enough room for a modal" threshold, a .large modal (like
   transaction history) takes over the full screen instead — same content,
   just filling the viewport like a page rather than floating as a card. */
@media (max-width:640px){
  .modal.large{position:fixed; inset:0; width:100%; height:100%; max-height:100%;
    border-radius:0; margin:0; padding:16px; overflow:auto;}
  .history-chart-wrap{height:200px;}
}

/* Login */
.login-body{display:flex; align-items:center; justify-content:center; min-height:100vh; padding:20px;}
.login-card{width:min(380px,100%); margin-top:0;}
.login-head{text-align:center; margin-bottom:18px;}
.login-head .ti{font-size:34px; color:var(--accent);}
.login-head h1{margin:8px 0 2px; font-size:20px;}
.login-actions .btn{flex:1; justify-content:center;}

/* Responsive */
@media (max-width:1024px){
  .dash{grid-template-columns:minmax(0,1fr);}
}
@media (max-width:720px){
  .chart-card{flex-direction:column; gap:18px;}
  .pie-side{flex:none; width:100%; max-width:340px; align-self:center;}
  .daily-wrap{height:160px;}
  .cat-side{width:100%; min-width:0;}
  .month-nav-arrow{width:30px; height:30px; font-size:14px;}
  /* The wrapped topbar puts the Add button at the LEFT edge, so a
     right-anchored menu would extend off-screen left — anchor left instead. */
  .menu{left:0; right:auto; max-width:calc(100vw - 24px);}
}
@media (max-width:560px){
  body{padding:16px 12px;}
  h1{font-size:20px;}
  .card{min-width:calc(50% - 6px);}
  .card .val{font-size:20px;}
  /* Phones: stack the second-currency amount under the main one so the
     transaction name keeps as much width as before the feature existed. */
  .tx .tx-amt{text-align:right;}
  .tx .tx-amt .amt2{display:block; margin-top:1px;}
  .modal{padding:18px 16px;}
  .modal-actions .btn{flex:1; justify-content:center;}
  .modal-actions .btn.danger{margin-left:0;}
  .sort-row{flex-direction:column; align-items:flex-start; gap:8px;}
  .dup-pair{flex-direction:column;}
  .dup-vs{transform:rotate(90deg); align-self:center;}
  .dup-actions .btn{flex:1; justify-content:center;}
  .review-card{flex-direction:column; align-items:stretch;}
  .review-actions .btn{flex:1; justify-content:center;}
  .month-nav-arrow{width:28px; height:28px; font-size:13px;}
  .dash-month-btn{font-size:17px;}
}
