/* =========================================================================
   This stylesheet predates the design specification. Its palette used to
   live here, in a :root block, and a second copy of it lived halfway down
   the file. Both are gone.

   Every name it still reads — --ink, --panel, --line, --accent, --ready,
   --issue, --radius-lg and the rest — is now declared once, by the bridge at
   the foot of tokens.css, which loads AFTER this file precisely so that it
   wins. Do not reintroduce a :root here: at equal specificity the later
   declaration takes it, and a palette declared in this file would silently
   put the pre-spec colours back under everything.

   See DECISIONS.md §12.
   ========================================================================= */
*{box-sizing:border-box;}
html,body{margin:0;padding:0;}
body{
  background: var(--rl-canvas);
  color:var(--ink);
  font-family:'Inter',system-ui,sans-serif;
  -webkit-font-smoothing:antialiased;
  min-height:100vh;
  padding-bottom:60px;
}
.display{font-family:'Fraunces',serif;}
.mono{font-family:'JetBrains Mono',monospace;}
a{color:inherit;}
button{font-family:inherit;}

/* ---------- Sign in ----------
   The one screen somebody sees before the app has told them anything about
   itself, and — until this rewrite — the one screen that ignored the theme
   entirely. It painted a fixed dark gradient in both modes and put white
   fields on it, so in dark mode you typed credentials into two glaring white
   boxes, and a browser autofill made it worse: Chrome forces its own
   background and near-black text into an autofilled field, which on a dark
   card is invisible until you select it.

   It is now the same paper-grey-or-ink surface as the rest of the product,
   in whichever theme is set, with the autofill override that keeps typed and
   remembered credentials looking identical.
   ------------------------------------------------------------------------ */
#loginScreen{
  position:fixed;inset:0;z-index:100;
  display:flex;align-items:center;justify-content:center;
  background:var(--rl-canvas);
  padding:20px;
}
.login-card{
  width:100%;max-width:400px;
  background:var(--rl-surface);
  border:1px solid var(--rl-line);
  border-radius:var(--rl-r-lg);
  box-shadow:var(--rl-e-2);
  padding:32px 30px 28px;
}
.login-mark{
  width:40px;height:40px;border-radius:var(--rl-r-sm);
  background:var(--rl-i-600);
  display:flex;align-items:center;justify-content:center;
  margin-bottom:18px;
  box-shadow:none;
}
.login-mark svg{width:20px;height:20px;}
.login-card h1{
  font-family:var(--rl-font-serif);font-weight:400;font-size:28px;line-height:34px;
  letter-spacing:-.01em;margin:0 0 4px;color:var(--rl-text);
}
.login-card p.sub{color:var(--rl-text-2);font-size:13.5px;line-height:19px;margin:0 0 24px;}
.field{margin-bottom:16px;}
.field label{
  display:block;font-size:12.5px;font-weight:500;letter-spacing:.005em;
  text-transform:none;color:var(--rl-text-2);margin-bottom:6px;
}
.field input{
  width:100%;height:38px;padding:0 10px;
  border-radius:var(--rl-r-sm);
  border:1px solid var(--rl-line-control);
  background:var(--rl-surface);
  color:var(--rl-text);
  font-size:15px;font-family:inherit;
  transition:border-color var(--rl-d-instant) var(--rl-ease-standard);
}
.field input::placeholder{color:var(--rl-text-3);}
.field input:focus{
  outline:none;
  border-color:var(--rl-i-600);
  background:var(--rl-surface);
  box-shadow:var(--rl-focus);
}
/* AUTOFILL. Chrome paints its own background and text colour into a remembered
   field and ignores `background`, so the only way to reach it is the inset
   shadow trick plus -webkit-text-fill-color. Without this, a saved password
   on the dark theme is dark grey text on Chrome's pale yellow — the single
   worst thing this screen can look like. The transition delay stops Chrome
   repainting its own colour back over ours a frame later. */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus{
  -webkit-text-fill-color:var(--rl-text);
  -webkit-box-shadow:inset 0 0 0 1000px var(--rl-surface);
  box-shadow:inset 0 0 0 1000px var(--rl-surface);
  caret-color:var(--rl-text);
  transition:background-color 100000s ease-in-out 0s;
}
.field input:-webkit-autofill:focus{
  -webkit-box-shadow:inset 0 0 0 1000px var(--rl-surface),var(--rl-focus);
  box-shadow:inset 0 0 0 1000px var(--rl-surface),var(--rl-focus);
}
.login-btn{
  width:100%;height:40px;
  border-radius:var(--rl-r-sm);border:none;
  background:var(--rl-i-600);
  color:#fff;font-weight:500;font-size:14.5px;cursor:pointer;margin-top:8px;
  box-shadow:none;
  transition:background var(--rl-d-instant) var(--rl-ease-standard);
}
.login-btn:hover{background:var(--rl-i-700);}
.login-btn:active{transform:scale(.98);}
.login-btn:focus-visible{outline:none;box-shadow:var(--rl-focus);}
.login-error{
  color:var(--rl-text-danger);font-size:12.5px;line-height:16px;margin-top:10px;display:none;
}

/* ---------- Header / Nav ---------- */
header.app-head{
  background:var(--rl-surface);
  color:#fff;padding:16px 20px 0;position:sticky;top:0;z-index:20;box-shadow:var(--shadow);
}
.head-inner{max-width:var(--content-max);margin:0 auto;}
.brand-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:14px;}
.brand{display:flex;align-items:center;gap:10px;}
.brand-mark{
  width:32px;height:32px;border-radius:9px;
  background:var(--rl-i-600);
  display:flex;align-items:center;justify-content:center;flex:none;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,0.25);
}
.brand-mark svg{width:17px;height:17px;}
.brand-name{font-family:'Fraunces',serif;font-weight:600;font-size:19px;letter-spacing:.01em;}
.brand-tag{font-size:10.5px;color:rgba(255,255,255,0.5);text-transform:uppercase;letter-spacing:.08em;margin-top:-2px;}
.user-row{display:flex;align-items:center;gap:12px;}
.user-chip{font-size:13px;color:rgba(255,255,255,0.75);}
.user-chip b{color:#fff;}
.logout-btn{
  background:rgba(255,255,255,0.08);border:1px solid rgba(255,255,255,0.14);
  color:#fff;padding:7px 13px;border-radius:8px;font-size:12.5px;cursor:pointer;
}
.logout-btn:hover{background:rgba(255,255,255,0.15);}

/* No overflow here on purpose: any overflow value other than visible makes
   this a clipping context, which would cut off the dropdown panels that
   hang below the bar. Eight compact items fit one row on a laptop and wrap
   cleanly below that. */
nav.tabs{display:flex;gap:2px;max-width:var(--content-max);margin:0 auto;flex-wrap:wrap;}
.tab-btn{
  background:transparent;border:none;color:rgba(255,255,255,0.66);
  padding:11px 13px 12px;font-size:13.5px;font-weight:550;cursor:pointer;
  white-space:nowrap;position:relative;border-radius:9px 9px 0 0;
  display:inline-flex;align-items:center;gap:7px;
  transition:color .15s ease, background .15s ease;
}
.tab-btn .tab-ico{width:15px;height:15px;flex:none;opacity:.75;}
.tab-btn::before{
  content:'';position:absolute;left:11px;right:11px;bottom:0;height:2.5px;
  border-radius:2px;background:transparent;transition:background .15s ease;
}
.tab-btn:hover{color:#fff;background:rgba(255,255,255,0.06);}
.tab-btn:hover .tab-ico{opacity:1;}
.tab-btn.active{color:#fff;}
.tab-btn.active .tab-ico{opacity:1;}
.tab-btn.active::before{background:var(--accent-light);}
.tab-btn.has-caret::after{
  content:'';width:5px;height:5px;margin-left:1px;
  border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;
  transform:rotate(45deg) translateY(-2px);opacity:.6;
}
.tab-dd{position:relative;}
.dd-panel{
  position:absolute;top:calc(100% + 6px);left:0;background:var(--panel);
  border:1px solid var(--line);
  border-radius:14px;box-shadow:var(--shadow-lift);padding:7px;
  min-width:286px;display:none;z-index:30;
  animation:ddIn .13s ease-out;
}
@keyframes ddIn{from{opacity:0;transform:translateY(-4px);}to{opacity:1;transform:none;}}
.dd-panel.open{display:block;}
.dd-item{
  display:flex;flex-direction:column;gap:2px;width:100%;text-align:left;
  background:none;border:none;padding:9px 11px;border-radius:9px;cursor:pointer;
}
.dd-item-label{font-size:13.5px;font-weight:600;color:var(--ink);line-height:1.25;}
.dd-item-desc{font-size:11.5px;color:var(--ink-soft);line-height:1.35;}
.dd-item:hover{background:var(--accent-bg);}
.dd-item:hover .dd-item-label{color:var(--accent-deep);}
.dd-item.active{background:var(--accent-bg);}
.dd-item.active .dd-item-label{color:var(--accent-deep);}

/* ---------- Account menu (replaces the inline name + log out pair) ---------- */
.acct-dd{position:relative;}
.acct-btn{
  display:flex;align-items:center;gap:8px;cursor:pointer;
  background:rgba(255,255,255,0.07);border:1px solid rgba(255,255,255,0.13);
  color:#fff;padding:5px 9px 5px 5px;border-radius:999px;
}
.acct-btn:hover{background:rgba(255,255,255,0.14);}
.acct-avatar{
  width:26px;height:26px;border-radius:50%;flex:none;
  background:var(--rl-i-600);
  display:flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:700;letter-spacing:.02em;
}
.acct-name{font-size:13px;font-weight:600;}
.acct-caret{width:13px;height:13px;opacity:.65;}
.acct-panel{left:auto;right:0;min-width:238px;}
.acct-head{padding:9px 11px 10px;border-bottom:1px solid var(--line);margin-bottom:5px;}
.acct-head-name{font-size:13.5px;font-weight:650;color:var(--ink);}
.acct-head-role{font-size:11.5px;color:var(--ink-soft);margin-top:1px;}

/* ---------- Layout ---------- */
main.content{max-width:var(--content-max);margin:0 auto;padding:22px 20px 10px;}
.view{display:none;}
.view.active{display:block;}
h2.view-title{font-family:'Fraunces',serif;font-weight:600;font-size:24px;margin:2px 0 3px;}
p.view-sub{color:var(--ink-soft);font-size:13.5px;margin:0 0 20px;}

.grid{display:grid;gap:16px;}
.grid-3{grid-template-columns:repeat(3,1fr);}
.grid-2{grid-template-columns:repeat(2,1fr);}
@media(max-width:900px){.grid-3,.grid-2{grid-template-columns:1fr;}}

.card{
  background:var(--panel);border-radius:var(--radius-lg);box-shadow:var(--shadow);
  padding:18px 20px;
}
.stat-card .stat-label{font-size:12px;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.05em;font-weight:600;}
.stat-card .stat-value{font-family:'Fraunces',serif;font-size:32px;font-weight:600;margin:6px 0 2px;}
.stat-card .stat-foot{font-size:12.5px;color:var(--ink-soft);}

.section-head{display:flex;align-items:baseline;justify-content:space-between;margin:26px 0 10px;}
.section-head h3{font-family:'Fraunces',serif;font-size:17px;font-weight:600;margin:0;}
.section-head .count-pill{
  background:var(--accent-bg);color:var(--accent-deep);font-size:11.5px;font-weight:700;
  padding:2px 9px;border-radius:20px;margin-left:8px;
}

table{width:100%;border-collapse:collapse;font-size:13.5px;}
table th{
  text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--ink-soft);padding:9px 10px;border-bottom:1.5px solid var(--line);font-weight:700;
}
table td{padding:11px 10px;border-bottom:1px solid var(--line);}
table tr:last-child td{border-bottom:none;}
.list-card{background:var(--panel);border-radius:var(--radius-lg);box-shadow:var(--shadow);overflow:hidden;}
.list-card .scroll-wrap{overflow-x:auto;}

.badge{
  display:inline-block;font-size:11.5px;font-weight:700;padding:3px 9px;border-radius:20px;
  white-space:nowrap;
}
.badge.ready{background:var(--ready-bg);color:var(--ready);}
.badge.occupied{background:var(--occupied-bg);color:var(--occupied);}
.badge.inspect{background:var(--inspect-bg);color:var(--inspect);}
.badge.issue{background:var(--issue-bg);color:var(--issue);}
.badge.pending{background:var(--inspect-bg);color:var(--inspect);}
.badge.signed{background:var(--ready-bg);color:var(--ready);}
.badge.paid{background:var(--ready-bg);color:var(--ready);}
.badge.overdue{background:var(--issue-bg);color:var(--issue);}

.empty-note{color:var(--ink-soft);font-size:13.5px;padding:16px 4px;}

.chart-wrap{position:relative;height:230px;}
.two-col{display:grid;grid-template-columns:1.4fr 1fr;gap:16px;}
@media(max-width:900px){.two-col{grid-template-columns:1fr;}}

.cal-toolbar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;margin-bottom:12px;}
.cal-legend{display:flex;gap:14px;flex-wrap:wrap;}
.cal-legend-item{font-size:12px;color:var(--ink-soft);display:inline-flex;align-items:center;gap:6px;}
.cal-legend-item .dot{width:9px;height:9px;border-radius:3px;display:inline-block;}
.cal-legend-item .dot.occupied{background:var(--occupied);}
.cal-legend-item .dot.ready{background:var(--ready);}
.cal-legend-item .dot.inspect{background:var(--inspect);}
.cal-legend-item .dot.issue{background:var(--issue);}
.cal-nav{display:flex;align-items:center;gap:8px;}
.cal-range{font-size:12.5px;color:var(--ink-soft);min-width:150px;text-align:center;}

.cal-filters{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:10px 0 4px;font-size:12.5px;color:var(--ink-soft);}
.cal-filters label{display:inline-flex;align-items:center;gap:5px;}
.cal-filters input[type="date"]{border:1px solid var(--line);border-radius:7px;padding:4px 7px;font:inherit;font-size:12.5px;background:var(--panel,#fff);color:inherit;}
.cal-filters .cal-quick{display:inline-flex;gap:4px;}
.cal-ci{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px;vertical-align:middle;border:1.5px solid currentColor;}
.cal-ci-in{background:var(--rl-surface);border-color:var(--rl-surface);}
.cal-ci-out{background:transparent;border-color:rgba(255,255,255,.6);}
.cal-ci-pending{background:transparent;border-style:dashed;border-color:rgba(255,255,255,.55);}
.cl-checkin{width:100%;border-collapse:collapse;font-size:13px;margin:4px 0 8px;}
.cl-checkin th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft);font-weight:700;padding:6px 10px 6px 0;border-bottom:1px solid var(--line);}
.cl-checkin td{padding:8px 10px 8px 0;border-bottom:1px solid var(--line-soft,var(--rl-line));}
/* The calendar is a frozen-header, frozen-column grid: .cal-header-row is
   `position:sticky;top:0` and .cal-label-col is `position:sticky;left:0`.
   The column worked and the header never did, for a reason that is easy to
   miss — declaring ONLY `overflow-x:auto` makes the computed `overflow-y`
   `auto` too (CSS does not allow one axis to be `visible` while the other
   is not). So .cal-wrap was a vertical scroll container whose height was
   its full content height: 3,011px of rooms that never scrolled, and a
   header row that therefore had nothing to stick to. Scrolling the page
   took the dates away at the first row and never brought them back.

   Bounding the height makes it the pane it was already written to be, and
   both frozen edges now do what they say. */
.cal-wrap{
  overflow:auto;
  max-height:calc(100vh - var(--rl-topbar-h) - var(--rl-sticky-top,0px) - var(--rl-s-12));
}
.cal-day-w:root{}
.cal-header-row{display:flex;position:sticky;top:0;background:var(--panel);z-index:2;border-bottom:1.5px solid var(--line);}
.cal-label-col{width:180px;flex:none;padding:10px 14px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft);border-right:1px solid var(--line);background:var(--panel);position:sticky;left:0;z-index:3;}
.cal-days-track{display:flex;}
.cal-listing-tag{display:block;width:fit-content;max-width:100%;margin:4px 0 0 auto;padding:2px 7px;border:none;border-radius:20px;
  background:var(--accent-bg);color:var(--accent-deep);font:inherit;font-family:var(--rl-font-sans);font-size:10.5px;font-weight:600;
  text-transform:none;letter-spacing:0;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;}
