  :root{
    /* ---- MONOCHROME: one jade-teal hue, expressed as a value ladder (LIGHT base) ---- */
    --bg:#eef4f0; --surface:#ffffff; --surface-2:#eef5f1; --surface-3:#e1ede7;
    --border:#d7e6df; --hair:#e7efeb;
    --text:#0d1e18; --text-2:#31473f; --muted:#5d7268;
    --accent:#0e9d68; --accent-strong:#0a7c52; --accent-fg:#ffffff; --accent-soft:rgba(14,157,104,.10);
    --surface-brand:radial-gradient(120% 110% at 100% 0%,rgba(14,157,104,.08),transparent 46%),var(--surface);
    --pos:#0e9d68; --pos-soft:rgba(14,157,104,.10);
    --neg:#075e3d; --neg-soft:rgba(7,94,61,.10);
    --calm:#6aa992;
    /* status ramp: reserved for budget severity only. ok reuses the brand jade; watch/over are the one deliberate warm hue added to the palette */
    --status-ok:var(--accent); --status-ok-soft:var(--accent-soft);
    --status-watch:#93701c; --status-watch-soft:rgba(147,112,28,.13);
    --status-over:#a8402a; --status-over-soft:rgba(168,64,42,.13);
    --shadow:0 1px 2px rgba(11,30,24,.06), 0 12px 30px -14px rgba(11,30,24,.20);
    --shadow-lg:0 30px 70px -30px rgba(11,30,24,.45);
    --font:-apple-system,BlinkMacSystemFont,"SF Pro Text","SF Pro Display","Segoe UI",Roboto,system-ui,sans-serif;
    /* radius scale: 4 tokens. the 40px icon circle (50%) and 56px FAB squircle are deliberate exceptions, kept literal */
    --r-xs:8px; --r-sm:12px; --r-md:18px; --r-lg:24px; --r-pill:999px;
    /* type scale: 8 steps, named by role rather than by component */
    --t-eyebrow:11px; --t-caption:12px; --t-body:13px; --t-control:15px; --t-subhead:17px; --t-section:20px; --t-stat:28px; --t-hero:40px;
    /* motion: 3 named steps, all routed through the reduced-motion kill switch below */
    --dur-tap:120ms; --dur-move:260ms; --dur-data:900ms;
  }
  @media (prefers-color-scheme:dark){
    :root{
      --bg:#0a1411; --surface:#0f1c18; --surface-2:#152621; --surface-3:#1b3029;
      --border:#243d34; --hair:#192b26;
      --text:#e4f0eb; --text-2:#b7ccc3; --muted:#738b82;
      --accent:#31c38b; --accent-strong:#4fdda4; --accent-fg:#04140e; --accent-soft:rgba(49,195,139,.11);
      --surface-brand:radial-gradient(120% 110% at 100% 0%,rgba(49,195,139,.08),transparent 46%),var(--surface);
      --pos:#31c38b; --pos-soft:rgba(49,195,139,.11);
      --neg:#68e0b2; --neg-soft:rgba(104,224,178,.14);
      --calm:#5d9180;
      --status-watch:#ceb255; --status-watch-soft:rgba(206,178,85,.14);
      --status-over:#db8065; --status-over-soft:rgba(219,128,101,.14);
      --shadow:0 1px 2px rgba(0,0,0,.34), 0 14px 34px -16px rgba(0,0,0,.62);
      --shadow-lg:0 40px 90px -30px rgba(0,0,0,.72);
    }
  }
  :root[data-theme="light"]{
    --bg:#eef4f0; --surface:#ffffff; --surface-2:#eef5f1; --surface-3:#e1ede7;
    --border:#d7e6df; --hair:#e7efeb;
    --text:#0d1e18; --text-2:#31473f; --muted:#5d7268;
    --accent:#0e9d68; --accent-strong:#0a7c52; --accent-fg:#ffffff; --accent-soft:rgba(14,157,104,.12);
    --pos:#0e9d68; --pos-soft:rgba(14,157,104,.12); --neg:#075e3d; --neg-soft:rgba(7,94,61,.12); --calm:#6aa992;
    --status-watch:#93701c; --status-watch-soft:rgba(147,112,28,.13);
    --status-over:#a8402a; --status-over-soft:rgba(168,64,42,.13);
    --shadow:0 1px 2px rgba(11,30,24,.06), 0 12px 30px -14px rgba(11,30,24,.20);
    --shadow-lg:0 30px 70px -30px rgba(11,30,24,.45);
  }
  :root[data-theme="dark"]{
    --bg:#0a1411; --surface:#0f1c18; --surface-2:#152621; --surface-3:#1b3029;
    --border:#243d34; --hair:#192b26;
    --text:#e4f0eb; --text-2:#b7ccc3; --muted:#738b82;
    --accent:#31c38b; --accent-strong:#4fdda4; --accent-fg:#04140e; --accent-soft:rgba(49,195,139,.11);
    --surface-brand:radial-gradient(120% 110% at 100% 0%,rgba(49,195,139,.08),transparent 46%),var(--surface);
    --pos:#31c38b; --pos-soft:rgba(49,195,139,.11); --neg:#68e0b2; --neg-soft:rgba(104,224,178,.14); --calm:#5d9180;
    --status-watch:#ceb255; --status-watch-soft:rgba(206,178,85,.14);
    --status-over:#db8065; --status-over-soft:rgba(219,128,101,.14);
    --shadow:0 1px 2px rgba(0,0,0,.34), 0 14px 34px -16px rgba(0,0,0,.62);
    --shadow-lg:0 40px 90px -30px rgba(0,0,0,.72);
  }

  *{box-sizing:border-box;}
  html,body{margin:0; overscroll-behavior-y:contain;}
  body{font-family:var(--font); background:var(--bg); color:var(--text); -webkit-font-smoothing:antialiased;
    text-rendering:optimizeLegibility;}
  body::before{content:''; position:fixed; z-index:0; inset:0 0 auto; height:calc(124px + env(safe-area-inset-top)); pointer-events:none;
    background:radial-gradient(70% 100% at 50% 0%,var(--accent-soft),transparent 72%); opacity:0; transition:opacity var(--dur-move);}
  body.is-pulling::before,body.is-refreshing::before{opacity:1;}
  .tnum{font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1;}
  ::selection{background:var(--accent-soft);}

  .app{max-width:480px; margin:0 auto; min-height:100dvh; position:relative;}
  .screen{display:none;} .screen.active{display:block;}
  .pad{padding:calc(14px + env(safe-area-inset-top)) 18px calc(120px + env(safe-area-inset-bottom));
    display:flex; flex-direction:column; gap:14px;}

  /* top bar */
  .topbar{display:flex; align-items:center; justify-content:space-between; padding:4px 2px 2px; gap:10px;}
  .topbar.topbar-nav{gap:8px;}
  .title{font-size:var(--t-section); font-weight:700; letter-spacing:-.02em;}
  .monthpick{font-family:var(--font); font-size:var(--t-control); font-weight:600; letter-spacing:-.01em; color:var(--text);
    background:var(--surface); border:1px solid var(--border); border-radius:var(--r-sm); padding:8px 12px; cursor:pointer;
    flex:1 1 auto; min-width:0; text-align:center; -webkit-appearance:none; appearance:none;}
  .monthpick::-webkit-calendar-picker-indicator{filter:grayscale(1) opacity(.5);}
  .toprow{display:flex; gap:8px; flex:0 0 auto;}
  .toprow.mrow{flex:1 1 auto; min-width:0;}
  .iconbtn{width:40px; height:40px; flex-shrink:0; border-radius:50%; border:1px solid var(--border); background:var(--surface);
    color:var(--text); display:grid; place-items:center; cursor:pointer; transition:background var(--dur-tap), transform var(--dur-tap);}
  .iconbtn:hover{background:var(--surface-2);} .iconbtn:active{transform:scale(.93);}

  /* cards + headings */
  .card{background:var(--surface-brand); border:1px solid var(--border); border-radius:var(--r-md); padding:18px; box-shadow:var(--shadow);}
  .eyebrow{font-size:var(--t-eyebrow); font-weight:600; letter-spacing:.09em; text-transform:uppercase; color:var(--muted);}
  .sec-h{display:flex; align-items:baseline; justify-content:space-between; margin:6px 2px -2px;}
  .link{background:none; border:none; color:var(--accent-strong); font-family:var(--font); font-size:var(--t-body);
    font-weight:600; cursor:pointer; padding:4px 2px; min-height:24px;}
  .link:hover{text-decoration:underline;}
  .muted{color:var(--muted);}

  /* hero */
  .hero{background:var(--surface-brand); padding:20px;}
  .hero-top{display:flex; align-items:center; justify-content:space-between;}
  .pill{display:inline-flex; align-items:center; gap:6px; font-size:var(--t-caption); font-weight:600; padding:5px 11px 5px 9px;
    border-radius:var(--r-pill); background:var(--pos-soft); color:var(--accent-strong);}
  .pill.bad{background:var(--neg-soft); color:var(--neg);}
  .pill .dot{width:7px; height:7px; border-radius:50%; background:currentColor;}
  .netfig{font-size:var(--t-hero); font-weight:700; letter-spacing:-.03em; line-height:1.04; margin:12px 0 0; color:var(--pos);}
  .netfig.neg{color:var(--neg);}
  .netfig .ccy{font-size:var(--t-section); font-weight:600; color:var(--muted); letter-spacing:0; margin-right:5px; vertical-align:4px;}
  .inout{display:flex; gap:20px; margin-top:12px; font-size:var(--t-body);}
  .inout .k{color:var(--muted); font-weight:500; margin-right:5px;}
  .inout b{font-weight:600;} .inout .up b{color:var(--pos);}
  .arrow{font-size:var(--t-eyebrow); margin-right:3px;} .up{color:var(--pos);}
  .hero hr{border:none; border-top:1px solid var(--hair); margin:16px 0;}
  .forecast{display:flex; align-items:center; gap:14px;}
  .forecast .ftxt .big{font-size:var(--t-control); font-weight:650; color:var(--text); letter-spacing:-.01em;}
  .forecast .ftxt .sub{font-size:var(--t-caption); color:var(--muted); margin-top:3px; line-height:1.45;}
  .ring{position:relative; width:60px; height:60px; flex:0 0 auto;}
  .ring svg{transform:rotate(-90deg);}
  .ring .track{stroke:var(--surface-3);}
  .ring .prog{stroke-linecap:round; stroke-dasharray:var(--circ); stroke-dashoffset:var(--circ);
    transition:stroke-dashoffset var(--dur-data) cubic-bezier(.22,1,.36,1);}
  .drawn .ring .prog{stroke-dashoffset:var(--target);}
  .ring .lbl{position:absolute; inset:0; display:grid; place-items:center; font-size:var(--t-body); font-weight:700; letter-spacing:-.02em;}

  /* budget rows */
  .attn{display:flex; flex-direction:column; gap:14px;}
  .brow .btop{display:flex; align-items:center; justify-content:space-between; font-size:var(--t-body); margin-bottom:7px; gap:8px;}
  .brow .cat{font-weight:600; display:flex; align-items:center; gap:7px; min-width:0;}
  .brow .cat .cdot{width:9px; height:9px; border-radius:3px; flex:0 0 auto;}
  .brow .vals{color:var(--muted); font-size:var(--t-caption); white-space:nowrap;} .brow .vals b{color:var(--text-2); font-weight:600;}
  .stchip{font-size:var(--t-eyebrow); font-weight:700; letter-spacing:.04em; text-transform:uppercase;
    padding:2px 7px; border-radius:var(--r-xs); margin-right:7px;}
  .stchip-ok{color:var(--status-ok); background:var(--status-ok-soft);}
  .stchip-watch{color:var(--status-watch); background:var(--status-watch-soft);}
  .stchip-over{color:var(--status-over); background:var(--status-over-soft);}
  .bar{height:8px; border-radius:5px; background:var(--surface-3); overflow:hidden;}
  .bar > span{display:block; height:100%; width:0; border-radius:5px; transition:width var(--dur-data) cubic-bezier(.22,1,.36,1);}
  .drawn .bar > span{width:var(--w);}
  .bar > span.hatch{background-image:repeating-linear-gradient(135deg, rgba(0,0,0,.16) 0 3px, transparent 3px 7px);}
  .budgetrow{display:grid; grid-template-columns:1fr 138px; gap:10px; align-items:center;}
  .budgetrow input{padding:7px 9px; font-size:var(--t-body); text-align:right;}
  .stepper{display:flex; align-items:stretch; border:1px solid var(--border); border-radius:10px; background:var(--surface-2); overflow:hidden;}
  .stepper button{width:36px; flex:0 0 auto; border:none; background:none; color:var(--accent-strong); font-size:16px; font-weight:650; cursor:pointer; padding:0; min-height:38px;}
  .stepper button:active{background:var(--surface-3);}
  .stepper input{border:none; border-radius:0; background:none; text-align:center; width:100%; min-width:0; padding:8px 0;}
  .stepper input:focus{box-shadow:none;}

  /* list rows */
  .rows{display:flex; flex-direction:column;}
  .r{display:flex; align-items:center; gap:12px; padding:12px 2px; border-bottom:1px solid var(--hair);}
  .r:last-child{border-bottom:none;}
  .r .ic{width:40px; height:40px; border-radius:var(--r-sm); flex:0 0 auto; display:grid; place-items:center; background:var(--surface-2); font-size:19px;}
  .r .ic.catic{background:color-mix(in srgb, var(--cat-color) 14%, var(--surface));}
  .r .mid{flex:1; min-width:0;}
  .r .mid .t{font-size:var(--t-control); font-weight:600; letter-spacing:-.01em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .r .mid .s{font-size:var(--t-caption); color:var(--muted); margin-top:2px; display:flex; align-items:center; gap:6px; flex-wrap:wrap;}
  .chip{font-size:var(--t-eyebrow); font-weight:500; color:var(--muted); background:var(--surface-2); border:1px solid var(--border); padding:1px 8px; border-radius:var(--r-pill);}
  .r .amt{font-size:var(--t-control); font-weight:650; letter-spacing:-.02em; white-space:nowrap; text-align:right;}
  .amt.out{color:var(--text);} .amt.in{color:var(--pos);}
  .due{font-size:var(--t-caption); color:var(--muted); white-space:nowrap; text-align:right;} .due b{display:block; color:var(--text-2); font-weight:600; font-size:var(--t-caption);}

  /* insights: donut + legend + trend + calendar */
  .chartbox{position:relative; height:200px;}
  .chartbox.skel::before{content:''; position:absolute; inset:22px; border-radius:50%; border:16px solid var(--surface-3); opacity:.5; animation:skel-pulse 1.4s ease-in-out infinite;}
  @keyframes skel-pulse{0%,100%{opacity:.35} 50%{opacity:.65}}
  #catlist{display:flex; flex-direction:column; gap:9px; margin-top:14px;}
  #catlist .lr{display:flex; align-items:center; gap:8px; font-size:var(--t-caption);}
  #catlist .lr .sw{width:9px; height:9px; border-radius:3px; flex:0 0 auto;}
  #catlist .lr .ln{flex:1; color:var(--text-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  #catlist .lr .lv{color:var(--muted); font-weight:600; white-space:nowrap;}
  .cal{display:grid; grid-template-columns:repeat(7,1fr); gap:5px; margin-top:4px;}
  .cal .dw{text-align:center; font-size:var(--t-eyebrow); color:var(--muted); padding-bottom:2px;}
  .cal .d{aspect-ratio:1; border-radius:var(--r-xs); background:var(--surface-2); display:flex; flex-direction:column;
    align-items:center; justify-content:center; font-size:var(--t-eyebrow); color:var(--text-2); gap:3px; position:relative;}
  .cal .d.today{outline:2px solid var(--accent); color:var(--text); font-weight:700;}
  .cal .d.fut{opacity:.5;}
  .cal .d .dots{display:flex; gap:2px;} .cal .d .dots i{width:4px; height:4px; border-radius:50%;}

  /* goals */
  .goal .gtop{display:flex; justify-content:space-between; align-items:baseline; font-size:var(--t-control); margin-bottom:8px; gap:8px;}
  .goal .gtop .gn{font-weight:600;} .goal .gtop .gv{font-size:var(--t-caption); color:var(--muted); white-space:nowrap;} .goal .gtop .gv b{color:var(--text-2);}
  .goal .gsub{display:flex; align-items:center; gap:8px; font-size:var(--t-caption); color:var(--muted); margin-top:8px;}

  /* forms */
  input, select, textarea{font-family:var(--font); background:var(--surface-2); color:var(--text);
    border:1px solid var(--border); border-radius:var(--r-sm); padding:11px 12px; font-size:var(--t-control); width:100%; -webkit-appearance:none; appearance:none;}
  input:focus, select:focus, textarea:focus{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft);}
  select{background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%237c948b' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>"); background-repeat:no-repeat; background-position:right 11px center; padding-right:34px;}
  label.fl{font-size:var(--t-eyebrow); font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); display:block; margin:0 0 6px 2px;}
  .form-row{display:flex; gap:10px;} .form-row > *{flex:1; min-width:0;}
  .field{display:flex; flex-direction:column;}
  .btn{padding:14px; border-radius:var(--r-sm); border:none; cursor:pointer; background:var(--accent); color:var(--accent-fg);
    font-family:var(--font); font-size:var(--t-control); font-weight:650; letter-spacing:-.01em; width:100%; transition:transform var(--dur-tap), filter var(--dur-tap);}
  .btn:hover{filter:brightness(1.05);} .btn:active{transform:scale(.99);}
  .btn:disabled{opacity:.4; cursor:not-allowed; filter:none;} .btn:disabled:hover{filter:none;} .btn:disabled:active{transform:none;}
  .btn.ghost{background:var(--surface-2); color:var(--text); border:1px solid var(--border);}
  .btn.sm{padding:9px 14px; font-size:var(--t-body); width:auto; border-radius:var(--r-sm);}
  .seg{display:flex; background:var(--surface-2); border:1px solid var(--border); border-radius:var(--r-sm); padding:3px; gap:3px;}
  .seg button{flex:1; background:none; border:none; color:var(--muted); font-family:var(--font); font-size:var(--t-body); font-weight:600;
    padding:8px; border-radius:9px; cursor:pointer;}
  .seg button.on{background:var(--surface); color:var(--text); box-shadow:var(--shadow);}
  .xbtn{background:none; border:none; color:var(--muted); cursor:pointer; font-size:var(--t-control); padding:9px 10px; line-height:1; min-width:24px; min-height:24px;}
  .xbtn:hover{color:var(--neg);}

  /* filter chips + search */
  .search{display:flex; align-items:center; gap:9px; background:var(--surface); border:1px solid var(--border); border-radius:14px; padding:0 14px; color:var(--muted);}
  .search input{border:none; background:none; padding:12px 0; box-shadow:none;}
  .search input:focus{box-shadow:none;}
  .filter{display:flex; gap:7px; overflow-x:auto; padding:2px 0; scrollbar-width:none;}
  .filter::-webkit-scrollbar{display:none;}
  .fchip{flex:0 0 auto; display:inline-flex; align-items:center; gap:6px; font-size:var(--t-body); font-weight:550; padding:7px 14px;
    border-radius:var(--r-pill); border:1px solid var(--border); background:var(--surface); color:var(--text-2); cursor:pointer; white-space:nowrap;
    font-family:var(--font);}
  .fchip.on{background:var(--text); color:var(--bg); border-color:var(--text);}

  /* activity swipe rows */
  .swipe{position:relative; overflow:hidden; border-radius:var(--r-md);}
  .swipe .del{position:absolute; inset:0 0 0 auto; width:88px; background:var(--status-over); color:#fff;
    display:flex; align-items:center; justify-content:center; font-size:var(--t-body); font-weight:600; cursor:pointer;}
  .swipe .face{position:relative; background:var(--surface-brand); border:1px solid var(--border); border-radius:var(--r-md);
    min-height:66px; padding:12px 14px; display:flex; align-items:center; gap:12px; box-shadow:var(--shadow);
    transition:transform var(--dur-move) cubic-bezier(.22,1,.36,1); touch-action:pan-y;}
  .swipe .face .mid .s{line-height:1.4;}
  .swipe .face .amt{flex:0 0 auto; max-width:36%;}
  .swipe.dragging .face{will-change:transform;}
  .swipe.open .face{transform:translateX(-88px);}
  .txlist{display:flex; flex-direction:column; gap:10px;}
  .r-amt-sub{font-size:var(--t-eyebrow); color:var(--muted); font-weight:400; text-align:right; margin-top:1px;}

  /* settings list */
  .slist{display:flex; flex-direction:column; background:var(--surface-brand); border:1px solid var(--border); border-radius:var(--r-md); overflow:hidden;}
  .si{display:flex; align-items:center; gap:13px; padding:14px 16px; border:none; border-bottom:1px solid var(--hair); cursor:pointer; background:none; width:100%; text-align:left; font-family:var(--font);}
  .si:last-child{border-bottom:none;} .si:hover{background:var(--surface-2);}
  .si .sic{width:30px; height:30px; border-radius:9px; background:var(--accent-soft); color:var(--accent-strong); display:grid; place-items:center; font-size:var(--t-control); flex:0 0 auto;}
  .si .sl{flex:1; min-width:0;} .si .sl .a{font-size:var(--t-control); font-weight:550; color:var(--text);} .si .sl .b{font-size:var(--t-caption); color:var(--muted); margin-top:1px;}
  .si .chev{color:var(--muted);}
  .switch{width:44px; height:26px; border-radius:var(--r-pill); background:var(--surface-3); position:relative; cursor:pointer; transition:background var(--dur-move); border:1px solid var(--border); flex:0 0 auto;}
  .switch.on{background:var(--pos);} .switch i{position:absolute; top:2px; left:2px; width:20px; height:20px; border-radius:50%; background:#fff; transition:transform var(--dur-move); box-shadow:0 1px 3px rgba(0,0,0,.3);}
  .switch.on i{transform:translateX(18px);}
  .switch:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
  .collapse{display:none; flex-direction:column; gap:12px; padding-top:4px;} .collapse.open{display:flex;}

  .hint{font-size:var(--t-caption); color:var(--muted); line-height:1.5;} .hint b{color:var(--text-2); font-weight:600;}
  code{background:var(--surface-2); border:1px solid var(--border); border-radius:5px; padding:1px 5px; font-size:var(--t-caption);}
  pre.digest{background:var(--surface-2); border:1px solid var(--border); border-radius:var(--r-sm); padding:14px; font-size:var(--t-body); white-space:pre-wrap; margin:0; line-height:1.55; font-family:ui-monospace,Menlo,Consolas,monospace;}
  .tblwrap{overflow-x:auto; -webkit-overflow-scrolling:touch;} .tblwrap::-webkit-scrollbar{height:6px;}
  table.imp{width:100%; border-collapse:collapse; font-size:var(--t-caption); min-width:460px;}
  table.imp th, table.imp td{padding:7px 6px; border-bottom:1px solid var(--hair); text-align:left; white-space:nowrap;}
  table.imp th{color:var(--muted); font-size:var(--t-eyebrow); font-weight:600;}
  table.imp td.a{text-align:right; font-variant-numeric:tabular-nums; font-weight:600;}
  .badge-new{color:var(--accent-strong); font-weight:600;} .badge-dup{color:var(--muted);}

  /* quick-add photo attach */
  .photo-prev{display:flex; align-items:center; gap:10px;}
  .photo-prev img{width:52px; height:52px; object-fit:cover; border-radius:10px; border:1px solid var(--border); flex:0 0 auto;}

  /* household avatars + member chips */
  .avatar{width:20px; height:20px; border-radius:50%; flex:0 0 auto; display:inline-grid; place-items:center;
    font-size:var(--t-eyebrow); font-weight:700; color:#fff; letter-spacing:.02em; text-transform:uppercase;}
  .avatar.lg{width:30px; height:30px; font-size:var(--t-body);}
  .together{display:flex; flex-direction:column; gap:14px;}
  .together .trow .ttop{display:flex; align-items:center; gap:9px; font-size:var(--t-body); margin-bottom:7px;}
  .together .trow .tn{font-weight:600; flex:1;}
  .together .trow .tv{color:var(--muted); font-size:var(--t-caption);} .together .trow .tv b{color:var(--text-2); font-weight:600;}

  /* tappable transaction rows */
  .r[tabindex], .swipe .face{cursor:pointer;}
  .r[tabindex]:focus-visible, .swipe .face:focus-visible{outline:2px solid var(--accent); outline-offset:2px; border-radius:var(--r-sm);}

  /* setup checklist (partner onboarding) */
  .steps{display:flex; flex-direction:column; gap:2px;}
  .step{display:flex; align-items:center; gap:12px; padding:10px 0;}
  .step .n{width:26px; height:26px; border-radius:50%; flex:0 0 auto; display:grid; place-items:center;
    font-size:var(--t-caption); font-weight:700; background:var(--surface-3); color:var(--text-2);}
  .step.done .n{background:var(--pos); color:var(--accent-fg);}
  .step .st{flex:1; min-width:0;} .step .st .a{font-size:var(--t-control); font-weight:600;} .step .st .b{font-size:var(--t-caption); color:var(--muted); margin-top:1px; line-height:1.45;}
  .step.done .st .a{color:var(--muted); text-decoration:line-through; font-weight:500;}

  /* digest sheet */
  .dgst{display:flex; flex-direction:column; gap:14px;}
  .dgst .dcard{background:var(--surface-2); border:1px solid var(--border); border-radius:var(--r-sm); padding:14px;}
  .dgst .dline{display:flex; align-items:baseline; justify-content:space-between; gap:10px; font-size:var(--t-body); padding:4px 0;}
  .dgst .dline .dk{color:var(--muted);} .dgst .dline b{font-weight:650;}

  /* bottom nav */
  .tabbar{position:fixed; bottom:0; left:50%; transform:translateX(-50%); width:100%; max-width:480px; z-index:15;
    height:calc(56px + env(safe-area-inset-bottom)); padding-bottom:env(safe-area-inset-bottom);
    display:flex; align-items:center; justify-content:space-around;
    background:color-mix(in srgb, var(--surface) 84%, transparent);
    backdrop-filter:saturate(1.6) blur(18px); -webkit-backdrop-filter:saturate(1.6) blur(18px); border-top:1px solid var(--hair);}
  .tab{flex:1; display:flex; flex-direction:column; align-items:center; gap:3px; background:none; border:none; color:var(--muted);
    font-family:var(--font); font-size:var(--t-eyebrow); font-weight:550; cursor:pointer; padding:6px 0;}
  .tab.on{color:var(--accent-strong);} .tab svg{display:block;}
  .fab{flex:0 0 auto; width:56px; height:56px; margin-top:-20px; border-radius:20px; border:none; cursor:pointer;
    background:linear-gradient(160deg, var(--accent), var(--accent-strong)); color:var(--accent-fg); display:grid; place-items:center;
    box-shadow:0 10px 22px -6px color-mix(in srgb, var(--accent) 55%, transparent); transition:transform var(--dur-tap);}
  .fab:active{transform:scale(.92);}

  /* sheets + modal */
  .scrim{position:fixed; inset:0; background:rgba(4,10,8,.5); opacity:0; pointer-events:none; transition:opacity var(--dur-move); z-index:20;}
  .scrim.show{opacity:1; pointer-events:auto;}
  /* Hidden sheets need visibility:hidden, not just translateY(102%): the translate only
     clears the screen while bottom is 0, and bottom rides up with --kb-offset — so with a
     keyboard (or its stuck aftermath) every hidden sheet peeked in from the bottom edge,
     the last one in the DOM (the invite sheet) painting on top. Same lesson as .updatebar. */
  .sheet{position:fixed; left:50%; transform:translateX(-50%) translateY(102%); bottom:var(--kb-offset,0px); width:100%; max-width:480px; z-index:21;
    background:var(--surface); border-radius:var(--r-lg) var(--r-lg) 0 0; padding:10px 20px calc(24px + env(safe-area-inset-bottom));
    visibility:hidden;
    transition:transform var(--dur-move) cubic-bezier(.22,1,.36,1), visibility 0s var(--dur-move); box-shadow:0 -20px 50px -20px rgba(0,0,0,.5);
    max-height:min(92dvh, calc(var(--vvh, 100dvh) - 28px)); overflow-y:auto;}
  /* ^ height is capped by the VISUAL viewport, not 100dvh - kb-offset: when iOS shifts
     the viewport chasing a focused caret, kb-offset shrinks and a dvh-based cap grows
     right as the visible space shrinks — letting the sheet's top edge clip off-screen.
     With the bottom pinned to the keyboard, height <= vvh keeps the top on screen. */
  .sheet.show{transform:translateX(-50%) translateY(0); visibility:visible;
    transition:transform var(--dur-move) cubic-bezier(.22,1,.36,1);}
  .sheet.notrans{transition:none;}
  .grab{width:38px; height:5px; border-radius:3px; background:var(--surface-3); margin:2px auto 14px;}
  .sheet h3{margin:0 0 14px; font-size:var(--t-subhead); letter-spacing:-.01em;}
  .sheet .stack{display:flex; flex-direction:column; gap:12px;}
  .amtin{display:flex; align-items:center; justify-content:center; gap:8px; padding:8px 0;}
  .amtin .c{font-size:var(--t-stat); color:var(--muted); font-weight:600;}
  .amtin select.ccy-pick{width:auto; border:none; background-color:var(--surface-2); border-radius:10px; font-size:var(--t-subhead); font-weight:650;
    color:var(--muted); padding:6px 22px 6px 10px; background-position:right 6px center; background-size:13px; flex:0 0 auto;}
  .amtin input{font-size:var(--t-hero); font-weight:700; letter-spacing:-.03em; text-align:center; border:none; background:none; padding:0; width:auto; max-width:210px;}
  .amtin input:focus{box-shadow:none;}
  .note{font-size:var(--t-caption); color:var(--muted); text-align:center; margin-top:6px; line-height:1.5;} .note b{color:var(--accent-strong);}
  .modal{position:fixed; left:50%; top:50%; transform:translate(-50%,-46%); width:min(340px,88vw); z-index:22; background:var(--surface);
    border:1px solid var(--border); border-radius:var(--r-lg); padding:22px; box-shadow:var(--shadow-lg); opacity:0; pointer-events:none; transition:opacity var(--dur-move), transform var(--dur-move);}
  .modal.show{opacity:1; pointer-events:auto; transform:translate(-50%,-50%);}
  .modal h4{margin:0 0 6px; font-size:var(--t-subhead);} .modal p{margin:0 0 18px; font-size:var(--t-body); color:var(--muted); line-height:1.5;}
  .modal .mrow{display:flex; gap:10px;}
  .toast{position:fixed; left:50%; bottom:calc(76px + env(safe-area-inset-bottom)); transform:translateX(-50%) translateY(16px);
    background:var(--text); color:var(--bg); font-size:var(--t-body); font-weight:600; padding:11px 18px; border-radius:var(--r-sm); z-index:30;
    opacity:0; pointer-events:none; transition:opacity var(--dur-move), transform var(--dur-move); box-shadow:var(--shadow-lg); max-width:90vw; text-align:center;}
  .toast.show{opacity:1; transform:translateX(-50%) translateY(0);}
  .pullrefresh{position:fixed; left:50%; top:calc(10px + env(safe-area-inset-top)); z-index:36;
    display:flex; flex-direction:column; align-items:center; gap:5px; color:var(--muted);
    font-size:var(--t-caption); font-weight:600; white-space:nowrap; pointer-events:none;
    opacity:0; visibility:hidden; transform:translateX(-50%) translateY(-12px) scale(.9);
    transition:transform var(--dur-tap),opacity var(--dur-tap),visibility 0s var(--dur-tap);}
  .pullrefresh.show{opacity:1; visibility:visible; transform:translateX(-50%) translateY(0) scale(1);
    transition:transform var(--dur-tap),opacity var(--dur-tap);}
  .pullrefresh svg{box-sizing:border-box; width:34px; height:34px; padding:8px; border-radius:50%;
    background:var(--surface); color:var(--accent-strong); border:1px solid color-mix(in srgb,var(--accent) 32%,var(--border));
    box-shadow:var(--shadow); transition:transform var(--dur-move),background var(--dur-move),color var(--dur-move);}
  .pullrefresh.ready{color:var(--accent-strong);}
  .pullrefresh.ready svg{background:var(--accent); color:var(--accent-fg); border-color:transparent;}
  .pullrefresh.ready svg{transform:rotate(180deg);}
  .pullrefresh.refreshing svg{animation:sp .7s linear infinite;}
  /* App updates use a compact snackbar above the tab bar, keeping the month controls clear. */
  .updatebar{position:fixed; left:50%; bottom:calc(74px + env(safe-area-inset-bottom));
    width:min(320px,calc(100vw - 32px)); min-height:58px; padding:9px 11px 9px 10px;
    transform:translateX(-50%) translateY(14px) scale(.98); z-index:35;
    display:flex; align-items:center; gap:10px; text-align:left; font-family:var(--font); color:var(--text);
    background:color-mix(in srgb,var(--surface) 92%,transparent); border:1px solid color-mix(in srgb,var(--accent) 28%,var(--border));
    border-radius:var(--r-md); box-shadow:0 18px 44px -20px rgba(0,0,0,.65),0 4px 14px rgba(0,0,0,.18);
    backdrop-filter:saturate(1.35) blur(18px); -webkit-backdrop-filter:saturate(1.35) blur(18px);
    opacity:0; visibility:hidden; pointer-events:none; cursor:pointer;
    transition:transform var(--dur-move) cubic-bezier(.22,1,.36,1),opacity var(--dur-move),visibility 0s var(--dur-move);}
  .updatebar.show{transform:translateX(-50%) translateY(0) scale(1); opacity:1; visibility:visible; pointer-events:auto;
    transition:transform var(--dur-move) cubic-bezier(.22,1,.36,1),opacity var(--dur-move);}
  .updatebar:hover{background:color-mix(in srgb,var(--surface) 96%,var(--accent-soft));}
  .updatebar:active{transform:translateX(-50%) translateY(1px) scale(.985);}
  .updatebar:focus-visible{outline:2px solid var(--accent); outline-offset:3px;}
  .updatebar:disabled{cursor:wait;}
  .updatebar-icon{width:36px; height:36px; flex:0 0 auto; display:grid; place-items:center; border-radius:11px;
    background:var(--accent-soft); color:var(--accent-strong);}
  .updatebar-icon svg{width:19px; height:19px;}
  .updatebar-copy{flex:1; min-width:0; display:flex; flex-direction:column; gap:1px;}
  .updatebar-title{font-size:var(--t-control); line-height:1.2; font-weight:650; letter-spacing:-.01em;}
  .updatebar-sub{font-size:var(--t-caption); line-height:1.25; color:var(--muted); font-weight:500;}
  .updatebar-arrow{width:18px; height:18px; flex:0 0 auto; color:var(--muted);}
  .updatebar.updating .updatebar-icon svg{animation:sp .7s linear infinite;}
  .updatebar.updating .updatebar-arrow{opacity:0;}
  body:has(.updatebar.show) .toast{bottom:calc(146px + env(safe-area-inset-bottom));}
  .empty{color:var(--muted); font-size:var(--t-body); padding:10px 2px; text-align:center;}

  /* rich empty states — one shared shape for every "nothing here yet" moment */
  .emptybox{display:flex; flex-direction:column; align-items:center; text-align:center; gap:3px; padding:28px 18px;}
  .emptybox .eico{width:48px; height:48px; border-radius:50%; display:grid; place-items:center; font-size:22px; line-height:1;
    background:var(--surface-2); border:1px solid var(--border); color:var(--text-2); margin-bottom:9px;}
  .emptybox.good .eico{background:var(--pos-soft); border-color:transparent; color:var(--accent-strong);}
  .emptybox.warn .eico{background:var(--status-over-soft); border-color:transparent; color:var(--status-over);}
  .emptybox .etitle{font-size:var(--t-control); font-weight:650; letter-spacing:-.01em; color:var(--text);}
  .emptybox .esub{font-size:var(--t-caption); color:var(--muted); line-height:1.5; max-width:33ch;}
  .emptybox .btn{width:auto; margin-top:13px;}

  /* loading skeletons — value-ladder placeholders that mirror the real layout, then a sweep of light */
  .sk{position:relative; overflow:hidden; background:var(--surface-3); border-radius:var(--r-xs);}
  .sk::after{content:''; position:absolute; inset:0; transform:translateX(-100%);
    background:linear-gradient(90deg, transparent, color-mix(in srgb, var(--text) 7%, transparent), transparent);
    animation:sk-shimmer 1.5s ease-in-out infinite;}
  @keyframes sk-shimmer{100%{transform:translateX(100%);}}
  .sk-line{height:11px; border-radius:6px;}
  .sk-circle{border-radius:50%;}
  .skrow{display:flex; align-items:center; gap:12px; padding:12px 2px; border-bottom:1px solid var(--hair);}
  .skrow:last-child{border-bottom:none;}
  .skrow .skmid{flex:1; display:flex; flex-direction:column; gap:7px;}
  #lockScreen{position:fixed; inset:0; z-index:60; display:none; background:var(--bg); flex-direction:column; align-items:center; justify-content:center; gap:16px;}
  #lockScreen.show{display:flex;}
  #lockPin{width:160px; text-align:center; font-size:var(--t-stat); letter-spacing:8px;}
  .spin{display:inline-block; width:16px; height:16px; border:2px solid var(--accent-soft); border-top-color:var(--accent); border-radius:50%; animation:sp .7s linear infinite;}
  @keyframes sp{to{transform:rotate(360deg);}}
  /* AI assistant */
  .ai-card{background:linear-gradient(150deg,var(--accent-soft),transparent 60%),var(--surface);}
  .ai-chips{display:flex; gap:8px; flex-wrap:wrap; margin-top:10px;}
  #aiSheet{display:flex; flex-direction:column; height:84dvh;}
  #aiThread{flex:1; overflow-y:auto; display:flex; flex-direction:column; gap:10px; padding:2px 1px 12px; overscroll-behavior:contain;}
  .msg{max-width:88%; padding:10px 14px; border-radius:16px; font-size:var(--t-body); line-height:1.55; word-break:break-word;}
  .msg .txt{white-space:pre-wrap;}
  .msg.me{align-self:flex-end; background:var(--accent-strong); color:#fff; border-bottom-right-radius:5px;}
  .msg.bot{align-self:flex-start; background:var(--surface-2); border-bottom-left-radius:5px;}
  .msg.bot .made{background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:1px 12px; margin-top:8px;}
  .msg.bot .made .r{border-bottom:none; padding:10px 0; cursor:pointer;}
  .msg.bot .made .r + .r{border-top:1px solid var(--hair);}
  .msg.bot .made.undone .r{opacity:.45; text-decoration:line-through; cursor:default;}
  .ai-inrow{display:flex; gap:8px; padding-top:10px; border-top:1px solid var(--hair); align-items:center;}
  .ai-inrow input{flex:1;}
  @media (prefers-reduced-motion:reduce){ *{transition:none !important; animation:none !important;} .ring .prog{stroke-dashoffset:var(--target);} .bar > span{width:var(--w);} }
