:root{color-scheme:dark;--bg:#0f1a2b;--panel:#152238;--panel-2:#1b2b45;--ink:#eef3fa;--muted:#a7b6cc;--line:#26395a;--accent:#f2b134;--btn:#f2b134;--btn-ink:#1a1200;--good:#3fc380;--warn:#f2b134;--bad:#ff6b6b;--link:#8fc1ff;--cold:#5b78a8;--r:14px;--gutter:16px;--chrome:112px;font-size:16px}
@media (prefers-color-scheme: light){:root{color-scheme:light;--bg:#f4f6fa;--panel:#ffffff;--panel-2:#e9eef6;--ink:#0f1a2b;--muted:#54657f;--line:#d3dbe8;--accent:#8a5600;--warn:#8a5600;--good:#14784a;--bad:#c62828;--link:#1c5fd0;--cold:#3a4c6d}}
*{box-sizing:border-box}html,body{margin:0;padding:0}
body{background:var(--bg);color:var(--ink);font:16px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,Helvetica,Arial,sans-serif;padding-bottom:calc(72px + env(safe-area-inset-bottom));-webkit-text-size-adjust:100%;accent-color:var(--accent)}
a{color:var(--link);text-decoration:none}a:hover{text-decoration:underline}
::selection{background:var(--accent);color:var(--btn-ink)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.chrome{position:sticky;top:0;z-index:5;background:var(--bg)}
header.top{padding:calc(12px + env(safe-area-inset-top)) var(--gutter) 10px;border-bottom:1px solid var(--line)}
.brand{display:flex;align-items:center;gap:8px;color:var(--muted);font-size:13px;letter-spacing:.02em;text-transform:uppercase;min-width:0}
/* One line of chrome, always: a long client name or a long person name truncates rather than pushing the screen's title down the phone. */
.brand>span:not(.dot){overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:3em}
.brand>span:not(.dot):not(.who){flex:0 2 auto}
.brand .dot{width:8px;height:8px;border-radius:50%;background:var(--accent);display:inline-block}
header h1{margin:4px 0 0;font-size:22px;font-weight:700;letter-spacing:-.01em}
.stamp{color:var(--muted);font-size:14px;margin-top:2px}.stamp.warn{color:var(--warn)}.stamp.bad{color:var(--bad);font-weight:600}
main{padding:12px var(--gutter) 24px;max-width:1100px;margin:0 auto}
/* The two roster screens ask for a wider desk; the phone is unaffected. */
@media (min-width:1200px){body.wide main{max-width:1320px}}
.cards{display:grid;grid-template-columns:1fr;gap:12px}
@media (min-width:720px){.cards{grid-template-columns:1fr 1fr}}
@media (min-width:1040px){.cards{grid-template-columns:1fr 1fr 1fr}}
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:14px 14px 10px}
.card h2{margin:0 0 8px;font-size:15px;color:var(--muted);font-weight:600;text-transform:uppercase;letter-spacing:.04em}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.stat{display:block;padding:10px 6px;border-radius:10px;background:var(--panel-2);text-align:center;color:inherit;min-height:72px}
a.stat:hover{text-decoration:none;outline:1px solid var(--line)}
.stat b.n{display:block;font-size:32px;line-height:1.05;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.stat span{display:block;font-size:13px;color:var(--muted);margin-top:4px;line-height:1.2}
.stat.bad b.n{color:var(--bad)}.stat.warn b.n{color:var(--warn)}.stat.good b.n{color:var(--good)}
@media (min-width:720px){.stat b.n{font-size:28px}}
.note{color:var(--muted);font-size:14px;margin:8px 0 0;max-width:68ch}
.line{margin:8px 0;font-size:14px;color:var(--muted);max-width:68ch}
/* The manager's first line in a meeting: bigger than a caption, numbers set to be counted. */
.line.overnight{max-width:none;font-size:15px;color:var(--ink);line-height:1.55;margin:4px 0 12px}
.line.overnight b{font-variant-numeric:tabular-nums}
.line.overnight .go{white-space:nowrap;font-weight:600}
.bands{display:flex;gap:6px;flex-wrap:wrap;margin:8px 0}
.band{background:var(--panel-2);border-radius:999px;padding:7px 12px;font-size:14px;color:var(--ink);min-height:36px;display:inline-flex;align-items:center;gap:4px}
.band b{font-weight:700;font-variant-numeric:tabular-nums}
a.band{color:var(--ink)}a.band:hover{text-decoration:none;outline:1px solid var(--line)}
.band.on{background:var(--btn);color:var(--btn-ink)}
table{width:100%;border-collapse:collapse;font-size:14px;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);overflow:hidden;font-variant-numeric:tabular-nums}
thead th{text-align:left;font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;padding:10px 10px;border-bottom:1px solid var(--line)}
tbody td{padding:10px;border-bottom:1px solid var(--line);vertical-align:top}
tbody tr:last-child td{border-bottom:0}
tr.breach td:first-child,tr.p1 td:first-child{box-shadow:inset 3px 0 0 var(--bad)}
/* The delinquency ledger: one column grid across every bucket, so the amounts stack into a single readable column. */
table.ledger{table-layout:fixed}
table.ledger th:first-child{width:52%}
table.ledger th:nth-child(2){width:20%}
table.ledger td:nth-child(2){text-align:right}
table.ledger td:last-child{text-align:right}
.amt{font-size:19px;font-weight:700;letter-spacing:-.01em;font-variant-numeric:tabular-nums;white-space:nowrap}
/* A count of nothing is not news: zeros recede so the manager's eye lands on the numbers that moved. */
.z{color:var(--muted)}
.pill{display:inline-block;border-radius:999px;padding:3px 9px;font-size:12px;font-weight:600;background:var(--panel-2);color:var(--ink);line-height:1.3}
.pill.p1{background:var(--bad);color:#fff}.pill.p2{background:var(--warn);color:var(--btn-ink)}.pill.p3{background:var(--panel-2)}
.pill.cold{background:var(--cold);color:#fff}.pill.robot{background:var(--panel-2);color:var(--muted)}
.pill.proposed{background:transparent;border:1px solid var(--line);color:var(--muted)}
.pill.guess{background:#3d2f12;color:var(--accent);border:1px solid #6a5220}
.pill.set{background:#12362a;color:var(--good);border:1px solid #1f5a45}
@media (prefers-color-scheme: light){.pill.guess{background:#fff4d6;border-color:#c99a2e}.pill.set{background:#dff6ea;border-color:#4fa87a}.pill.p2{color:#fff}}
.muted{color:var(--muted)}.small{font-size:13px}
@media (max-width:640px){table,thead,tbody{display:block}thead{display:none}tbody tr{display:flex;flex-wrap:wrap;gap:4px 12px;align-items:center;border-bottom:1px solid var(--line);padding:10px 12px}tbody td{display:block;border:0;padding:0}tbody td:first-child{flex:1 0 100%;font-size:16px;font-weight:600;order:0}tbody td:first-child .small{font-weight:400}tbody td[data-l]:not(:first-child)::before{content:attr(data-l) " · ";color:var(--muted);font-size:12px}tbody td[data-l="Priority"],tbody td[data-l="Clock"],tbody td[data-l="Pri"]{order:-1;flex:0 0 auto}tbody td[data-l="Priority"]::before,tbody td[data-l="Clock"]::before{content:none}
/* The desk on a phone: unit on its own line, then the amount, then the way into AppFolio. */
table.ledger td:nth-child(2),table.ledger td:last-child{text-align:left}
tr.breach,tr.p1{box-shadow:inset 3px 0 0 var(--bad)}tr.breach td:first-child,tr.p1 td:first-child{box-shadow:none}}
.rule{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:12px 14px;margin:0 0 10px;scroll-margin-top:calc(var(--chrome) + env(safe-area-inset-top))}
.rule .k{display:flex;justify-content:space-between;gap:8px;align-items:baseline;flex-wrap:wrap}
.rule .k strong{font-size:16px}.rule .k code{font-size:12px;color:var(--muted)}
.rule .basis{color:var(--muted);font-size:14px;margin:6px 0 8px}
.rule .row{display:flex;gap:8px;align-items:stretch}
/* Read-only (owners): the value the control would have carried, as plain text. */
.rule .value{font-size:16px;white-space:pre-wrap;overflow-wrap:anywhere}
.rule .value pre{margin:0;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap}
.rule .hint{color:var(--muted);font-size:13px;margin-top:6px}
.rule .err{color:var(--bad);font-size:14px;margin-top:6px;font-weight:600}
form.rule button{background:var(--panel-2);color:var(--ink)}form.rule.dirty button{background:var(--btn);color:var(--btn-ink)}
/* Every field in the system looks like the system: an email box is not a browser default next to a designed one. */
input[type=text],input[type=email],input[type=number],input[type=date],textarea{width:100%;background:var(--panel-2);color:var(--ink);border:1px solid var(--line);border-radius:10px;padding:12px;font:inherit;min-height:44px;caret-color:var(--accent)}
input::placeholder,textarea::placeholder{color:var(--muted);opacity:1}
select{max-width:100%;background:var(--panel-2);color:var(--ink);border:1px solid var(--line);border-radius:10px;padding:0 10px;font:inherit;min-height:44px}
textarea{min-height:64px}
.rule textarea{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:16px}
button{background:var(--btn);color:var(--btn-ink);border:0;border-radius:10px;padding:12px 14px;font:inherit;font-weight:700;cursor:pointer;white-space:nowrap;min-height:44px}
button.ghost{background:var(--panel-2);color:var(--ink)}
/* Taking someone out of dispatch should never look like saving an email address. */
button.ghost.danger{color:var(--bad)}
.inline{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.inline label{display:inline-flex;gap:6px;align-items:center;color:var(--muted);font-size:14px}
.inline input{width:auto;min-width:150px}
.cols{display:grid;grid-template-columns:1fr;gap:12px}
@media (min-width:860px){.cols{grid-template-columns:1fr 1fr 1fr}}
@media (max-width:859px){.cols>div:nth-child(2){order:-1}}
.sit{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:10px 12px;margin:0 0 8px}
.sit .t{font-weight:700}.sit .b{color:var(--muted);font-size:14px;margin-top:2px}.sit .i{color:var(--muted);font-size:12px;float:right}
.addyours{background:var(--panel);border:1px dashed var(--accent);border-radius:var(--r);padding:14px;margin:0 0 14px}
.addyours h2{margin:0 0 8px;font-size:16px}
.addyours .row{display:grid;gap:8px}
/* At desk width the whole add-a-person form is one line instead of four stacked ones. */
@media (min-width:720px){.addyours .row{grid-template-columns:1fr auto 1.2fr auto;align-items:center}}
.saved{color:var(--good);font-size:14px;margin-top:6px;font-weight:600}
.timeline{list-style:none;margin:0;padding:0}
.timeline li{padding:8px 0 8px 14px;border-left:2px solid var(--line);position:relative}
.timeline li::before{content:"";position:absolute;left:-5px;top:14px;width:8px;height:8px;border-radius:50%;background:var(--muted)}
.timeline .when{color:var(--muted);font-size:13px}
.timeline .what{font-size:14px}
.kv{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;font-size:14px}
.kv dt{color:var(--muted)}.kv dd{margin:0}
.sentence{background:var(--panel-2);padding:12px 14px;border-radius:10px;font-size:16px;font-weight:500;margin:12px 0;line-height:1.45}
.sentence::before{content:"Fair Housing";display:block;font-size:12px;text-transform:uppercase;letter-spacing:.06em;color:var(--accent);margin-bottom:4px;font-weight:700}
.alert{background:var(--panel-2);padding:10px 12px;border-radius:10px;font-size:14px;color:var(--bad);font-weight:600;margin:8px 0}
nav.bottom{position:fixed;left:0;right:0;bottom:0;display:flex;background:var(--panel);border-top:1px solid var(--line);padding:6px 4px calc(6px + env(safe-area-inset-bottom));z-index:6}
nav.bottom a{flex:1;display:flex;align-items:center;justify-content:center;min-height:44px;font-size:12px;color:var(--muted);padding:6px 2px;border-radius:8px;white-space:nowrap}
nav.bottom a.on{color:var(--ink);font-weight:700;background:var(--panel-2)}
nav.bottom a:hover{text-decoration:none}
@media (min-width:720px){nav.bottom{position:static;justify-content:center;gap:4px;border-top:0;border-bottom:1px solid var(--line);padding:6px 8px}nav.bottom a{flex:0 0 auto;font-size:14px;padding:8px 14px}body{padding-bottom:24px}}
h2.sec{font-size:16px;margin:16px 0 8px;scroll-margin-top:calc(var(--chrome) + env(safe-area-inset-top))}
h3.sec{font-size:14px;margin:12px 0 6px;color:var(--muted)}
.empty{color:var(--muted);padding:14px;text-align:center}
/* The only way back out of someone else's day on a phone: a real target, not a 20px line of text. */
.back{display:inline-flex;align-items:center;gap:4px;min-height:44px;padding:0 12px;margin:0 0 2px -12px;font-size:15px;font-weight:600;border-radius:999px}
.back:hover{text-decoration:none;background:var(--panel-2)}
.item{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:12px 14px;margin:0 0 10px}
.item.breach,.item.p1{box-shadow:inset 3px 0 0 var(--bad)}
.item-h{display:flex;flex-wrap:wrap;gap:6px 8px;align-items:center;font-size:17px;font-weight:600}
.item-m{color:var(--muted);font-size:14px;margin-top:4px}
/* The one sentence that says why this landed on you: read at arm's length, out-ranking the meta line above it. */
.why{font-size:16px;line-height:1.35;margin-top:8px;color:var(--ink)}
.why .k{color:var(--muted);font-weight:600}
.why::before{content:"";display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--accent);margin-right:6px;vertical-align:middle}
.item-f{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:12px}
form.act{display:inline-flex;gap:6px;align-items:stretch;margin:0}
/* The optional "why" note is not a button: display:contents lifts it out of its form so the buttons keep one row
   and the note takes a quiet full-width line of its own beneath them. [LEARNED] */
form.act.withnote{display:contents}
.item-f .reason{flex:1 0 100%;order:9;width:auto;min-height:44px;padding:10px 12px;font-size:15px}
form.act select{background:var(--panel-2);color:var(--ink);border:1px solid var(--line);border-radius:10px;padding:0 10px;min-height:44px;font:inherit}
form.act input[type=email]{width:auto;flex:1 1 12em;min-width:9em}
/* The way out to AppFolio is a tap target, and the pill that qualifies it never separates from it. */
.af-group{display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap;max-width:100%}
/* Outlined, not filled: a full-size target that still ranks below the filled verbs beside it. */
a.af{display:inline-flex;align-items:center;gap:4px;min-height:44px;padding:0 12px;border-radius:999px;background:transparent;border:1px solid var(--line);color:var(--link);font-size:14px;font-weight:600;white-space:nowrap}
a.af:hover{text-decoration:none;border-color:var(--link);background:var(--panel-2)}
@media (min-width:640px){.item-f .af-group{margin-left:auto}}
.login{max-width:440px;margin:28px auto}.loginform{display:grid;gap:10px;margin:10px 0 4px}.loginform label{color:var(--muted);font-size:15px}
.loginform input,.loginform button{font-size:17px;min-height:52px}
.login .note{margin-top:10px}
.brand .who{color:var(--ink);text-transform:none;letter-spacing:0;flex:0 1 auto}.brand .signout{margin-left:auto;flex:0 0 auto}.brand .signout button{min-height:32px;padding:6px 10px;font-size:13px;font-weight:600;position:relative}
/* The visual chip stays small; the thumb still gets its 44px. */
.brand .signout button::after{content:"";position:absolute;inset:-6px;border-radius:14px}
/* A td turned into a flex container drops out of the row box, so the phone (where cells are already blocks) gets the flex and the desk gets margins. */
.rowend>form+form{margin-left:8px}
@media (max-width:640px){.rowend{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.rowend>form+form{margin-left:0}}
form.act.grow{display:flex;width:100%}
.since{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:var(--r);padding:10px 14px;margin:0 0 12px}
.since ul{list-style:none;margin:0;padding:0}.since li{padding:4px 0;font-size:15px}.since .when{color:var(--muted);font-size:13px;margin-right:6px}
.pill.af{background:transparent;border:1px solid var(--line);color:var(--ink)}
.day{margin:12px 0 4px;font-size:13px;color:var(--muted);font-weight:600;text-transform:uppercase;letter-spacing:.04em}
.story{list-style:none;margin:0;padding:0}.story li{padding:6px 0;font-size:15px;border-bottom:1px solid var(--line)}.story .when{color:var(--muted);font-size:13px;margin-right:6px;font-variant-numeric:tabular-nums}
.story li.person{font-weight:600}.story li.loop{color:var(--accent)}
details.timeline-wrap{margin-top:14px}details.timeline-wrap summary{cursor:pointer;color:var(--muted);font-size:14px;min-height:44px;display:flex;align-items:center}