.cal-listing-tag:hover{text-decoration:underline;}
.cal-day-cell{width:64px;flex:none;text-align:center;padding:8px 0 7px;border-right:1px solid var(--line);position:relative;}
.cal-day-cell .dow{font-size:10px;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.04em;}
.cal-day-cell .dnum{font-family:'JetBrains Mono',monospace;font-size:13px;font-weight:700;margin-top:1px;}
.cal-day-cell.is-today{background:var(--accent-bg);}
.cal-day-cell.is-today .dnum{color:var(--accent-deep);}
/* Round 1 §3: "a more legible date header at scale" — a shaded band for
   the two weekend columns and a printed month abbreviation at the first
   column of a new month, so scanning ~19 date columns does not mean
   counting forward from the range label to work out which month a bar
   sits in. */
.cal-day-cell.is-weekend{background:var(--rl-surface-sunk,rgba(0,0,0,.02));}
.cal-day-cell.is-today.is-weekend{background:var(--accent-bg);}
.cal-day-cell.is-month-start{border-left:1.5px solid var(--rl-line-strong,var(--line));}
.cal-day-cell .mon{position:absolute;top:-14px;left:0;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--ink-soft);white-space:nowrap;}
.cal-body-row{display:flex;border-bottom:1px solid var(--line);}
.cal-body-row:last-child{border-bottom:none;}
.cal-track{position:relative;display:flex;}
.cal-track-cell{width:64px;flex:none;border-right:1px solid var(--line);min-height:46px;}
.cal-track-cell.is-weekend{background:var(--rl-surface-sunk,rgba(0,0,0,.02));}
/* Drop-target highlight while dragging a stay over a different room's
   track (round 1 §3) — toggled by rlOccDragEnter()/rlOccDragLeave() in
   occupancy.js, since :hover does not fire during an HTML5 drag. */
.cal-track.is-drop-target{background:var(--accent-bg);}
.cal-bar[draggable="true"]{cursor:grab;}
.cal-bar[draggable="true"]:active{cursor:grabbing;}
/* A stay bar is the same room in the same state as the plan draws it, so it
   uses the room-state palette from §3.2 rather than a gradient of its own.
   Occupied stays quiet — a calendar of bright indigo bars hides the two
   rooms in turn, which are the only ones anybody is looking for. */
.cal-bar{
  position:absolute;top:6px;bottom:6px;border-radius:var(--rl-r-xs);
  display:flex;align-items:center;padding:0 9px;font-size:12px;font-weight:500;
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis;box-shadow:none;
  border:1px solid transparent;
}
.cal-bar.occupied{background:var(--rl-room-occupied-fill);border-color:var(--rl-room-occupied-line);color:var(--rl-room-occupied-text);}
/* A stay bar opens that resident's contract — make it read as a control. */
.cal-bar.is-clickable{cursor:pointer;}
.cal-bar.is-clickable:hover{border-color:var(--rl-line-strong);}
.cal-bar.inspect{background:var(--rl-room-turn-fill);border-color:var(--rl-room-turn-line);color:var(--rl-room-turn-text);}
.cal-bar.issue{background:var(--rl-room-oos-fill);border-color:var(--rl-room-oos-line);color:var(--rl-room-oos-text);}
.cal-today-line{position:absolute;top:0;bottom:0;width:2px;background:var(--accent);z-index:1;opacity:.55;}

.room-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:10px;margin-top:8px;}
.room-tile{
  border-radius:12px;padding:10px 10px 9px;border:1.5px solid var(--line);background:var(--rl-surface);
  position:relative;
}
.room-tile .rn{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:13.5px;padding-right:64px;}
.room-tile .rb{font-size:11px;color:var(--ink-soft);margin:1px 0 7px;}
/* Kept subtle until hover so the room grid still reads as data first,
   controls second — this sits on every tile in Property Detail, and a
   portfolio-sized grid of visible delete buttons looks like a warning
   sign rather than a management screen. */
.room-tile-actions{
  position:absolute;top:5px;right:6px;display:flex;gap:2px;align-items:center;
  opacity:.3;transition:opacity .12s ease;
}
.room-tile:hover .room-tile-actions,
.room-tile:focus-within .room-tile-actions{opacity:1;}
.room-tile-remove,.room-tile-edit{
  border:none;background:none;color:var(--ink-soft);border-radius:6px;cursor:pointer;
  min-height:30px;display:inline-flex;align-items:center;justify-content:center;
}
.room-tile-remove{width:30px;font-size:15px;line-height:1;text-align:center;}
.room-tile-edit{min-width:30px;font-size:11px;font-weight:600;padding:0 7px;}
.room-tile-edit:hover{background:var(--accent-bg);color:var(--accent);}
.room-tile-remove:hover{background:var(--rl-tint-red-bg);color:var(--rl-text-danger);}

/* ---- Custom Reports: categorised source picker ---- */
.report-cat-head{font-family:'Fraunces',serif;font-size:15px;font-weight:600;margin:22px 0 10px;}
.report-cat-head:first-child{margin-top:0;}
.report-tile-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(128px,1fr));gap:12px;}
.report-tile{
  display:flex;flex-direction:column;align-items:flex-start;gap:10px;
  padding:14px 12px;border-radius:var(--radius-md);border:1.5px solid var(--line);background:var(--panel);
  cursor:pointer;text-align:left;font-family:inherit;color:inherit;
  transition:border-color .15s,box-shadow .15s,transform .15s;
}
.report-tile:hover{border-color:var(--accent-light);box-shadow:var(--shadow-lift);transform:translateY(-1px);}
.report-tile-icon{position:relative;width:34px;height:34px;color:var(--ink-soft);opacity:.5;}
.report-tile-icon svg{width:100%;height:100%;}
.report-tile-badge{
  position:absolute;left:16px;bottom:-6px;font-size:10px;font-weight:700;letter-spacing:.02em;
  padding:2px 6px;border-radius:6px;color:#fff;line-height:1.4;
}
.report-tile-label{font-size:13px;font-weight:600;line-height:1.3;}
/* Same colours as the tile badge, laid out inline for the builder header
   (the tile badge is absolutely positioned against the icon corner and
   breaks outside that context — this is a plain flow element). */
.report-inline-badge{
  font-size:10px;font-weight:700;letter-spacing:.02em;color:#fff;
  padding:2px 6px;border-radius:6px;line-height:1.4;flex:none;
}
.rc-portfolio{background:var(--rl-i-600);}
.rc-leasing{background:var(--rl-i-500);}
/* -600, not -500 like the other two: amber-500 is perceptually much
   lighter than indigo-500 at the same numeric weight, and white text on
   it measures 3.19:1 — below the 4.5:1 this 10px badge label needs.
   -600 (same step .rc-portfolio already uses) clears it at 4.77:1. */
.rc-people{background:var(--rl-a-600);}
.rc-ops{background:var(--rl-text-success);}
.rc-finance{background:var(--rl-text-danger);}

select, .btn-select{
  padding:7px 9px;border-radius:8px;border:1.5px solid var(--line);font-size:12.5px;
  background:var(--rl-surface);font-family:inherit;
}
.btn{
  background:var(--accent);color:#fff;border:none;padding:9px 15px;border-radius:9px;
  font-size:13px;font-weight:600;cursor:pointer;box-shadow:var(--shadow);
}
.btn:hover{background:var(--accent-deep);}
.btn.ghost{background:transparent;color:var(--accent-deep);border:1.5px solid var(--accent-bg);box-shadow:none;}
.btn.ghost:hover{background:var(--accent-bg);}
.btn.small{padding:6px 11px;font-size:12px;}

.listing-card{
  background:var(--panel);border-radius:var(--radius-lg);box-shadow:var(--shadow);overflow:hidden;
}
.listing-photo{
  height:120px;background:var(--rl-surface-sunk);
  display:flex;align-items:center;justify-content:center;color:var(--accent-deep);
  font-family:'JetBrains Mono',monospace;font-size:12px;letter-spacing:.05em;
}
.listing-body{padding:14px 16px 16px;}
.listing-body .rent{font-family:'Fraunces',serif;font-size:21px;font-weight:600;}
.listing-body .rent span{font-size:12px;font-weight:400;color:var(--ink-soft);}
.listing-meta{font-size:12.5px;color:var(--ink-soft);margin:3px 0 10px;}

/* One row per offer on a cluster card — a room count at one tenancy
   length. A cluster carries several of these (15 rooms at 42 weeks,
   10 at 51, and so on), so they need to read as a list, not as the
   single headline price the card used to show. */
.listing-offers{margin-top:10px;display:flex;flex-direction:column;gap:6px;}
.listing-offer{
  display:flex;align-items:flex-start;justify-content:space-between;gap:8px;
  background:var(--rl-surface);border:1px solid var(--line);border-radius:11px;padding:9px 11px;
}
.listing-offer.is-draft{opacity:.72;border-style:dashed;}
.listing-offer .lo-main{min-width:0;}
.listing-offer .lo-head{font-size:13px;display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
.listing-offer .lo-sub{font-size:11.5px;color:var(--ink-soft);margin-top:2px;}
.listing-offer .lo-actions{display:flex;gap:4px;flex-shrink:0;}
.btn.danger{color:var(--rl-text-danger);border-color:var(--rl-line-danger);}
.btn.danger:hover{background:var(--rl-tint-red-bg);}
.field-hint{font-size:11px;color:var(--ink-soft);margin-top:5px;}
.field-static{font-size:13.5px;font-weight:600;padding:6px 0;}
.modal-error{
  background:var(--rl-tint-red-bg);border:1px solid var(--rl-line-danger);color:var(--rl-text-danger);
  border-radius:10px;padding:9px 11px;font-size:12.5px;margin-bottom:10px;
}

.ops-subnav,.reports-subnav,.governance-subnav{display:flex;gap:6px;margin-bottom:16px;flex-wrap:wrap;}
.ops-sub-btn,.reports-sub-btn,.governance-sub-btn,.qf-chip{
  background:var(--rl-surface);border:1.5px solid var(--line);padding:7px 13px;border-radius:20px;
  font-size:12.5px;font-weight:600;cursor:pointer;color:var(--ink-soft);
}
/* Selected takes the accent TINT pair, not the accent as a fill with white
   on it. --accent-deep is a text weight and flips lightness between themes,
   so white on it was 2.3:1 in dark. The tint pair is correct in both, and
   matches how every other selected state in the system reads (§9.4). */
.ops-sub-btn.active,.reports-sub-btn.active,.governance-sub-btn.active,.qf-chip.active{background:var(--rl-tint-accent-bg);border-color:transparent;color:var(--rl-tint-accent-fg);font-weight:500;}
.ops-view,.reports-view{display:none;}
.ops-view.active,.reports-view.active{display:block;}

.contracts-layout{display:grid;grid-template-columns:340px 1fr;gap:16px;align-items:start;}
@media(max-width:900px){.contracts-layout{grid-template-columns:1fr;}}
.contracts-list{max-height:640px;overflow-y:auto !important;overflow-x:hidden;padding:6px;}
.contract-item{
  display:block;width:100%;text-align:left;background:none;border:none;border-radius:10px;
  padding:11px 12px;cursor:pointer;margin-bottom:2px;
}
.contract-item:hover{background:var(--accent-bg);}
.contract-item.active{background:var(--accent-bg);}
.contract-item .ci-title{font-size:13.5px;font-weight:600;margin-bottom:4px;}
.contract-item .ci-tenant{font-size:12px;color:var(--ink-soft);margin-bottom:6px;}
.contracts-detail{min-height:300px;}
.cd-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding-bottom:14px;border-bottom:1px solid var(--line);margin-bottom:16px;}
.cd-head h3{font-family:'Fraunces',serif;font-size:18px;font-weight:600;margin:0 0 4px;}
.cd-meta-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:20px;}
.cd-meta-grid .m-label{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft);font-weight:700;margin-bottom:3px;}
.cd-meta-grid .m-val{font-size:14px;font-weight:600;}
.cd-meta-grid .m-val.deadline{color:var(--issue);}
.cd-section-title{font-size:12.5px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--ink-soft);margin:18px 0 8px;}
.cd-sign-row{display:flex;align-items:center;justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--line);font-size:13.5px;}
.cd-sign-row:last-child{border-bottom:none;}
.cd-sign-name{font-weight:600;}

/* ---------- Contract lifecycle: created-by line, deadline strip,
   audit log / internal notes (spec items 6, 7, 9, 10) ---------- */
.cd-created{font-size:12px;color:var(--ink-soft);margin:-8px 0 14px;}
.cl-deadline{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:12px 14px;margin:0 0 18px;border:1px solid var(--line);border-radius:10px;background:var(--panel-2,var(--rl-surface-sunk));}
.cl-deadline .m-label{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft);font-weight:700;margin-bottom:3px;}
.cl-deadline .m-val{font-size:14px;font-weight:600;}
.cl-deadline button{margin-left:auto;}
.cl-avatar{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:28px;height:28px;border-radius:50%;font-size:11px;font-weight:700;letter-spacing:.02em;}
.cl-log{display:flex;flex-direction:column;gap:2px;margin-top:4px;}
.cl-log-row{display:flex;gap:11px;padding:11px 0;border-bottom:1px solid var(--line);}
.cl-log-row:last-child{border-bottom:none;}
.cl-log-body{flex:1;min-width:0;}
.cl-log-head{display:flex;justify-content:space-between;gap:10px;align-items:baseline;flex-wrap:wrap;}
.cl-log-head b{font-size:13.5px;}
.cl-log-when{font-size:11.5px;color:var(--ink-soft);white-space:nowrap;}
.cl-log-detail{font-size:12.5px;color:var(--ink-soft);margin-top:3px;line-height:1.5;}
.cl-note-compose{border:1px solid var(--line);border-radius:10px;padding:12px;margin:6px 0 16px;background:var(--panel-2,var(--rl-surface-sunk));}
.cl-note-compose textarea{width:100%;border:1px solid var(--line);border-radius:8px;padding:9px;font:inherit;font-size:13px;resize:vertical;background:var(--panel,#fff);color:inherit;}
.cl-note-actions{display:flex;align-items:center;gap:10px;margin-top:9px;flex-wrap:wrap;}
label.cl-check,.cl-check{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--ink-soft);text-transform:none;letter-spacing:0;font-weight:400;}
.cl-check input{margin:0;width:auto;}
.cd-danger-zone{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:22px;padding-top:14px;border-top:1px dashed var(--line);}
.cd-danger-zone span{font-size:11.5px;color:var(--ink-soft);}
.cw-tmpl-warn{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px;padding:10px 12px;
  border:1px solid var(--line);border-left:3px solid var(--pending,var(--rl-text-warning));border-radius:8px;font-size:12.5px;background:var(--panel-2,var(--rl-surface-sunk));}

/* ---------- Dashboard: shared icon chips, today tiles, card heads ----------
   The headline band, attention row and today strip themselves live in the
   DASHBOARD block near the foot of this file. */
.view-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;}

/* Icon chips: a soft-tinted circle sized off the semantic status colours
   already used for badges everywhere else, so a picked custom accent
   (theme customizer) or dark mode re-tints these for free. */
.tt-ico,.stat-ico{
  flex:0 0 auto;width:32px;height:32px;border-radius:10px;
  display:flex;align-items:center;justify-content:center;
  background:var(--accent-bg);color:var(--accent);margin-top:1px;
}
.tt-ico svg,.stat-ico svg{width:16px;height:16px;}
.tt-ico.ico-ready,.stat-ico.ico-ready{background:var(--ready-bg);color:var(--ready);}
.tt-ico.ico-issue,.stat-ico.ico-issue{background:var(--issue-bg);color:var(--issue);}
.tt-ico.ico-inspect,.stat-ico.ico-inspect{background:var(--inspect-bg);color:var(--inspect);}
/* .stat-card is otherwise a plain vertical label/value/foot stack — this
   variant, opt-in per instance via .has-ico, lays an icon chip beside it
   instead of restructuring the ~70 stat-cards that don't use one. */
.stat-card.has-ico{display:flex;gap:12px;align-items:flex-start;}
.stat-card.has-ico .stat-body{flex:1;min-width:0;}

.today-strip{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-top:14px;}
@media(max-width:820px){.today-strip{grid-template-columns:repeat(2,1fr);}}
.today-tile{
  display:flex;align-items:flex-start;gap:11px;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-md);
  padding:14px 16px;cursor:pointer;text-align:left;
  transition:border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.today-tile:hover{border-color:var(--accent-light);transform:translateY(-2px);box-shadow:var(--shadow-lift);}
.tt-body{display:flex;flex-direction:column;gap:1px;min-width:0;}
.tt-value{font-family:'Fraunces',serif;font-size:26px;font-weight:600;letter-spacing:-.03em;color:var(--ink);}
.tt-label{font-size:12.5px;color:var(--ink-soft);font-weight:600;}
.tt-note{font-size:11.5px;color:var(--issue);font-weight:600;min-height:14px;}

/* ---------- Chart cards: a touch more presence than a plain .card ---------- */
.chart-card{position:relative;overflow:hidden;}
.chart-card::before{
  content:'';position:absolute;inset:0 0 auto 0;height:2px;
  background:var(--rl-i-600);
  opacity:.75;
}
/* maintainAspectRatio:false makes Chart.js size the canvas from the
   container's own box in both dimensions via a ResizeObserver, rather
   than deriving height from a measured width — inside a CSS grid item
   (.report-grid) that first measurement can land before the grid has
   committed a track width, reading 0 and leaving the canvas invisible.
   An explicit width here removes the implicit, grid-timing-dependent one. */
.chart-wrap{position:relative;width:100%;}

.card-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:14px;}
.card-head h3{font-family:'Fraunces',serif;font-size:16px;font-weight:600;margin:0;}
.card-head-note{font-size:11.5px;color:var(--ink-soft);}
.chip-count{
  display:inline-block;background:var(--accent-bg);color:var(--accent-deep);
  font-size:11px;font-weight:700;padding:1px 7px;border-radius:20px;margin-left:6px;
}

/* ---------- Kanban (Leads) ---------- */
.kanban-board{display:flex;gap:14px;overflow-x:auto;padding-bottom:10px;}
.kanban-col{background:var(--panel);border-radius:var(--radius-lg);box-shadow:var(--shadow);min-width:230px;max-width:230px;flex:none;padding:12px;}
.kanban-col-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;}
.kanban-col-head h4{font-size:11.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft);margin:0;font-weight:700;}
.kanban-card{background:var(--rl-surface);border:1.5px solid var(--line);border-radius:10px;padding:10px 11px;margin-bottom:8px;}
.kanban-card .kc-name{font-weight:600;font-size:13px;margin-bottom:3px;}
.kanban-card .kc-meta{font-size:11.5px;color:var(--ink-soft);margin-bottom:2px;}
.kanban-card select{width:100%;margin-top:8px;}

/* ---------- Split layout (tickets etc, reuses contracts pattern) ---------- */
.split-layout{display:grid;grid-template-columns:340px 1fr;gap:16px;align-items:start;}
@media(max-width:900px){.split-layout{grid-template-columns:1fr;}}
.side-list{max-height:640px;overflow-y:auto;padding:6px;}
.side-item{display:block;width:100%;text-align:left;background:none;border:none;border-left:3px solid transparent;border-radius:10px;padding:11px 12px 11px 10px;cursor:pointer;margin-bottom:2px;}
/* Opt-in priority accent — only ticket rows carry pri-high/pri-medium,
   so this has no effect on the other .side-item lists (Contracts, etc). */
.side-item.pri-high{border-left-color:var(--issue);}
.side-item.pri-medium{border-left-color:var(--inspect);}
.side-item:hover,.side-item.active{background:var(--accent-bg);}
.side-item .si-title{font-size:13.5px;font-weight:600;margin-bottom:4px;}
.side-item .si-sub{font-size:12px;color:var(--ink-soft);margin-bottom:6px;}
.detail-panel{min-height:300px;}

/* ---------- Comments ---------- */
.comment{border-bottom:1px solid var(--line);padding:10px 0;font-size:13px;}
.comment:last-child{border-bottom:none;}
.comment .c-author{font-weight:600;}
.comment .c-meta{font-size:11px;color:var(--ink-soft);margin-top:3px;}
.comment-box{display:flex;gap:8px;margin-top:14px;}
.comment-box textarea{flex:1;border-radius:10px;border:1.5px solid var(--line);padding:9px 10px;font-family:inherit;font-size:13px;resize:vertical;min-height:44px;}

/* ---------- Forms ---------- */
.form-card{background:var(--panel);border-radius:var(--radius-lg);box-shadow:var(--shadow);padding:18px 20px;margin-bottom:20px;}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:12px;}
@media(max-width:700px){.form-grid{grid-template-columns:1fr;}}
.form-grid label,.field-block label{display:block;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--ink-soft);margin-bottom:5px;}
/* A tick or a radio with its explanation, inside a .field-block. The rule
   above is for field CAPTIONS — 11px, bold, uppercase — and applying it
   to a sentence someone has to read turns "Approved in your own banking
   app" into shouting. Specificity has to beat `.field-block label`, hence
   the compound selector rather than a bare class. */
.field-block label.choice-row,.form-grid label.choice-row{
  display:flex;gap:9px;align-items:flex-start;padding:7px 0;margin-bottom:0;
  font-size:13px;font-weight:400;text-transform:none;letter-spacing:normal;color:var(--ink);
}
.field-block label.choice-row input,.form-grid label.choice-row input{width:auto;margin-top:2px;flex:none;}
.choice-row b{display:block;font-size:13.5px;font-weight:600;color:var(--ink);}
.choice-row .choice-desc{display:block;font-size:12px;color:var(--ink-soft);font-weight:400;}
.choice-inline{display:flex;gap:20px;flex-wrap:wrap;padding:2px 0 8px;}
.form-grid input,.form-grid select,.form-grid textarea,.field-block input,.field-block select,.field-block textarea{
  width:100%;padding:9px 10px;border-radius:9px;border:1.5px solid var(--line);font-size:13.5px;font-family:inherit;background:var(--rl-surface);}
.form-grid input:focus,.form-grid select:focus,.form-grid textarea:focus{outline:none;border-color:var(--accent);background:var(--rl-surface);}
.field-block{margin-bottom:12px;}
.line-items-table{width:100%;font-size:13px;margin-bottom:8px;border-collapse:collapse;}
.line-items-table th{text-align:left;font-size:10.5px;text-transform:uppercase;color:var(--ink-soft);padding:6px 6px;}
.line-items-table td{padding:5px 6px;}
.line-items-table input{width:100%;padding:6px 7px;border-radius:6px;border:1.5px solid var(--line);font-size:13px;}
.inv-total-row{display:flex;justify-content:flex-end;gap:20px;padding:10px 4px;font-size:14.5px;font-weight:700;border-top:1.5px solid var(--line);margin-top:4px;}
.form-actions{display:flex;gap:8px;margin-top:6px;flex-wrap:wrap;}

/* ---------- Generic modal (used by New lead / New ticket / New contract) ---------- */
.modal-overlay{position:fixed;inset:0;background:rgba(20,24,34,0.45);display:flex;align-items:center;justify-content:center;z-index:100;padding:20px;}
.modal-box{background:var(--panel);border-radius:var(--radius-lg);box-shadow:var(--shadow-lift);width:100%;max-width:420px;max-height:85vh;overflow-y:auto;padding:22px;}
.modal-box h3{margin:0 0 16px;font-family:'Fraunces',serif;font-size:18px;}
.modal-box .form-actions{margin-top:16px;}

/* ---------- Email tracking ---------- */
.trk-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px;}
.trk-dot.on{background:var(--ready);}
.trk-dot.off{background:var(--line);}

/* ---------- Community ---------- */
.feed-card{background:var(--panel);border-radius:var(--radius-lg);box-shadow:var(--shadow);padding:16px 18px;margin-bottom:12px;}
.feed-card .fc-head{display:flex;justify-content:space-between;font-size:12px;color:var(--ink-soft);margin-bottom:8px;}
.feed-card .fc-head b{color:var(--ink);}
.feed-card .fc-body{font-size:14px;line-height:1.5;}
.event-card{display:flex;justify-content:space-between;align-items:center;background:var(--panel);border-radius:var(--radius-lg);box-shadow:var(--shadow);padding:14px 18px;margin-bottom:10px;}
.event-card .ev-title{font-weight:600;font-size:14.5px;}
.event-card .ev-meta{font-size:12.5px;color:var(--ink-soft);margin-top:2px;}

/* ---------- Reports ---------- */
.report-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;}
@media(max-width:900px){.report-grid{grid-template-columns:1fr;}}
.check-row{display:flex;flex-wrap:wrap;gap:8px 18px;}
.check-row label{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--ink);cursor:pointer;font-weight:500;}
.check-row input{cursor:pointer;}
.report-summary{display:flex;gap:10px;flex-wrap:wrap;margin:16px 0;}
.report-summary .rs-chip{background:var(--accent-bg);color:var(--accent-deep);font-size:12.5px;font-weight:700;padding:7px 13px;border-radius:20px;}

/* ---------- Settings / connection ---------- */
.conn-status{display:flex;align-items:center;gap:9px;font-size:13.5px;padding:13px 16px;border-radius:12px;background:var(--inspect-bg);color:var(--inspect);margin-bottom:18px;font-weight:600;}
.conn-status .dot2{width:8px;height:8px;border-radius:50%;background:currentColor;flex:none;}
.conn-status.ok{background:var(--ready-bg);color:var(--ready);}
.conn-status.err{background:var(--issue-bg);color:var(--issue);}
.settings-row{display:flex;align-items:center;justify-content:space-between;padding:13px 4px;border-bottom:1px solid var(--line);font-size:13.5px;}
.settings-row:last-child{border-bottom:none;}
.settings-row .sr-label{color:var(--ink-soft);}
code.inline{background:var(--accent-bg);color:var(--accent-deep);padding:2px 6px;border-radius:5px;font-family:'JetBrains Mono',monospace;font-size:12px;}

/* Bare <code> inside a hint — the report API's curl and IMPORTDATA examples.
   These carry a full URL with an id in it, which is longer than the modal is
   wide and has no spaces to break on, so it must be told it may break
   anywhere or it runs straight out of the box. */
.field-hint code{
  display:inline-block;max-width:100%;
  font-family:'JetBrains Mono',monospace;font-size:11.5px;
  overflow-wrap:anywhere;word-break:break-all;
}

.footnote{font-size:11.5px;color:var(--ink-soft);margin-top:26px;padding-top:14px;border-top:1px solid var(--line);}
::-webkit-scrollbar{height:8px;width:8px;}
::-webkit-scrollbar-thumb{background:var(--line);border-radius:8px;}

/* ---------- Global bar: property switcher + search (header) ---------- */
.global-bar{display:flex;align-items:center;gap:10px;padding:12px 0 14px;flex-wrap:wrap;border-top:1px solid rgba(255,255,255,0.08);margin-top:2px;}
.hdr-select{
  background:rgba(255,255,255,0.08);border:1px solid rgba(255,255,255,0.16);color:#fff;
  padding:8px 11px;border-radius:9px;font-size:12.5px;font-weight:600;font-family:inherit;
  max-width:230px;
}
.hdr-select:focus{outline:none;border-color:var(--accent-light);}
.hdr-select option{color:var(--ink);}
.gsearch-wrap{position:relative;flex:1;min-width:180px;max-width:340px;}
.gsearch-input{
  width:100%;background:rgba(255,255,255,0.08);border:1px solid rgba(255,255,255,0.16);color:#fff;
  padding:8px 12px 8px 32px;border-radius:9px;font-size:12.5px;font-family:inherit;
}
.gsearch-input::placeholder{color:rgba(255,255,255,0.45);}
.gsearch-input:focus{outline:none;border-color:var(--accent-light);background:rgba(255,255,255,0.13);}
.gsearch-icon{position:absolute;left:10px;top:50%;transform:translateY(-50%);opacity:.55;pointer-events:none;}
.gsearch-icon svg{width:14px;height:14px;display:block;}
.gsearch-results{
  position:absolute;top:calc(100% + 6px);left:0;right:0;background:var(--panel);border-radius:var(--radius-md);
  box-shadow:var(--shadow-lift);padding:6px;display:none;z-index:50;max-height:360px;overflow-y:auto;
}
.gsearch-results.open{display:block;}
.gsearch-row{display:block;width:100%;text-align:left;background:none;border:none;padding:9px 11px;border-radius:8px;cursor:pointer;}
.gsearch-row:hover{background:var(--accent-bg);}
.gsearch-row .gr-title{font-size:13px;font-weight:600;color:var(--ink);}
.gsearch-row .gr-sub{font-size:11.5px;color:var(--ink-soft);margin-top:1px;}
.gsearch-empty{padding:12px;font-size:12.5px;color:var(--ink-soft);}
.scope-note{font-size:12px;color:var(--accent-deep);background:var(--accent-bg);padding:7px 12px;border-radius:9px;margin-bottom:16px;display:inline-flex;align-items:center;gap:7px;font-weight:600;}
.scope-note button{background:none;border:none;color:var(--accent-deep);text-decoration:underline;cursor:pointer;font-size:12px;font-family:inherit;font-weight:600;padding:0;}

.grid-4{grid-template-columns:repeat(4,1fr);}
@media(max-width:1100px){.grid-4{grid-template-columns:repeat(2,1fr);}}
@media(max-width:560px){.grid-4{grid-template-columns:1fr;}}

/* ---------- Toolbars (search + filters above tables) ---------- */
.view-toolbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:0 0 14px;}
.toolbar-search{position:relative;flex:1;min-width:170px;max-width:300px;}
.toolbar-search input{
  width:100%;padding:9px 12px 9px 32px;border-radius:9px;border:1.5px solid var(--line);
  font-size:13px;font-family:inherit;background:var(--rl-surface);
}
.toolbar-search input:focus{outline:none;border-color:var(--accent);}
.toolbar-search svg{position:absolute;left:10px;top:50%;transform:translateY(-50%);width:14px;height:14px;opacity:.4;}
.qf-row{display:flex;gap:6px;flex-wrap:wrap;}
.spacer{flex:1;}

/* ---------- Pagination ---------- */
.pager-bar{display:flex;align-items:center;justify-content:flex-end;gap:10px;padding:12px 4px 4px;}
.pager-info{font-size:12px;color:var(--ink-soft);margin-right:4px;}

/* ---------- Properties (portfolio) ---------- */
#listingsGrid{grid-template-columns:repeat(auto-fill,minmax(min(100%,340px),1fr));}
.property-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px;}
.property-card{
  background:var(--panel);border-radius:var(--radius-lg);box-shadow:var(--shadow);padding:18px 20px;cursor:pointer;
  border:1.5px solid transparent;transition:box-shadow .15s, border-color .15s;
}
.property-card:hover{box-shadow:var(--shadow-lift);border-color:var(--accent-bg);}
.pc-top{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;}
.pc-name{font-family:'Fraunces',serif;font-weight:600;font-size:17px;margin:0;}
.pc-area{font-size:12px;color:var(--ink-soft);margin-top:2px;}
.pc-code{font-family:'JetBrains Mono',monospace;font-size:11px;background:var(--accent-bg);color:var(--accent-deep);padding:2px 8px;border-radius:20px;font-weight:700;flex:none;}
.pc-stats{display:flex;gap:16px;margin:14px 0 10px;}
.pc-stat b{font-family:'Fraunces',serif;font-size:19px;font-weight:600;display:block;}
.pc-stat span{font-size:11px;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.03em;}
.occ-track{height:7px;border-radius:6px;background:var(--line);overflow:hidden;margin:4px 0 8px;}
.occ-fill{height:100%;background:var(--rl-i-600);border-radius:6px;}
.pc-foot{display:flex;justify-content:space-between;align-items:center;font-size:12px;color:var(--ink-soft);padding-top:10px;border-top:1px solid var(--line);}
.pc-manager b{color:var(--ink);}
.property-detail-head{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;flex-wrap:wrap;margin-bottom:18px;}
.property-detail-head h2{margin-bottom:2px;}

/* ---------- Contacts / timeline ---------- */
.badge.muted{background:var(--line);color:var(--ink-soft);}
.badge.resident{background:var(--occupied-bg);color:var(--occupied);}
.badge.lead{background:var(--inspect-bg);color:var(--inspect);}
.contact-detail-head{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;border-bottom:1px solid var(--line);padding-bottom:14px;margin-bottom:16px;}
.contact-avatar-row{display:flex;align-items:center;gap:12px;}
.contact-avatar{
  width:42px;height:42px;border-radius:var(--rl-r-full);background:var(--rl-tint-accent-bg);
  color:var(--rl-tint-accent-fg);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:15px;flex:none;
  font-family:'Fraunces',serif;
}
.contact-flags{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px;}
.score-pill{font-size:11px;font-weight:700;padding:2px 9px;border-radius:20px;}
.score-hot{background:var(--ready-bg);color:var(--ready);}
.score-warm{background:var(--inspect-bg);color:var(--inspect);}
.score-cold{background:var(--line);color:var(--ink-soft);}
.timeline{margin-top:4px;}
.timeline-item{display:flex;gap:10px;padding:10px 0;border-bottom:1px solid var(--line);}
.timeline-item:last-child{border-bottom:none;}
.ti-dot{width:8px;height:8px;border-radius:50%;background:var(--accent);margin-top:5px;flex:none;}
.ti-dot.tk{background:var(--inspect);}
.ti-dot.pay{background:var(--ready);}
.ti-dot.em{background:var(--accent);}
.ti-dot.nt{background:var(--ink-soft);}
.ti-body{flex:1;font-size:13px;}
.ti-title{font-weight:600;}
.ti-meta{font-size:11.5px;color:var(--ink-soft);margin-top:1px;}
.note-box{display:flex;gap:8px;margin-top:6px;}
.note-box textarea{flex:1;border-radius:10px;border:1.5px solid var(--line);padding:9px 10px;font-family:inherit;font-size:13px;resize:vertical;min-height:44px;}
.contact-info-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px 16px;margin-bottom:18px;}
.contact-info-grid .m-label{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft);font-weight:700;margin-bottom:3px;}
.contact-info-grid .m-val{font-size:13.5px;font-weight:600;}

/* ---------- Tasks ---------- */
.task-group-head{font-size:12.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft);margin:22px 0 8px;}
.task-group-head:first-child{margin-top:0;}
.task-row{display:flex;align-items:flex-start;gap:12px;padding:12px 6px 12px 10px;border-bottom:1px solid var(--line);border-left:3px solid transparent;transition:border-color .15s ease,background .15s ease;}
.task-row:last-child{border-bottom:none;}
.task-row:hover{background:color-mix(in srgb,var(--accent) 3%,transparent);}
.task-row.overdue{border-left-color:var(--issue);}
.task-row.today{border-left-color:var(--inspect);}
.task-check{
  width:19px;height:19px;border-radius:6px;border:1.5px solid var(--line);flex:none;margin-top:1px;cursor:pointer;
  background:var(--rl-surface);display:flex;align-items:center;justify-content:center;
}
.task-check.done{background:var(--ready);border-color:var(--ready);}
.task-check.done svg{display:block;width:12px;height:12px;}
.task-row.done .task-title{text-decoration:line-through;color:var(--ink-soft);}
.task-title{font-size:13.5px;font-weight:600;}
.task-sub{font-size:12px;color:var(--ink-soft);margin-top:3px;display:flex;gap:10px;flex-wrap:wrap;}
.task-due{font-weight:700;}
.task-due.overdue{color:var(--issue);}
.task-due.today{color:var(--inspect);}

/* ---------- Automations ---------- */
.automation-card{background:var(--panel);border-radius:var(--radius-lg);box-shadow:var(--shadow);padding:16px 18px;margin-bottom:12px;display:flex;align-items:center;gap:16px;}
.automation-main{flex:1;}
.automation-title{font-weight:600;font-size:14px;margin-bottom:3px;}
.automation-desc{font-size:12.5px;color:var(--ink-soft);}
.automation-flow{font-family:'JetBrains Mono',monospace;font-size:11.5px;color:var(--accent-deep);background:var(--accent-bg);padding:5px 9px;border-radius:7px;margin-top:8px;display:inline-block;}
.automation-stat{text-align:center;flex:none;}
.automation-stat b{font-family:'Fraunces',serif;font-size:20px;display:block;}
.automation-stat span{font-size:10.5px;color:var(--ink-soft);text-transform:uppercase;}
.switch{position:relative;display:inline-block;width:38px;height:22px;flex:none;}
.switch input{opacity:0;width:0;height:0;position:absolute;}
.switch .slider{position:absolute;cursor:pointer;inset:0;background:var(--line);transition:.15s;border-radius:22px;}
.switch .slider:before{content:'';position:absolute;height:16px;width:16px;left:3px;top:3px;background:#fff;transition:.15s;border-radius:50%;box-shadow:0 1px 3px rgba(20,24,34,.25);}
.switch input:checked + .slider{background:var(--ready);}
.switch input:checked + .slider:before{transform:translateX(16px);}

/* ---------- Aging / arrears ---------- */
.aging-strip{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px;}
@media(max-width:700px){.aging-strip{grid-template-columns:repeat(2,1fr);}}
.aging-card{background:var(--panel);border-radius:var(--radius-md);box-shadow:var(--shadow);padding:14px 16px;text-align:center;}
.aging-card b{font-family:'Fraunces',serif;font-size:22px;display:block;}
.aging-card span{font-size:11px;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.03em;}
.aging-card.b0{border-top:3px solid var(--ready);}
.aging-card.b30{border-top:3px solid var(--inspect);}
.aging-card.b60{border-top:3px solid var(--rl-text-warning);}
.aging-card.b90{border-top:3px solid var(--issue);}

/* ---------- Inspections ---------- */
.insp-score{font-family:'Fraunces',serif;font-weight:600;font-size:15px;}

/* ---------- Sandbox / notice banner ---------- */
.sim-banner{
  background:var(--accent-bg);color:var(--accent-deep);font-size:12.5px;font-weight:600;line-height:1.5;
  padding:11px 15px;border-radius:10px;margin-bottom:18px;display:flex;align-items:flex-start;gap:9px;
}
.sim-banner svg{width:16px;height:16px;flex:none;margin-top:1px;}


/* ==================== ROOMLINE OPERATIONS REFRESH ====================
   What remains of a pre-spec restyle. Its :root — a second, later copy of
   the palette above it — and every rule for the old dark header, brand
   lockup, tab bar and login gradients have gone: that chrome no longer
   exists, and the colours now come from tokens.css. Only the type and
   spacing adjustments that are still doing work are kept.
   ==================================================================== */
main.content{max-width:1440px;padding:30px 24px 40px;}
h2.view-title{font-size:30px;letter-spacing:-.045em;margin-bottom:5px;}.view-sub{font-size:14px!important;}
.card,.list-card,.listing-card,.property-card,.feed-card,.event-card,.form-card,.automation-card,.aging-card{border:1px solid rgba(17,24,39,.06);box-shadow:var(--shadow);border-radius:var(--radius-lg);}
.card{padding:21px 22px;}
.stat-card{position:relative;overflow:hidden;}
.stat-card .stat-label{font-size:10.5px;letter-spacing:.1em;}.stat-card .stat-value{font-size:36px;letter-spacing:-.04em;position:relative;z-index:1;}
.section-head{margin:32px 0 12px;}.section-head h3{font-size:18px;letter-spacing:-.02em;}.section-head .count-pill{padding:4px 10px;}
table{font-size:13px;}table th{padding:11px 12px;font-size:10px;letter-spacing:.08em;}table td{padding:13px 12px;}
.badge{padding:4px 10px;font-size:10.5px;letter-spacing:.01em;}
.btn{border-radius:10px;background:var(--rl-i-600);box-shadow:0 6px 16px -4px var(--accent-ring);}.btn:hover{background:var(--rl-i-700);transform:translateY(-1px);box-shadow:0 10px 22px -6px var(--accent-ring);}.btn:active{transform:translateY(0);}.btn.ghost{background:var(--panel);box-shadow:none;border-color:color-mix(in srgb,var(--accent) 22%,var(--line));}.btn.ghost:hover{background:var(--accent-bg);border-color:var(--accent-light);}
.room-tile{border-radius:14px;background:color-mix(in srgb,var(--accent) 2.5%,var(--panel));padding:12px;border-color:color-mix(in srgb,var(--accent) 12%,var(--line));}
.listing-photo{height:145px;background:var(--rl-surface-sunk);}
.contract-item,.side-item{border-radius:12px;padding:12px 13px;}.contract-item.active,.side-item.active{box-shadow:inset 3px 0 var(--accent);}
.kanban-col{border:1px solid rgba(17,24,39,.06);box-shadow:var(--shadow);border-radius:18px;padding:14px;}.kanban-card{border-radius:12px;background:color-mix(in srgb,var(--accent) 2.5%,var(--panel));}
.cal-day-cell.is-today{background:var(--accent-bg);}.cal-bar{border-radius:10px;}
.form-card{padding:22px;}.form-grid input,.form-grid select,.form-grid textarea,.field-block input,.field-block select,.field-block textarea{border-radius:11px;background:color-mix(in srgb,var(--accent) 2.5%,var(--panel));}
.global-bar{border-top-color:rgba(255,255,255,.12);}
.gsearch-results{border:1px solid var(--line);}
@media(max-width:700px){header.app-head{padding-left:16px;padding-right:16px}main.content{padding:24px 16px 36px}.user-chip{display:none}.brand-row{padding-bottom:15px;flex-wrap:wrap;row-gap:10px}.user-row{flex-wrap:wrap;justify-content:flex-end}#propertyFilter{max-width:none;flex:1 1 100%;order:1}.global-bar{align-items:stretch}.gsearch-wrap{max-width:none;flex:1}.view-title{font-size:26px!important}}



/* ==================== DYNAMIC THEME CONTROLS ==================== */
/* Dark mode is defined once, in tokens.css §17 — a separate, deliberately
   chosen palette rather than an inversion. These rules used to carry a
   second one: their own near-black surfaces, two decorative radial
   gradients, and var(--rl-surface) — a GREEN-black — behind every input and select in
   the product, including the sign-in fields and every search box. That is
   why the dark theme read as a different, slightly bilious application.
   Everything here now resolves through the token layer. */
html[data-theme="dark"] body{background:var(--rl-canvas);}
html[data-theme="dark"] select,html[data-theme="dark"] input,html[data-theme="dark"] textarea{background:var(--rl-surface);color:var(--rl-text);border-color:var(--rl-line-control);}
html[data-theme="dark"] .btn-ghost{color:var(--rl-text);background:transparent;border-color:var(--rl-line-control);}
html[data-theme="dark"] .modal-scrim{background:var(--rl-overlay);}
html[data-theme="dark"] .chip{background:var(--rl-surface);color:var(--rl-text-2);border-color:var(--rl-line);}
html[data-theme="dark"] .chip.active{background:var(--rl-tint-accent-bg);color:var(--rl-tint-accent-fg);border-color:transparent;}
.theme-tools{display:inline-flex;align-items:center;gap:8px;}
.theme-toggle{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--line-strong);background:rgba(255,255,255,.42);color:var(--ink);border-radius:999px;padding:8px 12px;font:600 12px Inter,sans-serif;cursor:pointer;}
.theme-toggle:hover{border-color:var(--accent);transform:translateY(-1px);}
.theme-toggle .theme-icon{font-size:14px;line-height:1;}
.theme-customize{border:1px solid var(--line-strong);background:transparent;color:var(--ink);width:34px;height:34px;border-radius:50%;cursor:pointer;font-size:16px;}
.theme-customize:hover{background:color-mix(in srgb,var(--accent) 11%,transparent);}
.theme-panel{position:fixed;right:20px;top:92px;width:286px;z-index:120;background:var(--bg-panel,#fff);border:1px solid var(--line);border-radius:18px;padding:18px;box-shadow:0 22px 60px rgba(0,0,0,.18);display:none;}
.theme-panel.open{display:block;animation:theme-panel-in .18s ease-out;}
@keyframes theme-panel-in{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.theme-panel-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;}
.theme-panel-head strong{font-size:13px;letter-spacing:-.01em;}.theme-panel-close{border:0;background:none;color:var(--ink-soft);font-size:18px;cursor:pointer;}
.theme-control{margin-top:14px;}.theme-control label{display:flex;justify-content:space-between;align-items:center;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-soft);margin-bottom:8px;}
.theme-control input[type=color]{width:100%;height:38px;padding:3px;border:1px solid var(--line-strong);border-radius:10px;background:transparent;cursor:pointer;}
.theme-presets{display:flex;gap:8px;flex-wrap:wrap;}.theme-preset{width:27px;height:27px;border-radius:50%;border:2px solid transparent;cursor:pointer;box-shadow:0 0 0 1px var(--line-strong);}.theme-preset.active{border-color:var(--ink);box-shadow:0 0 0 2px var(--bg-panel),0 0 0 4px var(--accent);}
.theme-reset{width:100%;margin-top:16px;border:1px solid var(--line-strong);background:transparent;color:var(--ink);border-radius:10px;padding:9px;font:600 12px Inter,sans-serif;cursor:pointer;}
@media(max-width:560px){.theme-panel{right:12px;left:12px;top:80px;width:auto}.theme-toggle .theme-label{display:none}.theme-tools{gap:5px}}

/* RoomLine-specific dark surfaces and control styling */
html[data-theme="dark"] #app{background:var(--rl-canvas);}
html[data-theme="dark"] #app .card,html[data-theme="dark"] #app .list-card,html[data-theme="dark"] #app .property-card,html[data-theme="dark"] #app .listing-card,html[data-theme="dark"] #app .feed-card,html[data-theme="dark"] #app .event-card,html[data-theme="dark"] #app .form-card,html[data-theme="dark"] #app .automation-card,html[data-theme="dark"] #app .aging-card{background:var(--rl-surface);border-color:var(--rl-line);}
html[data-theme="dark"] #app table td,html[data-theme="dark"] #app table th{border-color:var(--rl-line-soft);}
/* A control in dark mode sits on --rl-surface with a --rl-line-control edge,
   the same relationship it has in light. It used to sit on var(--rl-surface), darker
   than the card it was in, which read as a hole rather than a field. */
html[data-theme="dark"] #app input,html[data-theme="dark"] #app select,html[data-theme="dark"] #app textarea{background:var(--rl-surface);color:var(--rl-text);border-color:var(--rl-line-control);}
html[data-theme="dark"] #app .room-tile,html[data-theme="dark"] #app .kanban-card,html[data-theme="dark"] #app .listing-offer{background:var(--rl-surface-raised);color:var(--rl-text);border-color:var(--rl-line);}
html[data-theme="dark"] #app .modal-error{background:var(--rl-tint-red-bg);border-color:var(--rl-r-700);color:var(--rl-tint-red-fg);}
html[data-theme="dark"] #app .btn.danger{background:transparent;color:var(--rl-text-danger);border-color:var(--rl-r-700);}
html[data-theme="dark"] #app .btn.danger:hover{background:var(--rl-tint-red-bg);}
html[data-theme="dark"] #app .btn.ghost{background:transparent;color:var(--rl-text);border-color:var(--rl-line-control);}


/* =========================================================
   TEAM CHANNEL, NOTIFICATIONS AND THE FILE STORE
   Everything below uses only the theme variables (--panel, --line,
   --ink, --ink-soft, --accent), which `html[data-theme="dark"] #app`
   redefines — so dark mode needs no second set of rules here.
   ========================================================= */

/* --- header icon buttons (bell, chat) --- */
.hdr-icon-btn{
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;flex:0 0 auto;border:1px solid var(--line);border-radius:9px;
  background:var(--panel);color:var(--ink-soft);cursor:pointer;padding:0;
  transition:color .15s ease,border-color .15s ease;
}
.hdr-icon-btn:hover{color:var(--ink);border-color:var(--accent-light);}
.hdr-icon-btn svg{width:18px;height:18px;}
.hdr-badge{
  position:absolute;top:-6px;right:-6px;min-width:17px;height:17px;padding:0 4px;
  border-radius:9px;background:var(--issue,var(--rl-text-danger));color:#fff;
  font-size:10.5px;font-weight:700;line-height:17px;text-align:center;
}

/* --- notifications dropdown --- */
/* Anchored to the RIGHT of the bell — .dd-panel defaults to left:0, which
   put 280px of a 370px panel off the right edge of the viewport since the
   bell sits in the top-right corner. */
.notif-panel{width:370px;max-width:calc(100vw - 32px);padding:0;overflow:hidden;left:auto;right:0;}
.notif-head{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:11px 14px;border-bottom:1px solid var(--line);font-size:13px;font-weight:600;
}
.notif-list{max-height:min(430px,60vh);overflow-y:auto;}
.notif-item{
  display:flex;gap:10px;width:100%;text-align:left;padding:11px 14px;
  background:none;border:0;border-bottom:1px solid var(--line);cursor:pointer;
}
.notif-item:hover{background:var(--accent-bg);}
.notif-item.unread{background:color-mix(in srgb,var(--accent) 7%,transparent);}
.notif-ico{
  flex:0 0 auto;width:26px;height:26px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--accent-bg);color:var(--accent);
}
.notif-ico svg{width:14px;height:14px;}
.notif-body{display:flex;flex-direction:column;gap:1px;min-width:0;}
.notif-line{font-size:12px;color:var(--ink-soft);}
.notif-title{font-size:13px;font-weight:600;color:var(--ink);overflow-wrap:anywhere;}
.notif-sub{font-size:12px;color:var(--ink-soft);}
.notif-when{font-size:11px;color:var(--ink-soft);margin-top:2px;}

/* --- the team channel panel ---
   Redesigned for actual depth: layered shadows instead of one flat line,
   gradient surfaces on anything meant to feel "raised" (avatars, the sent
   bubble, the compose bar, the send button), and a soft directional light
   (top-left highlight, bottom-right shadow) on the panel itself so it
   reads as a physical pane floating over the workspace, not a flat
   sidebar tacked on. */
.team-chat{
  position:fixed;top:0;right:0;bottom:0;width:380px;max-width:100vw;z-index:60;
  display:flex;flex-direction:column;
  background:var(--rl-surface);
  border-left:1px solid var(--line);
  box-shadow:-1px 0 0 rgba(255,255,255,.5) inset,-14px 0 40px rgba(20,24,34,.10),-2px 0 10px rgba(20,24,34,.06);
  transform:translateX(100%);transition:transform .26s cubic-bezier(.19,1,.22,1);
}
.team-chat.open{transform:translateX(0);}
html[data-theme="dark"] .team-chat{
  box-shadow:-1px 0 0 rgba(255,255,255,.04) inset,-14px 0 40px rgba(0,0,0,.35),-2px 0 10px rgba(0,0,0,.25);
}
html[data-theme="dark"] .chat-head{box-shadow:0 1px 0 rgba(255,255,255,.05) inset,0 6px 14px -10px rgba(0,0,0,.5);}
html[data-theme="dark"] .chat-channel{background:var(--rl-surface-raised);box-shadow:none;}
html[data-theme="dark"] .chat-att-file{background:rgba(255,255,255,.05);}
html[data-theme="dark"] .chat-pending-att.uploading::after{background:rgba(0,0,0,.4);}
.chat-head{
  display:flex;align-items:center;gap:8px;padding:13px 14px;
  background:var(--rl-surface);
  border-bottom:1px solid var(--line);
  box-shadow:0 1px 0 rgba(255,255,255,.6) inset,0 6px 14px -10px rgba(20,24,34,.4);
  position:relative;z-index:2;flex:0 0 auto;
}
.chat-channel{
  flex:1;font-size:13px;font-weight:700;padding:8px 10px;
  border:1px solid var(--line);border-radius:10px;
  background:var(--rl-surface);
  color:var(--ink);box-shadow:0 1px 2px rgba(20,24,34,.05),0 1px 0 rgba(255,255,255,.7) inset;
  transition:border-color .15s ease,box-shadow .15s ease;
}
.chat-channel:hover{border-color:var(--accent-light);}
.chat-close{
  width:28px;height:28px;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  border:1px solid transparent;border-radius:9px;background:none;font-size:19px;line-height:1;cursor:pointer;
  color:var(--ink-soft);transition:background .15s ease,color .15s ease,transform .15s ease;
}
.chat-close:hover{background:var(--issue-bg);color:var(--issue);border-color:transparent;}
.chat-close:active{transform:scale(.9);}
#chatHeadActions{display:flex;align-items:center;flex:0 0 auto;}
.chat-add-ppl{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:700;
  padding:6px 9px;border:1px solid var(--line);border-radius:9px;background:var(--panel);
  color:var(--ink-soft);cursor:pointer;white-space:nowrap;}
.chat-add-ppl:hover{border-color:var(--accent-light);color:var(--ink);}
.chat-body{
  flex:1;overflow-y:auto;padding:14px 12px;display:flex;flex-direction:column;gap:10px;
  background:
    transparent;
}
.chat-day{
  align-self:center;font-size:10.5px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;
  color:var(--ink-soft);background:var(--panel);border:1px solid var(--line);
  box-shadow:0 1px 2px rgba(20,24,34,.05);
  border-radius:20px;padding:3px 12px;margin:6px 0 2px;
}
.chat-msg{display:flex;gap:8px;align-items:flex-end;}
.chat-msg.mine{flex-direction:row-reverse;}
.chat-avatar{
  flex:0 0 auto;width:28px;height:28px;border-radius:50%;
  background:var(--rl-i-600);color:#fff;
  font-size:10.5px;font-weight:700;letter-spacing:.02em;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 2px 4px rgba(20,24,34,.18),inset 0 1px 0 rgba(255,255,255,.35);
}
.chat-bubble{
  position:relative;max-width:78%;background:var(--panel);
  border:1px solid var(--line);
  border-radius:16px;padding:8px 11px;
  box-shadow:0 1px 2px rgba(20,24,34,.06),0 6px 14px -8px rgba(20,24,34,.18);
}
.chat-msg.mine .chat-bubble{
  background:var(--rl-i-600);
  color:#fff;border-color:transparent;
  box-shadow:0 3px 8px -2px color-mix(in srgb,var(--accent) 55%,transparent),0 1px 0 rgba(255,255,255,.25) inset;
}
.chat-meta{display:block;font-size:11px;font-weight:600;color:var(--ink-soft);margin-bottom:2px;}
.chat-msg.mine .chat-meta{color:rgba(255,255,255,.85);}
.chat-text{display:block;font-size:13.5px;line-height:1.45;overflow-wrap:anywhere;}
.chat-mention{font-weight:700;padding:0 3px;border-radius:5px;background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent-deep);}
.chat-msg.mine .chat-mention{background:rgba(255,255,255,.22);color:#fff;}
.chat-del{
  position:absolute;top:-6px;right:-6px;width:19px;height:19px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line);background:var(--panel);cursor:pointer;
  color:var(--ink-soft);opacity:0;font-size:13px;line-height:1;padding:0;
  box-shadow:0 2px 5px rgba(20,24,34,.16);transition:opacity .12s ease,transform .12s ease,color .12s ease;
}
.chat-bubble:hover .chat-del{opacity:1;}
.chat-del:hover{color:var(--issue);transform:scale(1.1);}

/* --- attachments: an inline photo grid inside the bubble, or a small
   file chip for anything that is not an image --- */
.chat-atts{display:flex;flex-wrap:wrap;gap:5px;margin-top:5px;}
.chat-atts:first-child{margin-top:0;}
.chat-att-img{
  width:132px;height:96px;border-radius:10px;object-fit:cover;cursor:pointer;
  border:1px solid rgba(20,24,34,.08);box-shadow:0 3px 8px rgba(20,24,34,.16);
  transition:transform .15s ease,box-shadow .15s ease;display:block;background:var(--bg);
}
.chat-att-img:hover{transform:translateY(-2px) scale(1.015);box-shadow:0 8px 18px rgba(20,24,34,.22);}
.chat-att-file{
  display:flex;align-items:center;gap:7px;padding:6px 10px 6px 6px;
  background:rgba(255,255,255,.7);border:1px solid var(--line);border-radius:10px;
  font-size:12px;font-weight:600;color:inherit;cursor:pointer;max-width:220px;
  box-shadow:0 1px 2px rgba(20,24,34,.05);transition:transform .12s ease,box-shadow .12s ease;
}
.chat-msg.mine .chat-att-file{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.3);}
.chat-att-file:hover{transform:translateY(-1px);box-shadow:0 4px 10px rgba(20,24,34,.14);}
.chat-att-file .att-ico{
  flex:0 0 auto;width:26px;height:26px;border-radius:7px;display:flex;align-items:center;justify-content:center;
  background:var(--accent-bg);color:var(--accent);
}
.chat-msg.mine .chat-att-file .att-ico{background:rgba(255,255,255,.25);color:#fff;}
.chat-att-file .att-ico svg{width:14px;height:14px;}
.chat-att-file .att-meta{display:flex;flex-direction:column;gap:0;min-width:0;}
.chat-att-file .att-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.chat-att-file .att-size{font-size:10.5px;font-weight:500;opacity:.7;}

/* --- mention autocomplete: a floating card docked above the compose bar --- */
.chat-mention-pop{
  position:absolute;left:12px;right:12px;bottom:calc(100% + 8px);z-index:5;
  max-height:220px;overflow-y:auto;
  background:var(--panel);border:1px solid var(--line);border-radius:14px;
  box-shadow:0 10px 26px rgba(20,24,34,.18),0 2px 6px rgba(20,24,34,.08);
  padding:6px;display:none;
}
.chat-mention-pop.open{display:block;animation:chatMentionIn .14s cubic-bezier(.19,1,.22,1);}
@keyframes chatMentionIn{from{opacity:0;transform:translateY(4px);}to{opacity:1;transform:translateY(0);}}
.chat-mention-row{
  display:flex;align-items:center;gap:9px;padding:7px 8px;border-radius:9px;cursor:pointer;
}
.chat-mention-row .chat-avatar{width:24px;height:24px;font-size:9.5px;}
.chat-mention-name{font-size:13px;font-weight:700;}
.chat-mention-role{font-size:11px;color:var(--ink-soft);}
.chat-mention-row.active,.chat-mention-row:hover{background:var(--accent-bg);}
.chat-mention-row.active .chat-mention-name{color:var(--accent-deep);}
.chat-mention-empty{padding:10px;font-size:12px;color:var(--ink-soft);text-align:center;}

.chat-compose-wrap{
  position:relative;flex:0 0 auto;
  background:var(--rl-surface);
  border-top:1px solid var(--line);
  box-shadow:0 -6px 14px -12px rgba(20,24,34,.35);
}
.chat-pending-atts{
  display:flex;flex-wrap:wrap;gap:8px;padding:10px 12px 0;
}
.chat-pending-att{
  position:relative;width:56px;height:56px;border-radius:10px;overflow:hidden;
  border:1px solid var(--line);box-shadow:0 3px 8px rgba(20,24,34,.14);
  display:flex;align-items:center;justify-content:center;background:var(--bg);
}
.chat-pending-att img{width:100%;height:100%;object-fit:cover;display:block;}
.chat-pending-att .pa-ico{color:var(--ink-soft);}
.chat-pending-att .pa-ico svg{width:20px;height:20px;}
.chat-pending-att.uploading::after{
  content:'';position:absolute;inset:0;background:rgba(255,255,255,.55);
  animation:chatUploadPulse 1.1s ease-in-out infinite;
}
@keyframes chatUploadPulse{0%,100%{opacity:.35;}50%{opacity:.75;}}
.chat-pending-remove{
  position:absolute;top:2px;right:2px;width:16px;height:16px;border-radius:50%;
  border:0;background:rgba(20,24,34,.62);color:#fff;font-size:11px;line-height:1;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
}
.chat-compose{
  flex:0 0 auto;display:flex;gap:8px;align-items:flex-end;
  padding:10px 12px;position:relative;
}
.chat-attach-btn{
  flex:0 0 auto;width:36px;height:36px;border-radius:11px;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  border:1px solid var(--line);background:var(--panel);color:var(--ink-soft);
  box-shadow:0 1px 2px rgba(20,24,34,.05);
  transition:color .15s ease,border-color .15s ease,transform .12s ease,background .15s ease;
}
.chat-attach-btn:hover{color:var(--accent);border-color:var(--accent-light);background:var(--accent-bg);}
.chat-attach-btn:active{transform:scale(.92);}
.chat-attach-btn svg{width:17px;height:17px;}
.chat-compose textarea{
  flex:1;resize:none;max-height:120px;font:inherit;font-size:13.5px;
  padding:9px 12px;border:1px solid var(--line);border-radius:14px;
  background:var(--bg);color:var(--ink);
  box-shadow:0 1px 3px rgba(20,24,34,.07) inset;
  transition:border-color .15s ease,box-shadow .15s ease;
}
.chat-compose textarea:focus{
  outline:none;border-color:var(--accent-light);
  box-shadow:0 1px 3px rgba(20,24,34,.05) inset,0 0 0 3px color-mix(in srgb,var(--accent) 16%,transparent);
}
.chat-send-btn{
  flex:0 0 auto;width:36px;height:36px;border-radius:50%;border:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  background:var(--rl-i-600);color:#fff;
  box-shadow:0 3px 8px -1px color-mix(in srgb,var(--accent) 55%,transparent),0 1px 0 rgba(255,255,255,.3) inset;
  transition:transform .12s ease,box-shadow .12s ease;
}
.chat-send-btn svg{width:16px;height:16px;margin-left:1px;}
.chat-send-btn:hover{transform:translateY(-1px);box-shadow:0 5px 12px -1px color-mix(in srgb,var(--accent) 60%,transparent),0 1px 0 rgba(255,255,255,.3) inset;}
.chat-send-btn:active{transform:translateY(0) scale(.94);}
.chat-send-btn:disabled{opacity:.5;cursor:default;transform:none;box-shadow:none;}

/* The workspace is centred with its own max width, so the panel overlays
   rather than pushing content. Below the point where 380px of panel would
   cover most of the screen, it goes full width instead. */
@media (max-width:640px){
  .team-chat{width:100%;}
}

/* --- file store --- */
.file-ext{
  display:inline-block;min-width:38px;text-align:center;
  font-size:10px;font-weight:700;letter-spacing:.03em;
  padding:3px 6px;border-radius:5px;
  background:var(--accent-bg);color:var(--accent-deep);
}
.file-detail{margin-bottom:14px;}
.file-drow{
  display:flex;gap:12px;padding:6px 0;border-bottom:1px solid var(--line);font-size:13px;
}
.file-dlabel{flex:0 0 130px;color:var(--ink-soft);}
.file-dvalue{flex:1;overflow-wrap:anywhere;}
.file-locked{
  display:block;margin:12px 0 0;padding:11px 13px;border-radius:9px;font-size:12.5px;
  background:var(--inspect-bg,var(--rl-tint-amber-bg));color:var(--inspect,var(--rl-text-warning));
  border:1px solid color-mix(in srgb,var(--inspect,var(--rl-text-warning)) 30%,transparent);
}

/* --- arriving at a task from a notification --- */
.task-by{
  font-size:11px;color:var(--ink-soft);margin-left:6px;
  padding:1px 6px;border-radius:20px;background:var(--accent-bg);
}
.task-flash{
  animation:taskFlash 2.2s ease;
  border-radius:10px;
}
@keyframes taskFlash{
  0%,55%{background:color-mix(in srgb,var(--accent) 18%,transparent);}
  100%{background:transparent;}
}

/* =========================================================
   SITE-WIDE ELEVATION — every section, not just Dashboard.

   Everything below targets the dozen or so primitives every one of the
   ~25 views is actually built from (.card and its siblings, table,
   .badge, .btn, form inputs, .kanban-*, the modal, .empty-note, pills) —
   one pass here reaches every screen the same way the token refresh
   already does, rather than hand-redoing each view. Same depth/motion
   language as the Dashboard charts and the team channel: real hover
   states, a table that responds to the pointer, a modal that opens
   instead of appearing, badges and buttons with actual weight. Nothing
   here changes markup or class names, only how the existing ones look —
   nothing downstream that reads a class name to decide behaviour is
   affected. */

/* --- cards: uniform lift on hover, everywhere one appears --- */
.card,.list-card,.listing-card,.property-card,.feed-card,.event-card,
.form-card,.automation-card,.aging-card,.kanban-col{
  transition:box-shadow .18s ease, transform .18s ease, border-color .18s ease;
}
.listing-card:hover,.feed-card:hover,.event-card:hover,.automation-card:hover{
  box-shadow:var(--shadow-lift);transform:translateY(-2px);border-color:var(--accent-bg);
}
/* .property-card already had its own :hover (border + shadow, no lift) —
   left as-is rather than doubling up with a conflicting transform. */

/* --- tables: rows that respond to the pointer instead of sitting there
   as static text --- */
table tbody tr{transition:background .12s ease;}
table tbody tr:hover td{background:var(--accent-bg);}
table tbody tr:hover td:first-child{border-radius:8px 0 0 8px;}
table tbody tr:hover td:last-child{border-radius:0 8px 8px 0;}

/* --- badges: a status dot instead of flat color-on-color --- */
.badge{display:inline-flex;align-items:center;gap:5px;}
.badge::before{content:'';width:6px;height:6px;border-radius:50%;background:currentColor;flex:none;opacity:.85;}
.badge.muted::before{opacity:.5;}

/* --- buttons: consistent lift + press feedback everywhere a .btn
   appears, not only the ones that had already been hand-tuned --- */
.btn{transition:transform .12s ease, box-shadow .12s ease, background .15s ease, filter .12s ease;}
.btn:hover{filter:brightness(1.04);}
.btn:active{transform:translateY(0) scale(.97);}
.btn.ghost{transition:transform .12s ease,background .15s ease,border-color .15s ease;}
.btn.ghost:hover{transform:translateY(-1px);}
.btn.ghost:active{transform:translateY(0) scale(.97);}
.btn:disabled,.btn.ghost:disabled{opacity:.5;cursor:default;transform:none!important;filter:none;}

/* --- form inputs: a focus ring instead of a bare border-colour swap,
   matching the compose box in the team channel --- */
.field-block input:focus,.field-block select:focus,.field-block textarea:focus,
.form-grid input:focus,.form-grid select:focus,.form-grid textarea:focus,
.toolbar-search input:focus{
  outline:none;border-color:var(--accent-light);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 15%,transparent);
}

/* --- kanban cards: same depth language as everything else --- */
.kanban-card{box-shadow:0 1px 2px rgba(20,24,34,.05);transition:transform .15s ease,box-shadow .15s ease;}
.kanban-card:hover{transform:translateY(-2px);box-shadow:0 6px 14px -4px rgba(20,24,34,.2);}

/* --- side lists / contract picker rows: a small lift, not just a
   background swap, so the active one reads as selected rather than
   merely coloured --- */
.side-item,.contract-item{transition:background .12s ease, transform .12s ease;}
.side-item:hover,.contract-item:hover{transform:translateX(2px);}

/* --- the modal: a blurred backdrop and a scale-in instead of the box
   just appearing mid-frame --- */
.modal-overlay{backdrop-filter:blur(3px);animation:modalScrimIn .15s ease;}
.modal-box{animation:modalBoxIn .18s cubic-bezier(.19,1,.22,1);}
@keyframes modalScrimIn{from{opacity:0;}to{opacity:1;}}
@keyframes modalBoxIn{from{opacity:0;transform:scale(.96) translateY(6px);}to{opacity:1;transform:none;}}

/* --- empty states: this exact class carries "no rows yet", "loading…"
   and "couldn't load" alike across ~25 modules, so it stays text-first —
   but framed as a soft well rather than grey text with nothing round it,
   which read as unstyled rather than deliberately empty. */
.empty-note{
  padding:22px 16px;text-align:center;
  border:1.5px dashed var(--line);border-radius:var(--radius-md);
  background:color-mix(in srgb,var(--panel) 100%,var(--ink) 1.5%);
}

/* --- pills: .count-pill, .chip-count, .task-by and friends share this
   shape already — give the family a hairline border so it reads as a
   chip sitting on the surface rather than a flat colour patch --- */
.count-pill,.chip-count,.task-by,.hdr-badge{box-shadow:0 1px 0 rgba(255,255,255,.5) inset;}
html[data-theme="dark"] .count-pill,html[data-theme="dark"] .chip-count,
html[data-theme="dark"] .task-by,html[data-theme="dark"] .hdr-badge{box-shadow:none;}

/* --- room tiles, aging cards, automation cards: the same hover lift as
   everything above, for the handful of card-like elements that don't
   already share a selector with .card --- */
.room-tile,.aging-card{transition:transform .15s ease,box-shadow .15s ease;}
.room-tile:hover{transform:translateY(-1px);box-shadow:0 4px 10px rgba(20,24,34,.1);}

/* --- stat tiles: the plain label/value/foot KPI card used 70-odd times
   across every finance, ops and people screen. The same top accent bar
   as the Dashboard's chart cards, so a metric reads as "a system" rather
   than plain text sitting in a box — one rule, every stat tile in the
   app, no markup changes needed anywhere it's already used. --- */
.stat-card::before{
  content:'';position:absolute;inset:0 0 auto 0;height:2px;
  background:var(--rl-i-600);
  opacity:.65;
}


/* =========================================================
   DASHBOARD — headline band, attention row, today strip

   Replaces a flat eight-across "snapshot" in which a lapsed statutory
   check and a routine headcount were set in identical type. Three bands
   now, in descending order of how much a number should interrupt you:
   the headline money/occupancy figures, the queues that need action
   (tinted from their own data), and the day's movements.
   ========================================================= */

/* Tone tokens. Every dashboard tile paints from --tone/--tone-bg, and
   renderDashboard sets [data-tone] from the numbers themselves — so a
   clear board reads calm and green rather than permanently alarmed. */
#view-dashboard [data-tone="issue"]  {--tone:var(--issue);   --tone-bg:var(--issue-bg);}
#view-dashboard [data-tone="warn"]   {--tone:var(--inspect); --tone-bg:var(--inspect-bg);}
#view-dashboard [data-tone="ok"]     {--tone:var(--ready);   --tone-bg:var(--ready-bg);}
#view-dashboard [data-tone="ready"]  {--tone:var(--ready);   --tone-bg:var(--ready-bg);}
#view-dashboard [data-tone="idle"],
#view-dashboard [data-tone="accent"] {--tone:var(--accent);  --tone-bg:var(--accent-bg);}

/* ---------- Headline band ---------- */
.dash-hero{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:6px;}
@media(max-width:980px){.dash-hero{grid-template-columns:1fr;}}
.hero-metric{
  --tone:var(--accent);--tone-bg:var(--accent-bg);
  position:relative;overflow:hidden;
  background:
    var(--rl-surface);
  border:1px solid var(--line);border-radius:var(--radius-lg);
  padding:19px 22px 18px;box-shadow:var(--shadow);
  transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease;
}
/* A hairline of the tile's own colour along the top edge — the cheapest
   way to give three otherwise identical cards a read order. */
.hero-metric::before{
  content:'';position:absolute;inset:0 0 auto 0;height:3px;
  background:var(--tone);
}
.hero-metric[onclick]{cursor:pointer;}
.hero-metric[onclick]:hover{transform:translateY(-2px);box-shadow:var(--shadow-lift);border-color:color-mix(in srgb,var(--tone) 40%,var(--line));}
.hero-top{display:flex;align-items:center;gap:9px;margin-bottom:10px;}
.hero-ico{
  flex:0 0 auto;width:30px;height:30px;border-radius:9px;
  display:flex;align-items:center;justify-content:center;
  background:var(--tone-bg);color:var(--tone);
}
.hero-ico svg{width:16px;height:16px;}
.hero-label{
  font-size:11px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-soft);
}
.hero-value{
  display:block;font-family:'Fraunces',serif;font-weight:600;
  font-size:40px;line-height:1.05;letter-spacing:-.04em;color:var(--ink);
}
.hero-value.alert{color:var(--tone);}
.hero-bar{
  height:6px;border-radius:99px;margin:13px 0 11px;
  background:color-mix(in srgb,var(--ink) 8%,transparent);overflow:hidden;
}
.hero-bar i{
  display:block;height:100%;width:0;border-radius:99px;
  background:var(--tone);
  transition:width .6s cubic-bezier(.16,1,.3,1);
}
.hero-foot{font-size:12.5px;color:var(--ink);font-weight:600;line-height:1.45;}
.hero-foot.dim{color:var(--ink-soft);font-weight:500;font-size:11.5px;margin-top:2px;}

/* ---------- Needs attention ---------- */
.attention-head{align-items:center;justify-content:flex-start;gap:10px;}
.attention-head .count-pill{background:var(--issue-bg);color:var(--issue);}
.attention-head[data-clear="1"] .count-pill{background:var(--ready-bg);color:var(--ready);}
.attention-row{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;}
@media(max-width:1240px){.attention-row{grid-template-columns:repeat(3,1fr);}}
@media(max-width:780px){.attention-row{grid-template-columns:repeat(2,1fr);}}
@media(max-width:460px){.attention-row{grid-template-columns:1fr;}}
.att-tile{
  --tone:var(--accent);--tone-bg:var(--accent-bg);
  display:flex;align-items:flex-start;gap:11px;text-align:left;
  background:var(--panel);border:1px solid var(--line);
  border-left:3px solid var(--tone);
  border-radius:var(--radius-md);padding:14px 15px;cursor:pointer;font:inherit;
  transition:transform .15s ease,box-shadow .15s ease,border-color .15s ease;
}
.att-tile:hover{transform:translateY(-2px);box-shadow:var(--shadow-lift);}
.att-ico{
  flex:0 0 auto;width:30px;height:30px;border-radius:9px;
  display:flex;align-items:center;justify-content:center;
  background:var(--tone-bg);color:var(--tone);
}
.att-ico svg{width:16px;height:16px;}
.att-body{display:flex;flex-direction:column;gap:1px;min-width:0;}
.att-value{font-family:'Fraunces',serif;font-size:25px;font-weight:600;letter-spacing:-.03em;line-height:1.15;color:var(--ink);}
.att-label{font-size:12.5px;font-weight:600;color:var(--ink);}
.att-foot{font-size:11.5px;color:var(--ink-soft);overflow-wrap:anywhere;line-height:1.4;}
/* A cleared queue should stop competing for attention. */
.att-tile[data-tone="ok"]{background:color-mix(in srgb,var(--ready) 2.5%,var(--panel));}
.att-tile[data-tone="ok"] .att-value{color:var(--ink-soft);}
.att-tile[data-tone="issue"] .att-value{color:var(--tone);}

/* ---------- Today strip ---------- */
.today-strip{margin-top:0;}
.today-tile{align-items:flex-start;}
/* Only the tiles that actually navigate should lift on hover — the
   in-house count is a figure, not a link. */
div.today-tile{cursor:default;}
div.today-tile:hover{transform:none;box-shadow:none;border-color:var(--line);}
.tt-note.dim{color:var(--ink-soft);font-weight:500;}
/* Marks a panel that deliberately ignores the header's site filter. */
.section-head .head-note{font-size:11.5px;color:var(--ink-soft);font-weight:500;}

/* Dark mode restates the tone ramp only. The semantic --issue/--ready/
   --inspect tokens themselves are left alone on purpose: they are also the
   text colour inside the light-tinted badges used across every table, and
   brightening those would trade a fix here for unreadable badges there.
   var(--rl-text-danger) on a var(--rl-surface) card measures 3.1:1 — legal for large type and
   nothing else, which is too thin a margin for the one number on the
   dashboard that means someone owes money. */
html[data-theme="dark"] #view-dashboard [data-tone="issue"]{--tone:var(--rl-tint-red-fg);--tone-bg:var(--rl-tint-red-bg);}
html[data-theme="dark"] #view-dashboard [data-tone="warn"]{--tone:var(--rl-tint-amber-fg);--tone-bg:var(--rl-tint-amber-bg);}
html[data-theme="dark"] #view-dashboard [data-tone="ok"],
html[data-theme="dark"] #view-dashboard [data-tone="ready"]{--tone:var(--rl-tint-green-fg);--tone-bg:var(--rl-tint-green-bg);}
html[data-theme="dark"] #view-dashboard [data-tone="idle"],
html[data-theme="dark"] #view-dashboard [data-tone="accent"]{--tone:var(--rl-tint-accent-fg);--tone-bg:var(--rl-tint-accent-bg);}
/* The track the progress bar sits in needs to be lighter than the card in
   dark mode, not darker. */
html[data-theme="dark"] .hero-bar{background:var(--rl-surface-raised);}

/* =========================================================
   KEYBOARD FOCUS
   There was no :focus-visible rule anywhere in this file, so keyboard
   users got each browser's default outline where one survived and nothing
   at all on the many controls that set `outline:none` — including the
   login inputs. :focus-visible rather than :focus so a mouse click on a
   button doesn't leave a ring behind it.
   ========================================================= */
:where(a,button,input,select,textarea,[tabindex],.att-tile,.today-tile,.hero-metric[onclick]):focus-visible{
  outline:2px solid var(--accent);
  outline-offset:2px;
  border-radius:6px;
}
/* Inputs carry their own radius, so match it rather than boxing a pill in
   a rectangle. */
:where(input,select,textarea):focus-visible{outline-offset:1px;border-radius:inherit;}
/* On the dark header the accent is too close to the chrome to read. */
header.app-head :where(a,button,input,select,[tabindex]):focus-visible{
  outline-color:#fff;outline-offset:2px;
}

/* --- "New direct message" picker (openNewDmPicker, inside the shared
   #appModal) — reuses the @mention popover's row styling so a second
   "find a colleague" pattern isn't invented for one dialog. --- */
.chat-dm-picker-list{max-height:320px;overflow-y:auto;margin-top:4px;}
.chat-dm-picker-list .chat-mention-row{padding:9px 8px;}
.chat-dm-picker-list .chat-mention-row:hover{background:var(--accent-bg);cursor:pointer;}

/* =========================================================================
   CONTRACT CREATION WIZARD (js/contract-wizard.js)
   ========================================================================= */
.cw-overlay{position:fixed;inset:0;z-index:200;background:var(--rl-canvas);display:flex;flex-direction:column;overflow:auto;}
html[data-theme="dark"] .cw-overlay{background:var(--rl-canvas);}
.cw-shell{flex:1;display:flex;flex-direction:column;min-height:100%;}
.cw-shell-narrow{max-width:560px;margin:0 auto;width:100%;}
.cw-head{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;border-bottom:1px solid var(--line);background:var(--panel);position:sticky;top:0;z-index:2;}
.cw-brand{font-family:'Fraunces',serif;font-size:20px;font-weight:600;}
.cw-body{flex:1;display:grid;grid-template-columns:220px 1fr 280px;gap:0;align-items:start;}
@media(max-width:1000px){.cw-body{grid-template-columns:1fr;}.cw-rail{flex-direction:row;flex-wrap:wrap;border-right:none!important;border-bottom:1px solid var(--line);}.cw-aside{display:none;}}
.cw-rail{display:flex;flex-direction:column;gap:4px;padding:20px 16px;border-right:1px solid var(--line);position:sticky;top:65px;}
.cw-rail-title{font-weight:700;font-size:13px;margin-bottom:4px;line-height:1.35;}
.cw-rail-step{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:9px;border:none;background:none;font-size:13px;color:var(--ink-soft);cursor:pointer;text-align:left;width:100%;}
.cw-rail-step:disabled{opacity:.55;cursor:default;}
.cw-rail-step.active{background:var(--accent-bg);color:var(--ink);font-weight:700;}
.cw-rail-step.done{color:var(--ink);}
.cw-rail-num{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background:var(--line);color:var(--ink-soft);font-size:11px;font-weight:700;flex:none;}
.cw-rail-step.active .cw-rail-num{background:var(--accent-deep);color:#fff;}
.cw-rail-step.done .cw-rail-num{background:var(--rl-text-success);color:#fff;}
.cw-main{padding:28px 32px;max-width:760px;}
.cw-aside{padding:28px 24px;position:sticky;top:65px;}
.cw-aside-note{font-size:12.5px;color:var(--ink-soft);line-height:1.6;}
.cw-h{font-family:'Fraunces',serif;font-size:22px;margin:0 0 4px;}
.cw-sub{font-size:13px;color:var(--ink-soft);margin:0 0 18px;line-height:1.5;}
.cw-hint{font-size:11.5px;color:var(--ink-soft);margin:6px 0 0;}
.cw-card{border:1px solid var(--line);border-radius:12px;padding:16px;margin-bottom:16px;background:var(--panel);}
.cw-card .cd-section-title{margin-top:0;}
.cw-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 24px;border-top:1px solid var(--line);background:var(--panel);position:sticky;bottom:0;z-index:2;}
.cw-check{display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;}
.cw-check input{width:auto;}
.cw-tmpl-row{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;text-align:left;padding:14px 16px;border:1px solid var(--line);border-radius:12px;background:var(--panel);margin-bottom:10px;cursor:pointer;}
.cw-tmpl-row:hover{border-color:var(--accent);}
.cw-room-row,.cw-kv{display:flex;justify-content:space-between;gap:12px;padding:7px 0;border-bottom:1px solid var(--line);font-size:13px;}
.cw-room-row:last-child,.cw-kv:last-child{border-bottom:none;}
.cw-kv span:first-child{color:var(--ink-soft);}
.cw-yn-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 0;font-size:13px;}
.cw-yn{display:inline-flex;border:1px solid var(--line);border-radius:8px;overflow:hidden;}
.cw-yn button{border:none;background:var(--panel);padding:6px 16px;font-size:12.5px;cursor:pointer;color:var(--ink-soft);}
.cw-yn button.on{background:var(--accent-deep);color:#fff;font-weight:700;}
.cw-sched-preview{margin:8px 0 12px;border:1px solid var(--line);border-radius:10px;padding:4px 12px;}
.cw-util-head,.cw-util-row{display:grid;grid-template-columns:1.4fr 0.8fr 1.4fr;gap:10px;align-items:center;padding:7px 0;font-size:13px;}
.cw-util-head{font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft);border-bottom:1px solid var(--line);}
.cw-util-row{border-bottom:1px solid var(--line);}
.cw-switch{position:relative;display:inline-block;width:38px;height:22px;}
.cw-switch input{opacity:0;width:0;height:0;}
.cw-switch span{position:absolute;inset:0;background:var(--line);border-radius:22px;transition:.15s;cursor:pointer;}
.cw-switch span:before{content:"";position:absolute;width:16px;height:16px;left:3px;top:3px;background:#fff;border-radius:50%;transition:.15s;}
.cw-switch input:checked + span{background:var(--accent-deep);}
.cw-switch input:checked + span:before{transform:translateX(16px);}

/* =========================================================================
   LISTING EDITOR (js/listing-wizard.js) — reuses the .cw-* wizard shell
   ========================================================================= */
/* The listing editor is one long scrolling form, unlike the step-by-step
   contract wizard — so its overlay scrolls as a plain block rather than a
   flex column (a flex column with sticky head/foot swallows the scroll). */
#listingWizard{display:block;overflow-y:auto;}
#listingWizard .cw-shell{display:block;min-height:100%;}
#listingWizard .cw-head{position:sticky;top:0;}
#listingWizard .cw-rail,#listingWizard .cw-aside{position:sticky;top:72px;align-self:start;}
#listingWizard .cw-foot{position:sticky;bottom:0;}
.lw-sec{padding-bottom:28px;margin-bottom:12px;border-bottom:1px solid var(--line);scroll-margin-top:76px;}
.lw-sec:last-child{border-bottom:none;}
.lw-score{display:flex;flex-direction:column;align-items:center;gap:4px;padding:10px 0 16px;margin-bottom:8px;border-bottom:1px solid var(--line);}
.lw-score-ring{--pct:0;position:relative;width:60px;height:60px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:conic-gradient(var(--accent-deep) calc(var(--pct)*1%), var(--line) 0);}
.lw-score-ring::before{content:"";position:absolute;inset:6px;border-radius:50%;background:var(--panel);}
.lw-score-ring span{position:relative;z-index:1;font-weight:800;font-size:13px;color:var(--ink);}
.lw-score-label{font-size:11px;color:var(--ink-soft);text-align:center;line-height:1.4;}
.lw-media-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;}
.lw-media-item{border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--panel);}
.lw-media-item img{width:100%;height:110px;object-fit:cover;display:block;}
.lw-media-ph{width:100%;height:110px;display:flex;align-items:center;justify-content:center;color:var(--ink-soft);font-size:12px;background:var(--accent-bg);}
.lw-media-cap{width:100%;border:none;border-top:1px solid var(--line);padding:6px 8px;font-size:12px;background:var(--panel);}
.lw-media-actions{display:flex;align-items:center;gap:4px;padding:4px 6px;border-top:1px solid var(--line);}
.lw-media-actions button{border:none;background:none;cursor:pointer;font-size:13px;color:var(--ink-soft);padding:2px 6px;border-radius:6px;}
.lw-media-actions button:hover{background:var(--accent-bg);}
.lw-media-actions button.danger{margin-left:auto;color:var(--rl-text-danger);}
.lw-media-first{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--accent-deep);}
.lw-fac-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:8px;}
.lw-fac{display:flex;align-items:center;gap:7px;font-size:13px;cursor:pointer;}
.lw-fac input{width:auto;}
.lw-room-mode{display:flex;flex-wrap:wrap;gap:6px 18px;margin-bottom:8px;}
.lw-room-bar{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:4px 0 8px;}
.lw-room-bar select{width:auto;}
.lw-room-count{margin-left:auto;font-size:12px;font-weight:700;color:var(--ink-soft);}
.lw-room-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:6px;
  max-height:260px;overflow-y:auto;padding:2px;}
.lw-room{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:12px;cursor:pointer;
  border:1px solid var(--line);border-radius:8px;padding:6px 8px;min-height:36px;}
.lw-room input{width:auto;margin:0;}
.lw-room.is-on{border-color:var(--accent-deep);background:var(--accent-bg);}
.lw-room.is-off{cursor:not-allowed;opacity:.55;}
.lw-room-id{font-weight:700;color:var(--ink);}
.lw-room-why{flex-basis:100%;font-size:11px;color:var(--ink-soft);}
@media (max-width:719px){ .lw-room{min-height:44px;} }
.field-block .lw-room-mode label.cl-check,.field-block label.lw-room{display:flex;text-transform:none;letter-spacing:0;margin:0;}
.field-block .lw-room-mode label.cl-check{font-size:13px;font-weight:500;color:var(--ink);}
.field-block label.lw-room{font-size:12px;font-weight:500;color:var(--ink);}
.field-block .lw-room-mode input,.field-block .lw-room input{width:auto;margin:0;flex:none;}
.lw-fac-custom{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px;}
/* Listing Terms (20260927120000): a tickbox with its explanation under the label. */
.lw-term{display:flex;align-items:flex-start;gap:10px;padding:10px 0;cursor:pointer;text-transform:none;letter-spacing:0;font-weight:400;color:var(--ink);}
.lw-term + .lw-term{border-top:1px solid var(--line);}
.lw-term input{width:auto;margin:3px 0 0;flex:none;}
.lw-term b{display:block;font-size:13px;font-weight:600;}
.lw-term .field-hint{display:block;margin:2px 0 0;}
.lw-chip{display:inline-flex;align-items:center;gap:5px;font-size:12px;background:var(--accent-bg);color:var(--ink);
  padding:4px 8px;border-radius:20px;}
.lw-chip button{border:none;background:none;cursor:pointer;color:var(--ink-soft);font-size:13px;line-height:1;}
.lo-score{font-size:11px;font-weight:800;color:var(--ink-soft);background:var(--line);border-radius:20px;padding:2px 7px;margin-left:4px;}
.lo-score.full{background:var(--rl-text-success);color:#fff;}


/* ---------- Governance: regime, Code obligations, complaints ---------- */
.gov-summary{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:16px;}
.gov-stat{background:var(--rl-surface);border:1.5px solid var(--line);border-radius:10px;padding:12px 16px;min-width:120px;}
.gov-stat b{display:block;font-size:24px;line-height:1;}
.gov-stat span{display:block;margin-top:6px;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);}
.gov-stat.warn b{color:var(--warn,var(--rl-text-warning));}
.gov-alert{background:var(--rl-tint-amber-bg);border:1.5px solid var(--rl-a-200);color:var(--rl-text-warning);border-radius:10px;padding:11px 14px;margin-bottom:16px;font-size:13.5px;}
.gov-card{background:var(--rl-surface);border:1.5px solid var(--line);border-radius:12px;padding:16px;margin-bottom:12px;}
.gov-card-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:12px;}
.gov-card-head h4{margin:0 0 2px;font-size:15px;}
.gov-card-head .muted{font-size:12.5px;}
.gov-pill{font-size:11px;font-weight:700;padding:4px 10px;border-radius:20px;white-space:nowrap;}
.gov-pill.r-pbsa_code_exempt{background:var(--rl-tint-green-bg);color:var(--rl-text-success);}
.gov-pill.r-assured{background:var(--rl-tint-red-bg);color:var(--rl-text-danger);}
.gov-pill.r-common_law_licence{background:var(--rl-surface-sunk);color:var(--rl-text-2);}
.gov-warn{color:var(--rl-text-danger);font-size:13px;margin:0 0 10px;}
.gov-fields{display:flex;flex-wrap:wrap;gap:12px;}
.gov-fields label{display:flex;flex-direction:column;gap:4px;font-size:11px;letter-spacing:.05em;
  text-transform:uppercase;color:var(--ink-soft);min-width:150px;flex:1;}
.gov-fields input,.gov-fields select{font-size:13px;padding:7px 9px;border:1.5px solid var(--line);border-radius:8px;}
.gov-fields em{font-style:normal;font-size:11px;font-weight:700;}
.gov-fields em.bad{color:var(--rl-text-danger);}
.gov-fields em.warn{color:var(--rl-text-warning);}
.gov-duties{margin-top:12px;}
.gov-duties summary{cursor:pointer;font-size:12.5px;font-weight:500;color:var(--rl-text-2);min-height:32px;display:flex;align-items:center;}
.gov-duties ul{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-direction:column;gap:1px;}
.gov-duties li{display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:baseline;
  padding:7px 10px;background:var(--surface-2,var(--rl-surface-sunk));border-radius:6px;font-size:13px;}
.gov-duties li em{font-style:normal;font-size:11.5px;color:var(--ink-soft);}
.gov-duties li b{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;}
.gov-duties li.on b{color:var(--rl-text-success);}
.gov-duties li.off{opacity:.5;}
.gov-duties li.off b{color:var(--ink-soft);}
.gov-empty{background:var(--rl-surface);border:1.5px dashed var(--line);border-radius:12px;padding:24px;text-align:center;}
tr.row-late td{background:var(--rl-tint-amber-bg);}
tr.row-late em.bad{color:var(--rl-text-danger);font-style:normal;font-weight:700;font-size:11px;}


/* ---------- Letting pace ---------- */
.pace-controls{margin-bottom:14px;}
.pace-controls label{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);}
.pace-controls select{font-size:13px;padding:7px 9px;border:1.5px solid var(--line);border-radius:8px;margin-left:8px;}
.pace-delta{font-size:20px;font-weight:700;margin:0 0 4px;letter-spacing:-.01em;}
.pace-delta.ahead{color:var(--rl-text-success);}
.pace-delta.behind{color:var(--rl-text-danger);}
.pace-chart-wrap{margin-top:18px;overflow-x:auto;}
.pace-chart{width:100%;min-width:520px;height:auto;}
.pace-axis{stroke:var(--line);stroke-width:1;}
.pace-target{stroke:var(--line);stroke-width:1;stroke-dasharray:4 4;}
.pace-target-label{fill:var(--ink-soft);font-size:10px;}
.pace-line{fill:none;stroke-width:2.5;stroke-linejoin:round;stroke-linecap:round;}
.pace-line.current{stroke:var(--accent-deep,var(--rl-text-success));}
.pace-line.prior{stroke:var(--line);stroke-width:2;stroke-dasharray:5 4;}
.pace-now{stroke:var(--rl-text-danger);stroke-width:1;stroke-dasharray:3 3;}
.pace-dot{fill:var(--accent-deep,var(--rl-text-success));}
.pace-tick{fill:var(--ink-soft);font-size:10px;}
.pace-legend{display:flex;align-items:center;gap:7px;margin:10px 0 0;font-size:12px;color:var(--ink-soft);}
.pace-legend .k{width:16px;height:3px;border-radius:2px;display:inline-block;margin-left:10px;}
.pace-legend .k:first-child{margin-left:0;}
.pace-legend .k.current{background:var(--accent-deep,var(--rl-text-success));}
.pace-legend .k.prior{background:var(--line);}


/* ---------- Hazard clocks on tickets ---------- */
.hazard-panel{border:1.5px solid var(--line);border-left:4px solid var(--accent-deep,var(--rl-text-success));
  border-radius:10px;padding:13px 15px;margin:14px 0;background:var(--rl-surface);}
.hazard-panel.breached{border-left-color:var(--rl-text-danger);background:var(--rl-tint-red-bg);}
.hazard-head{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:11px;}
.hazard-tag{background:var(--rl-tint-red-bg);color:var(--rl-text-danger);font-size:11px;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;padding:3px 9px;border-radius:20px;}
.hazard-cat{background:var(--rl-tint-amber-bg);color:var(--rl-text-warning);font-size:11px;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;padding:3px 9px;border-radius:20px;}
.hazard-src{font-size:11px;color:var(--ink-soft);margin-left:auto;}
.hazard-stages{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:9px;}
.hz-stage{background:var(--surface-2,var(--rl-surface-sunk));border-radius:8px;padding:9px 11px;
  display:flex;flex-direction:column;gap:5px;align-items:flex-start;}
.hz-stage.late{background:var(--rl-tint-red-bg);}
.hz-stage.done{background:var(--rl-tint-green-bg);}
.hz-stage.done-late{background:var(--rl-tint-amber-bg);}
.hz-label{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-soft);font-weight:600;}
.hz-date{font-size:13px;font-weight:600;}
.hz-stage.late .hz-date{color:var(--rl-text-danger);}
.hz-temp{display:flex;align-items:center;gap:7px;margin-top:11px;font-size:13px;}
.hz-flag{display:inline-block;background:var(--rl-tint-red-bg);color:var(--rl-text-danger);font-size:10px;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;padding:2px 7px;border-radius:20px;margin:4px 6px 0 0;}
.hz-flag.ok{background:var(--rl-tint-green-bg);color:var(--rl-text-success);}
.hz-flag.amber{background:var(--rl-tint-amber-bg);color:var(--rl-tint-amber-fg);}
/* Parts on a ticket, and the Parts to order shopping list (2026-10-15). */
.tk-parts{width:100%;border-collapse:collapse;font-size:13px;margin:4px 0 8px;}
.tk-parts td{padding:7px 4px;border-top:1px solid var(--rl-line-soft);vertical-align:middle;}
.tk-shopping{padding-bottom:12px;margin-bottom:12px;border-bottom:1px solid var(--rl-line);}


/* ---------- Arrears escalation ladder ---------- */
.al-now{font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-soft);
  font-weight:700;margin-bottom:4px;}
.al-muted{font-size:12px;color:var(--ink-soft);}
.al-hist{margin-left:6px;}
.al-note{font-size:13px;color:var(--ink-soft);background:var(--surface-2,var(--rl-surface-sunk));
  border-radius:8px;padding:10px 12px;margin:12px 0;}
.al-check{display:flex;align-items:center;gap:8px;font-size:13px;margin:10px 0;}
.al-history{display:flex;flex-direction:column;gap:9px;max-height:340px;overflow-y:auto;}
.al-item{border:1px solid var(--line);border-radius:9px;padding:11px 13px;}
.al-item-head{display:flex;justify-content:space-between;gap:10px;font-size:13.5px;}
.al-item-head span{color:var(--ink-soft);font-size:12px;}
.al-item-sub{font-size:12px;color:var(--ink-soft);margin-top:3px;}
.al-item-detail{font-size:13px;margin-top:7px;}


/* ---------- Rent reminder stage toggles ---------- */
.rc-stages{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:8px;}
.rc-stage{display:flex;align-items:center;gap:9px;background:var(--surface-2,var(--rl-surface-sunk));
  border:1.5px solid var(--line);border-radius:9px;padding:10px 12px;cursor:pointer;font-size:13.5px;}
.rc-stage.off{opacity:.55;}
.rc-stage-label{flex:1;font-weight:600;}
.rc-stage-when{font-size:11px;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.05em;}


/* ---------- Countersign schedule preview ---------- */
.cs-sched{width:100%;border-collapse:collapse;font-size:13px;margin-top:4px;}
.cs-sched th{text-align:left;font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-soft);padding:4px 6px;border-bottom:1px solid var(--line);}
.cs-sched td{padding:7px 6px;border-bottom:1px solid var(--line);}
.cs-sched .cs-sched-amt{font-variant-numeric:tabular-nums;font-weight:600;white-space:nowrap;}
.cs-sched tr.cs-sched-missing td{background:var(--rl-tint-amber-bg);}
.cs-sched tr.cs-sched-total td{border-bottom:none;font-weight:700;}
.cs-sched input[type=date]{font-size:12.5px;padding:4px 6px;border:1.5px solid var(--line);border-radius:6px;}
.cs-sched-warn{font-size:12px;color:var(--rl-text-warning);background:var(--rl-tint-amber-bg);border-radius:8px;
  padding:9px 11px;margin:9px 0 0;}

/* =========================================================================
   REFUNDS (js/refunds.js)

   Two shapes worth a stylesheet: the STAGE CHAIN on a refund record, and
   the stages editor behind it. Everything else in the view reuses the
   contracts layout, the qf-chip strip and the stat cards.

   The chain is a vertical rail rather than the horizontal step bar the
   rest of the product uses for wizards, because the number of steps is
   not fixed — the office can add a seventh — and each step carries a name
   AND a person, which a horizontal bar cannot hold at this width without
   truncating one of them.
   ========================================================================= */
.ref-chain{border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;}
.ref-step{
  display:flex;align-items:center;gap:12px;
  padding:11px 14px;border-bottom:1px solid var(--line);
  background:var(--panel);
}
.ref-step:last-child{border-bottom:none;}
.ref-step.current{background:var(--rl-tint-accent-bg);}
.ref-dot{
  width:10px;height:10px;border-radius:50%;flex:none;
  border:2px solid var(--rl-line-control);background:transparent;
}
.ref-step.done .ref-dot{background:var(--rl-text-success);border-color:var(--rl-text-success);}
.ref-step.current .ref-dot{background:var(--rl-tint-accent-fg);border-color:var(--rl-tint-accent-fg);}
.ref-step-body{flex:1;min-width:0;display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;}
.ref-step-name{font-size:13.5px;font-weight:600;}
.ref-step.done .ref-step-name{color:var(--ink-soft);}
.ref-step-who{font-size:12.5px;color:var(--ink-soft);}
.ref-step-assignee{
  font:inherit;font-size:12.5px;padding:5px 8px;border-radius:8px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink);max-width:220px;
}

.ref-bank{margin:0 0 10px;display:grid;grid-template-columns:auto 1fr;gap:6px 16px;font-size:13.5px;}
.ref-bank dt{color:var(--ink-soft);}
.ref-bank dd{margin:0;font-weight:600;font-family:'JetBrains Mono',monospace;}

.ref-log{border-top:1px solid var(--line);}
.ref-log-row{padding:10px 0;border-bottom:1px solid var(--line);}
.ref-log-row:last-child{border-bottom:none;}
.ref-log-head{display:flex;justify-content:space-between;gap:10px;font-size:13px;font-weight:600;}
.ref-log-head span{font-weight:400;font-size:11.5px;color:var(--ink-soft);white-space:nowrap;}
.ref-log-detail{font-size:12.5px;color:var(--ink-soft);margin-top:3px;}

/* The editor. A stage is a block, not a table row: it carries two selects,
   a tick and two pieces of email copy, and squeezing that into columns
   made every field too narrow to read what was in it. */
.ref-stage-row{border:1px solid var(--line);border-radius:var(--radius);padding:12px;margin-bottom:10px;background:var(--panel);}
.ref-stage-head{display:flex;gap:6px;align-items:center;margin-bottom:10px;}
.ref-stage-head .ref-stage-name{flex:1;font:inherit;font-size:13.5px;font-weight:600;padding:7px 10px;border-radius:9px;border:1px solid var(--line);background:var(--panel);color:var(--ink);}
.ref-stage-body{display:grid;grid-template-columns:auto 1fr;gap:8px 12px;align-items:center;}
.ref-stage-body label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--ink-soft);}
.ref-stage-body label.choice-row{text-transform:none;letter-spacing:0;font-weight:500;font-size:12.5px;display:flex;gap:8px;align-items:flex-start;}
.ref-stage-body select,.ref-stage-body input,.ref-stage-body textarea{
  font:inherit;font-size:13px;padding:7px 9px;border-radius:9px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink);width:100%;
}
.ref-stage-body label.choice-row input{width:auto;}

/* The stages editor needs room the 420px default modal does not have. */
#appModal.wide .modal-box{max-width:680px;}

/* A one-line nudge, not an empty state. .empty-note is a 64px-tall dashed
   well built for "this table has nothing in it"; borrowing it for a single
   sentence produced a box four times the height of its own text. */
.ref-hint{
  margin:16px 0 0;padding:10px 12px;
  border-left:3px solid var(--rl-line-accent);
  border-radius:0 var(--radius) var(--radius) 0;
  background:var(--rl-tint-accent-bg);color:var(--rl-tint-accent-fg);
  font-size:12.5px;line-height:1.5;
}
.ref-hint strong{font-weight:600;}

/* =========================================================================
   MOVE-OUTS

   The inspection is the only table in the app that is a form: every row
   carries three controls and is meant to be walked top to bottom with a
   phone in one hand. So it borrows the table's alignment and none of its
   density — rows are tall enough to hit, and the chargeable ones are
   tinted so the money on the screen is findable without reading it.
   ========================================================================= */
.mo-check{width:100%;border-collapse:collapse;margin-bottom:var(--rl-s-1);}
.mo-check th{
  text-align:left;font-size:11px;font-weight:700;text-transform:uppercase;
  letter-spacing:.03em;color:var(--ink-soft);
  padding:0 var(--rl-s-2) var(--rl-s-2);border-bottom:1px solid var(--line);
}
.mo-check td{padding:var(--rl-s-2);border-bottom:1px solid var(--line-soft);vertical-align:middle;}
.mo-check tbody tr:last-child td{border-bottom:1px solid var(--line);}
.mo-check tfoot td{padding:var(--rl-s-2);font-size:13px;color:var(--ink-soft);}
.mo-check tfoot strong{color:var(--ink);font-size:14px;}
.mo-num{text-align:right;white-space:nowrap;}

/* A charged row is the exception, and the tint is what makes scanning for
   "what is this going to cost them" a glance rather than a read. */
.mo-row.charged{background:var(--rl-tint-red-bg);}
.mo-label{font-size:13.5px;font-weight:600;color:var(--ink);}
.mo-area{font-size:11.5px;color:var(--ink-soft);margin-top:1px;}
.mo-note{font-size:12.5px;color:var(--ink-soft);}
.mo-nocharge{color:var(--rl-text-3);}

.mo-check select,.mo-check input{
  font:inherit;font-size:13px;padding:6px 8px;border-radius:var(--radius-md);
  border:1px solid var(--line);background:var(--panel);color:var(--ink);width:100%;
}
.mo-charge{max-width:110px;text-align:right;}
.mo-cond{min-width:150px;}

.mo-foot{font-size:12.5px;color:var(--ink-soft);line-height:1.5;margin:var(--rl-s-2) 0 0;}
.mo-foot strong{color:var(--ink);font-weight:600;}

/* The final account reads as a statement, not a grid: two columns, the
   figures right-aligned under each other so the subtraction is visible. */
.mo-account{width:100%;border-collapse:collapse;margin:var(--rl-s-1) 0 var(--rl-s-2);max-width:420px;}
.mo-account td{padding:var(--rl-s-2) 0;font-size:13.5px;border-bottom:1px solid var(--line-soft);}
.mo-account tfoot td{
  border-bottom:none;border-top:1px solid var(--line);
  padding-top:var(--rl-s-2);font-size:14px;
}
.mo-account tfoot strong{font-size:16px;}

.mo-settle{display:grid;grid-template-columns:1fr 1fr;gap:var(--rl-s-3);max-width:420px;}
.mo-settle .field-block{margin-bottom:0;}

/* Narrow, but still a table: the tablet band, above §16.2's 719px card
   transform and below a comfortable desktop. The columns shrink and the
   table scrolls inside itself rather than any column being dropped — the
   note is the evidence behind a deduction, and hiding it would hide it
   from exactly the person standing in the room writing it.

   Below 719px §16.2 turns every row into a card and this must not fight
   it, which is why the band has a floor. */
@media (min-width: 720px) and (max-width: 900px){
  .mo-cond{min-width:0;}
  .mo-check{display:block;overflow-x:auto;}
  .mo-check td,.mo-check th{white-space:nowrap;}
  .mo-noteinput{min-width:160px;}
}
@media (max-width: 900px){
  .mo-settle{grid-template-columns:1fr;}
}
/* In the card list the three controls are the point of the card, so they
   get the width the label grid would otherwise take. */
@media (max-width: 719px){
  .mo-check select,.mo-check input{width:100%;}
  .mo-charge{max-width:none;text-align:left;}
  .mo-check tfoot td::before{width:auto;max-width:none;}
}
