/* =========================================================================
   RoomLine — SCREENS
   §10.1 Today (the year strip, the hero figure and its mini-plan, Needs you,
   This week) and the screen-level treatments that follow from §2's split
   between the ledger and the plan.
   ========================================================================= */

/* =========================================================================
   §10.1.2 THE YEAR STRIP — the product's signature element.

   Student housing is not a smooth business. It runs on a hard annual cycle:
   a September surge, a quiet mid-year, a January re-let window, a summer
   turn where the building empties and refills. Most PMS interfaces present
   every day as identical. This is the only place in the app that shows the
   shape of the year, and it makes the September wall visible in August,
   which is when it matters.

   It appears on Today and nowhere else.
   ========================================================================= */
/* =========================================================================
   TODAY — THE ESTATE, NINE AT A TIME

   Three across, so nine buildings fill a laptop screen and the tenth
   starts a fourth row rather than being hidden. The panels are identical
   on purpose: the only thing your eye should have to work on is where
   they differ.
   ========================================================================= */
#app .today-portfolio {
  display: flex; flex-wrap: wrap; align-items: stretch;
  gap: 0; margin: 0 0 var(--rl-s-5);
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-lg);
  background: var(--rl-surface); overflow: clip;
}
#app .tp-cell {
  flex: 1 1 128px; min-width: 0;
  padding: 12px var(--rl-s-4);
  border-right: 1px solid var(--rl-line-soft);
  display: flex; flex-direction: column; gap: 3px;
}
#app .tp-cell:last-child { border-right: 0; }
#app .tp-k {
  font-size: 10.5px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--rl-text-3);
}
#app .tp-v {
  font-family: var(--rl-font-mono); font-variant-numeric: tabular-nums;
  font-size: 19px; font-weight: 500; color: var(--rl-text); line-height: 1.15;
}
#app .tp-v.is-red    { color: var(--rl-text-danger); }
#app .tp-v.is-amber  { color: var(--rl-text-warning); }
#app .tp-v.is-green  { color: var(--rl-text-success); }
#app .tp-v.is-accent { color: var(--rl-text-accent); }
#app .tp-of { font-family: var(--rl-font-sans); font-size: 12.5px; color: var(--rl-text-3); font-weight: 400; }

/* As many columns as fit (2026-10-07): three fixed columns made each site
   card 1,250px wide on a 4K screen. */
#app .today-sites {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr));
  gap: var(--rl-s-3);
  margin: 0 0 var(--rl-s-6);
}

#app .today-site {
  display: flex; flex-direction: column; gap: 9px;
  padding: 14px var(--rl-s-4) 13px;
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-lg);
  background: var(--rl-surface); box-shadow: var(--rl-e-1);
  font: inherit; text-align: left; cursor: pointer;
  transition: border-color var(--rl-d-fast) var(--rl-ease-standard),
              box-shadow var(--rl-d-fast) var(--rl-ease-standard),
              transform var(--rl-d-fast) var(--rl-ease-standard);
}
#app .today-site:hover {
  border-color: var(--rl-line-strong); box-shadow: var(--rl-e-2);
  transform: translateY(-1px);
}
/* A quick press, not just a hover — the card underneath takes a moment to
   open, so the tile itself should answer the click immediately. */
#app .today-site:active {
  transform: translateY(0) scale(0.985);
  transition-duration: var(--rl-d-instant);
}
#app .today-site:focus-visible { outline: none; box-shadow: var(--rl-focus); }

#app .ts-head { display: flex; align-items: baseline; gap: var(--rl-s-3); }
#app .ts-name {
  flex: 1; min-width: 0; font-size: 14.5px; font-weight: 600; color: var(--rl-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#app .ts-pct {
  font-family: var(--rl-font-mono); font-variant-numeric: tabular-nums;
  font-size: 22px; font-weight: 500; color: var(--rl-text); line-height: 1;
}
#app .ts-pct i { font-style: normal; font-size: 12px; color: var(--rl-text-3); margin-left: 1px; }

/* One shape per building. The fill colour is the state, so a row of nine
   reads as a row of nine states before a single number is read. */
#app .ts-bar {
  display: block; height: 6px; border-radius: var(--rl-r-full);
  background: var(--rl-surface-sunk); overflow: hidden;
}
#app .ts-bar i { display: block; height: 100%; border-radius: inherit; background: var(--rl-i-600); }
#app .today-site[data-tone="full"] .ts-bar i { background: var(--rl-g-500); }
#app .today-site[data-tone="ok"]   .ts-bar i { background: var(--rl-i-600); }
#app .today-site[data-tone="low"]  .ts-bar i { background: var(--rl-a-500); }
#app .today-site[data-tone="poor"] .ts-bar i { background: var(--rl-r-500); }

#app .ts-beds {
  display: flex; align-items: baseline; gap: 7px;
  font-size: 12.5px; color: var(--rl-text-2);
}
#app .ts-rooms { color: var(--rl-text-3); font-size: 11.5px; }
#app .ts-facts { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 1px; }
#app .ts-fact {
  display: inline-flex; align-items: center;
  padding: 2px 7px; border-radius: var(--rl-r-full);
  background: var(--rl-surface-sunk); color: var(--rl-text-2);
  font-size: 11.5px; font-weight: 500; white-space: nowrap;
}
#app .ts-fact.is-red    { background: var(--rl-tint-red-bg);    color: var(--rl-tint-red-fg); }
#app .ts-fact.is-amber  { background: var(--rl-tint-amber-bg);  color: var(--rl-tint-amber-fg); }
#app .ts-fact.is-accent { background: var(--rl-tint-accent-bg); color: var(--rl-text-accent); }
#app .ts-fact.is-quiet  { background: transparent; color: var(--rl-text-3); padding-left: 0; font-weight: 400; }

/* The open panel keeps a mark, so it is obvious which of the nine the
   card below belongs to. */
#app .today-site.is-open {
  border-color: var(--rl-i-600);
  box-shadow: 0 0 0 1px var(--rl-i-600), var(--rl-e-1);
}

/* -------------------------------------------------------------------------
   ONE BUILDING'S CARD — opens as an overlay rather than navigating, so
   the estate you were comparing is still there, dimmed, behind it.

   First pass (same day) opened it in the page flow, under the grid — see
   the git history on this block for that version and why. Tejas tried it
   and wanted it to read as its own moment instead: big enough to actually
   work from, not another strip competing with nine tiles for the same
   scroll position. §todaySiteOverlay below is that; it is deliberately
   NOT the contract wizard's kind of overlay (.cw-overlay, styles.css) —
   it starts under the top bar rather than covering it, and is sized to
   leave the estate visible as a frame around it rather than replacing
   the screen outright.
   ------------------------------------------------------------------------- */
#app .tsc-overlay {
  position: fixed; top: var(--rl-top-h); left: 0; right: 0; bottom: 0;
  z-index: 90;
  display: flex; align-items: center; justify-content: center;
  padding: 6vh 8vw;
  background: rgba(20, 23, 31, .5);
  animation: modalScrimIn var(--rl-d-fast) var(--rl-ease-standard);
}
#app .tsc-overlay[hidden] { display: none; }
@media (max-width: 700px) { #app .tsc-overlay { padding: 3vh 4vw; } }

#app .today-sitecard {
  width: 100%; max-width: 1100px; max-height: 100%;
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-lg);
  background: var(--rl-surface); box-shadow: var(--rl-e-3);
  overflow-x: clip; overflow-y: auto;
  animation: modalBoxIn var(--rl-d-mid) var(--rl-ease-enter);
}
#app .today-sitecard:focus-visible { outline: none; }
#app .tsc-head {
  display: flex; align-items: flex-start; gap: var(--rl-s-4);
  padding: var(--rl-s-4) var(--rl-s-5);
  border-bottom: 1px solid var(--rl-line-soft);
}
#app .tsc-head h3 {
  margin: 0; font-family: var(--rl-font-serif); font-size: 19px; font-weight: 600;
  letter-spacing: -0.01em; color: var(--rl-text);
}
#app .tsc-head > div:first-child { flex: 1; min-width: 0; }
#app .tsc-sub { margin-top: 2px; font-size: 12.5px; color: var(--rl-text-3); }
#app .tsc-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
#app .tsc-fact {
  padding: 12px var(--rl-s-5);
  border-right: 1px solid var(--rl-line-soft);
  border-bottom: 1px solid var(--rl-line-soft);
  display: flex; flex-direction: column; gap: 3px; min-width: 0;
}
#app .tsc-k {
  font-size: 10.5px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--rl-text-3);
}
#app .tsc-v {
  font-family: var(--rl-font-mono); font-variant-numeric: tabular-nums;
  font-size: 17px; font-weight: 500; color: var(--rl-text);
}
#app .tsc-v.is-red    { color: var(--rl-text-danger); }
#app .tsc-v.is-amber  { color: var(--rl-text-warning); }
#app .tsc-v.is-green  { color: var(--rl-text-success); }
#app .tsc-v.is-accent { color: var(--rl-text-accent); }
#app .tsc-of { font-family: var(--rl-font-sans); font-size: 12px; color: var(--rl-text-3); font-weight: 400; }

/* TODAY, AT THIS SITE — who is arriving, who is leaving, who is being
   shown round and who is overdue, all already scoped to this building
   (see rlRenderSiteCard, today.js). The fact grid above answers "how
   much"; this answers "who", which a count alone never can. */
#app .tsc-lists {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  border-top: 1px solid var(--rl-line-soft);
}
#app .tsc-list {
  min-width: 0;
  padding: var(--rl-s-4) var(--rl-s-5);
  border-right: 1px solid var(--rl-line-soft);
  border-bottom: 1px solid var(--rl-line-soft);
}
#app .tsc-list-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--rl-s-2);
  margin-bottom: 7px;
}
#app .tsc-list-head h4 { margin: 0; font-size: 12.5px; font-weight: 600; color: var(--rl-text-2); }
#app .tsc-list-n {
  font-family: var(--rl-font-mono); font-variant-numeric: tabular-nums;
  color: var(--rl-text-3); font-weight: 500; margin-left: 2px;
}
#app .tsc-list-link {
  background: none; border: 0; padding: 0; font: inherit;
  font-size: 11.5px; font-weight: 500; color: var(--rl-text-accent); cursor: pointer;
}
#app .tsc-list-link:hover { text-decoration: underline; }
#app .tsc-row {
  display: flex; align-items: baseline; gap: 7px;
  padding: 5px 0; border-top: 1px solid var(--rl-line-soft);
}
#app .tsc-row:first-of-type { border-top: 0; }
#app .tsc-row-main {
  flex: 1; min-width: 0; font-size: 12.5px; color: var(--rl-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#app .tsc-row-sub { font-size: 11.5px; color: var(--rl-text-3); white-space: nowrap; }
#app .tsc-row-tag {
  font-size: 11px; font-weight: 600; white-space: nowrap;
  padding: 1px 6px; border-radius: var(--rl-r-full);
  background: var(--rl-surface-sunk); color: var(--rl-text-2);
}
#app .tsc-row-tag.is-red    { background: var(--rl-tint-red-bg);    color: var(--rl-tint-red-fg); }
#app .tsc-row-tag.is-amber  { background: var(--rl-tint-amber-bg);  color: var(--rl-tint-amber-fg); }
#app .tsc-row-tag.is-accent { background: var(--rl-tint-accent-bg); color: var(--rl-text-accent); }
#app .tsc-row.is-empty { padding: 5px 0; font-size: 12.5px; color: var(--rl-text-3); }
#app .tsc-more { margin-top: 5px; font-size: 11.5px; color: var(--rl-text-3); }

#app .tsc-links {
  display: flex; flex-wrap: wrap; gap: var(--rl-s-2);
  padding: var(--rl-s-4) var(--rl-s-5);
}

/* -------------------------------------------------------------------------
   OPENING THE CARD. DECISIONS.md #2 keeps route switches to a single
   enter, no stagger, because ~200 call sites assume the new view has
   already rendered — a rule about navigation, not about this. This is a
   local disclosure that never navigates, so a small stagger across the
   four lists above reads as polish rather than the clutter that rule
   was written to avoid.

   Gated by .tsc-animate, added only from rlOpenSite()'s own render pass
   (today.js) — never by the plain re-render a realtime update elsewhere
   on the estate triggers while this same card is already open. Without
   that gate the card would visibly re-enter under you every time
   somebody else's ticket or invoice changed. */
#app .today-sitecard.tsc-animate { animation: rl-view-in var(--rl-d-mid) var(--rl-ease-enter); }
#app .today-sitecard.tsc-animate .tsc-list {
  animation: rl-view-in var(--rl-d-base) var(--rl-ease-enter) both;
}
#app .today-sitecard.tsc-animate .tsc-list:nth-child(1) { animation-delay: var(--rl-d-instant); }
#app .today-sitecard.tsc-animate .tsc-list:nth-child(2) { animation-delay: calc(var(--rl-d-instant) + 40ms); }
#app .today-sitecard.tsc-animate .tsc-list:nth-child(3) { animation-delay: calc(var(--rl-d-instant) + 80ms); }
#app .today-sitecard.tsc-animate .tsc-list:nth-child(4) { animation-delay: calc(var(--rl-d-instant) + 120ms); }

.rl-year {
  position: relative;
  margin: var(--rl-s-2) 0 var(--rl-s-10);
  padding: 22px 0 48px;
  user-select: none;
}
.rl-year-track {
  position: relative;
  height: 28px;
  background: var(--rl-n-100);
  border-radius: var(--rl-r-xs);
  overflow: hidden;
}
[data-theme="dark"] .rl-year-track { background: #1E2430; }

/* Term periods are a slightly darker segment of the same material, not a
   second colour. The year is one object. */
.rl-year-term {
  position: absolute; top: 0; bottom: 0;
  background: var(--rl-n-200);
}
[data-theme="dark"] .rl-year-term { background: #2A3140; }
.rl-year-term-label {
  position: absolute; top: 50%; transform: translateY(-50%);
  padding-left: 6px;
  font-size: 11.5px; color: var(--rl-text-2);
  white-space: nowrap; pointer-events: none;
}
/* The term band is a lighter step than the track, so text-3 on it falls
   below AA in dark. Inside the band the label takes the brighter tone. */
[data-theme="dark"] .rl-year-term-label { color: var(--rl-n-300); }

/* Move-in density above the track, move-out below. Ticks, not bars: the
   question is "when does the wave hit", not "exactly how many". */
.rl-year-ticks { position: absolute; left: 0; right: 0; height: 20px; }
.rl-year-ticks[data-dir="in"]  { top: 0; }
.rl-year-ticks[data-dir="out"] { top: 50px; }
.rl-year-tick {
  position: absolute; bottom: 0; width: 3px;
  background: var(--rl-i-300); border-radius: 1px 1px 0 0;
}
.rl-year-ticks[data-dir="out"] .rl-year-tick {
  top: 0; bottom: auto;
  background: var(--rl-a-500); border-radius: 0 0 1px 1px;
}

/* Today. 2px, the brand indigo, with its date beneath. */
.rl-year-now { position: absolute; top: 16px; bottom: 22px; width: 2px; background: var(--rl-i-600); z-index: 3; }
/* The month ruler sits directly under the track; today's own date sits a
   line below it, so the two never overlap in the weeks around a month
   boundary — which is most of September, when this strip matters most. */
.rl-year-now-label {
  position: absolute; top: 96px;
  transform: translateX(-50%);
  font-size: 11.5px; font-weight: 500; color: var(--rl-text-accent);
  white-space: nowrap; z-index: 3;
}
.rl-year-months { position: absolute; left: 0; right: 0; top: 78px; height: 16px; }
.rl-year-month {
  position: absolute; font-size: 11.5px; color: var(--rl-text-3);
  transform: translateX(-50%); white-space: nowrap;
}

/* One hit target per week, spanning the whole strip, so the tooltip answers
   wherever the pointer happens to be. */
.rl-year-week {
  position: absolute; top: 0; bottom: 22px;
  border: none; background: transparent; padding: 0; cursor: pointer;
  z-index: 2;
}
.rl-year-week:hover { background: rgba(79,70,196,.06); }
.rl-year-week:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
.rl-year-tip {
  position: absolute; z-index: 6;
  background: var(--rl-n-900); color: var(--rl-n-0);
  border-radius: var(--rl-r-sm);
  padding: 6px 9px; font-size: 12.5px; line-height: 16px;
  white-space: nowrap; pointer-events: none;
  opacity: 0; transform: translate(-50%, 2px);
  transition: opacity var(--rl-d-instant) var(--rl-ease-standard);
}
[data-theme="dark"] .rl-year-tip { background: var(--rl-n-0); color: var(--rl-n-900); }
.rl-year-tip[data-open="true"] { opacity: 1; transform: translate(-50%, 0); }

/* §8.11 The one orchestrated moment. The marker slides from the year's start
   to its true position, once per session, because it communicates something
   real — where you are in the letting year — that a static marker would not.
   Nothing else in the product animates without a user action. */
@keyframes rl-year-arrive { from { transform: translateX(var(--rl-year-from)); } to { transform: none; } }
.rl-year[data-arrive="true"] .rl-year-now,
.rl-year[data-arrive="true"] .rl-year-now-label {
  animation: rl-year-arrive var(--rl-d-long) var(--rl-ease-standard) 120ms both;
}
.rl-year[data-arrive="true"] .rl-year-now-label { animation-name: rl-year-arrive-label; }
@keyframes rl-year-arrive-label {
  from { transform: translateX(calc(-50% + var(--rl-year-from))); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .rl-year[data-arrive="true"] .rl-year-now,
  .rl-year[data-arrive="true"] .rl-year-now-label { animation: none; }
}

/* =========================================================================
   §10.1.3 THE HERO FIGURE
   Occupancy at display scale in serif, with a miniature plan beside it —
   the building drawn at 12px room cells, non-interactive. The mini-plan is
   the visual proof of the number.
   ========================================================================= */
.today-hero {
  display: flex; align-items: flex-start; gap: var(--rl-s-12);
  flex-wrap: wrap;
  padding-bottom: var(--rl-s-8);
  border-bottom: 1px solid var(--rl-line-soft);
}
.today-hero-figure { min-width: 200px; }
.today-hero-figure .rl-display { display: block; margin: 2px 0 4px; }
.today-miniplan {
  display: flex; flex-direction: column; gap: 3px;
  /* Aligns the plan's first floor with the figure's baseline when the two
     sit side by side. Once the hero wraps there is nothing to align to, and
     the offset is just a hole in the page. */
  padding-top: 22px;
}
@media (max-width: 719px) { .today-miniplan { padding-top: 0; } .today-hero { gap: var(--rl-s-6); } }
.today-miniplan-row { display: flex; gap: 3px; flex-wrap: wrap; max-width: 520px; }
.today-miniplan i {
  width: 12px; height: 12px; border-radius: 2px;
  background: var(--rl-room-occupied-fill);
  border: 1px solid var(--rl-room-occupied-line);
  display: block;
}
.today-miniplan i[data-state="reserved"]  { background: var(--rl-room-reserved-fill); border-color: var(--rl-room-reserved-line); }
.today-miniplan i[data-state="available"] { background: var(--rl-room-available-fill); border-style: dashed; border-color: var(--rl-room-available-line); }
.today-miniplan i[data-state="turn"]      { background: var(--rl-room-turn-fill); border-color: var(--rl-room-turn-line); }
.today-miniplan i[data-state="oos"]       { background: var(--rl-room-oos-fill); border-color: var(--rl-room-oos-line); }
.today-legend { display: flex; flex-wrap: wrap; gap: var(--rl-s-3); margin-top: var(--rl-s-2); }
.today-legend span { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--rl-text-3); }
.today-legend i { width: 9px; height: 9px; border-radius: 2px; border: 1px solid var(--rl-room-occupied-line); background: var(--rl-room-occupied-fill); }

/* =========================================================================
   §10.1.5 NEEDS YOU
   A single list, not multiple cards. Every actionable item across the
   product in one column, ranked by urgency. Eight rows, then a link. The
   old screen showed five permanent tiles whether or not they had anything
   in them, which trained people to stop reading them.
   ========================================================================= */
.rl-needs { border-top: 1px solid var(--rl-line-soft); }
.rl-need {
  display: flex; align-items: center; gap: var(--rl-s-3);
  width: 100%; padding: 11px var(--rl-s-3) 11px var(--rl-s-4);
  border: none; border-bottom: 1px solid var(--rl-line-soft);
  background: transparent; text-align: left; cursor: pointer;
  box-shadow: inset 3px 0 var(--rl-n-300);
  transition: background var(--rl-d-instant) var(--rl-ease-standard);
}
.rl-need:hover { background: var(--rl-n-25); }
[data-theme="dark"] .rl-need:hover { background: var(--rl-surface-raised); }
.rl-need:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
.rl-need[data-sev="fail"] { box-shadow: inset 3px 0 var(--rl-r-500); }
.rl-need[data-sev="warn"] { box-shadow: inset 3px 0 var(--rl-a-500); }
.rl-need[data-sev="info"] { box-shadow: inset 3px 0 var(--rl-i-500); }
.rl-need-ico { width: 16px; height: 16px; flex: none; color: var(--rl-text-3); }
.rl-need-body { flex: 1; min-width: 0; }
.rl-need-title { display: block; font-size: 13.5px; color: var(--rl-text); }
.rl-need-sub { display: block; font-size: 12.5px; color: var(--rl-text-3); }
.rl-need-when { font-size: 12.5px; color: var(--rl-text-3); flex: none; }
.rl-need-chev { width: 14px; height: 14px; flex: none; color: var(--rl-n-400); }
.rl-need-more { padding: 10px var(--rl-s-4); font-size: 13px; }

/* §9.7 "Everyone's paid up" is a good empty state and should feel like one.
   Not every empty screen is a deficiency. */
.rl-needs-clear {
  padding: var(--rl-s-8) var(--rl-s-4);
  border-bottom: 1px solid var(--rl-line-soft);
  color: var(--rl-text-2);
}
.rl-needs-clear b { font-family: var(--rl-font-serif); font-size: 21px; font-weight: 400; color: var(--rl-text); display: block; margin-bottom: 2px; }

/* =========================================================================
   §10.1.6 THIS WEEK
   Seven columns: arrivals, departures, viewings, inspections per day.
   Today's column is tinted. Clicking a day filters the relevant screen.
   ========================================================================= */
.rl-week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; background: var(--rl-line-soft); border: 1px solid var(--rl-line-soft); border-radius: var(--rl-r-md); overflow: hidden; }
.rl-week-day {
  background: var(--rl-surface); border: none; text-align: left; cursor: pointer;
  padding: var(--rl-s-3); min-height: 104px;
  transition: background var(--rl-d-instant) var(--rl-ease-standard);
}
.rl-week-day:hover { background: var(--rl-n-25); }
[data-theme="dark"] .rl-week-day:hover { background: var(--rl-surface-raised); }
.rl-week-day[data-today="true"] { background: var(--rl-tint-accent-bg); }
/* Today's column is the one tinted cell in the strip, and --rl-text-3 lands
   just under AA on the tint in both themes — 4.47:1 on indigo-50, worse on
   indigo-900. Everything inside it moves one step towards the text colour. */
.rl-week-day[data-today="true"] .rl-week-name,
.rl-week-day[data-today="true"] .rl-week-quiet { color: var(--rl-text-2); }
[data-theme="dark"] .rl-week-day[data-today="true"] .rl-week-name,
[data-theme="dark"] .rl-week-day[data-today="true"] .rl-week-quiet { color: var(--rl-i-200); }
.rl-week-day:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
.rl-week-name { font-size: 12.5px; color: var(--rl-text-3); }
.rl-week-date { font-family: var(--rl-font-serif); font-size: 21px; line-height: 26px; font-variant-numeric: tabular-nums; margin-bottom: 6px; }
.rl-week-line { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--rl-text-2); line-height: 18px; }
.rl-week-line i { width: 6px; height: 6px; border-radius: 1px; flex: none; }
.rl-week-line[data-kind="in"]  i { background: var(--rl-i-500); }
.rl-week-line[data-kind="out"] i { background: var(--rl-a-500); }
.rl-week-line[data-kind="view"] i { background: var(--rl-n-400); }
.rl-week-quiet { font-size: 12.5px; color: var(--rl-text-3); }
@media (max-width: 900px) {
  .rl-week { grid-template-columns: repeat(2, 1fr); }
}

/* =========================================================================
   §10.1 Ledger sections below the fold.
   Reverse-chronological, quiet, and last: this is the least important thing
   on the screen and it sits at the bottom.
   ========================================================================= */
.today-detail { margin-top: var(--rl-section-gap); }
.today-detail .grid { gap: var(--rl-s-6); }

/* §2 The plan wants space; the ledger wants alignment. Charts on Today sit
   on the canvas with a hairline, not in a floating card. */
.chart-card, #app .chart-card { box-shadow: none; border: 1px solid var(--rl-line); }
.chart-wrap { position: relative; }

/* =========================================================================
   §10.2 PORTFOLIO — plan mode. The building as a drawing.
   ========================================================================= */
.rl-plan-controls { display: flex; align-items: center; gap: var(--rl-s-2); flex-wrap: wrap; margin-bottom: var(--rl-s-4); }
.rl-plan { border-top: 1px solid var(--rl-line-soft); }
.rl-plan-floor:last-child { border-bottom: none; }
.rl-plan-occ { font-size: 12.5px; color: var(--rl-text-3); font-variant-numeric: tabular-nums; }

/* The room grid on Property detail, restated in the room-state palette so
   the plan and the grid say the same thing about the same room. */
.room-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--rl-s-2); }

/* =========================================================================
   §10.6 FINANCE — ledger mode throughout. Dense, aligned, tabular.
   ========================================================================= */
#view-arrears table td, #view-rentcollections table td,
#view-invoicing table td, #view-payments table td,
#view-stripe table td, #view-reconciliation table td {
  font-variant-numeric: tabular-nums lining-nums;
}

/* =========================================================================
   §10.7 INBOX — unread is a dot, not bold text. Bold-vs-regular for read
   state makes a list visually noisy.
   ========================================================================= */
.rl-unread-dot { width: 6px; height: 6px; border-radius: var(--rl-r-full); background: var(--rl-i-600); flex: none; }

/* =========================================================================
   §10.9 SETTINGS — prose width, one column, each setting a row.
   ========================================================================= */
#view-settings .card, #view-settings .form-card { max-width: var(--rl-prose); }

/* =========================================================================
   The team channel, brought onto the token layer. It was the one surface
   with its own gradients and its own idea of a shadow.
   ========================================================================= */
.team-chat, #app .team-chat {
  background: var(--rl-surface);
  border-left: 1px solid var(--rl-line);
  box-shadow: var(--rl-e-2);
}
.chat-head, #app .chat-head { box-shadow: none; border-bottom: 1px solid var(--rl-line); background: var(--rl-surface); }
.chat-channel, #app .chat-channel { background: var(--rl-surface) !important; box-shadow: none !important; }
.chat-bubble { border-radius: var(--rl-r-md); }

/* Notification popover, on the same footing as every other menu. */
.dd-panel, #app .dd-panel {
  background: var(--rl-surface-raised);
  border: 1px solid var(--rl-line);
  border-radius: var(--rl-r-lg);
  box-shadow: var(--rl-e-2);
}
.notif-head { border-bottom: 1px solid var(--rl-line-soft); }

/* =========================================================================
   §9.6 The property KPI row, restated as metric blocks.
   properties.js still computes and writes these four figures — the
   arithmetic there is careful and is left alone. What changes is that they
   stop being four identical rounded rectangles with coloured icon discs and
   become label / figure / note separated by hairline rules.
   ========================================================================= */
/* Every KPI row in the product, not only Portfolio's. §9.6 again: a metric
   is a label, a figure and a note with space around it. Wrapping each one in
   a bordered card with a tinted icon disc turns nine different screens into
   the same grid of identical rounded rectangles, and the icon discs end up
   the loudest objects on a page whose subject is the numbers. */
#app .card.stat-card,
#propertyDetailKpis .card.stat-card {
  background: transparent; border: none; border-radius: 0;
  box-shadow: none; padding: 0;
  display: block;
}
#app .card.stat-card .stat-ico, #propertyDetailKpis .stat-ico { display: none; }
/* A 2px indigo-to-green gradient ran across the top of every KPI on every
   screen. It encoded nothing — the same three colours everywhere — and §22
   rules out gradients as decoration. */
#app .card.stat-card::before { content: none; }
#app .card.stat-card .stat-label, #propertyDetailKpis .stat-label {
  font-size: 12.5px; font-weight: 400; color: var(--rl-text-2);
}
#app .card.stat-card .stat-value, #propertyDetailKpis .stat-value {
  font-family: var(--rl-font-serif); font-weight: 400;
  font-size: 32px !important; line-height: 36px; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums; margin: 4px 0 2px;
}
#app .card.stat-card .stat-foot, #propertyDetailKpis .stat-foot {
  font-size: 12.5px; line-height: 16px; color: var(--rl-text-3);
}

#propertyDetailKpis {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--rl-s-6); margin: var(--rl-s-6) 0;
}

/* THE HAIRLINE RULES ONLY APPEAR WHILE THE ROW IS ACTUALLY ONE ROW.

   §9.6 says the rules between the columns are the structure, and they are —
   while the metrics sit side by side. The moment the grid wraps, a
   `border-left` on every-sibling-but-the-first draws a stray vertical line
   down the middle of the second row; and with the gap removed so the rules
   meet the edges, the wrapped blocks collide with the ones above them. That
   is what a four-metric Finance header did at tablet width.

   Below the width at which each grid stops being a single row — 1100px for
   grid-4 and 900px for the others, matching styles.css's own breakpoints —
   the metrics keep an ordinary gap and no rules at all. */
@media (min-width: 1100px) {
  #app .grid.grid-4:has(> .card.stat-card) { gap: 0; }
  #app .grid.grid-4 > .card.stat-card { padding-right: var(--rl-s-8); }
  #app .grid.grid-4 > .card.stat-card + .card.stat-card {
    border-left: 1px solid var(--rl-line-soft); padding-left: var(--rl-s-8);
  }
  #propertyDetailKpis { gap: 0; }
  #propertyDetailKpis > .card.stat-card { padding-right: var(--rl-s-8); }
  #propertyDetailKpis > .card.stat-card + .card.stat-card {
    border-left: 1px solid var(--rl-line-soft); padding-left: var(--rl-s-8);
  }
}
/* A figure that opens the list it counts. Quiet until pointed at — a
   hover tint and the focus ring, no underline or chevron. */
#app .stat-card.is-link { cursor: pointer; border-radius: var(--rl-r-sm);
  transition: background var(--rl-d-fast) var(--rl-ease-standard); }
#app .stat-card.is-link:hover { background: var(--rl-surface-sunk); }
#app .stat-card.is-link:focus-visible { outline: none; box-shadow: var(--rl-focus); }

@media (min-width: 900px) {
  #app .grid.grid-3:has(> .card.stat-card),
  #app .grid.grid-2:has(> .card.stat-card) { gap: 0; }
  #app .grid.grid-3 > .card.stat-card,
  #app .grid.grid-2 > .card.stat-card { padding-right: var(--rl-s-8); }
  #app .grid.grid-3 > .card.stat-card + .card.stat-card,
  #app .grid.grid-2 > .card.stat-card + .card.stat-card {
    border-left: 1px solid var(--rl-line-soft); padding-left: var(--rl-s-8);
  }
}

/* =========================================================================
   §10 SHARED INBOX
   The queue was the same generic side-list/side-item primitive every other
   view uses, so it read as "a list", not "an inbox". This is the mail-client
   treatment: a monogram on every row and every message, the real HTML body
   of an email rendered on a paper card, a contact-context block, and a
   composer with a Reply / Internal-note split and a template picker.
   ========================================================================= */

/* --- folder tabs (Open / Unassigned / Mine / Snoozed / Closed) --- */
.inbox-folders { display: flex; flex-wrap: wrap; gap: var(--rl-s-2); margin: 0 0 var(--rl-s-4); }
.inbox-folder {
  display: inline-flex; align-items: center; gap: 7px; min-height: 32px;
  padding: 0 12px; border-radius: var(--rl-r-full);
  border: 1px solid var(--rl-line); background: var(--rl-surface);
  font-size: 13px; font-weight: 500; color: var(--rl-text-2); cursor: pointer;
  transition: background var(--rl-d-fast) var(--rl-ease-standard),
              border-color var(--rl-d-fast) var(--rl-ease-standard),
              color var(--rl-d-fast) var(--rl-ease-standard);
}
.inbox-folder:hover { border-color: var(--rl-line-strong); color: var(--rl-text); }
.inbox-folder.active {
  background: var(--rl-tint-accent-bg); border-color: var(--rl-line-accent);
  color: var(--rl-text-accent); font-weight: 600;
}
.inbox-folder:focus-visible { outline: none; box-shadow: var(--rl-focus); }
.inbox-folder-n {
  min-width: 18px; padding: 0 5px; height: 17px; border-radius: var(--rl-r-full);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums;
  background: var(--rl-line); color: var(--rl-text-2);
}
.inbox-folder.active .inbox-folder-n { background: var(--rl-tint-accent-bg); color: var(--rl-text-accent); }

/* --- monogram, deterministic hue by name (same palette as the contract
       record's audit-log avatars, which clear §18 on every hue) --- */
.inbox-avatar {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--rl-r-full);
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
}
.inbox-avatar.lg { width: 40px; height: 40px; font-size: 14px; }

/* --- list rows --- */
#inboxList .side-item.inbox-row {
  display: grid; grid-template-columns: auto 1fr; gap: 10px;
  padding: 11px 12px; align-items: start;
}
.inbox-row-main { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.inbox-row-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.inbox-row-name {
  font-size: 13.5px; font-weight: 500; color: var(--rl-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: inline-flex; align-items: center; gap: 6px;
}
.inbox-row.unread .inbox-row-name { font-weight: 700; }
.inbox-row-time { flex: none; font-size: 11.5px; color: var(--rl-text-2); white-space: nowrap; }
.inbox-row-subj {
  font-size: 12.5px; color: var(--rl-text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: flex; align-items: center; gap: 6px;
}
.inbox-row.unread .inbox-row-subj { color: var(--rl-text); font-weight: 500; }
.inbox-row-snippet {
  font-size: 12px; color: var(--rl-text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.inbox-row-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.inbox-dot { width: 7px; height: 7px; border-radius: var(--rl-r-full); background: var(--rl-i-600); flex: none; }
.inbox-ch-ico { width: 13px; height: 13px; flex: none; color: var(--rl-text-3); }

/* priority stripe on the row — the selected row's own accent bar wins */
.inbox-row[data-priority="high"]:not(.active)   { box-shadow: inset 3px 0 var(--rl-a-500); }
.inbox-row[data-priority="urgent"]:not(.active) { box-shadow: inset 3px 0 var(--rl-r-500); }

/* small inline flags on a row / thread head */
.inbox-flag, .inbox-tag, .inbox-pri {
  font-size: 10.5px; font-weight: 600; padding: 1px 7px; border-radius: var(--rl-r-xs);
  display: inline-flex; align-items: center; line-height: 1.6;
}
.inbox-flag.awaiting   { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }
.inbox-flag.overdue    { background: var(--rl-tint-red-bg); color: var(--rl-tint-red-fg); }
.inbox-flag.unassigned { background: var(--rl-line); color: var(--rl-text-2); }
.inbox-flag.snoozed    { background: var(--rl-tint-accent-bg); color: var(--rl-tint-accent-fg); }
.inbox-pri.inbox-pri-high   { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }
.inbox-pri.inbox-pri-urgent { background: var(--rl-tint-red-bg); color: var(--rl-tint-red-fg); }
.inbox-pri.inbox-pri-low    { background: var(--rl-line); color: var(--rl-text-2); }
.inbox-tag { background: var(--rl-line); color: var(--rl-text-2); }

/* --- the reading pane ---
   .inbox-top (head, actions), .inbox-aside (the contact), .inbox-body
   (the thread and composer). Stacked in that order by default; on a wide
   Shared inbox the contact moves beside the thread and pins under the
   tab bar, so scrolling a long thread leaves it where it is. The Sales
   inbox pane (#lcEmailPane) is narrower and keeps the stacked order. */
.inbox-thread { display: flex; flex-direction: column; }
@media (min-width: 1200px) {
  #inboxDetail .inbox-thread {
    display: grid; grid-template-columns: minmax(0, 1fr) 300px;
    grid-template-rows: auto 1fr; grid-template-areas: "top aside" "body aside";
    column-gap: var(--rl-s-5);
  }
  #inboxDetail .inbox-top   { grid-area: top; min-width: 0; }
  #inboxDetail .inbox-body  { grid-area: body; min-width: 0; }
  #inboxDetail .inbox-aside {
    grid-area: aside; align-self: start;
    position: sticky; top: calc(var(--rl-sticky-top, 0px) + var(--rl-s-3));
    max-height: calc(100vh - var(--rl-topbar-h) - var(--rl-sticky-top, 0px) - var(--rl-s-10));
    overflow-y: auto;
  }
  #inboxDetail .inbox-aside .inbox-context { margin-bottom: 0; }
  #inboxDetail .inbox-aside .inbox-context-grid { grid-template-columns: 1fr; }
}
.inbox-thread-head { display: flex; align-items: flex-start; gap: 12px; padding-bottom: 14px; border-bottom: 1px solid var(--rl-line); }
.inbox-thread-id { flex: 1; min-width: 0; }
.inbox-thread-id h3 { font-family: var(--rl-font-serif); font-size: 19px; font-weight: 600; margin: 0 0 3px; }
.inbox-thread-sub { font-size: 13.5px; color: var(--rl-text); font-weight: 500; margin-bottom: 3px; }
.inbox-thread-meta { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--rl-text-3); flex-wrap: wrap; }
.inbox-sep { width: 3px; height: 3px; border-radius: var(--rl-r-full); background: var(--rl-line-strong); flex: none; }

.inbox-actions { display: flex; flex-wrap: wrap; gap: 6px; padding: 12px 0; }
.inbox-tagrow { display: flex; flex-wrap: wrap; gap: 5px; padding-bottom: 10px; }
.inbox-snooze-note {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--rl-text-2);
  background: var(--rl-tint-accent-bg); border: 1px solid var(--rl-line-accent);
  border-radius: var(--rl-r-sm); padding: 8px 12px; margin-bottom: 12px;
}

/* contact context */
.inbox-context {
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-md);
  background: var(--rl-surface-sunk); margin-bottom: 16px;
}
.inbox-context > summary {
  list-style: none; cursor: pointer; padding: 10px 14px; min-height: 32px;
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; font-weight: 600; color: var(--rl-text-2);
}
.inbox-context > summary::-webkit-details-marker { display: none; }
.inbox-context > summary::before {
  content: ""; width: 6px; height: 6px; border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor; transform: rotate(-45deg);
  transition: transform var(--rl-d-fast) var(--rl-ease-standard); flex: none;
}
.inbox-context[open] > summary::before { transform: rotate(45deg); }
.inbox-context-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px 18px; padding: 4px 14px 14px;
}
.inbox-ctx-label { font-size: 11px; font-weight: 600; color: var(--rl-text-3); margin-bottom: 2px; }
.inbox-ctx-val { font-size: 13px; color: var(--rl-text); overflow-wrap: anywhere; }
.inbox-context-foot { padding: 0 14px 14px; }

/* thread messages */
.inbox-thread-list { display: flex; flex-direction: column; gap: 12px; padding: 4px 0 16px; }
.inbox-msg { border: 1px solid var(--rl-line); border-radius: var(--rl-r-md); background: var(--rl-surface); overflow: hidden; }
.inbox-msg.outbound { border-color: var(--rl-line-accent); background: var(--rl-tint-accent-bg); }
.inbox-msg.note { border-color: var(--rl-a-200); background: var(--rl-tint-amber-bg); }
.inbox-msg-head { display: flex; align-items: center; gap: 10px; padding: 10px 12px; }
.inbox-msg-who { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.inbox-msg-name { font-size: 13px; font-weight: 600; color: var(--rl-text); display: flex; align-items: center; gap: 6px; }
.inbox-msg-tag {
  font-size: 10px; font-weight: 600; padding: 0 6px; border-radius: var(--rl-r-xs);
  background: var(--rl-surface); color: var(--rl-text-3); border: 1px solid var(--rl-line);
}
.inbox-msg-addr { font-size: 11.5px; color: var(--rl-text-2); overflow-wrap: anywhere; }
.inbox-msg-time { flex: none; font-size: 11.5px; color: var(--rl-text-2); }
.inbox-msg-body { padding: 0 12px 12px; }
.inbox-msg-text, .inbox-msg-note-body { font-size: 13.5px; line-height: 1.5; color: var(--rl-text); overflow-wrap: anywhere; }
.inbox-msg-quote {
  font-size: 12.5px; color: var(--rl-text-3); margin-top: 8px;
  border-left: 2px solid var(--rl-line); padding-left: 10px; overflow-wrap: anywhere;
}
.inbox-quote-btn { margin-top: 8px; }
.inbox-msg-pending { margin: 0 12px 12px; font-size: 12px; color: var(--rl-text-warning); }
.inbox-msg-caption { padding: 0 12px 10px; font-size: 11.5px; color: var(--rl-text-3); }

/* the email itself, rendered as it was authored — on paper, in both themes */
.inbox-html-wrap { overflow-x: auto; }
.inbox-html {
  background: var(--rl-n-0); color: var(--rl-n-900);
  border: 1px solid var(--rl-n-200); border-radius: var(--rl-r-sm);
  padding: 14px 16px; font-size: 13.5px; line-height: 1.5;
}
.inbox-html img { max-width: 100%; height: auto; }
.inbox-html a { color: var(--rl-b-700); }
.inbox-html table { max-width: 100%; }
.inbox-html * { max-width: 100%; }
.inbox-img-blocked { display: none; }
.inbox-img-note {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 12px; color: var(--rl-text-3); padding: 8px 12px 0;
}

/* composer — sits at the end of the thread, the same place every other
   RoomLine detail panel puts its reply box (a tall sticky composer covers
   the messages it is a reply to) */
.inbox-compose {
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-md);
  background: var(--rl-surface-sunk);
  padding: 10px 12px; margin-top: 4px;
}
.inbox-compose-tabs { display: flex; gap: 4px; margin-bottom: 10px; border-bottom: 1px solid var(--rl-line); }
.inbox-ctab {
  min-height: 32px; padding: 0 12px; background: none; border: none;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  font-size: 13px; font-weight: 500; color: var(--rl-text-3); cursor: pointer;
}
.inbox-ctab.active { color: var(--rl-text-accent); border-bottom-color: var(--rl-i-600); font-weight: 600; }
.inbox-ctab:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
.inbox-compose-tools { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.inbox-tool-label { font-size: 11px; font-weight: 600; color: var(--rl-text-3); }
.inbox-compose-tools .btn-select { max-width: 240px; }
.inbox-compose textarea { width: 100%; }
.inbox-compose-row { margin-top: 8px; }
.inbox-compose-hint { font-size: 11.5px; color: var(--rl-text-3); margin: 6px 0 0; }

/* =========================================================================
   RECORD PANE — the shared master/detail skeleton, restated.
   The detail pane on Tenancies (and, on rollout, every split view) was a
   stack of small things: a header, then a 2-col value grid, then a SECOND
   2-col value grid, then a row of bordered pill tabs, then more grids. Too
   many boxes for one column.

   This is the calmer version, and it is deliberately close to Today: a
   summary block whose only ornament is the record's own numbers on a
   hairline row, one quiet underlined tab strip, and section dividers that
   are a label and a rule rather than a tracked-out shout.
   ========================================================================= */
.rl-summary { padding-bottom: 16px; border-bottom: 1px solid var(--rl-line); margin-bottom: 4px; }
.rl-summary-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.rl-summary-top h3 {
  font-family: var(--rl-font-serif); font-size: 20px; font-weight: 400;
  line-height: 26px; letter-spacing: -0.01em; margin: 0;
}
.rl-summary-badges { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; flex-wrap: wrap; }
.rl-summary-sub { font-size: 12.5px; color: var(--rl-text-3); margin-top: 4px; }
.rl-summary-sub a { color: var(--rl-text-accent); }
.rl-dot {
  display: inline-block; width: 3px; height: 3px; border-radius: var(--rl-r-full);
  background: var(--rl-line-strong); vertical-align: middle; margin: 0 7px;
}

/* The record summary reuses the §9.6 metric idea but at record scale, so
   every rule here is scoped under .rl-summary — the Today metric row
   (bare .rl-metrics) keeps its 32px figures untouched. */
.rl-summary .rl-metrics { display: flex; flex-wrap: wrap; margin: 16px 0 0; }
.rl-summary .rl-metric {
  flex: 1 1 130px; min-width: 110px; padding: 0 20px;
  border-left: 1px solid var(--rl-line-soft);
}
.rl-summary .rl-metric:first-child { padding-left: 0; border-left: none; }
.rl-summary .rl-metric-label { font-size: 11.5px; color: var(--rl-text-2); margin: 0 0 3px; letter-spacing: .005em; }
.rl-summary .rl-metric-value {
  font-family: var(--rl-font-serif); font-size: 22px; font-weight: 400;
  line-height: 26px; color: var(--rl-text); display: block; margin: 0;
  font-variant-numeric: tabular-nums lining-nums; letter-spacing: -0.01em;
}
.rl-summary .rl-metric-value.warn { color: var(--rl-text-danger); }
@media (max-width: 700px) {
  .rl-summary .rl-metric { flex-basis: 45%; padding: 0; border-left: none; margin: 6px 0; }
}

/* quiet tab strip — underline, not pills */
.rl-recordtabs {
  display: flex; flex-wrap: wrap; gap: 0 2px;
  margin: 14px 0 18px; border-bottom: 1px solid var(--rl-line);
}
.rl-recordtab {
  flex: 0 0 auto; background: none; border: none;
  padding: 8px 12px; margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  font-size: 13px; font-weight: 500; color: var(--rl-text-3);
  cursor: pointer; white-space: nowrap; min-height: 34px;
}
.rl-recordtab:hover { color: var(--rl-text-2); }
.rl-recordtab.active { color: var(--rl-text); border-bottom-color: var(--rl-i-600); font-weight: 600; }
.rl-recordtab:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
.rl-recordtab .n { color: var(--rl-text-3); font-weight: 400; margin-left: 5px; }
.rl-recordtab.active .n { color: var(--rl-text-2); }

/* compact fact list — replaces the second/third .cd-meta-grid */
.rl-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px 24px; margin: 2px 0 18px;
}
.rl-fact-label { font-size: 11.5px; color: var(--rl-text-2); }
.rl-fact-value { font-size: 13.5px; color: var(--rl-text); font-weight: 500; margin-top: 1px; overflow-wrap: anywhere; }
.rl-fact-value.warn { color: var(--rl-text-danger); }

/* section divider — a label and a hairline */
.rl-sec {
  display: flex; align-items: center; gap: 10px;
  font-size: 12.5px; font-weight: 600; color: var(--rl-text-2);
  margin: 22px 0 10px;
}
.rl-sec:first-child { margin-top: 4px; }
.rl-sec::after { content: ""; flex: 1; height: 1px; background: var(--rl-line-soft); }
.rl-sec .n { font-weight: 400; color: var(--rl-text-3); }

/* quiet master rows — a primary line, one dim line, and a flag only when
   the tenancy is the exception. A list where every row says the same word
   is not carrying information. Scoped to #contractsList so the move-outs
   and refunds lists (same .contract-item class, different row shape) are
   untouched until they get the same pass. */
#contractsList .contract-item { display: flex; flex-direction: column; }
#contractsList .ci-head { display: flex; align-items: baseline; gap: 8px; }
#contractsList .ci-title {
  flex: 1; min-width: 0; margin-bottom: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#contractsList .ci-tenant { margin-bottom: 0; }
/* a small "this row is the exception" flag — a tenancy that needs a hand,
   an invoice with no address, etc. */
#app .ci-flag, #app .rl-flag {
  display: inline-flex; align-items: center; flex: 0 0 auto;
  font-size: 10.5px; font-weight: 600; padding: 1px 7px;
  border-radius: var(--rl-r-xs);
  background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg);
}
#app .ci-flag.issue, #app .rl-flag.issue { background: var(--rl-tint-red-bg); color: var(--rl-tint-red-fg); }

/* =========================================================================
   THE ROLL-OUT — the same declutter, applied to every split view at once
   by restating the shared primitives rather than editing 20 render
   functions. .cd-* is the pre-spec detail-pane family (Tenancies, Leads,
   Sequences, Move-outs, Refunds, Conduct, Compliance, Appointments, …);
   .contact-* is the one Contacts uses. Both get the calm treatment.
   ========================================================================= */

/* section divider: a label and a hairline, never a tracked-out shout */
#app .cd-section-title {
  display: flex; align-items: center; gap: 10px;
  font-size: 12.5px; font-weight: 600; color: var(--rl-text-2);
  letter-spacing: .005em; text-transform: none;
  margin: 22px 0 10px;
}
#app .cd-section-title::after { content: ""; flex: 1; height: 1px; background: var(--rl-line-soft); }
#app .cw-card .cd-section-title, #app .lw-card .cd-section-title,
#app .cd-section-title:first-child { margin-top: 4px; }

/* value grids: auto-fit (not a forced 1fr 1fr), lighter figures */
#app .cd-meta-grid, #app .contact-info-grid {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px 24px; margin-bottom: 18px;
}
#app .cd-meta-grid .m-label, #app .contact-info-grid .m-label {
  font-size: 11.5px; font-weight: 400; color: var(--rl-text-2); margin-bottom: 2px;
}
#app .cd-meta-grid .m-val, #app .contact-info-grid .m-val {
  font-size: 13.5px; font-weight: 500;
}
#app .cd-meta-grid .m-val.deadline, #app .cd-meta-grid .m-val.warn { color: var(--rl-text-danger); }

/* detail headers: the calmer serif, a touch more air below */
#app .cd-head, #app .contact-detail-head { padding-bottom: 16px; margin-bottom: 18px; }
#app .cd-head h3, #app .contact-detail-head h3 {
  font-family: var(--rl-font-serif); font-size: 20px; font-weight: 400;
  line-height: 26px; letter-spacing: -0.01em;
}

/* related-object rows (relRow / .cd-sign-row): hairline, tighter */
#app .cd-sign-row { border-bottom-color: var(--rl-line-soft); padding: 9px 0; font-size: 13px; }
#app .cd-sign-name { font-weight: 500; }

/* master lists: quieter secondary line, lighter title weight, tighter rhythm */
#app .side-item .si-title, #app .contract-item .ci-title { font-weight: 500; }
#app .side-item .si-sub, #app .contract-item .ci-tenant { color: var(--rl-text-2); margin-bottom: 4px; }
#app .side-item .si-sub:last-child, #app .contract-item .ci-tenant:last-child { margin-bottom: 0; }

/* in-view sub-tabs: a lighter pill (was a 1.5px border, 20px radius) */
#app .ops-sub-btn, #app .reports-sub-btn, #app .governance-sub-btn {
  border-width: 1px; border-radius: var(--rl-r-sm);
  padding: 6px 12px; font-weight: 500; font-size: 12.5px;
}
#app .ops-sub-btn.active, #app .reports-sub-btn.active, #app .governance-sub-btn.active {
  border-color: transparent;
}

/* the "created by" line under a record header */
#app .cd-created { color: var(--rl-text-3); }

/* an identifier in a table cell is a link, not a bordered button */
#app .rl-idlink {
  background: none; border: none; cursor: pointer;
  display: inline-flex; align-items: center; min-height: 30px; padding: 0 2px;
  font-family: var(--rl-font-mono); font-size: 12.5px; white-space: nowrap;
  color: var(--rl-text-accent); text-decoration: none;
}
#app .rl-idlink:hover { text-decoration: underline; }
#app .rl-idlink:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); border-radius: 2px; }

/* the trailing actions column of a table: tight, right-aligned */
#app .rl-rowacts { display: flex; gap: 6px; justify-content: flex-end; flex-wrap: wrap; align-items: center; }

/* Invoicing table: the reference column and the two dates should not wrap
   (a table with 8 columns wraps "Rent — room CAM-101" to four lines
   otherwise). */
#app #tblInvoicingMain td:nth-child(2),
#app #tblInvoicingMain td:nth-child(5),
#app #tblInvoicingMain td:nth-child(6),
#app #tblInvoicingMain th:nth-child(5),
#app #tblInvoicingMain th:nth-child(6) { white-space: nowrap; }

/* =========================================================================
   THE FILTER BAR — the toolbar above every list, restated as a quiet row
   of pills. The native <select> keeps working; it just stops looking like
   an OS dropdown from 2009. Scoped to .view-toolbar / .btn-select so form
   selects in modals and .field-block keep the standard input look.
   ========================================================================= */
#app .view-toolbar { gap: var(--rl-s-2); margin-bottom: var(--rl-s-4); }

#app .toolbar-search { min-width: 190px; max-width: 300px; }
#app .toolbar-search input {
  width: 100%; height: 36px; padding: 0 12px 0 32px;
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-full);
  background: var(--rl-surface-sunk); color: var(--rl-text);
  font-size: 13px; font-family: inherit;
  transition: background var(--rl-d-instant) var(--rl-ease-standard), border-color var(--rl-d-instant) var(--rl-ease-standard);
}
#app .toolbar-search input::placeholder { color: var(--rl-text-3); }
#app .toolbar-search input:focus {
  outline: none; background: var(--rl-surface);
  border-color: var(--rl-line-control); box-shadow: var(--rl-focus);
}
#app .toolbar-search svg { left: 12px; width: 14px; height: 14px; opacity: .55; }

#app .view-toolbar .btn-select,
#app .view-toolbar select,
#app .btn-select {
  appearance: none; -webkit-appearance: none;
  height: 36px; min-height: 36px;
  padding: 0 30px 0 13px;
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-full);
  background-color: var(--rl-surface);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5' fill='none' stroke='%238990A0' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center;
  font-size: 12.5px; font-weight: 500; color: var(--rl-text-2);
  cursor: pointer;
}
#app .view-toolbar .btn-select:hover,
#app .view-toolbar select:hover,
#app .btn-select:hover { border-color: var(--rl-line-strong); color: var(--rl-text); }
#app .view-toolbar .btn-select:focus,
#app .view-toolbar select:focus,
#app .btn-select:focus {
  outline: none; border-color: var(--rl-line-control);
  box-shadow: var(--rl-focus); color: var(--rl-text);
}
/* A select that is off its default option — an active filter — reads as
   one, without a line of JS. (Chrome 105+, Safari 15.4+; degrades to the
   plain pill everywhere else.) */
#app .view-toolbar select:has(option:checked:not([value=""]):not(:first-child)) {
  border-color: var(--rl-line-accent);
  background-color: var(--rl-tint-accent-bg);
  color: var(--rl-text-accent);
}

/* =========================================================================
   THE FILTER BAR COMPONENT (js/filter-bar.js, 2026-10-01)
   Views strip, toolbar, the active-filter line, and the selection bar.
   Everything inside the toolbar is the pill language above.
   ========================================================================= */
#app .rl-fbar { margin-bottom: var(--rl-s-3); }
#app .rl-fbar-views { margin-bottom: var(--rl-s-3); }
#app .rl-fbar-views[hidden] { display: none; }
#app .rl-fbar-views button.is-mine { display: inline-flex; align-items: center; gap: 4px; }
#app .rl-fbar-vx {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; margin-right: -4px; border-radius: var(--rl-r-full);
  color: var(--rl-text-3); opacity: 0; transition: opacity var(--rl-d-fast) var(--rl-ease-standard);
}
#app .rl-fbar-views button:hover .rl-fbar-vx,
#app .rl-fbar-views button[aria-pressed="true"] .rl-fbar-vx,
#app .rl-fbar-vx:focus-visible { opacity: 1; }
#app .rl-fbar-vx:hover { background: var(--rl-surface-sunk); color: var(--rl-text); }
#app .rl-fbar-vx:focus-visible { outline: none; box-shadow: var(--rl-focus); }

#app .rl-fbar-row { margin-bottom: var(--rl-s-2); }
#app .rl-fbar-search { flex: 0 1 300px; min-width: 220px; }
#app .rl-fbar-quick { display: contents; }
#app .rl-fbar-morebtn { height: 36px; border-radius: var(--rl-r-full); }
#app .rl-fbar-morebtn.is-set { border-color: var(--rl-line-accent); background: var(--rl-tint-accent-bg); color: var(--rl-text-accent); }
#app .rl-fbar-n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 4px; border-radius: var(--rl-r-full);
  background: var(--rl-text-accent); color: var(--rl-surface);
  font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums;
}
#app .rl-fbar-extra:empty { display: none; }
#app .rl-fbar-extra { display: inline-flex; gap: var(--rl-s-2); }
#app .rl-fbar-menuwrap { position: relative; }
#app .rl-fbar-menubtn { width: 36px; height: 36px; padding: 0; justify-content: center; border-radius: var(--rl-r-full); }
#app .rl-fbar-menu { right: 0; top: calc(100% + 6px); min-width: 260px; transform-origin: top right; }

/* What is on, each removable; and what it hides, on the same line. */
#app .rl-fbar-chips {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--rl-s-2);
  min-height: 28px; margin-bottom: var(--rl-s-3);
}
#app .rl-fbar-chip {
  display: inline-flex; align-items: center; gap: 2px;
  height: 32px; padding: 0 2px 0 11px; border-radius: var(--rl-r-full);
  background: var(--rl-tint-accent-bg); color: var(--rl-text-accent);
  font-size: 12.5px; max-width: 100%;
}
#app .rl-fbar-chip > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#app .rl-fbar-chip b { font-weight: 600; }
#app .rl-fbar-chip button {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 30px; height: 30px; border: 0; border-radius: var(--rl-r-full);
  background: transparent; color: inherit; cursor: pointer;
}
#app .rl-fbar-chip button:hover { background: color-mix(in srgb, currentColor 14%, transparent); }
#app .rl-fbar-chip button:focus-visible { outline: none; box-shadow: var(--rl-focus); }
#app .rl-fbar-clear {
  border: 0; background: none; min-height: 32px; padding: 0 6px; cursor: pointer;
  font-size: 12.5px; color: var(--rl-text-2); text-decoration: underline; text-underline-offset: 2px;
}
#app .rl-fbar-clear:hover { color: var(--rl-text); }
#app .rl-fbar-count { margin-left: auto; font-size: 12.5px; color: var(--rl-text-2); font-variant-numeric: tabular-nums; }
#app .rl-fbar-count b { color: var(--rl-text); font-weight: 600; }
#app .rl-fbar-count span { color: var(--rl-text-3); }

/* The selection bar sticks under the top bar while you scroll the list. */
#app .rl-fbar-bulk {
  position: sticky; top: var(--rl-s-2); z-index: 5;
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--rl-s-2);
  padding: var(--rl-s-2) var(--rl-s-3); margin-bottom: var(--rl-s-3);
  border: 1px solid var(--rl-line-accent); border-radius: var(--rl-r-md, 8px);
  background: var(--rl-surface-raised); box-shadow: var(--rl-e-1);
}
#app .rl-fbar-bulk[hidden] { display: none; }
#app .rl-fbar-bulk-n { font-size: 13px; color: var(--rl-text-2); margin-right: var(--rl-s-2); }
#app .rl-fbar-bulk-n b { color: var(--rl-text); }
#app .rl-fbar-bulk-acts { display: inline-flex; flex-wrap: wrap; gap: var(--rl-s-2); margin-left: auto; }

/* The checkbox column. */
#app table th.rl-col-select, #app table td.rl-col-select { width: 36px; padding-right: 0; }
#app input.rl-sel { width: 16px; height: 16px; margin: 0; cursor: pointer; vertical-align: middle; }
/* The tick is drawn at 16px; the label round it is the 32px target. */
#app .rl-sel-hit { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; margin: -8px; cursor: pointer; }
#app table tbody tr:has(> td.rl-col-select input.rl-sel:checked) > td { background: var(--rl-tint-accent-bg); }

/* The "More filters" editor: two columns of fields on desktop. */
#app .rl-fbar-editor, .rl-fbar-editor {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--rl-s-5);
  max-height: min(62vh, 560px); overflow-y: auto; padding-right: 4px;
}
.rl-fbar-multi {
  display: flex; flex-direction: column; gap: 2px; max-height: 168px; overflow-y: auto;
  padding: 6px 8px; border: 1px solid var(--rl-line); border-radius: var(--rl-r-sm);
}
/* .field-block in the selectors to outrank styles.css's caption rule
   (`.field-block label`: 11px bold uppercase) and its full-width input
   rule, both wrong on a tick list — the same escape .perm-picker makes.
   No #app prefix: the dialog is a child of <body>, outside #app. */
.field-block .rl-fbar-multi label.rl-fbar-opt {
  display: flex; align-items: center; gap: 8px; min-height: 28px; margin: 0; padding: 0;
  font-size: 13px; font-weight: 400; text-transform: none; letter-spacing: normal;
  color: var(--rl-text); cursor: pointer;
}
.field-block .rl-fbar-multi label.rl-fbar-opt input[type="checkbox"] {
  width: 16px; height: 16px; min-height: 0; flex: 0 0 auto; margin: 0; padding: 0;
  border-radius: 3px; background: none;
}
.rl-fbar-none { font-size: 12.5px; color: var(--rl-text-3); }
.rl-fbar-pair { display: flex; align-items: center; gap: 8px; }
.rl-fbar-pair > span { font-size: 12.5px; color: var(--rl-text-3); }
.rl-fbar-pair input { flex: 1; min-width: 0; }
.rl-fbar-date { display: flex; flex-direction: column; gap: 8px; }
.rl-fbar-date[data-custom="false"] .rl-fbar-pair { display: none; }
#app .rl-fbar-narrow { display: none; }
@media (max-width: 719px) {
  /* One row on a phone: search, Filters, the menu. The quick selects
     would stack four pills high above the chips that already say what is
     set, so they go behind Filters with everything else. */
  #app .rl-fbar-quick, #app .rl-fbar-row > .spacer, #app .rl-fbar-wide { display: none; }
  #app .rl-fbar-narrow { display: inline; }
  #app .rl-fbar-n.rl-fbar-narrow { display: inline-flex; }
  #app .rl-fbar-row { flex-wrap: nowrap; }
  #app .rl-fbar-search { flex: 1 1 auto; min-width: 0; max-width: none; }
  #app .rl-fbar-morebtn, #app .rl-fbar-menubtn { flex: none; }
  #app .rl-fbar-morebtn.is-set-narrow { border-color: var(--rl-line-accent); background: var(--rl-tint-accent-bg); color: var(--rl-text-accent); }
  #app table tbody tr:has(> td.rl-col-select input.rl-sel:checked) { background: var(--rl-tint-accent-bg); }
  #app table tbody tr:has(> td.rl-col-select input.rl-sel:checked) > td { background: none; }
  #app .rl-fbar-editor, .rl-fbar-editor { grid-template-columns: 1fr; }
  #app .rl-fbar-count { margin-left: 0; width: 100%; }
  /* On the card list the checkbox sits top-right of the card, and the
     next cell takes over as the card's title. */
  #app table tr:has(> td.rl-col-select) { position: relative; }
  #app table td.rl-col-select { position: absolute; top: var(--rl-s-3); right: var(--rl-s-3); width: auto; padding: 0; }
  #app table td.rl-col-select::before { display: none; }
  #app table td.rl-col-select + td { font-size: 15px; font-weight: 500; color: var(--rl-text); margin-bottom: 4px; padding-right: 32px; }
  #app table td.rl-col-select + td::before { display: none; }
  #app table th.rl-col-select { display: none; }
}

/* quick-filter chips (Contacts type, Move-outs, Refunds stage): the same
   pill language as the selects */
#app .qf-chip {
  height: 36px; min-height: 36px; padding: 0 14px;
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-full);
  background: var(--rl-surface); color: var(--rl-text-2);
  font-size: 12.5px; font-weight: 500; cursor: pointer;
  /* inline-flex drops the whitespace text node between a label and its
     count span, so without a gap "Open 0" rendered as "Open0". */
  display: inline-flex; align-items: center; gap: 6px;
}
#app .qf-chip-n { font-variant-numeric: tabular-nums; color: var(--rl-text-3); }
#app .qf-chip.active .qf-chip-n { color: inherit; opacity: .7; }
#app .qf-chip:hover { border-color: var(--rl-line-strong); color: var(--rl-text); }
#app .qf-chip.active {
  border-color: var(--rl-line-accent);
  background: var(--rl-tint-accent-bg); color: var(--rl-text-accent);
}
#app .qf-row { gap: var(--rl-s-2); }

/* =========================================================================
   THE NEEDS-ATTENTION STRIP

   What is left of five sections. Each chip is one question a register
   used to answer, asked of people instead of rows. It sits under the
   view title as a quiet secondary row rather than a tab bar, because §5
   says one navigation in one place — this is a filter on a list, not a
   second navigation.

   The count carries the tone, not the chip: a strip of five saturated
   pills would be five alarms, and most days most of them are routine.
   ========================================================================= */
#app .rl-flags {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--rl-s-2); margin: 0 0 var(--rl-s-4);
}
#app .rl-flags-lead {
  font-size: 11px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--rl-text-3);
  margin-right: var(--rl-s-1);
}
#app .rl-flagchip {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 30px; padding: 0 10px 0 12px;
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-full);
  background: var(--rl-surface); color: var(--rl-text-2);
  font: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer;
}
#app .rl-flagchip:hover { border-color: var(--rl-line-strong); color: var(--rl-text); }
#app .rl-flagchip:focus-visible { outline: none; box-shadow: var(--rl-focus); }
#app .rl-flagchip .n {
  min-width: 18px; padding: 0 5px; border-radius: var(--rl-r-full);
  background: var(--rl-surface-sunk); color: var(--rl-text-3);
  font-family: var(--rl-font-mono); font-size: 11px; text-align: center;
}
#app .rl-flagchip.is-red .n   { background: var(--rl-tint-red-bg);   color: var(--rl-tint-red-fg); }
#app .rl-flagchip.is-amber .n { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }
#app .rl-flagchip.is-quiet { color: var(--rl-text-3); }
#app .rl-flagchip[aria-pressed="true"] {
  border-color: var(--rl-line-accent);
  background: var(--rl-tint-accent-bg); color: var(--rl-text-accent);
}

/* Now only Properties' building picker (#propertyPicker) — Occupancy's
   own "Estate" box was removed 2026-09-22 (Buildings & rooms already has
   its own nav rail entry, so the shortcut link was redundant). */
#app .rl-registers {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--rl-s-2); margin: 0 0 var(--rl-s-4);
}
#app .rl-registers-lead {
  font-size: 11px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--rl-text-3);
  margin-right: var(--rl-s-1);
}
#app .rl-register {
  height: 30px; padding: 0 12px;
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-full);
  background: var(--rl-surface); color: var(--rl-text-2);
  font: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer;
  display: inline-flex; align-items: center;
}
#app .rl-register:hover { border-color: var(--rl-line-strong); color: var(--rl-text); }
#app .rl-register.is-on {
  border-color: var(--rl-i-600); background: var(--rl-i-600); color: var(--rl-n-0); font-weight: 600;
}
#app .rl-register:focus-visible { outline: none; box-shadow: var(--rl-focus); }

/* =========================================================================
   EMBEDDED RECORDS

   A tenancy, an inspection, a conduct case and a compliance check are all
   drawn by the file that owns them, into a host element this record
   provides. They arrive carrying their own markup — .cd-head, .rl-facts,
   tables — which was written for a full-width detail pane, so the wrapper
   gives them the padding a p360-panel body would have had and lets a wide
   table scroll rather than burst the column.
   ========================================================================= */
#app .p360-embed { padding: var(--rl-s-4); overflow-x: auto; }
#app .p360-embed > .cd-head:first-child { margin-top: 0; }
#app .p360-tbl tr.is-open > td { background: var(--rl-surface-sunk); }
#app .p360-tl-item.is-open { background: var(--rl-surface-sunk); }

/* =========================================================================
   §10.10 360 — THE PERSON RECORD

   Three columns: what is fixed about the person (left), what has happened
   to them (centre), what needs doing about them (right). The centre column
   is the only one that changes when you move between the record's tabs,
   so the person never leaves the screen.

   The record is the one place in the product that leads with the serif
   face at title size. A person's name is not a view title — it is the
   subject — and reading it as one is the whole difference between a record
   and a filtered list.
   ========================================================================= */
#app #view-p360 { padding-top: 0; }

#app .p360-head { padding: var(--rl-s-5) 0 0; }
#app .p360-head-top { display: flex; align-items: flex-start; gap: var(--rl-s-4); }

#app .p360-monogram {
  width: 60px; height: 60px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--rl-r-lg);
  background: var(--rl-tint-accent-bg); color: var(--rl-text-accent);
  border: 1px solid var(--rl-line-soft);
  font-family: var(--rl-font-serif); font-size: 23px; font-weight: 600;
}
#app .p360-ident { flex: 1; min-width: 0; }
#app .p360-name {
  margin: 0; font-family: var(--rl-font-serif);
  font-size: 30px; line-height: 1.15; font-weight: 600; letter-spacing: -0.015em;
  color: var(--rl-text); text-wrap: balance;
}
#app .p360-where {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--rl-s-2);
  margin-top: var(--rl-s-1); font-size: 13px; color: var(--rl-text-2);
}
/* A bare <span> is inline, so width/height did nothing to it and the
   separator collapsed to zero wherever it was used outside a flex row —
   which is how "People here" rendered as DiegoPatelKiraMarsh. Spacing
   still comes from the flex gap inside .p360-where; the margin below is
   only for the inline contexts that have no gap to give it. */
#app .p360-dot {
  display: inline-block; vertical-align: middle;
  width: 3px; height: 3px; border-radius: 50%;
  background: var(--rl-line-strong); flex: none;
}
#app .p360-fact .p360-dot { margin: 0 7px; }
#app .p360-mono { font-family: var(--rl-font-mono); font-size: 12.5px; }
#app .p360-actions { display: flex; gap: var(--rl-s-2); flex: none; }

#app .p360-stage {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px 3px 7px; border-radius: var(--rl-r-full);
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.01em; white-space: nowrap;
}
#app .p360-stage::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor;
}
#app .p360-stage.is-green  { background: var(--rl-tint-green-bg);  color: var(--rl-tint-green-fg); }
#app .p360-stage.is-accent { background: var(--rl-tint-accent-bg); color: var(--rl-tint-accent-fg); }
#app .p360-stage.is-quiet  { background: var(--rl-surface-sunk);   color: var(--rl-text-2); }

/* The chips are the scan. No chips means this person is fine — which is
   why they are the only saturated colour on the record, and why they are
   buttons: each one is a link to the pane that explains it. */
#app .p360-chips {
  display: flex; flex-wrap: wrap; gap: var(--rl-s-2); margin-top: var(--rl-s-4);
}
#app .p360-chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 30px;   /* §9 minimum target; it was 29 */
  padding: 5px 11px; border-radius: var(--rl-r-md);
  font-size: 12.5px; font-weight: 500; font-family: inherit;
  border: 1px solid transparent; cursor: pointer;
  transition: filter var(--rl-d-fast) var(--rl-ease-standard);
}
#app .p360-chip b { font-family: var(--rl-font-mono); font-weight: 500; font-variant-numeric: tabular-nums; }
#app .p360-chip:hover { filter: brightness(0.97); }
[data-theme="dark"] #app .p360-chip:hover { filter: brightness(1.18); }
#app .p360-chip.is-red   { background: var(--rl-tint-red-bg);   color: var(--rl-tint-red-fg);   border-color: var(--rl-r-200); }
#app .p360-chip.is-amber { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); border-color: var(--rl-a-200); }
#app .p360-chip.is-green { background: var(--rl-tint-green-bg); color: var(--rl-tint-green-fg); border-color: var(--rl-g-200); }
#app .p360-chip.is-quiet { background: var(--rl-surface-sunk);  color: var(--rl-text-2);        border-color: var(--rl-line); }

#app .p360-tabs {
  display: flex; gap: 2px; margin-top: var(--rl-s-5);
  border-bottom: 1px solid var(--rl-line);
}
#app .p360-tab {
  padding: 9px 13px; border: 0; background: none; font-family: inherit; font-size: 13px;
  color: var(--rl-text-3); border-bottom: 2px solid transparent; margin-bottom: -1px;
  cursor: pointer; transition: color var(--rl-d-fast) var(--rl-ease-standard);
}
#app .p360-tab:hover { color: var(--rl-text); }
#app .p360-tab[aria-selected="true"] {
  color: var(--rl-text); font-weight: 600; border-bottom-color: var(--rl-i-600);
}
#app .p360-tab-n {
  font-family: var(--rl-font-mono); font-size: 11px; color: var(--rl-text-3); margin-left: 5px;
}

/* ---- the three columns ---- */
#app .p360-body {
  display: grid; grid-template-columns: 236px minmax(0, 1fr) 250px;
  gap: var(--rl-s-5); padding-top: var(--rl-s-5); align-items: start;
}
/* THE THREE COLUMNS STAY.

   Dropping the "Now" rail on this tab did give the agreement room, and it
   also moved the record's centre line every time you changed tab — the
   thing you were reading slid sideways. The columns are fixed; what the
   agreement needed was not more of the page, it was the whole of the
   column it already had.

   So the embed carries no padding of its own and the agreement's own
   blocks run to the panel edges. It was losing ~40px on each side to a
   wrapper that existed only because every other pane wanted one. */
#app .p360-embed { padding: 0; }
#app .p360-embed > #contractsDetail { padding: 0; }
#app .p360-embed .rl-summary,
#app .p360-embed .rl-facts,
#app .p360-embed .rl-sec,
#app .p360-embed > div > table { padding-left: var(--rl-s-4); padding-right: var(--rl-s-4); }
#app .p360-embed .cd-meta-grid { padding: 0 var(--rl-s-4) var(--rl-s-3); }
#app .p360-embed .form-actions { padding: 0 var(--rl-s-4) var(--rl-s-4); }
#app .p360-embed table { width: 100%; }
/* The rows that were still running into the panel's left edge: the
   signatory list and the rent-payment line are plain .cd-sign-row divs,
   one level too deep for the `> div > table` rule above, so "Aisha
   Achebe · Signed" started at the border while the heading over it was
   inset 16px. Same inset as everything else in the agreement. */
#app .p360-embed .cd-sign-row,
#app .p360-embed .settings-row,
#app .p360-embed .cl-deadline,
#app .p360-embed .empty-note,
#app .p360-embed .rl-alert { margin-left: var(--rl-s-4); margin-right: var(--rl-s-4); }
#app .p360-embed .cl-checkin { margin: 0 var(--rl-s-4); width: calc(100% - 2 * var(--rl-s-4)); }
#app .p360-agmts { display: flex; flex-wrap: wrap; gap: var(--rl-s-2); margin-bottom: var(--rl-s-3); }

/* =========================================================================
   THE BOOKING STATE, AND THE BOOKINGS BEHIND A PERSON

   Two tones the stage chip never had. "Held" and "History debtor" are
   the two states that mean something is running out or something is owed,
   and a scan that renders both in the same grey as "Enquiry" is not a
   scan. Same tint tokens every other warning in the product uses.
   ========================================================================= */
#app .p360-stage.is-amber { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }
#app .p360-stage.is-red   { background: var(--rl-tint-red-bg);   color: var(--rl-tint-red-fg); }

/* The line beside the state chip on the record head — "Room held, 3h 12m
   left", "Arrives 21 Sep". Quiet, because it explains the chip rather
   than competing with it. */
#app .p360-statenote { font-size: 12.5px; color: var(--rl-text-2); }

/* THE REFERENCE. Monospaced and selectable — you read it out or copy it,
   you never click it, so it is deliberately not a button. */
#app .rl-bookref, .rl-bookref {
  font-family: var(--rl-font-mono); font-size: 12.5px; letter-spacing: 0.02em;
  color: var(--rl-text-2); user-select: all;
}

/* THE BOOKINGS LIST on the record's Tenancy tab. One row per booking:
   reference, state, where. A row is a button because picking one changes
   which agreement is open below it. */
#app .p360-bookings { display: flex; flex-direction: column; }
#app .p360-booking {
  display: flex; align-items: center; gap: var(--rl-s-3);
  width: 100%; min-height: 44px; padding: var(--rl-s-2) var(--rl-s-4);
  background: none; border: 0; border-top: 1px solid var(--rl-line-soft);
  text-align: left; cursor: pointer; font: inherit; color: inherit;
}
#app .p360-booking:first-child { border-top: 0; }
#app .p360-booking:hover { background: var(--rl-surface-sunk); }
#app .p360-booking:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
#app .p360-booking.is-open { background: var(--rl-tint-accent-bg); }
#app .p360-booking-ref {
  font-family: var(--rl-font-mono); font-size: 12.5px; font-weight: 600;
  min-width: 74px; flex: none;
}
#app .p360-booking-where {
  margin-left: auto; text-align: right; font-size: 12.5px; color: var(--rl-text-2);
}
/* --rl-text-2, not --rl-text-3: this line sits on the accent tint when its
   booking is the open one, and text-3 there measures 4.12:1 in dark —
   under the 4.5 §18 asks for. */
#app .p360-booking-note { display: block; font-size: 11.5px; color: var(--rl-text-2); }
/* The count beside "Bookings" in the panel head. */
#app .p360-panel-n {
  display: inline-block; margin-left: 5px; padding: 0 6px; border-radius: var(--rl-r-full);
  background: var(--rl-surface-sunk); color: var(--rl-text-2);
  /* The panel heading is uppercased; a count inside it must not be, or
     rlAudit reports a transform on a number that cannot have one. */
  font-size: 11.5px; font-weight: 600; text-transform: none; letter-spacing: 0;
}
/* "+1 more booking" under a directory row's reference. */
#app .p360-dir-more { color: var(--rl-text-accent); }
@media (max-width: 1180px) {
  #app .p360-body { grid-template-columns: minmax(0, 1fr) 250px; }
  #app .p360-col-id { grid-column: 1 / -1; order: 3; }
  #app .p360-col-id .p360-panel { display: inline-block; vertical-align: top; width: 100%; }
}
@media (max-width: 860px) {
  #app .p360-body { grid-template-columns: minmax(0, 1fr); }
  #app .p360-head-top { flex-wrap: wrap; }
  #app .p360-actions { width: 100%; }
}

#app .p360-panel {
  background: var(--rl-surface); border: 1px solid var(--rl-line);
  border-radius: var(--rl-r-md); box-shadow: var(--rl-e-1); overflow: clip;
}
#app .p360-panel + .p360-panel { margin-top: var(--rl-s-3); }
#app .p360-panel-head {
  display: flex; align-items: center; gap: var(--rl-s-2);
  padding: 11px var(--rl-s-4); border-bottom: 1px solid var(--rl-line-soft);
}
#app .p360-panel-head h3 {
  margin: 0; font-family: var(--rl-font-sans); font-size: 11px; font-weight: 600;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--rl-text-3);
}
/* §9's 30px minimum target. These read as links and are sized as links,
   which made them 17–20px high — under the minimum, and there are now
   three of them in a panel head and up to three in every table row since
   the record started doing the work. The type is unchanged; only the box
   around it grew. */
#app .p360-more {
  margin-left: auto; display: inline-flex; align-items: center; min-height: 30px;
  border: 0; background: none; padding: 2px 4px;
  font-family: inherit; font-size: 12px; color: var(--rl-text-accent); cursor: pointer;
}
#app .p360-more + .p360-more { margin-left: 0; }
#app .p360-more:hover { text-decoration: underline; }
#app .p360-panel-body { padding: var(--rl-s-3) var(--rl-s-4); }

#app .p360-facts { display: flex; flex-direction: column; gap: 11px; }
#app .p360-facts-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--rl-s-4);
}
#app .p360-fact .k {
  font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--rl-text-3);
}
#app .p360-fact .v { font-size: 13px; margin-top: 1px; word-break: break-word; }
#app .p360-fact-sub { font-size: 12px; color: var(--rl-text-3); margin-top: 1px; }
#app .p360-link {
  border: 0; background: none; padding: 0; font-family: inherit; font-size: inherit;
  color: var(--rl-text-accent); cursor: pointer;
}
#app .p360-link:hover { text-decoration: underline; }
/* Every .p360-link is a control somebody taps, so every one of them gets
   §9's 30px target — including the flatmate names in "People here", which
   are links to those people's records and were 17px high. inline-flex
   keeps them flowing inside the sentence they sit in. */
#app .p360-link { display: inline-flex; align-items: center; min-height: 30px; }

/* ---- timeline ---- */
#app .p360-filters {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 11px var(--rl-s-4); border-bottom: 1px solid var(--rl-line-soft);
}
#app .p360-fchip {
  display: inline-flex; align-items: center; min-height: 30px;
  padding: 4px 10px; border-radius: var(--rl-r-full); font-family: inherit; font-size: 12px;
  border: 1px solid var(--rl-line); background: var(--rl-surface); color: var(--rl-text-2);
  cursor: pointer;
}
#app .p360-fchip:hover { background: var(--rl-surface-sunk); }
#app .p360-fchip[aria-pressed="true"] {
  background: var(--rl-n-800); border-color: var(--rl-n-800); color: var(--rl-n-0); font-weight: 500;
}
[data-theme="dark"] #app .p360-fchip[aria-pressed="true"] {
  background: var(--rl-i-600); border-color: var(--rl-i-600); color: #fff;
}

#app .p360-tl { list-style: none; margin: 0; padding: var(--rl-s-1) 0; }
#app .p360-tl-day {
  padding: 10px var(--rl-s-4) var(--rl-s-1);
  font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--rl-text-3); font-weight: 600;
}
#app .p360-tl-item {
  display: grid; grid-template-columns: 26px minmax(0, 1fr) auto;
  gap: 11px; padding: 9px var(--rl-s-4); align-items: start;
  border-top: 1px solid var(--rl-line-soft);
}
#app .p360-tl-item:hover { background: var(--rl-surface-sunk); }
#app .p360-tl-ico {
  width: 26px; height: 26px; border-radius: var(--rl-r-md); display: grid; place-items: center;
  background: var(--rl-surface-sunk); border: 1px solid var(--rl-line-soft);
}
#app .p360-tl-ico svg { width: 14px; height: 14px; stroke: var(--rl-text-3); }
#app .p360-tl-ico.is-pay    { background: var(--rl-tint-green-bg); border-color: transparent; }
#app .p360-tl-ico.is-pay svg{ stroke: var(--rl-tint-green-fg); }
#app .p360-tl-ico.is-due    { background: var(--rl-tint-red-bg); border-color: transparent; }
#app .p360-tl-ico.is-due svg{ stroke: var(--rl-tint-red-fg); }
#app .p360-tl-ico.is-parcel     { background: var(--rl-tint-amber-bg); border-color: transparent; }
#app .p360-tl-ico.is-parcel svg { stroke: var(--rl-tint-amber-fg); }
#app .p360-tl-ico.is-sign     { background: var(--rl-tint-accent-bg); border-color: transparent; }
#app .p360-tl-ico.is-sign svg { stroke: var(--rl-tint-accent-fg); }
#app .p360-tl-t { font-size: 13px; line-height: 1.4; }
#app .p360-tl-m { font-size: 12px; color: var(--rl-text-3); margin-top: 2px; }
#app .p360-tl-when {
  font-size: 11.5px; color: var(--rl-text-3); font-family: var(--rl-font-mono);
  white-space: nowrap; padding-top: 2px;
}
#app .p360-tl-empty { padding: var(--rl-s-6) var(--rl-s-4); text-align: center; color: var(--rl-text-3); font-size: 13px; }

/* ---- now rail ---- */
#app .p360-now-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--rl-s-3);
  padding: 9px var(--rl-s-4); border-top: 1px solid var(--rl-line-soft); font-size: 13px;
}
#app .p360-now-row:first-child { border-top: 0; }
#app .p360-now-row .k { color: var(--rl-text-2); }
#app .p360-now-row .v {
  font-family: var(--rl-font-mono); font-variant-numeric: tabular-nums; font-weight: 500;
}
#app .p360-now-row .v.is-red   { color: var(--rl-text-danger); }
#app .p360-now-row .v.is-amber { color: var(--rl-text-warning); }
#app .p360-now-row .v.is-green { color: var(--rl-text-success); }

/* The launcher menu, and the thread. */
#app .p360-newwrap { position: relative; display: inline-flex; }
#app .p360-caret { font-size: 9px; opacity: .6; margin-left: 3px; }
#app .p360-newpop { top: calc(100% + 6px); right: 0; left: auto; transform-origin: top right; min-width: 208px; }

/* -------------------------------------------------------------------------
   THE THREAD — both halves of the correspondence, newest first, each one
   openable. Direction is carried by a rail down the left rather than by a
   chat bubble: this is a record being read, not a conversation being had.
   ------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------
   THE COMPOSER — at the top of the thread, above what you are replying to,
   collapsed until wanted.
   ------------------------------------------------------------------------- */
#app .p360-compose-shut {
  display: flex; align-items: center; gap: var(--rl-s-3);
  padding: var(--rl-s-3) var(--rl-s-4);
  border-bottom: 1px solid var(--rl-line-soft);
}
#app .p360-compose-to { font-size: 12.5px; color: var(--rl-text-3); }
#app .p360-compose {
  padding: var(--rl-s-4);
  border-bottom: 1px solid var(--rl-line-soft);
  background: var(--rl-surface-sunk);
}
#app .p360-compose-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--rl-s-2);
  margin-bottom: var(--rl-s-3);
}
#app .p360-compose-row .p360-compose-to { flex: 1; min-width: 120px; }
#app .p360-compose-subj, #app .p360-compose-body {
  width: 100%; margin-bottom: var(--rl-s-2);
  border: 1px solid var(--rl-line-control); border-radius: var(--rl-r-md);
  background: var(--rl-surface); color: var(--rl-text);
  font-family: inherit; font-size: 13.5px; padding: 9px 11px;
}
#app .p360-compose-body { line-height: 1.55; resize: vertical; min-height: 120px; }
#app .p360-compose-subj:focus, #app .p360-compose-body:focus {
  outline: none; border-color: var(--rl-i-600); box-shadow: var(--rl-focus-inset);
}
/* A bare file input is 21px tall, which is under §9's target. Given the
   height of the controls it sits between rather than left to the browser. */
#app .p360-compose-att {
  display: block; width: 100%; min-height: 34px; padding: 6px 0;
  font-size: 12.5px; color: var(--rl-text-3); margin-bottom: var(--rl-s-2);
}
#app .p360-compose-actions { display: flex; gap: var(--rl-s-2); }

#app .p360-thread { list-style: none; margin: 0; padding: 0; }
#app .p360-msg { border-bottom: 1px solid var(--rl-line-soft); }
#app .p360-msg:last-child { border-bottom: 0; }
#app .p360-msg-head {
  width: 100%; display: grid;
  grid-template-columns: 18px minmax(72px, auto) minmax(0, 1fr) auto;
  align-items: baseline; gap: var(--rl-s-3);
  padding: 10px var(--rl-s-4);
  border: 0; background: none; font: inherit; text-align: left; cursor: pointer;
}
#app .p360-msg-head:hover { background: var(--rl-surface-sunk); }
#app .p360-msg-head:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
#app .p360-msg-dir { font-size: 13px; color: var(--rl-text-3); }
#app .p360-msg.is-in  .p360-msg-dir { color: var(--rl-text-accent); }
#app .p360-msg.is-note .p360-msg-dir { color: var(--rl-text-warning); }
#app .p360-msg-who { font-size: 12.5px; font-weight: 600; color: var(--rl-text); }
#app .p360-msg-subj {
  font-size: 13px; color: var(--rl-text-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#app .p360-msg.is-open .p360-msg-subj { white-space: normal; }
#app .p360-msg-when { font-size: 11.5px; color: var(--rl-text-3); white-space: nowrap; }
#app .p360-msg-body { padding: 0 var(--rl-s-4) 14px 44px; }
#app .p360-msg-meta { font-size: 11.5px; color: var(--rl-text-3); margin-bottom: 7px; }
#app .p360-msg-text { font-size: 13.5px; line-height: 1.55; color: var(--rl-text); }
#app .p360-msg-html {
  background: var(--rl-surface); border: 1px solid var(--rl-line-soft);
  border-radius: var(--rl-r-md); padding: var(--rl-s-4);
  font-size: 13.5px; line-height: 1.5; overflow-x: auto;
}
#app .p360-msg.is-in .p360-msg-head { background: var(--rl-tint-accent-bg); }
#app .p360-msg.is-in.is-open .p360-msg-head,
#app .p360-msg.is-in .p360-msg-head:hover { background: var(--rl-tint-accent-bg); }

/* ---- tables inside the record ---- */
#app .p360-tblwrap { overflow-x: auto; }
#app table.p360-tbl { border-collapse: collapse; width: 100%; font-size: 12.5px; }
#app table.p360-tbl th {
  text-align: left; font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--rl-text-3); font-weight: 600; padding: 9px var(--rl-s-4);
  border-bottom: 1px solid var(--rl-line); white-space: nowrap;
}
#app table.p360-tbl td { padding: 9px var(--rl-s-4); border-bottom: 1px solid var(--rl-line-soft); }
/* The wrapper scrolls (.p360-tblwrap), so a narrow centre column should
   push the table sideways rather than fold "8 Sept 2026" onto three
   lines and stack three action links on top of each other. Only the
   free-text column — a subject, a file name — is allowed to wrap. */
#app table.p360-tbl th, #app table.p360-tbl td { white-space: nowrap; }
#app table.p360-tbl td.p360-wrap { white-space: normal; min-width: 160px; }
#app table.p360-tbl tr:last-child td { border-bottom: 0; }
#app table.p360-tbl th.num, #app table.p360-tbl td.num {
  text-align: right; font-family: var(--rl-font-mono); font-variant-numeric: tabular-nums;
}
#app table.p360-tbl th.num { font-family: var(--rl-font-sans); }

/* Row actions inside a record table. Laid out as a right-aligned run of
   quiet links rather than buttons: a table of twelve invoices with three
   buttons on every line reads as a control panel, and the row is the
   thing being read. */
#app table.p360-tbl td.p360-rowacts {
  text-align: right; white-space: nowrap;
}
#app table.p360-tbl td.p360-rowacts .p360-link + .p360-link { margin-left: var(--rl-s-3); }
/* div only: as a <td> class this same name must stay a table cell, and
   turning it into a wrapping flex container is what stacked "Send / Copy
   link / Mark paid" onto two lines inside a cell already told not to
   wrap. */
#app div.p360-rowacts { display: flex; flex-wrap: wrap; gap: var(--rl-s-3); }
#app .p360-tl-item .p360-rowacts { margin-top: 5px; }

/* An invoice past its due date says so in the row, because "pending" and
   "pending since March" are different facts. */
#app .p360-late {
  font-size: 10.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--rl-text-danger);
}

/* ---- the arrears ladder, as a position rather than a list ---- */
#app .p360-ladder { display: flex; padding: var(--rl-s-4); }
#app .p360-rung {
  flex: 1; text-align: center; font-size: 11px; padding: 7px 2px;
  border: 1px solid var(--rl-line); border-right: 0; color: var(--rl-text-3);
  font-family: var(--rl-font-mono); background: var(--rl-surface); white-space: nowrap;
}
#app .p360-rung:first-child { border-radius: var(--rl-r-sm) 0 0 var(--rl-r-sm); }
#app .p360-rung:last-child  { border-right: 1px solid var(--rl-line); border-radius: 0 var(--rl-r-sm) var(--rl-r-sm) 0; }
#app .p360-rung.is-done { background: var(--rl-surface-sunk); color: var(--rl-text-2); }
#app .p360-rung.is-at {
  background: var(--rl-tint-red-bg); color: var(--rl-tint-red-fg);
  border-color: var(--rl-r-200); font-weight: 600;
}

#app .p360-kbd {
  font-family: var(--rl-font-mono); font-size: 11px;
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-xs); padding: 1px 5px;
  background: var(--rl-surface-sunk);
}

/* =========================================================================
   §10.10b EVERYONE — the directory that opens records.
   ========================================================================= */
#app .p360-dir-row { cursor: pointer; }
#app .p360-dir-row:hover { background: var(--rl-surface-sunk); }
#app .p360-dir-row:focus-visible { box-shadow: var(--rl-focus-inset); outline: none; }
#app .p360-dir-who { display: flex; align-items: center; gap: var(--rl-s-3); }
#app .p360-dir-mono {
  width: 30px; height: 30px; flex: none; display: grid; place-items: center;
  border-radius: var(--rl-r-md); background: var(--rl-surface-sunk);
  border: 1px solid var(--rl-line-soft); color: var(--rl-text-2);
  font-family: var(--rl-font-serif); font-size: 12.5px; font-weight: 600;
}
#app .p360-dir-name { display: block; font-size: 13.5px; color: var(--rl-text); }
#app .p360-dir-sub  { display: block; font-size: 11.5px; color: var(--rl-text-3); }
#app .p360-dir-quiet { color: var(--rl-text-3); }
#app .p360-dir-flags { display: flex; flex-wrap: wrap; gap: 5px; }
#app .p360-mc {
  font-size: 11px; padding: 1px 7px; border-radius: var(--rl-r-xs);
  font-family: var(--rl-font-mono);
}
#app .p360-mc.is-red   { background: var(--rl-tint-red-bg);   color: var(--rl-tint-red-fg); }
#app .p360-mc.is-amber { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }
#app .p360-owing { color: var(--rl-text-danger); font-weight: 500; }

/* The rail names the open record under 360, so you can always see whose
   record you are in without reading the page. */
#app .rl-subnav-item.is-record { font-weight: 600; }


/* =========================================================================
   DEED OF ASSIGNMENT (js/assignments.js)

   Two places: the panel on the agreement, and the dialog that prepares
   and completes one. The dialog's two columns are the point of it — the
   outgoing tenant's account on the left, the incoming tenant's on the
   right, adding up to one tenancy — so they sit side by side on a desk
   and stack on a phone.
   ========================================================================= */
.asg-sub { display: block; font-size: 11.5px; font-weight: 400; color: var(--rl-text-2); }
.asg-sub-inline { font-weight: 400; color: var(--rl-text-3); margin-left: var(--rl-s-1); }
.asg-note { font-size: 12px; color: var(--rl-text-2); margin: var(--rl-s-1) 0 var(--rl-s-3); line-height: 1.5; }
.asg-row-end { display: inline-flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: var(--rl-s-2); }
.asg-row-actions { display: inline-flex; gap: var(--rl-s-1); }
/* .cd-danger-zone too: Delete / Cancel sat flush against the panel edge
   inside the record while everything above them was inset, which the
   deed's zone — the same class, stacked right above Cancel — made plain. */
#app .p360-embed .asg-note,
#app .p360-embed .cd-danger-zone { margin-left: var(--rl-s-4); margin-right: var(--rl-s-4); }

.asg-split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--rl-s-4); margin: var(--rl-s-4) 0 var(--rl-s-2); }
.asg-col { background: var(--rl-surface-sunk); border: 1px solid var(--rl-line-soft); border-radius: var(--rl-r-md);
           padding: var(--rl-s-3) var(--rl-s-4); min-width: 0; }
.asg-col-h { font-size: 12.5px; font-weight: 600; color: var(--rl-text); margin-bottom: var(--rl-s-2); }
.asg-line { display: flex; justify-content: space-between; gap: var(--rl-s-3); font-size: 12.5px; color: var(--rl-text-2);
            padding: var(--rl-s-1) 0; border-bottom: 1px solid var(--rl-line-soft); }
.asg-line span:last-child { color: var(--rl-text); font-variant-numeric: tabular-nums; text-align: right; }
.asg-outcome { margin-top: var(--rl-s-3); padding: var(--rl-s-2) var(--rl-s-3); border-radius: var(--rl-r-sm);
               background: var(--rl-surface); font-size: 13px; color: var(--rl-text); }
.asg-outcome span { display: block; font-size: 11.5px; color: var(--rl-text-2); margin-top: var(--rl-s-1); }
.asg-outcome.good { background: var(--rl-tint-green-bg); color: var(--rl-tint-green-fg); }
.asg-outcome.warn { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }
.asg-outcome.good span, .asg-outcome.warn span { color: inherit; opacity: .85; }
.asg-modes { display: flex; flex-direction: column; gap: var(--rl-s-1); margin: var(--rl-s-2) 0; }
.asg-sched { table-layout: fixed; }
.asg-sched th:nth-child(2) { width: 170px; }
.asg-sched th:nth-child(3) { width: 130px; }
.asg-sched th:nth-child(4) { width: 44px; }
.asg-sched input { width: 100%; min-width: 0; }
.asg-sched .asg-amt { text-align: right; }
.asg-sched td, .asg-sched th { padding-right: var(--rl-s-2); }
.asg-off { color: var(--rl-text-danger); }
.asg-when { align-self: end; font-size: 12px; color: var(--rl-text-2); padding-bottom: var(--rl-s-2); }
.asg-rtr { display: flex !important; margin-top: var(--rl-s-3); font-size: 13px !important; color: var(--rl-text) !important; }
.asg-deed { white-space: pre-wrap; font: 12.5px/1.6 var(--rl-font-mono); max-height: 60vh; overflow: auto;
            background: var(--rl-surface-sunk); padding: var(--rl-s-4); border-radius: var(--rl-r-md); margin: 0; }
@media (max-width: 719px) {
  .asg-split { grid-template-columns: 1fr; }
}

/* =========================================================================
   THE BOOKING.COM SIDE (2026-09-23) — js/short-stays.js, BOOKINGCOM-PLAN.md

   The side switch sits beside the logo, not on the bar: the bar is the
   side's own navigation and changes wholesale when the switch moves, so
   the switch cannot live inside the thing it replaces.

   Colours on the calendar are the room-state tokens the occupancy grid
   already uses, so a guest, a student and a block read the same on both
   sides: reserved = a Booking.com guest, occupied = a student tenancy,
   oos = blocked, available = free.
   ========================================================================= */
.rl-top-left { display: flex; align-items: center; gap: var(--rl-s-3); min-width: 0; position: relative; z-index: 1; }
.rl-side { position: relative; }
.rl-top-left .rl-top-brand { flex: none; }
.rl-side-btn .rl-side-short { display: none; }
/* The Booking.com side's bar has three items each side of Today, so the
   left group reaches the switch at about 1400px — "B.com" from there down. */
@media (max-width: 1440px) {
  .rl-side-btn .rl-side-long { display: none; }
  .rl-side-btn .rl-side-short { display: inline; }
}
/* Where the nav drops to icons (shell.css does it at 980px) is moved up
   while the switch is on the bar: measured, the switch's 60px pushed the
   AXO left group into it from 1080px, and the Booking.com side's three
   right-hand items reached the tools from 1260px. The centre pill keeps
   its label, as it does at 980. */
@media (max-width: 1080px) {
  :root[data-side] .rl-navitem .rl-nav-label { display: none; }
  :root[data-side] .rl-navitem { padding: 0 10px; }
  :root[data-side] .rl-navitem.is-hub .rl-nav-label { display: inline; }
}
@media (max-width: 1280px) {
  :root[data-side="ota"] .rl-navitem .rl-nav-label { display: none; }
  :root[data-side="ota"] .rl-navitem { padding: 0 10px; }
  :root[data-side="ota"] .rl-navitem.is-hub .rl-nav-label { display: inline; }
}
@media (max-width: 719px) {
  .rl-top-left { flex: none; }
  /* A phone bar has 375px and this side needs 397 with its centre pill.
     The pill is the bottom tab bar's first item again (Today), so on the
     Booking.com side it is the one thing that can go. */
  :root[data-side="ota"] .rl-top-nav .rl-navitem.is-hub { display: none; }
}
.rl-side[hidden] { display: none; }
.rl-side-btn {
  display: inline-flex; align-items: center; gap: var(--rl-s-1);
  height: 28px; padding: 0 var(--rl-s-2);
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-md);
  background: var(--rl-surface-sunk); cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 600; color: var(--rl-text-2); white-space: nowrap;
  transition: border-color var(--rl-d-fast) var(--rl-ease-standard), color var(--rl-d-fast) var(--rl-ease-standard);
}
.rl-side-btn:hover { border-color: var(--rl-line-strong); color: var(--rl-text); }
.rl-side-btn:focus-visible { outline: none; box-shadow: var(--rl-focus); }
/* On the Booking.com side the switch carries the accent: somebody who
   looks up from a screen should be able to tell which side they are on
   without reading the bar. */
.rl-side-btn.is-ota { background: var(--rl-tint-accent-bg); border-color: var(--rl-line-accent); color: var(--rl-text-accent); }
.rl-side-caret { width: 12px; height: 12px; opacity: .6; }
.rl-side:has(.rl-sidepop[data-open="true"]) .rl-side-caret { transform: rotate(180deg); }
.rl-sidepop { top: calc(100% + 6px); left: 0; min-width: 240px; }
.rl-side-item span:first-child { display: flex; flex-direction: column; text-align: left; }
.rl-side-item small { font-size: 11.5px; color: var(--rl-text-3); font-weight: 400; }
.rl-side-item .rl-menu-tick { margin-left: auto; }

.ss-head { display: flex; align-items: center; justify-content: space-between; gap: var(--rl-s-3); flex-wrap: wrap; margin-bottom: var(--rl-s-3); }
.ss-head-tools { display: flex; align-items: center; gap: var(--rl-s-2); flex-wrap: wrap; }
.ss-lede { font-size: 13.5px; color: var(--rl-text-2); margin: 0 0 var(--rl-s-3); }
.ss-head .ss-lede { margin: 0; font-weight: 600; color: var(--rl-text); }
.ss-sub { font-size: 11.5px; color: var(--rl-text-3); margin-top: 2px; }
.ss-warn { color: var(--rl-text-warning); }
.ss-fine { font-size: 12.5px; color: var(--rl-text-3); margin: var(--rl-s-3) 0 0; max-width: 72ch; }
.ss-note { font-size: 13.5px; margin: 0; white-space: pre-wrap; }
.ss-mono { font-family: var(--rl-font-mono); font-size: 12px; }
.ss-table td { vertical-align: top; }
.ss-view .section-head h3 .n { font-weight: 400; color: var(--rl-text-3); margin-left: var(--rl-s-1); }
.ss-empty { padding: var(--rl-s-6); }
.ss-empty h3 { margin: 0 0 var(--rl-s-2); }
.ss-empty p { color: var(--rl-text-2); max-width: 70ch; }
.ss-card h3 { margin: 0 0 var(--rl-s-2); font-size: 15px; }
.ss-card p { font-size: 13.5px; color: var(--rl-text-2); }
.ss-conn-grid { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.ss-steps { padding-left: var(--rl-s-5); font-size: 13.5px; line-height: 1.55; }
.ss-steps li { margin-bottom: var(--rl-s-2); }
.ss-steps code { font-family: var(--rl-font-mono); font-size: 12px; background: var(--rl-surface-sunk); padding: 1px var(--rl-s-1); border-radius: var(--rl-r-xs); }
.ss-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--rl-s-3); }
.ss-3col { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 var(--rl-s-3); }
@media (max-width: 719px) { .ss-2col, .ss-3col { grid-template-columns: 1fr; } }
.ss-more { margin: var(--rl-s-2) 0 var(--rl-s-3); }
.ss-more summary { cursor: pointer; font-size: 13px; color: var(--rl-text-2); padding: var(--rl-s-1) 0; }
.ss-more[open] summary { margin-bottom: var(--rl-s-2); }
.ss-roomrow { display: flex; align-items: center; gap: var(--rl-s-2); flex-wrap: wrap; margin: var(--rl-s-2) 0; }
.ss-roomnow { min-width: 140px; margin-right: var(--rl-s-2); }
.ss-view textarea, #appModal textarea#ssStaffNotes { width: 100%; }

/* The calendar: one row per room, one column per night. Bars are placed
   by grid-column, so a stay is one element however long it is. */
.ss-cal { padding: 0; overflow-x: auto; }
.ss-cal-row {
  display: grid;
  grid-template-columns: 132px repeat(var(--ss-days), minmax(26px, 1fr));
  grid-auto-flow: dense;
  align-items: center;
  min-width: calc(132px + var(--ss-days) * 26px);
  min-height: 34px;
  border-bottom: 1px solid var(--rl-line-soft);
  background:
    repeating-linear-gradient(to right, transparent 0, transparent calc(100% / var(--ss-days) - 1px),
      var(--rl-line-soft) calc(100% / var(--ss-days) - 1px), var(--rl-line-soft) calc(100% / var(--ss-days)))
    132px 0 / calc(100% - 132px) 100% no-repeat;
}
.ss-cal-row:last-child { border-bottom: none; }
.ss-cal-room {
  grid-column: 1; grid-row: 1;
  position: sticky; left: 0; z-index: 1;
  display: flex; flex-direction: column; justify-content: center;
  height: 100%; padding: var(--rl-s-1) var(--rl-s-3);
  background: var(--rl-surface); border-right: 1px solid var(--rl-line);
  font-size: 12.5px; line-height: 1.2;
}
.ss-cal-room span { font-size: 10.5px; color: var(--rl-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-cal-headrow { position: sticky; top: 0; z-index: 2; background: var(--rl-surface); min-height: 40px; }
.ss-cal-day { grid-row: 1; text-align: center; font-size: 10.5px; color: var(--rl-text-3); line-height: 1.15; }
.ss-cal-day b { display: block; font-size: 12px; color: var(--rl-text-2); font-weight: 600; }
.ss-cal-day.is-wkend b { color: var(--rl-text-3); }
.ss-cal-day.is-today b { color: var(--rl-text-accent); }
.ss-bar {
  grid-row: 1; height: 24px; margin: 0 1px;
  display: flex; align-items: center; padding: 0 var(--rl-s-2);
  border: 1px solid; border-radius: var(--rl-r-xs);
  font-family: inherit; font-size: 11.5px; text-align: left;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis; min-width: 0;
}
.ss-bar.is-guest   { background: var(--rl-room-reserved-fill); border-color: var(--rl-room-reserved-line); color: var(--rl-room-reserved-text); cursor: pointer; font-weight: 600; }
.ss-bar.is-guest:hover { border-color: var(--rl-i-500); }
.ss-bar.is-guest:focus-visible { outline: none; box-shadow: var(--rl-focus); }
.ss-bar.is-inhouse { border-left-width: 3px; }
.ss-bar.is-student { background: var(--rl-room-occupied-fill); border-color: var(--rl-room-occupied-line); color: var(--rl-room-occupied-text); }
.ss-bar.is-block   { background: var(--rl-room-oos-fill); border-color: var(--rl-room-oos-line); color: var(--rl-room-oos-text); }
.ss-legend { display: flex; flex-wrap: wrap; gap: var(--rl-s-4); margin: 0 0 var(--rl-s-3); font-size: 12px; color: var(--rl-text-2); }
.ss-legend span::before { content: ""; display: inline-block; width: 12px; height: 12px; border: 1px solid; border-radius: var(--rl-r-xs); vertical-align: -2px; margin-right: var(--rl-s-1); }
.ss-legend .is-guest::before   { background: var(--rl-room-reserved-fill); border-color: var(--rl-room-reserved-line); }
.ss-legend .is-student::before { background: var(--rl-room-occupied-fill); border-color: var(--rl-room-occupied-line); }
.ss-legend .is-block::before   { background: var(--rl-room-oos-fill); border-color: var(--rl-room-oos-line); }
.ss-legend .is-free::before    { background: var(--rl-room-available-fill); border-color: var(--rl-room-available-line); }

/* Inventory: a number per night. Low and zero are the ones that matter. */
.ss-inv { font-variant-numeric: tabular-nums; }
.ss-inv th.ss-inv-type { text-align: left; min-width: 180px; position: sticky; left: 0; background: var(--rl-surface); z-index: 1; }
.ss-inv-day { text-align: center; font-size: 10.5px; font-weight: 500; color: var(--rl-text-3); min-width: 30px; }
.ss-inv-day.is-wkend { color: var(--rl-text-3); background: var(--rl-surface-sunk); }
.ss-inv-cell { text-align: center; font-family: var(--rl-font-mono); font-size: 12.5px; }
.ss-inv-cell.is-low  { background: var(--rl-room-turn-fill); color: var(--rl-room-turn-text); }
.ss-inv-cell.is-zero { background: var(--rl-room-oos-fill); color: var(--rl-room-oos-text); }
.ss-inv-cell.is-off  { color: var(--rl-text-disabled); }
/* A night the extranet was told something different: more than there is
   (red — Booking.com can sell a room that is gone) or fewer (amber — a
   room left unsold). Marked with an inset edge so it reads on top of the
   low/zero fills rather than replacing them. */
.ss-inv-cell.is-over  { box-shadow: inset 0 -3px 0 var(--rl-r-500); color: var(--rl-text-danger); font-weight: 600; }
.ss-inv-cell.is-stale { box-shadow: inset 0 -3px 0 var(--rl-a-500); }

/* The extranet to-do: what to type into Booking.com's bulk edit. */
.ss-todo { padding: var(--rl-s-4) var(--rl-s-5); margin-bottom: var(--rl-s-4); border-left: 3px solid var(--rl-a-500); }
.ss-todo.is-over { border-left-color: var(--rl-r-500); }
.ss-todo.is-ok { border-left-color: var(--rl-g-500); }
.ss-todo h3 { margin: 0; font-size: 15px; }
.ss-todo-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--rl-s-3); flex-wrap: wrap; }
.ss-todo-type { margin-top: var(--rl-s-4); }
.ss-todo-typehead { display: flex; align-items: baseline; gap: var(--rl-s-2); flex-wrap: wrap; }
.ss-todo-typehead .btn { margin-left: auto; }
/* min(340px, 100%): on a phone the card is narrower than one 340px column,
   and a bare minmax(340px, …) ran the "too many" warning off the screen. */
.ss-ranges { list-style: none; margin: var(--rl-s-2) 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr)); gap: var(--rl-s-1) var(--rl-s-4); }
.ss-ranges li > span:first-child, .ss-ranges li b { white-space: nowrap; }
.ss-ranges li { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--rl-s-2); padding: var(--rl-s-1) var(--rl-s-2); border-radius: var(--rl-r-sm); background: var(--rl-surface-sunk); font-size: 13px; font-variant-numeric: tabular-nums; }
.ss-ranges li b { font-family: var(--rl-font-mono); font-size: 12.5px; }
.ss-ranges li.is-over { background: var(--rl-tint-red-bg); }
.ss-ranges li.is-over .ss-sub { color: var(--rl-tint-red-fg); }

/* Today's warnings, and the import card when the last import is old. */
.ss-alert { display: flex; align-items: center; gap: var(--rl-s-3); flex-wrap: wrap; margin: var(--rl-s-3) 0 0;
  padding: var(--rl-s-3) var(--rl-s-4); border-radius: var(--rl-r-md); font-size: 13.5px;
  background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }
.ss-alert.is-over { background: var(--rl-tint-red-bg); color: var(--rl-tint-red-fg); }
.ss-alert .btn { margin-left: auto; }
.ss-import-card { padding: var(--rl-s-4) var(--rl-s-5); border-left: 3px solid var(--rl-g-500); }
.ss-import-card.is-stale { border-left-color: var(--rl-a-500); }

/* Occupancy */
.ss-view .grid.grid-4 + .grid.grid-4 { margin-top: var(--rl-s-4); }
.ss-chart-card { padding: var(--rl-s-4) var(--rl-s-5); margin-top: var(--rl-s-4); }
.ss-chart-card h3 { margin: 0; font-size: 15px; }
.ss-chart { position: relative; height: 240px; margin-top: var(--rl-s-3); }
.ss-bar-mini { height: 4px; margin-top: var(--rl-s-1); border-radius: var(--rl-r-full); background: var(--rl-surface-sunk); overflow: hidden; max-width: 90px; }
.ss-bar-mini i { display: block; height: 100%; background: var(--rl-i-500); }

/* Guest messages: the list, the thread, the composer. */
.ss-msg-layout { display: grid; grid-template-columns: minmax(240px, 320px) minmax(0, 1fr); gap: var(--rl-s-4); align-items: start; }
@media (max-width: 900px) { .ss-msg-layout { grid-template-columns: 1fr; } }
.ss-msg-list { padding: var(--rl-s-3); max-height: 70vh; overflow-y: auto; }
.ss-msg-list .toolbar-search { margin-bottom: var(--rl-s-2); }
.ss-msg-item {
  display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left;
  padding: var(--rl-s-2) var(--rl-s-3); margin: 2px 0;
  border: 1px solid transparent; border-radius: var(--rl-r-md); background: none; cursor: pointer;
  font-family: inherit; font-size: 13px; color: var(--rl-text);
}
.ss-msg-item:hover { background: var(--rl-surface-sunk); }
.ss-msg-item:focus-visible { outline: none; box-shadow: var(--rl-focus); }
.ss-msg-item.is-open { background: var(--rl-tint-accent-bg); border-color: var(--rl-line-accent); }
/* text-3 on the accent tint is 4.07:1 in dark mode; text-2 clears AA. */
.ss-msg-item.is-open .ss-sub { color: var(--rl-text-2); }
.ss-msg-item.is-unread b::after { content: ""; display: inline-block; width: 7px; height: 7px; margin-left: var(--rl-s-1); border-radius: var(--rl-r-full); background: var(--rl-i-600); vertical-align: 1px; }
.ss-msg-item-top { display: flex; justify-content: space-between; gap: var(--rl-s-2); }
.ss-msg-snip { font-size: 12px; color: var(--rl-text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-msg-pane { padding: var(--rl-s-4); display: flex; flex-direction: column; min-height: 420px; }
.ss-msg-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--rl-s-3); padding-bottom: var(--rl-s-3); border-bottom: 1px solid var(--rl-line-soft); }
.ss-chat { flex: 1; max-height: 52vh; overflow-y: auto; padding: var(--rl-s-3) 0; display: flex; flex-direction: column; gap: var(--rl-s-3); }
#appModal .ss-chat { max-height: 46vh; }
.ss-msg { display: flex; flex-direction: column; align-items: flex-start; max-width: 78%; }
.ss-msg.is-us { align-self: flex-end; align-items: flex-end; }
.ss-msg-bubble { padding: var(--rl-s-2) var(--rl-s-3); border-radius: var(--rl-r-lg); background: var(--rl-surface-sunk); font-size: 13.5px; line-height: 1.45; overflow-wrap: anywhere; }
.ss-msg.is-us .ss-msg-bubble { background: var(--rl-tint-accent-bg); color: var(--rl-text); }
.ss-msg-meta { font-size: 11px; color: var(--rl-text-3); margin-top: 3px; }
.ss-chat-empty { color: var(--rl-text-3); font-size: 13px; padding: var(--rl-s-6) var(--rl-s-2); text-align: center; }
.ss-chat-setup { padding: var(--rl-s-3); border-radius: var(--rl-r-md); background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); font-size: 13px; }
.ss-chat-setup p { margin: 0 0 var(--rl-s-2); }
.ss-chat-setup code { font-family: var(--rl-font-mono); font-size: 12px; }
.ss-composer { border-top: 1px solid var(--rl-line-soft); padding-top: var(--rl-s-3); }
.ss-composer textarea { width: 100%; resize: vertical; }
.ss-composer-foot { display: flex; justify-content: space-between; align-items: center; gap: var(--rl-s-3); margin-top: var(--rl-s-2); flex-wrap: wrap; }

/* =========================================================================
   SALES (2026-09-25) — the year bar, the follow-up chips, the Pipeline's
   Follow-ups list and the Overview page. js/sales-core.js, js/leads.js,
   js/sales-overview.js. Built from the same parts as everything else: the
   segmented control for the year, the metric row for the figures (as
   buttons, because each is a filter), tints for state, hairlines for
   structure. No new colours.
   ========================================================================= */
#app .sales-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--rl-s-2) var(--rl-s-3);
  margin: 0 0 var(--rl-s-4);
}
#app .sales-bar .rl-seg { flex-wrap: wrap; }
#app .sales-bar-site { display: inline-flex; align-items: center; gap: var(--rl-s-1); margin-left: auto; }

#app .sales-metrics {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0; margin: 0 0 var(--rl-s-5);
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-md); background: var(--rl-surface);
  overflow: hidden;
}
#app .sales-metric {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: var(--rl-s-3) var(--rl-s-4); text-align: left;
  background: transparent; border: none; border-left: 1px solid var(--rl-line-soft);
  color: inherit; font: inherit; cursor: pointer;
  transition: background var(--rl-d-fast) var(--rl-ease-standard);
}
#app .sales-metric:first-child { border-left: none; }
#app .sales-metric:hover:not(:disabled) { background: var(--rl-surface-sunk); }
#app .sales-metric:disabled { cursor: default; }
#app .sales-metric:focus-visible { outline: none; box-shadow: var(--rl-focus); position: relative; z-index: 1; }
#app .sales-metric .rl-metric-value { font-size: 26px; line-height: 30px; margin: 2px 0 0; }
#app .sales-metric.is-warn .rl-metric-value { color: var(--rl-text-warning); }
#app .sales-metric.is-on { background: var(--rl-tint-accent-bg); box-shadow: inset 0 -2px 0 var(--rl-i-500); }
#app .sales-metric-sub { font-size: 12px; color: var(--rl-text-3); line-height: 16px; }

#app .sales-note {
  margin: calc(var(--rl-s-2) * -1) 0 var(--rl-s-4); padding: var(--rl-s-2) var(--rl-s-3);
  font-size: 13px; color: var(--rl-text-2);
  background: var(--rl-surface-sunk); border-radius: var(--rl-r-sm);
}
#app .sales-note[hidden] { display: none; }
#app .sales-count { font-weight: 400; color: var(--rl-text-3); font-size: 13px; margin-left: var(--rl-s-1); }
#app .sales-head-actions { display: flex; gap: var(--rl-s-2); align-items: center; flex-wrap: wrap; }

/* Chips on a card, a row or the record. One shape, four states. */
#app .sales-fu, #app .sales-term, #app .sales-tag {
  display: inline-flex; align-items: center; white-space: nowrap;
  font-size: 12px; line-height: 18px; padding: 0 6px; border-radius: var(--rl-r-xs);
  background: var(--rl-surface-sunk); color: var(--rl-text-2);
}
#app .sales-fu.is-overdue { background: var(--rl-tint-red-bg); color: var(--rl-tint-red-fg); font-weight: 500; }
#app .sales-fu.is-today   { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); font-weight: 500; }
#app .sales-fu.is-week    { background: var(--rl-tint-accent-bg); color: var(--rl-tint-accent-fg); }
#app .sales-fu.is-none    { background: transparent; color: var(--rl-text-3); padding-left: 0; }
#app .sales-term { font-variant-numeric: tabular-nums; }
#app .sales-term.is-inferred { background: transparent; box-shadow: inset 0 0 0 1px var(--rl-line); }
#app .sales-term.is-unknown { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }
#app .sales-tag.is-warn { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }

#app .sales-owner {
  flex: none; display: inline-grid; place-items: center;
  width: 22px; height: 22px; border-radius: var(--rl-r-full);
  font-size: 10.5px; font-weight: 600; letter-spacing: .02em;
  background: var(--rl-tint-accent-bg); color: var(--rl-tint-accent-fg);
}
#app .sales-owner.is-none { background: transparent; color: var(--rl-text-3); border: 1px dashed var(--rl-line-strong); }
#app .sales-owner-select { max-width: 150px; font-size: 13px; }

/* The card. */
#app .kanban-card .kc-name { align-items: center; }
#app .kanban-card .kc-tags { display: flex; flex-wrap: wrap; gap: 4px; margin: 2px 0 6px; }
#app .kanban-card .kc-actions { display: flex; gap: var(--rl-s-2); align-items: center; margin-top: var(--rl-s-2); }
#app .kanban-card .kc-actions .btn { flex: none; }
#app .kanban-card .kc-actions .kc-move { flex: 1; margin-top: 0; min-width: 0; }
#app .kanban-card.is-overdue { box-shadow: inset 3px 0 var(--rl-r-500); }
#app .kanban-card[data-locked="true"] { cursor: default; }
#app .kanban-more { width: 100%; margin-top: 6px; }

/* Follow-ups: the day's list, grouped by when. */
#app .sales-fu-list { display: grid; gap: var(--rl-s-5); }
#app .sales-fu-group h4 {
  display: flex; align-items: center; gap: var(--rl-s-2);
  font-size: 13px; font-weight: 600; color: var(--rl-text-2); margin: 0 0 var(--rl-s-2);
}
#app .sales-fu-group[data-fu="overdue"] h4 { color: var(--rl-text-danger); }
#app .sales-fu-row {
  display: grid; align-items: center; gap: var(--rl-s-3);
  grid-template-columns: minmax(180px, 2fr) minmax(160px, 1.4fr) auto auto auto;
  padding: var(--rl-s-2) var(--rl-s-3);
  background: var(--rl-surface); border: 1px solid var(--rl-line-soft); border-top: none;
}
#app .sales-fu-group h4 + .sales-fu-row { border-top: 1px solid var(--rl-line-soft); border-radius: var(--rl-r-md) var(--rl-r-md) 0 0; }
#app .sales-fu-row:last-child { border-radius: 0 0 var(--rl-r-md) var(--rl-r-md); }
#app .sales-fu-group h4 + .sales-fu-row:last-child { border-radius: var(--rl-r-md); }
#app .sales-fu-who { display: flex; flex-direction: column; min-width: 0; }
#app .sales-fu-name { font-weight: 500; color: var(--rl-text); text-decoration: none; }
#app .sales-fu-name:hover { text-decoration: underline; text-underline-offset: 2px; }
#app .sales-fu-what { font-size: 12.5px; color: var(--rl-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#app .sales-fu-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 12.5px; color: var(--rl-text-2); }
#app .sales-fu-phone { font-family: var(--rl-font-mono); font-size: 12px; color: var(--rl-text-accent); }

/* Forms. */
#app .sales-quick { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
#app .sales-quick .chip { min-height: 26px; padding: 0 8px; font-size: 12px; }
#app .sales-check { display: flex; align-items: center; gap: var(--rl-s-2); font-size: 13.5px; margin: var(--rl-s-2) 0; }
#app .sales-form-sec { margin-top: var(--rl-s-4); }
#app .sales-park { padding: var(--rl-s-3); margin-bottom: var(--rl-s-3); background: var(--rl-surface-sunk); border-radius: var(--rl-r-sm); }
#app .sales-park[hidden], #app .sales-park [hidden] { display: none; }
#app .sales-log-who { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 var(--rl-s-3); }

/* Overview. */
#app .sales-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); gap: var(--rl-s-4); margin-bottom: var(--rl-s-4); }
#app .sales-card { margin: 0; }
#app #salesBeds { margin-bottom: var(--rl-s-4); }
#app .sales-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--rl-s-3); margin-bottom: var(--rl-s-3); }
#app .sales-card-head h3 { margin: 0; font-size: 15px; font-weight: 600; }
#app .sales-empty { margin: 0; font-size: 13.5px; }
#app .sales-calls { display: grid; }
#app .sales-call {
  display: grid; grid-template-columns: 1fr auto auto auto; align-items: center; gap: var(--rl-s-2);
  padding: var(--rl-s-2) 0; border-top: 1px solid var(--rl-line-soft);
}
#app .sales-call:first-child { border-top: none; padding-top: 0; }
#app .sales-call-who { display: flex; flex-direction: column; min-width: 0; }
#app .sales-call-who a { font-weight: 500; color: var(--rl-text); text-decoration: none; }
#app .sales-call-who span { font-size: 12.5px; color: var(--rl-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#app .sales-more { font-size: 12.5px; color: var(--rl-text-3); margin: var(--rl-s-2) 0 0; }
#app .sales-subnotes { display: flex; flex-wrap: wrap; gap: var(--rl-s-2); margin-top: var(--rl-s-3); padding-top: var(--rl-s-2); border-top: 1px solid var(--rl-line-soft); }

#app .sales-funnel { display: grid; gap: var(--rl-s-2); }
#app .sales-funnel-row { display: grid; grid-template-columns: 110px 1fr 90px; align-items: center; gap: var(--rl-s-3); font-size: 13px; }
#app .sales-funnel-label { color: var(--rl-text-2); }
#app .sales-funnel-track { height: 10px; background: var(--rl-surface-sunk); border-radius: var(--rl-r-xs); overflow: hidden; }
#app .sales-funnel-bar { display: block; height: 100%; background: var(--rl-i-400); border-radius: var(--rl-r-xs); }
#app .sales-funnel-row:last-child .sales-funnel-bar { background: var(--rl-g-500); }
#app .sales-funnel-n { text-align: right; font-variant-numeric: tabular-nums; font-weight: 500; }
#app .sales-funnel-pct { margin-left: 6px; font-weight: 400; color: var(--rl-text-3); font-size: 12px; }
#app .sales-lost { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-top: var(--rl-s-4); padding-top: var(--rl-s-3); border-top: 1px solid var(--rl-line-soft); font-size: 13px; }
#app .sales-lost .rl-metric-label { width: 100%; }
#app .sales-lost-item b { font-variant-numeric: tabular-nums; }

#app .sales-table { width: 100%; }
#app .sales-beds td:first-child { font-weight: 500; }
#app .sales-total td { border-top: 1px solid var(--rl-line); font-weight: 600; }
#app .sales-any-b { display: block; font-size: 12px; font-weight: 400; color: var(--rl-text-3); }
#app .sales-flag { font-size: 12px; color: var(--rl-text-3); white-space: nowrap; }
#app .sales-flag.is-hot { color: var(--rl-tint-amber-fg); background: var(--rl-tint-amber-bg); padding: 0 6px; border-radius: var(--rl-r-xs); }
#app .sales-flag.is-full { color: var(--rl-tint-green-fg); background: var(--rl-tint-green-bg); padding: 0 6px; border-radius: var(--rl-r-xs); }

#app .sales-weekly { margin-top: var(--rl-s-4); padding-top: var(--rl-s-3); border-top: 1px solid var(--rl-line-soft); }
#app .sales-weekly-bars { display: flex; align-items: flex-end; gap: 4px; height: 56px; margin-top: var(--rl-s-2); }
#app .sales-weekly-bar { flex: 1; background: var(--rl-i-200); border-radius: 2px 2px 0 0; min-height: 2px; }
#app .sales-weekly-bar.is-now { background: var(--rl-i-500); }
#app .sales-weekly-axis { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--rl-text-3); margin-top: 4px; }

#app .sales-mini { display: flex; flex-wrap: wrap; gap: var(--rl-s-4) var(--rl-s-6); }
#app .sales-mini-item { display: flex; flex-direction: column; }
#app .sales-mini-item b { font-family: var(--rl-font-serif); font-weight: 400; font-size: 24px; line-height: 30px; font-variant-numeric: tabular-nums; }

/* ---- Sales Overview, 2026-09-27 redesign. A headline band (beds sold),
   a four-step flow that replaced the metric row AND the funnel card, then a
   main column for the work and a narrower side column for context. ---- */
#app .so-hero {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); align-items: end;
  gap: var(--rl-s-4) var(--rl-s-8);
  padding: var(--rl-s-5) var(--rl-s-6) var(--rl-s-6);
  margin: 0 0 var(--rl-s-4);
  background: var(--rl-surface); border: 1px solid var(--rl-line); border-radius: var(--rl-r-lg);
}
#app .so-hero-copy { display: flex; flex-direction: column; gap: var(--rl-s-1); min-width: 0; }
#app .so-hero-title {
  margin: 0; font-family: var(--rl-font-serif); font-weight: 400;
  font-size: 22px; line-height: 1.2; letter-spacing: -0.01em; color: var(--rl-text-2);
  text-wrap: balance;
}
#app .so-hero-big { font-size: 44px; line-height: 1; color: var(--rl-text); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
#app .so-hero-sub { margin: var(--rl-s-1) 0 0; font-size: 13.5px; color: var(--rl-text-2); }
#app .so-hero-sub b { color: var(--rl-text); font-weight: 600; }
#app .so-meter-wrap { display: flex; flex-direction: column; gap: var(--rl-s-2); min-width: 0; }
#app .so-meter {
  display: flex; height: 14px; overflow: hidden;
  background: var(--rl-surface-sunk); border-radius: var(--rl-r-full);
  box-shadow: inset 0 0 0 1px var(--rl-line-soft);
}
#app .so-meter span { display: block; height: 100%; transition: width var(--rl-d-slow) var(--rl-ease-standard); }
#app .so-meter-booked, #app .so-key-booked { background: var(--rl-g-500); }
#app .so-meter-progress, #app .so-key-progress { background: var(--rl-i-400); }
#app .so-key-left { background: var(--rl-surface-sunk); box-shadow: inset 0 0 0 1px var(--rl-line); }
#app .so-meter-key { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rl-s-1) var(--rl-s-4); font-size: 12.5px; color: var(--rl-text-2); font-variant-numeric: tabular-nums; }
#app .so-meter-key i { display: inline-block; width: 8px; height: 8px; border-radius: var(--rl-r-xs); margin-right: 6px; vertical-align: 0; }
#app .so-meter-key .btn { margin-left: auto; }

#app .so-flow {
  display: grid; grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr; align-items: stretch;
  margin: 0 0 var(--rl-s-5);
  background: var(--rl-surface); border: 1px solid var(--rl-line); border-radius: var(--rl-r-md);
}
#app .so-flow-step {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0;
  padding: var(--rl-s-3) var(--rl-s-4) var(--rl-s-4); text-align: left;
  background: transparent; border: none; border-radius: var(--rl-r-md); color: inherit; font: inherit; cursor: pointer;
  transition: background var(--rl-d-fast) var(--rl-ease-standard), transform var(--rl-d-instant) var(--rl-ease-standard);
}
#app .so-flow-step:hover { background: var(--rl-surface-sunk); }
#app .so-flow-step:active { transform: translateY(1px); }
#app .so-flow-step:focus-visible { outline: none; box-shadow: var(--rl-focus); }
#app .so-flow-n { font-family: var(--rl-font-serif); font-size: 30px; line-height: 36px; color: var(--rl-text); font-variant-numeric: tabular-nums; }
#app .so-flow-step.is-last .so-flow-n { color: var(--rl-text-success); }
#app .so-flow-step.is-zero .so-flow-n { color: var(--rl-text-3); }
#app .so-flow-sub { font-size: 12px; line-height: 16px; color: var(--rl-text-3); }
#app .so-flow-conv {
  align-self: center; font-size: 11.5px; font-weight: 500; color: var(--rl-text-2);
  padding: 2px var(--rl-s-2); border-radius: var(--rl-r-xs); background: var(--rl-line);
  font-variant-numeric: tabular-nums; position: relative;
}
#app .so-flow-conv::after { content: "→"; margin-left: 4px; color: var(--rl-text-3); }

#app .so-body { display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(280px, 1fr); gap: var(--rl-s-4); align-items: start; }
#app .so-main, #app .so-side { display: grid; gap: var(--rl-s-4); min-width: 0; }
#app .so-panel {
  background: var(--rl-surface); border: 1px solid var(--rl-line); border-radius: var(--rl-r-md);
  padding: var(--rl-s-4) var(--rl-s-4) var(--rl-s-5); min-width: 0;
}
#app .so-side .so-panel { background: transparent; border-color: var(--rl-line-soft); }
#app .so-panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--rl-s-3); margin: 0 0 var(--rl-s-3); }
#app .so-panel-head h3 { margin: 0; font-size: 14.5px; font-weight: 600; letter-spacing: -0.005em; }
#app .so-count { display: inline-block; margin-left: 6px; padding: 0 6px; font-size: 12px; font-weight: 500; line-height: 18px; border-radius: var(--rl-r-xs); background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); font-variant-numeric: tabular-nums; }
#app .so-muted { font-size: 12.5px; color: var(--rl-text-3); }
#app .so-empty { display: flex; flex-direction: column; gap: 2px; padding: var(--rl-s-4); border-radius: var(--rl-r-sm); background: var(--rl-surface-sunk); font-size: 13px; color: var(--rl-text-2); }
#app .so-empty b { color: var(--rl-text); font-weight: 600; }

#app .so-calls { display: grid; }
#app .so-call {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: var(--rl-s-3);
  padding: var(--rl-s-2) var(--rl-s-2); margin: 0 calc(var(--rl-s-2) * -1);
  border-radius: var(--rl-r-sm); transition: background var(--rl-d-fast) var(--rl-ease-standard);
}
#app .so-call + .so-call { box-shadow: 0 -1px 0 var(--rl-line-soft); }
#app .so-call:hover { background: var(--rl-surface-sunk); }
#app .so-avatar { width: 32px; height: 32px; font-size: 12px; }
#app .so-call-who { display: flex; flex-direction: column; min-width: 0; }
#app .so-call-who a { font-weight: 500; color: var(--rl-text); text-decoration: none; }
#app .so-call-who a:hover { text-decoration: underline; text-underline-offset: 2px; }
#app .so-call-who span { font-size: 12.5px; color: var(--rl-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#app .so-call-meta { display: flex; align-items: center; gap: 6px; }
#app .so-more { margin-top: var(--rl-s-2); }
#app .so-foot { display: flex; flex-wrap: wrap; gap: var(--rl-s-2); margin-top: var(--rl-s-3); padding-top: var(--rl-s-3); border-top: 1px solid var(--rl-line-soft); }

#app .so-bars { display: grid; gap: var(--rl-s-1); }
#app .so-bar-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px var(--rl-s-3);
  padding: 6px var(--rl-s-2); margin: 0 calc(var(--rl-s-2) * -1); border-radius: var(--rl-r-sm);
  color: inherit; text-decoration: none; transition: background var(--rl-d-fast) var(--rl-ease-standard);
}
#app .so-bar-row:hover { background: var(--rl-surface-sunk); }
#app .so-bar-label { font-size: 13px; color: var(--rl-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#app .so-bar-n { font-size: 13px; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
#app .so-bar-n small { margin-left: 6px; font-weight: 400; font-size: 11.5px; color: var(--rl-text-3); }
#app .so-bar-track { grid-column: 1 / -1; height: 4px; border-radius: var(--rl-r-full); background: var(--rl-surface-sunk); overflow: hidden; }
#app .so-bar-track span { display: block; height: 100%; background: var(--rl-i-400); border-radius: inherit; }

#app .so-kv { display: grid; }
#app .so-kv > div { display: grid; grid-template-columns: minmax(0, 1fr) auto 72px; gap: var(--rl-s-3); align-items: baseline; padding: 6px 0; font-size: 13px; }
#app .so-kv > div + div { border-top: 1px solid var(--rl-line-soft); }
#app .so-kv b { font-variant-numeric: tabular-nums; font-weight: 600; }
#app .so-kv small { font-size: 11.5px; color: var(--rl-text-3); text-align: right; }
#app .so-beds { margin-top: var(--rl-s-4); overflow-x: auto; }
#app .so-side .sales-weekly { margin-top: 0; padding-top: 0; border-top: none; }

@media (max-width: 1100px) {
  #app .so-body { grid-template-columns: 1fr; }
}
@media (max-width: 719px) {
  #app .so-hero { grid-template-columns: 1fr; padding: var(--rl-s-4); }
  #app .so-hero-big { font-size: 36px; }
  #app .so-flow { grid-template-columns: 1fr 1fr; }
  #app .so-flow-conv { display: none; }
  #app .so-flow-step { border-radius: 0; }
  #app .so-flow-step:nth-of-type(even) { border-left: 1px solid var(--rl-line-soft); }
  #app .so-flow-step:nth-of-type(n+3) { border-top: 1px solid var(--rl-line-soft); }
  #app .so-call { grid-template-columns: auto minmax(0, 1fr) auto; }
  #app .so-call-meta { grid-column: 2 / -1; grid-row: 2; }
}

/* Renewals: what they said in the portal. */
#app .sales-said { font-size: 12.5px; padding: 0 6px; border-radius: var(--rl-r-xs); }
#app .sales-said.is-yes   { background: var(--rl-tint-green-bg); color: var(--rl-tint-green-fg); }
#app .sales-said.is-maybe { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }
#app .sales-said.is-no    { background: var(--rl-tint-red-bg); color: var(--rl-tint-red-fg); }

@media (max-width: 719px) {
  #app .sales-bar-site { margin-left: 0; }
  #app .sales-metrics { grid-template-columns: repeat(2, 1fr); }
  #app .sales-metric { border-left: none; border-top: 1px solid var(--rl-line-soft); }
  #app .sales-metric:nth-child(-n+2) { border-top: none; }
  #app .sales-metric:nth-child(even) { border-left: 1px solid var(--rl-line-soft); }
  #app .sales-fu-row { grid-template-columns: 1fr auto; }
  #app .sales-fu-meta, #app .sales-fu-owner { grid-column: 1 / -1; }
  #app .sales-grid { grid-template-columns: 1fr; }
  #app .sales-call { grid-template-columns: 1fr auto; }
  #app .sales-funnel-row { grid-template-columns: 90px 1fr 70px; }
  #app .sales-beds { display: block; overflow-x: auto; }
}

/* =========================================================================
   §16.2 TAP TARGETS ON A THUMB — 44px, non-negotiable.

   The filter chips, the register buttons and the record's inline links
   are 30px on a pointer, which is right there and wrong on a phone. This
   block sits at the end of screens.css deliberately: shell.css declares
   the rest of the mobile layout but loads BEFORE this file, so the same
   override written there loses to these components' own 30px rule.
   ========================================================================= */
@media (max-width: 719px) {
  #app .rl-flagchip,
  #app .rl-register,
  #app .qf-chip,
  #app .p360-link,
  #app .p360-more,
  #app .p360-fchip,
  #app .p360-chip,
  #app .p360-tab,
  #app .sales-bar .rl-seg button,
  #app #leadsViewSeg button,
  #app .sales-quick .chip,
  #app .kanban-card .kc-actions .btn { min-height: 44px; }
  #app .p360-msg-head { padding-top: 13px; padding-bottom: 13px; }
  /* The filter dropdowns (26 Sept 2026). `.btn-select` is pinned at 36px by
     the toolbar rules above with a more specific selector than
     components.css's own mobile 44px, so every filter on every screen was
     under the bar — 57 of them in one audit pass at 390px. The same
     selectors, restated here after those rules, win on a phone. */
  #app .view-toolbar .btn-select,
  #app .view-toolbar select,
  #app .btn-select { height: 44px; min-height: 44px; }
  /* The inbox and live-chat folder chips and the composer's tabs were 32px,
     the record-reference links (RL-…, INV-…, a booking's guest) 30px. */
  #app .inbox-folder,
  #app .inbox-ctab,
  #app .rl-idlink { min-height: 44px; }
  /* Still under it after the 2026-10-12 audit at 390px: the dashboard tabs
     (38px), Invoices' mode switch and filter chips (32px), the chip's own
     remove button (30px) and the inbox contact disclosure (38px). */
  #app .mdb-tab,
  #app .rl-fbar-chip,
  #app .rl-fbar-clear,
  #app .inbox-context > summary,
  #view-livechat details > summary,
  #app .ws-group > summary { min-height: 44px; }
  #app .rl-fbar-chip button { width: 44px; height: 44px; }
  /* Still under the bar, and left: the room-tile edit/remove affordances
     (30px), which sit on a tile too small to make room for 44px ones. */
}

/* ROWS THAT RAN OFF A PHONE (26 Sept 2026, _ui_audit at 390px).
   A segmented control with six options (Tickets' types) is wider than the
   screen, and the Settings-row and viewing-hours rows lay a field and
   three or four buttons in one line that never wraps. Each wraps instead,
   as Sales' own segmented bar already does. */
@media (max-width: 719px) {
  #app .rl-seg { flex-wrap: wrap; max-width: 100%; }
  #app .settings-row { flex-wrap: wrap; gap: 8px; }
  #app .settings-row .rl-rename { max-width: 100%; }
  #app .vh-day, #app .vh-slot { flex-wrap: wrap; }
  #app .vh-day > .vh-times { min-width: 0; }
}

/* =========================================================================
   LIVE CHAT (2026-09-25, js/live-chat.js) — list | conversation | enquiry.
   The folder chips, avatar and flags are the shared inbox's own classes;
   only the chat-shaped parts are new.
   ========================================================================= */
.rl-menu-item .rl-badge {
  margin-left: auto; min-width: 17px; height: 17px; padding: 0 5px;
  border-radius: var(--rl-r-full); font-family: var(--rl-font-mono);
  font-size: 10.5px; line-height: 17px; text-align: center;
  background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg);
}
.lc-titlebar { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--rl-s-4); flex-wrap: wrap; }
.lc-top { display: flex; align-items: center; justify-content: space-between; gap: var(--rl-s-3); flex-wrap: wrap; margin-bottom: var(--rl-s-3); }
.lc-top .inbox-folders { margin: 0; }
.lc-search { min-width: 240px; }
.lc-layout {
  display: grid; grid-template-columns: 300px minmax(0, 1fr) 280px; gap: var(--rl-s-4);
  align-items: stretch; height: calc(100vh - 290px); min-height: 460px;
}
.lc-list { overflow-y: auto; padding: var(--rl-s-1); display: flex; flex-direction: column; gap: 2px; min-height: 0; }
.lc-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px; align-items: start;
  width: 100%; text-align: left; padding: 10px; border: 0; border-radius: var(--rl-r-sm);
  background: transparent; color: var(--rl-text); cursor: pointer; font: inherit;
}
.lc-row:hover { background: var(--rl-surface-sunk); }
.lc-row.active { background: var(--rl-tint-accent-bg); box-shadow: inset 3px 0 var(--rl-i-600); }
.lc-row:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
.lc-av { position: relative; display: inline-flex; }
.lc-online {
  position: absolute; right: -1px; bottom: -1px; width: 10px; height: 10px; border-radius: var(--rl-r-full);
  background: var(--rl-g-500); box-shadow: 0 0 0 2px var(--rl-surface);
}
.lc-row-main { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.lc-row-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.lc-row-name { font-size: 13.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lc-row.unread .lc-row-name { font-weight: 700; }
.lc-row-time { flex: none; font-size: 11.5px; color: var(--rl-text-2); }
.lc-row-snip { font-size: 12.5px; color: var(--rl-text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lc-row.unread .lc-row-snip { color: var(--rl-text); }
.lc-row-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.lc-empty { padding: var(--rl-s-6) var(--rl-s-4); font-size: 13px; color: var(--rl-text-2); text-align: center; line-height: 1.5; }
.lc-muted { font-size: 12.5px; color: var(--rl-text-2); }

.lc-pane { display: flex; flex-direction: column; min-height: 0; padding: 0; overflow: hidden; }
.lc-head { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--rl-line); }
.lc-head:empty { display: none; }
.lc-head-id { flex: 1; min-width: 0; }
.lc-head-id h3 { font-family: var(--rl-font-serif); font-size: 18px; font-weight: 600; margin: 0 0 2px; }
.lc-head-meta { display: flex; flex-wrap: wrap; gap: 8px; font-size: 12px; color: var(--rl-text-2); }
.lc-presence { display: inline-flex; align-items: center; gap: 6px; }
.lc-presence.is-on { color: var(--rl-text-success); font-weight: 500; }
.lc-presence.is-on::before { content: ""; width: 7px; height: 7px; border-radius: var(--rl-r-full); background: var(--rl-g-500); }
.lc-page { font-family: var(--rl-font-mono); font-size: 11.5px; color: var(--rl-text-3); max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lc-head .lc-back, #app .lc-head .lc-back { display: none; }
.lc-thread { flex: 1; min-height: 0; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 10px; background: var(--rl-surface-sunk); }
.lc-day, .lc-sys { align-self: center; font-size: 11.5px; color: var(--rl-text-2); }
.lc-day { font-weight: 600; margin-top: 4px; }
.lc-msg { display: flex; flex-direction: column; max-width: min(72%, 560px); gap: 3px; }
.lc-msg.is-visitor { align-self: flex-start; }
.lc-msg.is-staff { align-self: flex-end; align-items: flex-end; }
.lc-bubble {
  padding: 9px 12px; border-radius: 14px; font-size: 13.5px; line-height: 1.5;
  overflow-wrap: anywhere; background: var(--rl-surface); color: var(--rl-text); border: 1px solid var(--rl-line);
}
.lc-msg.is-visitor .lc-bubble { border-bottom-left-radius: 4px; }
.lc-msg.is-staff .lc-bubble { background: var(--rl-i-600); color: var(--rl-n-0); border-color: transparent; border-bottom-right-radius: 4px; }
.lc-msg-meta { font-size: 11px; color: var(--rl-text-3); }
.lc-compose { display: flex; gap: 8px; align-items: flex-end; padding: 12px; border-top: 1px solid var(--rl-line); background: var(--rl-surface); }
.lc-compose textarea { flex: 1; resize: none; min-height: 42px; max-height: 160px; font: inherit; font-size: 13.5px; }
.lc-compose .lc-template { flex: 0 0 auto; width: 150px; }
#app .lc-compose .lc-template[hidden] { display: none; }
@media (max-width: 719px) { .lc-compose { flex-wrap: wrap; } .lc-compose .lc-template { width: 100%; } }

.lc-side { overflow-y: auto; min-height: 0; display: flex; flex-direction: column; gap: var(--rl-s-4); }
.lc-side:empty { display: none; }
.lc-side .rl-sec { margin: 0 0 6px; }
.lc-kv { display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 8px; font-size: 13px; padding: 3px 0; }
.lc-kv > span:first-child { color: var(--rl-text-2); }
.lc-kv a { color: var(--rl-text-accent); overflow-wrap: anywhere; }
.lc-side-actions { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.lc-side .btn-select { width: 100%; }

@media (max-width: 1180px) {
  .lc-layout { grid-template-columns: 280px minmax(0, 1fr); }
  .lc-side { grid-column: 2; max-height: none; }
  .lc-layout { height: auto; }
  .lc-pane { height: calc(100vh - 290px); min-height: 460px; }
}
@media (max-width: 719px) {
  .lc-layout { grid-template-columns: minmax(0, 1fr); }
  .lc-layout[data-open="true"] .lc-list { display: none; }
  .lc-layout[data-open="false"] .lc-pane, .lc-layout[data-open="false"] .lc-side { display: none; }
  .lc-side { grid-column: auto; }
  .lc-head .lc-back, #app .lc-head .lc-back { display: inline-flex; }
  .lc-pane { height: calc(100vh - 220px); }
  .lc-msg { max-width: 85%; }
  .lc-search { min-width: 0; width: 100%; }
}
/* Sales inbox (2026-09-27): email rows beside chat rows, the email thread
   in the same pane, "not taken yet" banner, and the incoming-chat prompt. */
.lc-row-subj { display: flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--rl-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lc-row-subj svg { flex: none; width: 13px; height: 13px; color: var(--rl-text-3); }
.lc-kind { font-size: 10.5px; font-weight: 600; letter-spacing: 0.02em; padding: 0 5px; line-height: 17px; border-radius: var(--rl-r-xs); background: var(--rl-line); color: var(--rl-text-2); }
.lc-kind.is-chat { background: var(--rl-tint-accent-bg); color: var(--rl-tint-accent-fg); }
.lc-layout[data-kind="email"] { grid-template-columns: 300px minmax(0, 1fr); }
.lc-layout[data-kind="email"] .lc-side { display: none; }
.lc-email-pane { flex: 1; min-height: 0; overflow-y: auto; padding: var(--rl-s-4); }
#app .lc-email-pane[hidden], #app .lc-head[hidden], #app .lc-thread[hidden], #app .lc-connect[hidden], #app .lc-compose[hidden], #app .lc-emailtoo[hidden] { display: none; }
#app .lc-email-pane .lc-back-mail { display: none; margin-bottom: var(--rl-s-2); }
.lc-connect {
  display: flex; align-items: center; justify-content: space-between; gap: var(--rl-s-3); flex-wrap: wrap;
  padding: 10px 16px; font-size: 13px; background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg);
  border-bottom: 1px solid var(--rl-line);
}
.lc-take { display: inline-flex; align-items: center; gap: 6px; }
.lc-take-dot { width: 8px; height: 8px; border-radius: var(--rl-r-full); background: var(--rl-n-400); }
.lc-take-dot.is-on { background: var(--rl-g-500); }
.lc-offer {
  position: fixed; right: var(--rl-s-6); bottom: var(--rl-s-6); z-index: 250; width: min(360px, calc(100vw - 32px));
  padding: var(--rl-s-4); border-radius: var(--rl-r-lg);
  background: var(--rl-surface); color: var(--rl-text); border: 1px solid var(--rl-line);
  box-shadow: var(--rl-e-3);
  animation: lc-offer-in var(--rl-d-mid) var(--rl-ease-enter);
}
@keyframes lc-offer-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .lc-offer { animation: none; } }
.lc-offer-top { display: flex; align-items: center; gap: var(--rl-s-2); font-size: 13px; }
.lc-offer-dot { width: 9px; height: 9px; border-radius: var(--rl-r-full); background: var(--rl-g-500); box-shadow: 0 0 0 4px var(--rl-tint-green-bg); }
.lc-offer-timer { margin-left: auto; font-family: var(--rl-font-mono); font-size: 12px; color: var(--rl-text-3); }
.lc-offer-who { margin-top: var(--rl-s-2); font-family: var(--rl-font-serif); font-size: 17px; }
.lc-offer-text { margin: var(--rl-s-1) 0 0; font-size: 13px; color: var(--rl-text-2); line-height: 1.45; }
.lc-offer-actions { display: flex; gap: var(--rl-s-2); margin-top: var(--rl-s-3); }
@media (max-width: 1180px) {
  .lc-layout[data-kind="email"] { grid-template-columns: 280px minmax(0, 1fr); }
}
@media (max-width: 719px) {
  .lc-layout[data-kind="email"] { grid-template-columns: minmax(0, 1fr); }
  #app .lc-email-pane .lc-back-mail { display: inline-flex; }
  .lc-offer { right: 16px; left: 16px; bottom: 16px; width: auto; }
}

/* Live chat: office hours + reply by email */
.lc-titlebar-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.lc-hours-chip {
  display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: var(--rl-r-full);
  font-size: 12.5px; font-weight: 600; background: var(--rl-line); color: var(--rl-text-2);
}
.lc-hours-chip.is-on { background: var(--rl-tint-green-bg); color: var(--rl-tint-green-fg); }
.lc-hours-chip.is-on::before { content: ""; width: 7px; height: 7px; border-radius: var(--rl-r-full); background: var(--rl-g-500); }
.lc-emailtoo { display: flex; align-items: center; gap: 8px; padding: 0 12px 10px; font-size: 12.5px; color: var(--rl-text-2); background: var(--rl-surface); overflow-wrap: anywhere; }
.lc-emailtoo[hidden] { display: none; }
.lc-emailed { color: var(--rl-text-accent); font-weight: 600; }
.lc-hr-days { display: flex; flex-direction: column; gap: 6px; margin: var(--rl-s-3) 0; }
.lc-hr-days.is-muted { opacity: .5; }
.lc-hr-row { display: grid; grid-template-columns: 130px 1fr auto 1fr; gap: 8px; align-items: center; }
.lc-hr-row .sales-check { margin: 0; }
@media (max-width: 719px) { .lc-hr-row { grid-template-columns: 1fr 1fr auto 1fr; } }

/* ---------------------------------------------------------------------
   PUBLIC SITE → OFFERS (js/website.js, site_offers)
   One row per offer: artwork, what it is, where it runs, whether it is
   live right now. The chip carries the status because "is this on the
   site?" is the one question the office asks of this list.
   --------------------------------------------------------------------- */
#app .so-row {
  display: flex; align-items: center; gap: var(--rl-s-3);
  padding: var(--rl-s-3) 0; border-top: 1px solid var(--rl-line-soft);
}
#app .so-row:first-child { border-top: 0; }
#app .so-row[data-status="hidden"] .so-thumb,
#app .so-row[data-status="ended"] .so-thumb { opacity: .5; }
#app .so-thumb {
  flex: none; width: 96px; aspect-ratio: 16 / 9; border-radius: var(--rl-r-sm); overflow: hidden;
  background: var(--rl-tint-accent-bg); color: var(--rl-tint-accent-fg);
  display: grid; place-items: center; text-align: center;
}
#app .so-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
#app .so-thumb-text { font-size: 11px; font-weight: 600; padding: 0 var(--rl-s-1); line-height: 1.2; }
#app .so-main { flex: 1; min-width: 0; }
#app .so-title { font-size: 14px; font-weight: 600; color: var(--rl-text); }
#app .so-hl { font-weight: 500; color: var(--rl-text-accent); margin-left: var(--rl-s-1); }
#app .so-sub { font-size: 12.5px; color: var(--rl-text-3); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#app .so-status {
  flex: none; font-size: 11.5px; font-weight: 600; padding: 2px var(--rl-s-2); border-radius: var(--rl-r-xs);
  background: var(--rl-surface-sunk); color: var(--rl-text-2);
}
#app .so-status[data-status="live"] { background: var(--rl-tint-green-bg); color: var(--rl-tint-green-fg); }
#app .so-status[data-status="scheduled"] { background: var(--rl-tint-amber-bg); color: var(--rl-tint-amber-fg); }
#app .so-actions { flex: none; display: flex; gap: var(--rl-s-1); }
@media (max-width: 719px) {
  #app .so-row { flex-wrap: wrap; }
  #app .so-main { flex-basis: calc(100% - 96px - var(--rl-s-3)); }
  #app .so-status { margin-left: calc(96px + var(--rl-s-3)); }
  #app .so-actions { margin-left: auto; }
}

/* The editor dialog (lives in #appModal, outside #app). */
.so-form .so-opt { font-weight: 400; color: var(--rl-text-3); }
.so-form .so-hint { font-size: 12px; color: var(--rl-text-3); margin: var(--rl-s-1) 0 0; }
.so-form .so-err { color: var(--rl-text-danger); font-size: 13px; margin: var(--rl-s-2) 0 0; }
.so-image-field { display: flex; gap: var(--rl-s-4); align-items: flex-start; margin-bottom: var(--rl-s-4); }
.so-image-preview {
  flex: none; width: 220px; aspect-ratio: 16 / 9; border-radius: var(--rl-r-md); overflow: hidden;
  background: var(--rl-surface-sunk); border: 1px dashed var(--rl-line-strong);
  display: grid; place-items: center; text-align: center;
}
.so-image-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.so-image-preview span { font-size: 12px; color: var(--rl-text-3); padding: var(--rl-s-3); }
.so-image-actions { display: flex; flex-wrap: wrap; gap: var(--rl-s-2); align-items: center; }
.so-image-actions label.btn { cursor: pointer; }
.so-props { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--rl-s-1) var(--rl-s-3); }
.so-check { display: flex !important; align-items: center; gap: var(--rl-s-2); font-weight: 400 !important; font-size: 13px !important; text-transform: none !important; letter-spacing: normal !important; color: var(--rl-text) !important; margin: var(--rl-s-1) 0; cursor: pointer; }
.so-check input { width: auto; margin: 0; }
@media (max-width: 719px) {
  .so-image-field { flex-direction: column; }
  .so-image-preview { width: 100%; }
}

/* Settings → Workspace (js/workspace-settings.js). Borrows the offers
   editor's field furniture (.so-form); the groups fold so the card is one
   line per concern until somebody opens it. */
.ws-group { margin-top: var(--rl-s-3); }
.ws-group > summary { cursor: pointer; list-style: none; min-height: 32px; border-radius: var(--rl-r-sm); }
.ws-group > summary:hover { color: var(--rl-text); }
.ws-group > summary:focus-visible { outline: none; box-shadow: var(--rl-focus); }
.ws-group > summary::-webkit-details-marker { display: none; }
.ws-group > summary::before { content: "▸"; margin-right: var(--rl-s-1); color: var(--rl-text-3); }
.ws-group[open] > summary::before { content: "▾"; }
#workspaceSettingsCard .so-image-preview { width: 120px; aspect-ratio: 1; }
#workspaceSettingsCard .so-image-preview img { object-fit: contain; }

/* =========================================================================
   SYSTEM HEALTH (js/health.js). One status vocabulary everywhere on the
   screen — data-s="ok|warn|fail|info" — so a dot, a row, a strip cell and
   the summary all read the same colour for the same state.
   ========================================================================= */
.hl-dot { display: inline-block; flex: none; width: 9px; height: 9px; border-radius: 50%; margin-right: var(--rl-s-2); background: var(--rl-n-300); vertical-align: middle; }
.hl-dot[data-s="ok"]   { background: var(--rl-g-500); }
.hl-dot[data-s="warn"] { background: var(--rl-a-500); }
.hl-dot[data-s="fail"] { background: var(--rl-r-500); }
.hl-dot[data-s="info"] { background: var(--rl-n-300); }

.hl-summary { display: flex; align-items: center; gap: var(--rl-s-4); padding: var(--rl-s-4) var(--rl-s-5);
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-lg); background: var(--rl-surface); margin-bottom: var(--rl-s-4); }
.hl-summary[data-s="ok"]   { background: var(--rl-tint-green-bg); }
.hl-summary[data-s="warn"] { background: var(--rl-tint-amber-bg); border-color: var(--rl-a-200); }
.hl-summary[data-s="fail"] { background: var(--rl-tint-red-bg); border-color: var(--rl-line-danger); }
.hl-summary-main { flex: 1; min-width: 0; }
.hl-big { font-family: var(--rl-font-serif); font-size: 20px; font-weight: 600; display: flex; align-items: center; }
.hl-big .hl-dot { width: 12px; height: 12px; }
.hl-sub { font-size: 12.5px; color: var(--rl-text-2); margin-top: var(--rl-s-1); }

.hl-strip-wrap { margin-bottom: var(--rl-s-4); }
.hl-strip-head { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--rl-text-3); margin-bottom: var(--rl-s-1); }
.hl-strip { display: flex; gap: 1px; height: 22px; align-items: stretch; background: var(--rl-surface-sunk); border-radius: var(--rl-r-sm); overflow: hidden; }
.hl-cell { flex: 1; min-width: 2px; background: var(--rl-n-300); }
.hl-cell[data-s="ok"]   { background: var(--rl-g-500); }
.hl-cell[data-s="warn"] { background: var(--rl-a-500); }
.hl-cell[data-s="fail"] { background: var(--rl-r-500); }
.hl-strip-empty { font-size: 12px; color: var(--rl-text-3); padding: 0 var(--rl-s-2); align-self: center; }

.hl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: var(--rl-s-4); margin-bottom: var(--rl-s-4); align-items: start; }
.hl-card h3 { display: flex; align-items: center; margin: 0 0 var(--rl-s-2); font-family: var(--rl-font-serif); font-size: 15px; }
.hl-count { margin-left: auto; font-family: var(--rl-font-sans); font-size: 11.5px; font-weight: 400; color: var(--rl-text-3); }
.hl-problems { margin-bottom: var(--rl-s-4); }
.hl-row { display: flex; align-items: flex-start; gap: 0; padding: var(--rl-s-2) 0; border-top: 1px solid var(--rl-line-soft); }
.hl-row:first-of-type { border-top: 0; }
.hl-row .hl-dot { margin-top: 5px; }
.hl-row-main { flex: 1; min-width: 0; }
.hl-label { font-size: 13px; font-weight: 500; overflow-wrap: anywhere; }
.hl-group { font-weight: 400; color: var(--rl-text-3); margin-right: var(--rl-s-2); }
.hl-detail { font-size: 12px; color: var(--rl-text-2); overflow-wrap: anywhere; }
.hl-row[data-s="fail"] .hl-detail { color: var(--rl-text-danger); }
.hl-ms { flex: none; font-family: var(--rl-font-mono); font-size: 11px; color: var(--rl-text-3); margin-left: var(--rl-s-2); }

/* Sentry card: the title row carries a Refresh button. */
.hl-sentry-head { display: flex; align-items: flex-start; gap: var(--rl-s-3); }
.hl-sentry-head h3 { flex: 1; }
.hl-errors a { color: inherit; }
.hl-errors { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.hl-errors th { text-align: left; font-weight: 500; color: var(--rl-text-3); padding: var(--rl-s-1) var(--rl-s-2); border-bottom: 1px solid var(--rl-line); }
.hl-errors td { padding: var(--rl-s-2); border-bottom: 1px solid var(--rl-line-soft); vertical-align: top; overflow-wrap: anywhere; }
.hl-err-row { cursor: pointer; }
.hl-err-row:hover td { background: var(--rl-surface-sunk); }
.hl-stack { margin: 0 0 var(--rl-s-2); padding: var(--rl-s-3); background: var(--rl-surface-sunk); border-radius: var(--rl-r-sm);
  font-family: var(--rl-font-mono); font-size: 11.5px; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 260px; overflow: auto; }
.hl-alert-row { display: flex; gap: var(--rl-s-2); }
.hl-alert-row input { flex: 1; min-width: 0; }
.hl-summary-actions { display: flex; align-items: center; gap: var(--rl-s-2); flex-wrap: wrap; }
.hl-seg { display: inline-flex; border: 1px solid var(--rl-line); border-radius: var(--rl-r-sm); overflow: hidden; background: var(--rl-surface); }
.hl-seg button { border: 0; background: none; padding: 5px 10px; font: inherit; font-size: 12.5px; color: var(--rl-text-2); cursor: pointer; min-height: 30px; }
.hl-seg button + button { border-left: 1px solid var(--rl-line); }
.hl-seg button.on { background: var(--rl-surface-sunk); color: var(--rl-text); font-weight: 600; }
.hl-section { font-family: var(--rl-font-serif); font-size: 16px; margin: var(--rl-s-6) 0 var(--rl-s-3); }
.hl-explain { font-size: 12px; color: var(--rl-text-2); margin: 0 0 var(--rl-s-3); max-width: 80ch; }
.hl-link { border: 0; background: none; padding: 0; min-height: 32px; font: inherit; color: var(--rl-text-accent); cursor: pointer; }
.hl-link:hover { text-decoration: underline; }

/* Status is carried by a dot + a word everywhere; these are the fills. */
.hl-cell[data-s="none"], .hl-legend i[data-s="none"] { background: var(--rl-n-200); }
.hl-cell[data-s="info"] { background: var(--rl-g-500); }

/* Tiles */
.hl-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--rl-s-3); margin-bottom: var(--rl-s-4); }
.hl-tile { border: 1px solid var(--rl-line); border-radius: var(--rl-r-md); background: var(--rl-surface); padding: var(--rl-s-3) var(--rl-s-4); min-width: 0; }
.hl-tile-label { font-size: 12px; color: var(--rl-text-2); display: flex; align-items: center; }
.hl-tile-label .hl-dot { width: 7px; height: 7px; }
.hl-tile-value { font-family: var(--rl-font-serif); font-size: 26px; line-height: 1.2; font-variant-numeric: tabular-nums; margin: var(--rl-s-1) 0; }
.hl-tile-sub { font-size: 11.5px; color: var(--rl-text-3); overflow-wrap: anywhere; }
.hl-meter { height: 6px; border-radius: 3px; background: var(--rl-surface-sunk); overflow: hidden; margin: var(--rl-s-1) 0; }
.hl-meter span { display: block; height: 100%; border-radius: 3px; background: var(--rl-g-500); }
.hl-meter[data-s="warn"] span { background: var(--rl-a-500); }
.hl-meter[data-s="fail"] span { background: var(--rl-r-500); }

/* Timeline + run duration */
.hl-timeline { margin-bottom: var(--rl-s-4); }
.hl-strip-lg { height: 28px; }
.hl-strip .hl-cell { cursor: default; }
.hl-legend { display: inline-flex; align-items: center; gap: var(--rl-s-1); flex-wrap: wrap; }
.hl-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-left: var(--rl-s-2); }
.hl-legend i[data-s="ok"] { background: var(--rl-g-500); }
.hl-legend i[data-s="warn"] { background: var(--rl-a-500); }
.hl-legend i[data-s="fail"] { background: var(--rl-r-500); }
.hl-axis { display: flex; justify-content: space-between; font-size: 11px; color: var(--rl-text-3); margin-top: 3px; font-variant-numeric: tabular-nums; }
.hl-bars-head { margin-top: var(--rl-s-3); }
.hl-bars { display: flex; gap: 1px; height: 44px; align-items: flex-end; border-bottom: 1px solid var(--rl-line); }
.hl-bar-slot { flex: 1; min-width: 1px; height: 100%; display: flex; align-items: flex-end; }
.hl-bar { display: block; width: 100%; background: var(--hl-chart); border-radius: 2px 2px 0 0; opacity: .75; }
.hl-bar-slot:hover .hl-bar { opacity: 1; }

/* Response times */
.hl-grid-wide { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); }
.hl-lat { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.hl-lat th { text-align: left; font-weight: 500; color: var(--rl-text-3); padding: var(--rl-s-1) var(--rl-s-2); border-bottom: 1px solid var(--rl-line); white-space: nowrap; }
.hl-lat td { padding: 5px var(--rl-s-2); border-bottom: 1px solid var(--rl-line-soft); vertical-align: middle; }
.hl-lat .num { text-align: right; font-family: var(--rl-font-mono); font-size: 11.5px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.hl-lat-name { min-width: 130px; }
.hl-lat-name .hl-label { font-size: 12.5px; }
.hl-lat-spark { width: 38%; min-width: 120px; }
.hl-lat-group td { padding-top: var(--rl-s-3); font-size: 11.5px; font-weight: 600; color: var(--rl-text-2); border-bottom: 1px solid var(--rl-line); }
.hl-scale { font-weight: 400; }
.hl-warm, .hl-lat td.hl-warm { color: var(--rl-text-success); }
.hl-spark { display: block; width: 100%; height: 28px; overflow: visible; }
.hl-spark-line { fill: none; stroke: var(--hl-chart); stroke-width: 1.5px; stroke-linejoin: round; stroke-linecap: round; }
.hl-spark-grid { stroke: var(--rl-line-soft); stroke-width: 1px; stroke-dasharray: 2 3; }
.hl-spark-over { fill: var(--rl-a-500); }
.hl-spark-fail { fill: var(--rl-r-500); }
.hl-spark-warn { fill: var(--rl-a-500); }
.hl-spark-hit { fill: transparent; }
.hl-spark-hit:hover { fill: var(--rl-line-soft); fill-opacity: .6; }
.hl-code { display: inline-block; margin-left: var(--rl-s-2); padding: 0 5px; border-radius: var(--rl-r-xs); font-family: var(--rl-font-mono); font-size: 10.5px; font-weight: 500; line-height: 17px; vertical-align: 1px;
  background: var(--rl-surface-sunk); color: var(--rl-text-2); border: 1px solid var(--rl-line); cursor: help; }
.hl-code[data-ok="0"] { background: var(--rl-tint-red-bg); color: var(--rl-text-danger); border-color: var(--rl-line-danger); }
.hl-lat .hl-code { margin-left: 0; }

/* Incidents */
.hl-inc-list { list-style: none; margin: 0; padding: 0; max-height: 420px; overflow: auto; }
.hl-inc-list li { display: grid; grid-template-columns: 92px 1fr auto; gap: var(--rl-s-2); align-items: baseline; padding: 6px 0 6px var(--rl-s-3);
  border-top: 1px solid var(--rl-line-soft); font-size: 12.5px; position: relative; }
.hl-inc-list li::before { content: ""; position: absolute; left: 0; top: 8px; bottom: 8px; width: 3px; border-radius: 2px; background: var(--rl-a-500); }
.hl-inc-list li[data-s="fail"]::before { background: var(--rl-r-500); }
.hl-inc-list li.hl-detail::before { display: none; }
.hl-inc-when { color: var(--rl-text-3); font-variant-numeric: tabular-nums; font-size: 11.5px; }
.hl-inc-what { min-width: 0; overflow-wrap: anywhere; }
.hl-inc-dur { font-family: var(--rl-font-mono); font-size: 11px; color: var(--rl-text-2); white-space: nowrap; }

/* Heatmap */
.hl-heat-row { display: grid; grid-template-columns: minmax(120px, 220px) 1fr; gap: var(--rl-s-3); align-items: center; padding: 3px 0; }
.hl-heat-name { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hl-heat-n { margin-left: var(--rl-s-2); color: var(--rl-text-3); font-size: 11px; }
.hl-heat-strip { height: 14px; }

/* Database */
.hl-db { margin-bottom: var(--rl-s-4); }
.hl-db-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--rl-s-6); margin-bottom: var(--rl-s-3); }
.hl-gauge { margin-bottom: var(--rl-s-3); }
.hl-gauge-head { display: flex; justify-content: space-between; gap: var(--rl-s-2); font-size: 12px; color: var(--rl-text-2); }
.hl-gauge-head span:last-child { font-variant-numeric: tabular-nums; color: var(--rl-text-3); }
.hl-gauge .hl-meter { height: 8px; }
.hl-db-facts { display: flex; gap: var(--rl-s-4); flex-wrap: wrap; font-size: 12px; color: var(--rl-text-2); }
.hl-sub-h { font-size: 12px; font-weight: 600; color: var(--rl-text-2); margin: var(--rl-s-3) 0 var(--rl-s-2); }
.hl-barlist-row { display: grid; grid-template-columns: minmax(90px, 150px) 1fr 64px; gap: var(--rl-s-2); align-items: center; padding: 2px 0; font-size: 12px; }
.hl-barlist-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--rl-font-mono); font-size: 11px; }
.hl-barlist-track { height: 8px; background: var(--rl-surface-sunk); border-radius: 0 4px 4px 0; overflow: hidden; }
.hl-barlist-track span { display: block; height: 100%; background: var(--hl-chart); border-radius: 0 4px 4px 0; opacity: .8; }
.hl-barlist-row:hover .hl-barlist-track span { opacity: 1; }
.hl-barlist-v { text-align: right; font-family: var(--rl-font-mono); font-size: 11px; color: var(--rl-text-3); }

/* Errors per day */
.hl-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--rl-s-2); height: 84px; align-items: end; margin-bottom: var(--rl-s-3); }
.hl-day { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; }
.hl-day-bar { width: 60%; max-width: 36px; background: var(--rl-a-500); border-radius: 4px 4px 0 0; }
.hl-day-n { font-size: 11px; color: var(--rl-text-2); font-variant-numeric: tabular-nums; }
.hl-day-l { font-size: 11px; color: var(--rl-text-3); border-top: 1px solid var(--rl-line); width: 100%; text-align: center; padding-top: 2px; }

/* Redesign 2026-10-04: one sentence, then what to do, then areas. */
.hl-hero { border: 1px solid var(--rl-line); border-radius: var(--rl-r-lg); background: var(--rl-surface); padding: var(--rl-s-5); margin-bottom: var(--rl-s-4); border-left-width: 4px; }
.hl-hero[data-s="ok"]   { border-left-color: var(--rl-g-500); }
.hl-hero[data-s="warn"] { border-left-color: var(--rl-a-500); }
.hl-hero[data-s="fail"] { border-left-color: var(--rl-r-500); background: var(--rl-tint-red-bg); }
.hl-hero-top { display: flex; align-items: flex-start; gap: var(--rl-s-4); }
.hl-hero-main { flex: 1; min-width: 0; }
.hl-hero .hl-big { font-size: 24px; }
.hl-hero-strip-wrap { margin-top: var(--rl-s-4); }
.hl-hero-strip { height: 18px; margin-top: var(--rl-s-4); }
.hl-hero-strip-wrap .hl-hero-strip { margin-top: 0; }
.hl-fix { font-size: 12px; color: var(--rl-text); margin-top: var(--rl-s-1); padding-left: var(--rl-s-2); border-left: 2px solid var(--rl-line-strong); }
.hl-areas { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: var(--rl-s-3); margin-bottom: var(--rl-s-4); align-items: start; }
.hl-area, .hl-tech { border: 1px solid var(--rl-line); border-radius: var(--rl-r-md); background: var(--rl-surface); }
.hl-area > summary, .hl-tech > summary { list-style: none; cursor: pointer; padding: var(--rl-s-3) var(--rl-s-4); display: flex; flex-direction: column; gap: 2px; min-height: 44px; justify-content: center; }
.hl-area > summary::-webkit-details-marker, .hl-tech > summary::-webkit-details-marker { display: none; }
.hl-area > summary:hover, .hl-tech > summary:hover { background: var(--rl-surface-sunk); }
.hl-area > summary:focus-visible, .hl-tech > summary:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
.hl-area-head { display: flex; align-items: center; font-size: 13.5px; }
.hl-area-state { margin-left: auto; font-size: 12px; color: var(--rl-text-3); }
.hl-area[data-s="warn"] .hl-area-state { color: var(--rl-text-warning); font-weight: 600; }
.hl-area[data-s="fail"] .hl-area-state { color: var(--rl-text-danger); font-weight: 600; }
.hl-area-blurb { font-size: 12px; color: var(--rl-text-3); padding-left: 17px; }
.hl-area-body { padding: 0 var(--rl-s-4) var(--rl-s-2); border-top: 1px solid var(--rl-line-soft); }
.hl-known { font-size: 12px; color: var(--rl-text-2); padding: var(--rl-s-2) var(--rl-s-4); border-radius: var(--rl-r-md); background: var(--rl-surface-sunk); margin-bottom: var(--rl-s-4); }
.hl-tech { margin-bottom: var(--rl-s-4); }
.hl-tech[open] > summary { border-bottom: 1px solid var(--rl-line-soft); }
.hl-tech[open] { padding-bottom: var(--rl-s-3); }
.hl-tech > *:not(summary) { margin-left: var(--rl-s-4); margin-right: var(--rl-s-4); }
.hl-tech-bar { display: flex; justify-content: flex-end; padding: var(--rl-s-3) 0; }

/* The one tooltip */
.hl-tip { position: fixed; z-index: 9999; max-width: 320px; padding: 6px 9px; border-radius: var(--rl-r-sm); pointer-events: none;
  background: var(--rl-n-900); color: var(--rl-n-0); font-size: 12px; line-height: 1.4; box-shadow: var(--shadow-lift); }

:root { --hl-chart: var(--rl-i-500); }
:root[data-theme="dark"] { --hl-chart: var(--rl-i-300); }
:root[data-theme="dark"] .hl-tip { background: var(--rl-n-100); color: var(--rl-n-900); }
:root[data-theme="dark"] .hl-cell[data-s="none"], :root[data-theme="dark"] .hl-legend i[data-s="none"] { background: var(--rl-line-strong); }

@media (max-width: 1100px) {
  .hl-grid-wide { grid-template-columns: 1fr; }
}
@media (max-width: 719px) {
  .hl-summary { flex-direction: column; align-items: stretch; }
  .hl-hero-top { flex-direction: column; align-items: stretch; }
  .hl-areas { grid-template-columns: 1fr; }
  .hl-grid { grid-template-columns: 1fr; }
  .hl-db-grid { grid-template-columns: 1fr; gap: 0; }
  .hl-heat-row { grid-template-columns: 1fr; gap: 2px; }
  .hl-inc-list li { grid-template-columns: 1fr auto; }
  .hl-inc-when { grid-column: 1 / -1; }
  /* The latency table keeps its sparkline readable on a phone: each row a
     small card — name, a full-width line, then the four figures in a row —
     instead of the generic one-label-per-line card (§16.2). */
  #app table.hl-lat tr { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px var(--rl-s-2); padding: var(--rl-s-2) var(--rl-s-3); }
  #app table.hl-lat td { display: block; padding: 0; }
  #app table.hl-lat td.hl-lat-name, #app table.hl-lat td.hl-lat-spark { grid-column: 1 / -1; width: auto; min-width: 0; }
  #app table.hl-lat td.hl-lat-name { margin-bottom: 0; font-size: 13px; }
  #app table.hl-lat td.hl-lat-spark::before { display: none; }
  #app table.hl-lat td.num::before { display: block; width: auto; font-family: var(--rl-font-sans); font-size: 11px; }
  #app table.hl-lat tr.hl-lat-group { display: block; border: 0; background: none; padding: var(--rl-s-3) 0 var(--rl-s-1); margin: 0; }
  #app table.hl-lat tr.hl-lat-group td { font-size: 12px; }
}

/* =========================================================================
   FINANCE → INVOICES (js/finance.js, 2026-10-01)
   ========================================================================= */
#app .fin-head { display: flex; align-items: center; gap: var(--rl-s-2); flex-wrap: wrap; margin-bottom: var(--rl-s-4); }
#app .fin-head .rl-seg[hidden], #app [data-fin-mode][hidden] { display: none; }
#app .fin-head .rl-seg button { min-height: 32px; }
@media (max-width: 719px) { #app .fin-head .rl-seg button { min-height: 44px; } }

/* Five figures: one row on a wide screen, then the same fall-back as grid-4. */
#app .grid.grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); margin-bottom: var(--rl-s-6); }
@media (min-width: 1100px) {
  #app .grid.grid-5:has(> .card.stat-card) { gap: 0; }
  #app .grid.grid-5 > .card.stat-card { padding-right: var(--rl-s-6); }
  #app .grid.grid-5 > .card.stat-card + .card.stat-card { border-left: 1px solid var(--rl-line-soft); padding-left: var(--rl-s-6); }
}
@media (max-width: 1099px) { #app .grid.grid-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { #app .grid.grid-5 { grid-template-columns: 1fr; } }

/* The aging cards are buttons now: each filters the list to its band. */
#app button.aging-card { font: inherit; color: inherit; cursor: pointer; width: 100%; }
#app button.aging-card:focus-visible { outline: none; box-shadow: var(--rl-focus-inset, var(--rl-focus)); }
#app .aging-card.is-on { background: var(--rl-tint-accent-bg); }
#app .aging-card.is-on span { color: var(--rl-text-accent); font-weight: 500; }

#app .fin-sub { font-size: 11.5px; color: var(--rl-text-3); line-height: 1.35; }
#app .fin-sub.is-late { color: var(--rl-text-danger, var(--rl-tint-red-fg)); }
#app #tblInvoicingMain td:nth-child(7), #app #tblInvoicingMain th:nth-child(7) { white-space: nowrap; }

/* The row's ⋯ menu button, and the shared menu it opens. */
#app .rl-rowmenu-btn { width: 32px; padding: 0; justify-content: center; }
.rl-rowmenu { min-width: 220px; z-index: 80; }
.rl-menu-item.is-danger { color: var(--rl-text-danger, var(--rl-tint-red-fg)); }

/* Bulk confirmation dialogs (outside #app). */
.fin-bulk-intro { font-size: 13px; color: var(--rl-text-2); margin: 0 0 12px; line-height: 1.5; }
.fin-bulk-warn { font-size: 12.5px; color: var(--rl-text-danger, var(--rl-tint-red-fg)); margin: 0 0 12px; }
.fin-bulk-more { font-size: 12.5px; color: var(--rl-text-3); margin: 8px 0 12px; }
.fin-bulk-list {
  max-height: 280px; overflow-y: auto; border: 1px solid var(--rl-line); border-radius: var(--rl-r-sm);
  font-size: 12.5px;
}
.fin-bulk-row {
  display: grid; grid-template-columns: minmax(90px, 1fr) minmax(70px, auto) minmax(0, 2fr); gap: 12px;
  padding: 7px 10px; border-top: 1px solid var(--rl-line-soft);
}
.fin-bulk-row:first-child { border-top: 0; }
.fin-bulk-row span:last-child { color: var(--rl-text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rc-stages input[type="checkbox"] { width: 16px; height: 16px; flex: none; margin: 0; }
#app .fin-ladder { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
#app .fin-ladder .al-now { flex-basis: 100%; }
#app #tblArrears td:nth-child(8) { min-width: 170px; }

/* Arrears emails (2026-10-01): the automation card and the log. */
#app .fin-auto { padding: var(--rl-s-4) var(--rl-s-5); margin-bottom: var(--rl-s-4); }
#app .fin-auto.is-on { box-shadow: inset 3px 0 var(--rl-g-500); }
#app .fin-auto-head { display: flex; gap: var(--rl-s-5); align-items: flex-start; justify-content: space-between; }
#app .fin-auto-head h3 { margin: 0 0 4px; font-size: 15px; }
#app .fin-auto-head p { margin: 0; font-size: 13px; color: var(--rl-text-2); line-height: 1.5; max-width: 760px; }
#app .fin-auto-switch { display: flex; align-items: center; gap: var(--rl-s-2); flex: none; }
#app .fin-auto-next { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rl-s-2) var(--rl-s-5);
  margin-top: var(--rl-s-4); padding-top: var(--rl-s-3); border-top: 1px solid var(--rl-line-soft); font-size: 13px; color: var(--rl-text-2); }
#app .fin-auto-next b { color: var(--rl-text); font-variant-numeric: tabular-nums; }
#app .fin-auto-last { margin: var(--rl-s-3) 0 0; font-size: 12.5px; color: var(--rl-text-3); }
#app .fin-paused { flex-basis: 100%; font-size: 11.5px; color: var(--rl-tint-amber-fg); }
#app .fin-when { white-space: nowrap; }
#app .fin-what { display: inline-block; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
@media (max-width: 719px) { #app .fin-auto-head { flex-direction: column; } #app .fin-what { max-width: 100%; white-space: normal; } }
.fin-q-h { font-size: 13px; margin: 14px 0 6px; } .fin-q-h span { color: var(--rl-text-3); font-weight: 400; }
.fin-mail { border: 1px solid var(--rl-line); border-radius: var(--rl-r-sm); padding: 12px 14px; margin-top: 12px; background: var(--rl-surface); }
.fin-mail-meta { font-size: 12px; color: var(--rl-text-3); }
.fin-mail-subj { font-weight: 600; margin: 4px 0 10px; }
.fin-mail-body { white-space: pre-wrap; font-size: 13px; line-height: 1.55; color: var(--rl-text); }

/* ---------------------------------------------------------------------
   Instagram reels (Website → Instagram reels). Rows reuse the offer row
   (.so-row); the thumbnail is portrait, like the reel. The editor puts the
   video beside its fields, the cover underneath it.
   --------------------------------------------------------------------- */
#app .so-thumb.sr-thumb { width: 54px; aspect-ratio: 9 / 16; }
@media (max-width: 719px) {
  #app .so-row:has(.sr-thumb) .so-main { flex-basis: calc(100% - 54px - var(--rl-s-3)); }
  #app .so-row:has(.sr-thumb) .so-status { margin-left: calc(54px + var(--rl-s-3)); }
}
.sr-form { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: var(--rl-s-4) var(--rl-s-5); align-items: start; }
.sr-media { display: grid; gap: var(--rl-s-3); }
.sr-stage {
  width: 240px; aspect-ratio: 9 / 16; border-radius: var(--rl-r-md); overflow: hidden;
  background: var(--rl-surface-sunk); border: 1px dashed var(--rl-line-strong);
  display: grid; place-items: center; text-align: center;
}
.sr-stage span { font-size: 12px; line-height: 1.5; color: var(--rl-text-3); padding: var(--rl-s-3); }
.sr-stage video { width: 100%; height: 100%; object-fit: cover; background: #000; display: block; }
.sr-media-actions { display: flex; flex-wrap: wrap; gap: var(--rl-s-2); }
.sr-media-actions label.btn { cursor: pointer; }
.sr-cover-row { display: flex; gap: var(--rl-s-3); align-items: center; }
.sr-cover { flex: none; width: 54px; aspect-ratio: 9 / 16; border-radius: var(--rl-r-sm); overflow: hidden; background: var(--rl-surface-sunk); }
.sr-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sr-cover-row .so-hint { margin: 0; }
.sr-actions { grid-column: 1 / -1; }
@media (max-width: 719px) {
  .sr-form { grid-template-columns: 1fr; }
  .sr-stage { width: min(240px, 100%); justify-self: center; }
}

/* Appointment availability editor (2026-10-04): the booking window was a
   column of stretched radio buttons; now one select + its input, and the
   week is a compact Monday-first grid. */
.atpl-win { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rl-s-2); }
.modal-box .atpl-win select, .modal-box .atpl-win input { width: auto; flex: none; }
.modal-box .atpl-win .atpl-num { width: 84px; }
.atpl-to { font-size: 12.5px; color: var(--rl-text-3); }
.atpl-week { border: 1px solid var(--rl-line); border-radius: var(--rl-r-md); overflow: hidden; }
.atpl-day { display: grid; grid-template-columns: 96px minmax(0, 1fr) auto; gap: var(--rl-s-3); align-items: center;
  padding: var(--rl-s-2) var(--rl-s-3); border-top: 1px solid var(--rl-line-soft); min-height: 48px; }
.atpl-day:first-child { border-top: 0; }
.atpl-day.is-off { background: var(--rl-surface-sunk); }
.atpl-day-name { font-size: 13px; font-weight: 600; }
.atpl-day.is-off .atpl-day-name { color: var(--rl-text-3); font-weight: 500; }
.atpl-ranges { display: flex; flex-wrap: wrap; gap: var(--rl-s-2); min-width: 0; }
.atpl-range { display: inline-flex; align-items: center; gap: var(--rl-s-1); padding: 2px 2px 2px var(--rl-s-1);
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-sm); background: var(--rl-surface); }
.modal-box .atpl-range input[type="time"] { width: auto; border: 0; padding: 4px; min-height: 32px; background: transparent; }
.atpl-x { border: 0; background: none; color: var(--rl-text-3); font-size: 18px; line-height: 1; width: 32px; height: 32px;
  border-radius: var(--rl-r-sm); cursor: pointer; }
.atpl-x:hover { background: var(--rl-tint-red-bg); color: var(--rl-text-danger); }
.atpl-x:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
.atpl-off { font-size: 12.5px; color: var(--rl-text-3); }
.atpl-day-actions { display: flex; gap: var(--rl-s-1); white-space: nowrap; }
.atpl-active { display: flex; align-items: center; gap: var(--rl-s-2); margin-top: var(--rl-s-3); font-size: 13px; }
.modal-box .atpl-active input { width: auto; }
@media (max-width: 719px) {
  .atpl-day { grid-template-columns: 1fr auto; }
  .atpl-ranges { grid-column: 1 / -1; grid-row: 2; }
}

/* =========================================================================
   MY DASHBOARDS (2026-10-06, js/my-dashboard.js)

   The bar above Today chooses between the estate and the dashboards this
   person has built. A dashboard is a four-column grid of widgets in 112px
   rows; each widget spans 1–4 columns and 1–6 rows, packed densely so a
   quarter-width tile drops into the gap a half-width chart leaves. Every
   widget is the same card — header, body — so a board of twelve different
   things still reads as one surface.
   ========================================================================= */
#app .mdb-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--rl-s-3); flex-wrap: wrap;
  margin: 0 0 var(--rl-s-4);
  border-bottom: 1px solid var(--rl-line);
}
#app .mdb-tabs {
  display: flex; align-items: stretch; gap: var(--rl-s-1);
  min-width: 0; max-width: 100%;
  overflow-x: auto; scrollbar-width: none;
}
#app .mdb-tabs::-webkit-scrollbar { display: none; }
#app .mdb-tab {
  display: inline-flex; align-items: center; gap: 6px;
  padding: var(--rl-s-2) var(--rl-s-3); margin-bottom: -1px;
  border: 0; border-bottom: 2px solid transparent; background: none;
  font: inherit; font-size: 13.5px; font-weight: 500; white-space: nowrap;
  color: var(--rl-text-2); cursor: pointer;
  transition: color var(--rl-d-fast) var(--rl-ease-standard), border-color var(--rl-d-fast) var(--rl-ease-standard);
}
#app .mdb-tab:hover { color: var(--rl-text); }
#app .mdb-tab[aria-selected="true"] { color: var(--rl-text); border-bottom-color: var(--rl-i-600); }
#app .mdb-tab:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); border-radius: var(--rl-r-sm); }
#app .mdb-tab-new { color: var(--rl-text-3); }
#app .mdb-tab-new:hover { color: var(--rl-text-accent); }
#app .mdb-home { display: inline-flex; color: var(--rl-text-accent); }
#app .mdb-ico { width: 15px; height: 15px; flex: none; }
#app .mdb-home .mdb-ico { width: 13px; height: 13px; }

#app .mdb-actions {
  display: flex; align-items: center; gap: var(--rl-s-2); flex-wrap: wrap;
  padding: 0 0 var(--rl-s-2);
}
#app .mdb-actions .btn { display: inline-flex; align-items: center; gap: 5px; }
#app .mdb-actions .btn .mdb-ico { width: 14px; height: 14px; }
#app .mdb-ishome {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12.5px; color: var(--rl-text-3); padding: 0 var(--rl-s-2);
}
#app .mdb-ishome .mdb-ico { width: 13px; height: 13px; color: var(--rl-text-accent); }
#app .mdb-site select { min-height: 32px; max-width: 200px; font-size: 13px; padding-right: var(--rl-s-6); }
#app .mdb-danger { color: var(--rl-text-danger); }

/* ---- the grid ---------------------------------------------------------- */
#app .mdb-board {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: 112px;
  grid-auto-flow: row dense;
  gap: var(--rl-s-3);
  margin: 0 0 var(--rl-s-8);
}
#app .mdb-board[hidden] { display: none; }
#app .mdb-w[data-w="2"] { grid-column: span 2; }
#app .mdb-w[data-w="3"] { grid-column: span 3; }
#app .mdb-w[data-w="4"] { grid-column: span 4; }
#app .mdb-w[data-h="2"] { grid-row: span 2; }
#app .mdb-w[data-h="3"] { grid-row: span 3; }
#app .mdb-w[data-h="4"] { grid-row: span 4; }
#app .mdb-w[data-h="5"] { grid-row: span 5; }
#app .mdb-w[data-h="6"] { grid-row: span 6; }
@media (max-width: 1100px) {
  #app .mdb-board { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #app .mdb-w[data-w="3"], #app .mdb-w[data-w="4"] { grid-column: span 2; }
}
/* A phone keeps two columns: number tiles pair up, everything wider
   than a quarter takes the full width. One tile per screen-width row
   made a twelve-widget board a long scroll of mostly empty cards. */
@media (max-width: 700px) {
  #app .mdb-board { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--rl-s-2); }
  #app .mdb-w[data-w="2"], #app .mdb-w[data-w="3"], #app .mdb-w[data-w="4"] { grid-column: span 2; }
  #app .mdb-w-head { padding-left: var(--rl-s-3); }
  #app .mdb-w-body { padding-left: var(--rl-s-3); padding-right: var(--rl-s-3); }
  #app .mdb-kpi { margin-left: calc(-1 * var(--rl-s-3)); margin-right: calc(-1 * var(--rl-s-3)); padding-left: var(--rl-s-3); padding-right: var(--rl-s-3); }
}

#app .mdb-w {
  position: relative; min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-lg);
  background: var(--rl-surface); box-shadow: var(--rl-e-1);
  overflow: hidden;
}
#app .mdb-w-head {
  display: flex; align-items: center; gap: var(--rl-s-2);
  min-height: 34px; padding: var(--rl-s-2) var(--rl-s-3) 0 var(--rl-s-4);
}
#app .mdb-w-title {
  flex: 1; min-width: 0; margin: 0;
  font-family: var(--rl-font-sans); font-size: 10.5px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--rl-text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#app .mdb-w-site {
  flex: none; padding: 1px 7px; border-radius: var(--rl-r-full);
  background: var(--rl-tint-accent-bg); color: var(--rl-text-accent);
  font-size: 11px; font-weight: 500; white-space: nowrap;
  max-width: 45%; overflow: hidden; text-overflow: ellipsis;
}
#app .mdb-w-body {
  flex: 1; min-height: 0; position: relative;
  display: flex; flex-direction: column;
  padding: var(--rl-s-1) var(--rl-s-4) var(--rl-s-3);
  container-type: inline-size;
}
#app .mdb-quiet { margin: auto 0; font-size: 13px; line-height: 1.45; color: var(--rl-text-3); }
#app .mdb-link {
  border: 0; background: none; padding: 0; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 500; color: var(--rl-text-accent);
}
#app .mdb-link:hover { text-decoration: underline; }

/* ---- a number ---------------------------------------------------------- */
#app .mdb-kpi {
  flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 3px;
  margin: 0 calc(-1 * var(--rl-s-4)) calc(-1 * var(--rl-s-3));
  padding: 0 var(--rl-s-4) var(--rl-s-3);
  border: 0; background: none; text-align: left; font: inherit; color: inherit; cursor: pointer;
  min-width: 0;
}
#app .mdb-kpi.is-static { cursor: default; }
#app .mdb-kpi:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); border-radius: var(--rl-r-lg); }
#app .mdb-kpi-v {
  font-family: var(--rl-font-mono); font-variant-numeric: tabular-nums;
  /* Sized to the card (the body is a size container), so £1,269,126
     still fits in a quarter-width tile on a phone. */
  font-size: min(28px, 15cqi); font-weight: 500; line-height: 1.05; color: var(--rl-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#app .mdb-w[data-h="2"] .mdb-kpi-v, #app .mdb-w[data-w="2"] .mdb-kpi-v { font-size: min(36px, 15cqi); }
#app .mdb-kpi[data-tone="bad"]  .mdb-kpi-v { color: var(--rl-text-danger); }
#app .mdb-kpi[data-tone="warn"] .mdb-kpi-v { color: var(--rl-text-warning); }
#app .mdb-kpi[data-tone="good"] .mdb-kpi-v { color: var(--rl-text-success); }
#app .mdb-kpi-foot {
  font-size: 12px; color: var(--rl-text-3); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#app .mdb-kpi-bar {
  display: block; height: 4px; margin-top: 5px;
  border-radius: var(--rl-r-full); background: var(--rl-surface-sunk); overflow: hidden;
}
#app .mdb-kpi-bar i { display: block; height: 100%; border-radius: inherit; background: var(--rl-i-600);
  transition: width var(--rl-d-slow) var(--rl-ease-standard); }
#app .mdb-kpi[data-tone="bad"]  .mdb-kpi-bar i { background: var(--rl-r-500); }
#app .mdb-kpi[data-tone="warn"] .mdb-kpi-bar i { background: var(--rl-a-500); }
#app .mdb-kpi[data-tone="good"] .mdb-kpi-bar i { background: var(--rl-g-500); }
#app .mdb-spark { display: block; height: 26px; margin-top: 4px; color: var(--rl-i-600); }
#app .mdb-kpi[data-tone="bad"]  .mdb-spark { color: var(--rl-r-500); }
#app .mdb-kpi[data-tone="warn"] .mdb-spark { color: var(--rl-a-500); }
#app .mdb-kpi[data-tone="good"] .mdb-spark { color: var(--rl-g-500); }
#app .mdb-spark svg { display: block; width: 100%; height: 100%; overflow: visible; }
#app .mdb-spark polyline { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
#app .mdb-spark polygon { fill: currentColor; opacity: .1; stroke: none; }

/* ---- charts ------------------------------------------------------------ */
#app .mdb-chart { position: relative; flex: 1; min-height: 0; }
#app .mdb-chart canvas { position: absolute; inset: 0; }
#app .mdb-chart-foot { flex: none; padding-top: var(--rl-s-2); font-size: 12px; color: var(--rl-text-3); }

/* ---- lists and tables -------------------------------------------------- */
#app .mdb-list-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--rl-s-1); }
#app .mdb-count { font-family: var(--rl-font-mono); font-size: 22px; font-weight: 500; color: var(--rl-text); line-height: 1.1; }
#app .mdb-list {
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  margin: 0 calc(-1 * var(--rl-s-2));
}
#app .mdb-row {
  width: 100%; display: flex; align-items: center; gap: var(--rl-s-2);
  padding: 7px var(--rl-s-2); border: 0; border-top: 1px solid var(--rl-line-soft);
  background: none; font: inherit; text-align: left; color: inherit; cursor: pointer;
  border-radius: var(--rl-r-sm);
  transition: background-color var(--rl-d-instant) var(--rl-ease-standard);
}
#app .mdb-row:first-child { border-top-color: transparent; }
#app .mdb-row:hover { background: var(--rl-surface-sunk); }
#app .mdb-row:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
#app .mdb-row-main { flex: 0 1 auto; min-width: 0; font-size: 13.5px; font-weight: 500; color: var(--rl-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#app .mdb-row-sub { flex: 1 1 0; min-width: 0; font-size: 12px; color: var(--rl-text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#app .mdb-row-tag {
  flex: none; margin-left: auto; padding: 1px 7px; border-radius: var(--rl-r-full);
  background: var(--rl-surface-sunk); color: var(--rl-text-2);
  font-size: 11.5px; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums;
}
#app .mdb-row-tag[data-tone="bad"]    { background: var(--rl-tint-red-bg);    color: var(--rl-tint-red-fg); }
#app .mdb-row-tag[data-tone="warn"]   { background: var(--rl-tint-amber-bg);  color: var(--rl-tint-amber-fg); }
#app .mdb-row-tag[data-tone="accent"] { background: var(--rl-tint-accent-bg); color: var(--rl-text-accent); }
#app .mdb-more { padding: var(--rl-s-2); font-size: 12px; color: var(--rl-text-3); }
#app .mdb-table-wrap { flex: 1; min-height: 0; overflow: auto; margin: 0 calc(-1 * var(--rl-s-2)); }
#app .mdb-table { width: 100%; border-collapse: collapse; font-size: 13px; }
#app .mdb-table th { position: sticky; top: 0; background: var(--rl-surface); text-align: left;
  font-size: 11px; font-weight: 600; color: var(--rl-text-3); padding: 6px var(--rl-s-2); border-bottom: 1px solid var(--rl-line); white-space: nowrap; }
#app .mdb-table td { padding: 6px var(--rl-s-2); border-bottom: 1px solid var(--rl-line-soft); color: var(--rl-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 240px; }
#app .mdb-table td.rl-num, #app .mdb-table td:last-child.rl-num { text-align: right; font-variant-numeric: tabular-nums; }
#app .mdb-table tfoot td { font-weight: 600; border-bottom: 0; }

/* ---- note and shortcuts ------------------------------------------------ */
#app .mdb-note { flex: 1; overflow-y: auto; font-size: 13.5px; line-height: 1.5; color: var(--rl-text); }
#app .mdb-note p { margin: 0 0 var(--rl-s-2); }
#app .mdb-w[data-type="note"]:has(.mdb-note[data-tone="accent"]) { background: var(--rl-tint-accent-bg); border-color: var(--rl-line-accent); }
#app .mdb-w[data-type="note"]:has(.mdb-note[data-tone="amber"])  { background: var(--rl-tint-amber-bg); }
#app .mdb-w[data-type="note"]:has(.mdb-note[data-tone="green"])  { background: var(--rl-tint-green-bg); }
#app .mdb-w[data-type="note"]:has(.mdb-note[data-tone="red"])    { background: var(--rl-tint-red-bg); }
#app .mdb-links { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; margin: 0 calc(-1 * var(--rl-s-2)); }
#app .mdb-shortcut {
  display: flex; align-items: center; justify-content: space-between; gap: var(--rl-s-2);
  padding: 7px var(--rl-s-2); border: 0; border-radius: var(--rl-r-sm); background: none;
  font: inherit; font-size: 13.5px; font-weight: 500; color: var(--rl-text); text-align: left; cursor: pointer;
}
#app .mdb-shortcut:hover { background: var(--rl-surface-sunk); color: var(--rl-text-accent); }
#app .mdb-shortcut .mdb-ico { color: var(--rl-text-3); }

/* ---- Today's own pieces, moved in ------------------------------------- */
#app .mdb-w-body.is-adopted { overflow-y: auto; overscroll-behavior: contain; }
#app .mdb-w-body.is-adopted > .today-sites { margin: 0; grid-template-columns: repeat(3, minmax(0, 1fr)); }
@container (max-width: 720px) { #app .mdb-w-body.is-adopted > .today-sites { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@container (max-width: 420px) { #app .mdb-w-body.is-adopted > .today-sites { grid-template-columns: minmax(0, 1fr); } }
#app .mdb-w-body.is-adopted > .today-portfolio { margin: 0; border: 0; border-radius: 0; background: none; }
#app .mdb-w[data-type="portfolio"] .mdb-w-body { padding: 0; justify-content: center; }
#app .mdb-w[data-type="portfolio"] .mdb-w-head { display: none; }
#app .mdb-w-body.is-adopted > .rl-year { margin: 0 var(--rl-s-2); }
#app .mdb-w-body.is-adopted > .rl-week { flex: 1; }

/* ---- empty, add, editing ---------------------------------------------- */
#app .mdb-empty {
  grid-column: 1 / -1; grid-row: span 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--rl-s-2);
  border: 1px dashed var(--rl-line-strong); border-radius: var(--rl-r-lg);
  text-align: center; padding: var(--rl-s-6); color: var(--rl-text-3); font-size: 13.5px;
}
#app .mdb-empty b { font-family: var(--rl-font-serif); font-weight: 400; font-size: 21px; color: var(--rl-text); }
#app .mdb-add {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--rl-s-1);
  border: 1px dashed var(--rl-line-strong); border-radius: var(--rl-r-lg);
  background: none; font: inherit; font-size: 13px; font-weight: 500; color: var(--rl-text-3); cursor: pointer;
  transition: color var(--rl-d-fast) var(--rl-ease-standard), border-color var(--rl-d-fast) var(--rl-ease-standard), background-color var(--rl-d-fast) var(--rl-ease-standard);
}
#app .mdb-add:hover { color: var(--rl-text-accent); border-color: var(--rl-i-600); background: var(--rl-tint-accent-bg); }
#app .mdb-add .mdb-ico { width: 20px; height: 20px; }

#app .mdb-board.is-editing .mdb-w { box-shadow: 0 0 0 1px var(--rl-line-strong); }
#app .mdb-board.is-editing .mdb-w-body { pointer-events: none; user-select: none; }
#app .mdb-board.is-editing .mdb-w-title { color: var(--rl-text-2); }
#app .mdb-grip {
  display: inline-flex; margin-left: calc(-1 * var(--rl-s-2));
  padding: 2px; border-radius: var(--rl-r-sm); color: var(--rl-text-3);
  cursor: grab; touch-action: none;
}
#app .mdb-grip:hover { background: var(--rl-surface-sunk); color: var(--rl-text); }
#app .mdb-board.is-sorting, #app .mdb-board.is-sorting * { cursor: grabbing !important; }
#app .mdb-w-tools { display: inline-flex; gap: 1px; flex: none; }
/* With a mouse the tools wait for the pointer, so a quarter-width tile in
   edit mode still shows its title; on touch there is no hover, so they stay. */
@media (hover: hover) {
  #app .mdb-w-tools {
    position: absolute; top: 5px; right: 6px; z-index: 2;
    padding: 1px; border-radius: var(--rl-r-md);
    background: var(--rl-surface-raised); box-shadow: var(--rl-e-2);
    opacity: 0; transform: translateY(-2px); pointer-events: none;
    transition: opacity var(--rl-d-fast) var(--rl-ease-standard), transform var(--rl-d-fast) var(--rl-ease-standard);
  }
  #app .mdb-w:hover .mdb-w-tools, #app .mdb-w:focus-within .mdb-w-tools { opacity: 1; transform: none; pointer-events: auto; }
  #app .mdb-w.is-dragging .mdb-w-tools { opacity: 0; }
}
#app .mdb-tool {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border: 0; border-radius: var(--rl-r-sm);
  background: none; color: var(--rl-text-3); cursor: pointer;
}
#app .mdb-tool:hover { background: var(--rl-surface-sunk); color: var(--rl-text); }
#app .mdb-tool.is-danger:hover { background: var(--rl-tint-red-bg); color: var(--rl-text-danger); }
#app .mdb-tool:focus-visible { outline: none; box-shadow: var(--rl-focus); }
#app .mdb-resize {
  position: absolute; right: 0; bottom: 0; width: 18px; height: 18px;
  cursor: nwse-resize; touch-action: none;
  background:
    linear-gradient(135deg, transparent 50%, var(--rl-line-strong) 50%, var(--rl-line-strong) 58%, transparent 58%,
                    transparent 70%, var(--rl-line-strong) 70%, var(--rl-line-strong) 78%, transparent 78%);
}
#app .mdb-w.is-dragging {
  z-index: 3; opacity: .92; box-shadow: var(--rl-e-3); transform: scale(1.015);
  pointer-events: none;
}
#app .mdb-w.is-resizing { z-index: 3; box-shadow: 0 0 0 2px var(--rl-i-600), var(--rl-e-2); }
@media (max-width: 700px) { #app .mdb-resize { display: none; } }

/* A board arrives once — on opening it, not on every realtime redraw. */
@keyframes mdb-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
#app .mdb-board.mdb-enter > * { animation: mdb-in var(--rl-d-mid) var(--rl-ease-enter) backwards; }
#app .mdb-board.mdb-enter > :nth-child(2) { animation-delay: calc(var(--rl-d-instant) * .3); }
#app .mdb-board.mdb-enter > :nth-child(3) { animation-delay: calc(var(--rl-d-instant) * .6); }
#app .mdb-board.mdb-enter > :nth-child(4) { animation-delay: calc(var(--rl-d-instant) * .9); }
#app .mdb-board.mdb-enter > :nth-child(5) { animation-delay: calc(var(--rl-d-instant) * 1.2); }
#app .mdb-board.mdb-enter > :nth-child(6) { animation-delay: calc(var(--rl-d-instant) * 1.5); }
#app .mdb-board.mdb-enter > :nth-child(n+7) { animation-delay: calc(var(--rl-d-instant) * 1.8); }
@keyframes mdb-new { from { box-shadow: 0 0 0 2px var(--rl-i-600), var(--rl-e-2); } to { box-shadow: 0 0 0 1px var(--rl-line-strong); } }
#app .mdb-w.is-new { animation: mdb-new var(--rl-d-long) var(--rl-ease-standard); }

/* ---- the dialogs (outside #app, so unprefixed) ------------------------ */
#appModal.wide .modal-box:has(.mdb-gallery) { max-width: 880px; }
.mdb-gallery { display: flex; flex-direction: column; gap: var(--rl-s-3); }
.mdb-gallery-search { width: 100%; min-height: 38px; padding: 0 var(--rl-s-3);
  border: 1px solid var(--rl-line-control); border-radius: var(--rl-r-sm);
  background: var(--rl-surface); color: var(--rl-text); font: inherit; font-size: 14.5px; }
.mdb-gallery-search:focus { outline: none; border-color: var(--rl-i-600); box-shadow: var(--rl-focus); }
.mdb-gallery-cats { display: flex; gap: var(--rl-s-1); flex-wrap: wrap; }
.mdb-gcat {
  padding: 5px var(--rl-s-3); border: 1px solid var(--rl-line); border-radius: var(--rl-r-full);
  background: var(--rl-surface); font: inherit; font-size: 12.5px; font-weight: 500; color: var(--rl-text-2); cursor: pointer;
}
.mdb-gcat:hover { border-color: var(--rl-line-strong); color: var(--rl-text); }
.mdb-gcat[aria-selected="true"] { background: var(--rl-i-600); border-color: var(--rl-i-600); color: var(--rl-text-invert); }
.mdb-gallery-list { max-height: min(56vh, 520px); overflow-y: auto; overscroll-behavior: contain; padding-right: 2px; }
.mdb-gsub { margin: var(--rl-s-4) 0 var(--rl-s-2); font-size: 10.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--rl-text-3); }
.mdb-gsub:first-child { margin-top: 0; }
.mdb-gcards { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: var(--rl-s-2); }
.mdb-gcard {
  display: flex; align-items: center; gap: var(--rl-s-3); min-width: 0;
  padding: var(--rl-s-2) var(--rl-s-3); border: 1px solid var(--rl-line); border-radius: var(--rl-r-md);
  background: var(--rl-surface); font: inherit; text-align: left; color: var(--rl-text); cursor: pointer;
  transition: border-color var(--rl-d-fast) var(--rl-ease-standard), box-shadow var(--rl-d-fast) var(--rl-ease-standard), transform var(--rl-d-fast) var(--rl-ease-standard);
}
.mdb-gcard:hover:not(:disabled) { border-color: var(--rl-i-600); box-shadow: var(--rl-e-2); transform: translateY(-1px); }
.mdb-gcard:active:not(:disabled) { transform: scale(.985); transition-duration: var(--rl-d-instant); }
.mdb-gcard:focus-visible { outline: none; box-shadow: var(--rl-focus); }
.mdb-gcard:disabled { opacity: .5; cursor: default; }
.mdb-gicon { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: var(--rl-r-md); background: var(--rl-tint-accent-bg); color: var(--rl-text-accent); }
.mdb-gicon .mdb-ico { width: 17px; height: 17px; }
.mdb-gtext { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mdb-gtext b { font-size: 13.5px; font-weight: 500; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.mdb-gtext span { font-size: 12px; color: var(--rl-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mdb-gval { flex: none; font-family: var(--rl-font-mono); font-size: 13.5px; color: var(--rl-text-2); font-variant-numeric: tabular-nums; }
.mdb-ico { width: 15px; height: 15px; flex: none; }

.mdb-form label { display: block; font-size: 12.5px; font-weight: 500; color: var(--rl-text-2); margin-bottom: 5px; text-transform: none; letter-spacing: .005em; }
.mdb-form select, .mdb-form input, .mdb-form textarea { width: 100%; }
.mdb-form .mdb-f-wide { grid-column: 1 / -1; }
.mdb-form .mdb-f-end { align-self: end; min-height: 36px; }
.mdb-form label.mdb-check, .mdb-check { display: flex; align-items: center; gap: var(--rl-s-2); font-size: 13.5px; color: var(--rl-text); margin: 0; }
.mdb-form .mdb-check input, .mdb-check input { width: auto; min-height: 0; }
.mdb-hint { margin: 0; font-size: 12.5px; color: var(--rl-text-3); }
.modal-box > .mdb-hint { margin-bottom: var(--rl-s-3); }
.mdb-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 6px var(--rl-s-3);
  max-height: 260px; overflow-y: auto; padding: var(--rl-s-2); border: 1px solid var(--rl-line); border-radius: var(--rl-r-md); }
.mdb-block { margin-bottom: var(--rl-s-4); }
.mdb-label { display: block; font-size: 12.5px; font-weight: 500; color: var(--rl-text-2); margin-bottom: 6px; }
.mdb-templates { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--rl-s-2); }
.mdb-template { position: relative; display: block; cursor: pointer; }
.mdb-template input { position: absolute; opacity: 0; pointer-events: none; }
.mdb-template-body {
  display: flex; flex-direction: column; gap: 3px; height: 100%;
  padding: var(--rl-s-3); border: 1px solid var(--rl-line); border-radius: var(--rl-r-md); background: var(--rl-surface);
  transition: border-color var(--rl-d-fast) var(--rl-ease-standard), box-shadow var(--rl-d-fast) var(--rl-ease-standard);
}
.mdb-template-body b { font-size: 13.5px; font-weight: 600; color: var(--rl-text); }
.mdb-template-body span { font-size: 12px; line-height: 1.4; color: var(--rl-text-3); }
.mdb-template:hover .mdb-template-body { border-color: var(--rl-line-strong); }
.mdb-template input:checked + .mdb-template-body { border-color: var(--rl-i-600); box-shadow: 0 0 0 1px var(--rl-i-600); background: var(--rl-tint-accent-bg); }
.mdb-template input:focus-visible + .mdb-template-body { box-shadow: var(--rl-focus); }
@media (max-width: 719px) { .mdb-form.form-grid { grid-template-columns: minmax(0, 1fr); } }

/* ---- second pass, 2026-10-06: dates, comparisons, team, live feeds ---- */
/* The figure never gives way to its comparison: on a narrow tile the
   comparison drops to its own line instead. */
#app .mdb-kpi-row { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--rl-s-2); row-gap: 0; min-width: 0; }
#app .mdb-kpi-row .mdb-kpi-v { flex: none; max-width: 100%; }
#app .mdb-delta {
  flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--rl-text-3);
}
#app .mdb-delta span { font-weight: 400; color: var(--rl-text-3); }
#app .mdb-delta[data-tone="good"] { color: var(--rl-text-success); }
#app .mdb-delta[data-tone="bad"]  { color: var(--rl-text-danger); }
#app .mdb-kpi.is-alerting { box-shadow: inset 0 0 0 2px var(--rl-r-500); border-radius: var(--rl-r-lg); }
#app .mdb-w:has(.mdb-kpi.is-alerting) { border-color: var(--rl-line-danger); }
#app .mdb-w-bell { display: inline-flex; color: var(--rl-text-3); }
#app .mdb-w-bell .mdb-ico { width: 13px; height: 13px; }
#app .mdb-team-chip { display: inline-flex; color: var(--rl-text-3); }
#app .mdb-team-chip .mdb-ico { width: 13px; height: 13px; }
#app .mdb-tab[aria-selected="true"] .mdb-team-chip { color: var(--rl-text-accent); }
#app .mdb-pace-ahead { color: var(--rl-text-success); }
#app .mdb-pace-behind { color: var(--rl-text-danger); }
#app .mdb-table tr.is-link { cursor: pointer; }
#app .mdb-table tr.is-link:hover td { background: var(--rl-surface-sunk); }
#app .mdb-list-day {
  position: sticky; top: 0; z-index: 1;
  padding: var(--rl-s-2) var(--rl-s-2) var(--rl-s-1); background: var(--rl-surface);
  font-size: 10.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--rl-text-3);
}
#app .mdb-dot, #appModal .mdb-dot { flex: none; width: 8px; height: 8px; border-radius: var(--rl-r-full); background: var(--rl-i-600); }
#app .mdb-dot[data-tone="good"] { background: var(--rl-g-500); }
#app .mdb-dot[data-tone="warn"] { background: var(--rl-a-500); }
#app .mdb-dot[data-tone="bad"]  { background: var(--rl-r-500); }

/* The "more" menu. */
#app .mdb-more { position: relative; display: inline-flex; }
#app .mdb-more-btn { padding-left: var(--rl-s-2); padding-right: var(--rl-s-2); }
#app .mdb-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; min-width: 240px;
  display: flex; flex-direction: column; padding: var(--rl-s-1);
  background: var(--rl-surface-raised); border: 1px solid var(--rl-line); border-radius: var(--rl-r-md); box-shadow: var(--rl-e-3);
}
#app .mdb-menu[hidden] { display: none; }
#app .mdb-menu-item {
  display: flex; align-items: center; gap: var(--rl-s-2); padding: 8px var(--rl-s-3);
  border: 0; border-radius: var(--rl-r-sm); background: none; font: inherit; font-size: 13.5px; color: var(--rl-text); text-align: left; cursor: pointer;
}
#app .mdb-menu-item .mdb-ico { color: var(--rl-text-3); }
#app .mdb-menu-item:hover, #app .mdb-menu-item:focus-visible { outline: none; background: var(--rl-surface-sunk); }
#app .mdb-menu-item.is-danger { color: var(--rl-text-danger); }
#app .mdb-menu-item.is-danger .mdb-ico { color: currentColor; }
#app .mdb-menu-sep { height: 1px; margin: var(--rl-s-1) 0; background: var(--rl-line-soft); }

/* The map. */
#app .mdb-map { position: relative; isolation: isolate; z-index: 0; flex: 1; min-height: 0; border-radius: var(--rl-r-md); overflow: hidden; background: var(--rl-surface-sunk); }
#app .mdb-map .mdb-quiet { padding: var(--rl-s-4); }
#app .mdb-map .leaflet-tooltip { font-family: var(--rl-font-sans); font-size: 12px; }
/* The tiles are light; in dark mode they are inverted rather than swapped
   for a second tile service. Markers sit above the tile pane, untouched. */
#app .mdb-map .leaflet-tile-pane { filter: saturate(.55); }
[data-theme="dark"] #app .mdb-map .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(.85) contrast(.9) saturate(.55); }
#app .mdb-map-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
#app .mdb-map-key { flex: none; }
#app .mdb-board.is-editing .mdb-map { filter: saturate(.6); }

/* The click-through dialog (outside #app). */
#appModal .mdb-drill-list { max-height: min(60vh, 520px); overflow-y: auto; margin: 0 calc(-1 * var(--rl-s-2)); }
#appModal .mdb-row {
  width: 100%; display: flex; align-items: center; gap: var(--rl-s-2);
  padding: 8px var(--rl-s-2); border: 0; border-top: 1px solid var(--rl-line-soft);
  background: none; font: inherit; text-align: left; color: var(--rl-text); cursor: pointer; border-radius: var(--rl-r-sm);
}
#appModal .mdb-row:first-child { border-top-color: transparent; }
#appModal .mdb-row:hover:not(:disabled) { background: var(--rl-surface-sunk); }
#appModal .mdb-row:disabled { cursor: default; opacity: 1; }
#appModal .mdb-row-main { flex: 0 1 auto; min-width: 0; font-size: 13.5px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#appModal .mdb-row-sub { flex: 1 1 0; min-width: 0; font-size: 12px; color: var(--rl-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#appModal .mdb-row-tag {
  flex: none; margin-left: auto; padding: 1px 7px; border-radius: var(--rl-r-full);
  background: var(--rl-surface-sunk); color: var(--rl-text-2); font-size: 11.5px; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums;
}
#appModal .mdb-row-tag[data-tone="bad"]    { background: var(--rl-tint-red-bg);    color: var(--rl-tint-red-fg); }
#appModal .mdb-row-tag[data-tone="warn"]   { background: var(--rl-tint-amber-bg);  color: var(--rl-tint-amber-fg); }
#appModal .mdb-row-tag[data-tone="accent"] { background: var(--rl-tint-accent-bg); color: var(--rl-text-accent); }

/* ---- the office screen ---------------------------------------------- */
body.mdb-tv #rlTop, body.mdb-tv #rlTabbar, body.mdb-tv #rlSubNav, body.mdb-tv .rl-crumbs,
body.mdb-tv #view-dashboard > .view-title, body.mdb-tv #todayGreeting, body.mdb-tv #todayLabel,
body.mdb-tv #app .mdb-bar { display: none !important; }
body.mdb-tv #view-dashboard { padding-top: 64px; }
body.mdb-tv #app .mdb-board { grid-auto-rows: 128px; gap: var(--rl-s-4); }
body.mdb-tv #app .mdb-kpi-v { font-size: min(44px, 14cqi); }
body.mdb-tv #app .mdb-w-title { font-size: 12px; }
.mdb-tv-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  display: flex; align-items: center; gap: var(--rl-s-4);
  padding: var(--rl-s-3) var(--rl-s-6);
  background: var(--rl-canvas); border-bottom: 1px solid var(--rl-line);
  color: var(--rl-text);
}
.mdb-tv-bar b { font-family: var(--rl-font-serif); font-weight: 400; font-size: 22px; }
.mdb-tv-date { color: var(--rl-text-2); font-size: 14px; }
.mdb-tv-clock { margin-left: auto; font-family: var(--rl-font-mono); font-size: 26px; font-variant-numeric: tabular-nums; }
.mdb-tv-tools { display: flex; align-items: center; gap: var(--rl-s-2); opacity: .35; transition: opacity var(--rl-d-fast) var(--rl-ease-standard); }
.mdb-tv-bar:hover .mdb-tv-tools, .mdb-tv-tools:focus-within { opacity: 1; }
.mdb-tv-tools .mdb-tool { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border: 0; border-radius: var(--rl-r-sm); background: none; color: var(--rl-text-2); cursor: pointer; }
.mdb-tv-tools .mdb-tool:hover { background: var(--rl-surface-sunk); color: var(--rl-text); }
.mdb-tv-tools .mdb-check { font-size: 13px; color: var(--rl-text-2); }

/* ---- print / PDF ------------------------------------------------------ */
@media print {
  @page { size: A4 landscape; margin: 10mm; }
  body { background: var(--rl-n-0) !important; }
  #rlTop, #rlTabbar, #rlSubNav, .rl-crumbs, .rl-toasts, #appModal, .mdb-tv-bar,
  #view-dashboard > .view-title, #todayLabel, #app .mdb-bar, #app .mdb-add, #app .mdb-resize, #app .mdb-w-tools, #app .mdb-grip { display: none !important; }
  #app, #app .rl-frame, #app .rl-scroll, #app .rl-content, #app main.content { display: block !important; height: auto !important; max-height: none !important; overflow: visible !important; }
  #app .mdb-board { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; grid-auto-rows: 96px; gap: 8px; }
  #app .mdb-w[data-w="2"] { grid-column: span 2 !important; }
  #app .mdb-w[data-w="3"] { grid-column: span 3 !important; }
  #app .mdb-w[data-w="4"] { grid-column: span 4 !important; }
  #app .mdb-w { box-shadow: none !important; break-inside: avoid; }
  #app .mdb-list, #app .mdb-table-wrap { overflow: hidden !important; }
}

/* The KPI strip at the top of each section is retired. One rule hides every
   copy, the static ones in app.html and those finance/refunds/short-stays/…
   render, while the ids they write into stay in the DOM. */
#app .grid:has(> .stat-card) { display: none; }

/* =========================================================================
   FINANCE → RECONCILIATION (js/reconciliation.js, 2026-10-09)
   ========================================================================= */
#app .recon-amt { font-family: var(--rl-font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
#app .recon-amt.is-in { color: var(--rl-text-success, var(--rl-tint-green-fg)); }
#app .recon-amt.is-out { color: var(--rl-text); }
#app table.p360-tbl tfoot td { border-top: 1px solid var(--rl-line); border-bottom: 0; font-weight: 600; }
/* The dialog sits outside #app. */
.recon-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 12px; }
@media (max-width: 560px) { .recon-grid { grid-template-columns: 1fr; } }
.recon-opt { font-weight: 400; color: var(--rl-text-3); }
.recon-hint { font-size: 12px; color: var(--rl-text-3); margin-top: 4px; }
.recon-check { display: flex; align-items: center; gap: 8px; font-size: 13px; margin: 4px 0 8px; }
.recon-check input { width: 16px; height: 16px; min-height: 0; }
.fin-bulk-warn:empty { display: none; }

/* Viewings calendar (js/viewings.js renderViewingCalendar): one site, one
   week, one row per slot. The grid scrolls sideways inside its card on a
   phone; the page itself never does. */
.vc-wrap { overflow-x: auto; }
.vc-grid { width: 100%; min-width: 760px; border-collapse: collapse; table-layout: fixed; font-size: 12.5px; }
.vc-grid th, .vc-grid td { border: 1px solid var(--line); padding: 4px; vertical-align: top; }
.vc-grid thead th { font-weight: 600; background: var(--rl-surface-sunk); text-align: left; }
.vc-grid tbody th { width: 56px; font-weight: 600; color: var(--ink-soft); white-space: nowrap; }
.vc-grid th.vc-today { color: var(--rl-tint-accent-fg); background: var(--rl-tint-accent-bg); }
.vc-closed { font-weight: 400; color: var(--ink-soft); font-size: 11.5px; }
.vc-off { background: var(--rl-surface-sunk); }
.vc-free { color: var(--ink-soft); font-size: 11.5px; }
.vc-book { display: flex; flex-direction: column; gap: 3px; padding: 5px 6px; border-radius: 6px; cursor: pointer; border-left: 3px solid; }
.vc-book b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vc-book span { color: var(--ink-soft); }
.vc-inperson { background: var(--rl-tint-green-bg); border-left-color: var(--rl-tint-green-fg); }
.vc-virtual { background: var(--rl-tint-accent-bg); border-left-color: var(--rl-tint-accent-fg); }
.vc-book:focus-visible { outline: 2px solid var(--rl-tint-accent-fg); outline-offset: 1px; }
.vc-book .btn { align-self: flex-start; white-space: nowrap; }

/* =========================================================================
   OCCUPANCY — A STAY IS COLOURED BY ITS BOOKING STAGE (2026-10-12, Tejas).
   The class is st-<key> from rlBookingState() (booking-state.js), and each
   stage wears the tone its chip wears on the 360 record, so a colour means
   the same thing on both screens. Two stages share a hue with a room
   state, and the treatment tells them apart:
     Held (amber) is DASHED — not committed yet; Maintenance is a solid fill.
     History debtor (red) is the quiet past-stay fill with a red edge and
     red text; Blocked is a full red fill.
   Tentative and Held only appear if a resident row exists before the
   booking is paid; the legend carries them so the vocabulary is whole.
   The legend swatches (.cal-sw) share these rules with the bars.
   ========================================================================= */
.cal-sw {
  width: 18px; height: 10px; border-radius: var(--rl-r-xs);
  display: inline-block; border: 1px solid transparent; flex: none;
}
.cal-sw.inspect { background: var(--rl-room-turn-fill); border-color: var(--rl-room-turn-line); }
.cal-sw.issue   { background: var(--rl-room-oos-fill);  border-color: var(--rl-room-oos-line); }
/* Blocked carries the out-of-service hatch, so it never reads as the
   red-edged History debtor next to it. */
.cal-bar.issue, .cal-sw.issue {
  background: var(--rl-room-oos-fill); border-color: var(--rl-r-500); color: var(--rl-room-oos-text);
  background-image: repeating-linear-gradient(135deg, transparent 0 6px, color-mix(in srgb, var(--rl-r-500) 18%, transparent) 6px 8px);
}

.cal-bar.st-tentative, .cal-sw.st-tentative {
  background: transparent; border: 1px dashed var(--rl-line-strong); color: var(--rl-text-2);
}
.cal-bar.st-held, .cal-sw.st-held {
  background: var(--rl-stage-held-fill); border: 1px dashed var(--rl-stage-held-line); color: var(--rl-stage-held-text);
}
.cal-bar.st-reserved, .cal-sw.st-reserved {
  background: var(--rl-stage-reserved-fill); border-color: var(--rl-stage-reserved-line); color: var(--rl-stage-reserved-text);
}
.cal-bar.st-in_room, .cal-sw.st-in_room {
  background: var(--rl-stage-inroom-fill); border-color: var(--rl-stage-inroom-line); color: var(--rl-stage-inroom-text);
}
.cal-bar.st-history, .cal-sw.st-history,
.cal-bar.st-lapsed, .cal-bar.st-cancelled {
  background: var(--rl-room-occupied-fill); border-color: var(--rl-room-occupied-line); color: var(--rl-text-2);
}
.cal-bar.st-history_debtor, .cal-sw.st-history_debtor {
  background: var(--rl-room-occupied-fill); border-color: var(--rl-room-occupied-line);
  border-left: 3px solid var(--rl-text-danger); color: var(--rl-text-danger);
}

/* =========================================================================
   SETTINGS — one place with its own navigation (2026-10-14, js/settings.js
   rlSettingsFrame). Two panes: the page list, sticky under the top bar,
   and one page at a time. Forms keep a reading measure; tables (health,
   audit, the sign-in log) take the width.
   ========================================================================= */
#app .set-shell {
  display: grid; grid-template-columns: 220px minmax(0, 1fr);
  gap: var(--rl-s-10); align-items: start;
}
#app .set-nav {
  position: sticky; top: calc(var(--rl-top-h) + var(--rl-s-4));
  display: flex; flex-direction: column; gap: var(--rl-s-5);
  max-height: calc(100vh - var(--rl-top-h) - var(--rl-s-8)); overflow-y: auto;
  padding: var(--rl-s-1) var(--rl-s-1) var(--rl-s-4) 0;
  scrollbar-width: thin; scrollbar-color: var(--rl-line) transparent;
}
#app .set-nav::-webkit-scrollbar { width: 6px; }
#app .set-nav::-webkit-scrollbar-thumb { background: var(--rl-line); border-radius: 3px; }
#app .set-nav::-webkit-scrollbar-track { background: transparent; }
#app .set-group { display: flex; flex-direction: column; gap: 1px; }
#app .set-group-label {
  font-size: 11px; line-height: 16px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--rl-text-3); padding: 0 var(--rl-s-3) var(--rl-s-1);
}
#app .set-item {
  display: flex; align-items: center; width: 100%; min-height: 32px;
  padding: 0 var(--rl-s-3); border: 0; border-radius: var(--rl-r-sm);
  background: none; font: inherit; font-size: 13.5px; color: var(--rl-text-2);
  text-align: left; cursor: pointer;
  transition: background-color 150ms cubic-bezier(.2,.7,.2,1), color 150ms cubic-bezier(.2,.7,.2,1);
}
#app .set-item:hover { background: var(--rl-line-soft); color: var(--rl-text); }
#app .set-item[aria-current="page"] {
  background: var(--rl-surface); color: var(--rl-text-accent); font-weight: 500; box-shadow: var(--rl-e-1);
}
#app .set-item:focus-visible { outline: none; box-shadow: var(--rl-focus); }

#app .set-main { min-width: 0; }
#app .set-head { margin: 0 0 var(--rl-s-6); max-width: 760px; }
#app .set-title {
  margin: 0; font-family: var(--rl-font-serif); font-size: 28px; line-height: 34px;
  font-weight: 400; letter-spacing: -.01em; color: var(--rl-text); text-wrap: balance;
}
#app .set-sub { margin: var(--rl-s-2) 0 0; font-size: 14px; line-height: 20px; color: var(--rl-text-2); max-width: 68ch; }
#app .set-body { display: flex; flex-direction: column; gap: var(--rl-s-4); max-width: 760px; }
#app .set-shell.is-wide .set-head,
#app .set-shell.is-wide .set-body { max-width: none; }
#app .set-body > [hidden], #app .set-body [hidden].ws-group { display: none !important; }
#app .set-body > .card { margin: 0; }

/* The Workspace card inside a page: the page title replaces its own
   heading and blurb; Save stays, top right. Groups are sections, not
   accordions — a page only holds the ones that belong together. */
#app .set-body #workspaceSettingsCard { position: relative; }
#app .set-body #workspaceSettingsCard > div:first-child {
  position: absolute; top: var(--rl-s-5); right: var(--rl-s-5); z-index: 1; margin: 0 !important;
}
#app .set-body #workspaceSettingsCard details.ws-group:not([hidden]) > summary { margin-top: var(--rl-s-1); }
#app .set-body #workspaceSettingsCard details.ws-group:not([hidden]) ~ details.ws-group:not([hidden]) > summary { margin-top: var(--rl-s-6); }
#app .set-body #workspaceSettingsCard details.ws-group.is-solo { padding-top: var(--rl-s-10); }
#app .set-body #workspaceSettingsCard > div:first-child > h3,
#app .set-body #workspaceSettingsCard > p:first-of-type { display: none; }
#app .set-body details.ws-group > summary {
  list-style: none; pointer-events: none; cursor: default;
  font-size: 15px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--rl-text);
  margin: var(--rl-s-6) 0 var(--rl-s-3);
}
#app .set-body details.ws-group > summary::-webkit-details-marker { display: none; }
#app .set-body details.ws-group > summary::before, #app .set-body details.ws-group > summary::after { display: none; }
#app .set-body details.ws-group:not([hidden]) ~ details.ws-group:not([hidden]) { border-top: 1px solid var(--rl-line-soft); }
#app .set-body details.ws-group.is-solo > summary { display: none; }

/* Narrower than a desk: the page list becomes a strip along the top. */
@media (max-width: 899px) {
  #app .set-shell { grid-template-columns: minmax(0, 1fr); gap: var(--rl-s-5); }
  #app .set-nav {
    position: static; max-height: none;
    flex-direction: row; gap: var(--rl-s-1); overflow-x: auto; scrollbar-width: none;
    margin: 0 calc(-1 * var(--rl-s-4)); padding: var(--rl-s-2) var(--rl-s-4);
    background: var(--rl-canvas); border-bottom: 1px solid var(--rl-line);
  }
  #app .set-nav::-webkit-scrollbar { display: none; }
  #app .set-group { display: contents; }
  #app .set-group-label { display: none; }
  #app .set-item { width: auto; white-space: nowrap; flex: none; }
  #app .set-title { font-size: 22px; line-height: 28px; }
}

/* =========================================================================
   SCREENS SAY WHERE YOU ARE AGAIN — the 2026-10-14 screen pass.
   DECISIONS.md "Screens say where you are again". Eleven operational
   screens (compliance, renewals, pace, waitlist, public site, tickets,
   tasks, appointments, resident requests, sequences, automations) and the
   Settings frame. Tokens only; no new colours.
   ========================================================================= */

/* ---- The page head: title, the figures that used to be a KPI strip,
   and the screen's own actions on the same line. */
#app .pg-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  flex-wrap: wrap; gap: var(--rl-s-3) var(--rl-s-6);
  margin: 0 0 var(--rl-s-5);
}
#app .pg-head-main { min-width: 0; display: flex; flex-direction: column; gap: var(--rl-s-1); }
#app .pg-head h2.pg-title {
  margin: 0; font-family: var(--rl-font-serif); font-size: 28px; line-height: 34px;
  font-weight: 400; letter-spacing: -.01em; color: var(--rl-text); text-wrap: balance;
}
#app .pg-facts {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px var(--rl-s-4);
  margin: 0; font-size: 13.5px; line-height: 20px; color: var(--rl-text-2);
}
#app .pg-fact { font: inherit; color: inherit; background: none; border: 0; padding: 0; white-space: nowrap; }
#app .pg-fact b { font-weight: 600; color: var(--rl-text); font-variant-numeric: tabular-nums; }
#app .pg-fact.is-zero, #app .pg-fact.is-zero b { color: var(--rl-text-3); font-weight: 500; }
#app button.pg-fact { cursor: pointer; border-radius: var(--rl-r-xs); text-decoration: underline; text-decoration-color: transparent;
  text-underline-offset: 3px; transition: text-decoration-color var(--rl-d-fast) var(--rl-ease-standard); }
#app button.pg-fact:hover { text-decoration-color: var(--rl-line-strong); }
#app button.pg-fact:focus-visible { outline: none; box-shadow: var(--rl-focus); }
#app .pg-actions { display: flex; align-items: center; flex-wrap: wrap; gap: var(--rl-s-2); margin-left: auto; }
/* The Sales year/site bar lives in the head on Renewals, Pace and Waitlist. */
#app .pg-head.has-bar { align-items: center; }
#app .pg-head .sales-bar, #app .pg-head .rl-flags { margin: 0; }
#app .pg-head .sales-bar-site { margin-left: var(--rl-s-2); }
#app .pg-push { margin-left: auto; }
@media (max-width: 719px) {
  #app .pg-head h2.pg-title { font-size: 22px; line-height: 28px; }
  #app .pg-actions { margin-left: 0; width: 100%; }
  #app .pg-head .sales-bar-site { margin-left: 0; }
}

/* ---- Settings: on a wide screen the frame sits in the middle at a reading
   width instead of hugging the left edge of a 2,500px window. Pages that
   are tables (health, audit, sign-ins) still take the whole width. */
#app .set-shell:not(.is-wide) { max-width: 1180px; margin-inline: auto; }
#app .set-shell:not(.is-wide) .set-head,
#app .set-shell:not(.is-wide) .set-body { max-width: none; }
@media (min-width: 1500px) {
  #app .set-shell:not(.is-wide) .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--rl-s-6); }
}

/* ---- One filter row where there were two (Tickets). */
#app .pg-filterrow { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rl-s-2) var(--rl-s-4); margin: 0 0 var(--rl-s-3); }
#app .pg-filterrow > .rl-seg { margin: 0; }
#app .view-toolbar > .rl-flags { margin: 0; }

/* ---- Lists: a selected row is a tint and a hairline ring, not a 3px
   stripe; ticket priority is written, not a coloured edge. */
#app .side-item, #app .side-item.pri-high, #app .side-item.pri-medium { border-left-color: transparent; }
#app .side-item.active { background: var(--rl-tint-accent-bg); box-shadow: inset 0 0 0 1px var(--rl-line-accent); }
#app .si-flags { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rl-s-1); margin-top: var(--rl-s-2); }
#app .si-flags .hz-flag { margin: 0; }
#app .tk-pri { font-size: 12px; font-weight: 500; color: var(--rl-text-warning); }
#app .tk-fields { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); column-gap: var(--rl-s-4); }

/* ---- Small dropdowns inside table rows. */
#app select.cell-select {
  min-height: 30px; padding: 0 28px 0 var(--rl-s-2); max-width: 170px;
  font: inherit; font-size: 13px; color: var(--rl-text);
  border: 1px solid var(--rl-line); border-radius: var(--rl-r-sm);
  background-color: var(--rl-surface);
  transition: border-color var(--rl-d-fast) var(--rl-ease-standard);
}
#app select.cell-select:hover { border-color: var(--rl-line-strong); }
#app select.cell-select:focus-visible { outline: none; box-shadow: var(--rl-focus); }

/* ---- Alerts: a tint and a border, no thick coloured edge. */
#app .rl-alert[data-sev="fail"], #app .rl-alert[data-sev="warn"] { box-shadow: none; }

/* ---- Tasks: tick, what, who, when — aligned columns. */
#app #tasksListWrap { padding: var(--rl-s-2) var(--rl-s-5) var(--rl-s-4); }
#app .task-group-head {
  display: flex; align-items: baseline; gap: var(--rl-s-2);
  margin: var(--rl-s-5) 0 var(--rl-s-1); padding: 0 0 var(--rl-s-2);
  font-size: 13px; font-weight: 600; color: var(--rl-text); border-bottom: 1px solid var(--rl-line);
}
#app .task-group-head:first-child { margin-top: var(--rl-s-2); }
#app .task-group-head span { font-weight: 500; color: var(--rl-text-3); font-variant-numeric: tabular-nums; }
#app .task-group-head.is-overdue span { color: var(--rl-text-danger); }
#app .task-row {
  display: grid; grid-template-columns: 24px minmax(0, 1fr) minmax(140px, 220px) 110px;
  align-items: center; gap: var(--rl-s-4);
  padding: var(--rl-s-3) var(--rl-s-2); border-left: 0; border-bottom: 1px solid var(--rl-line-soft);
}
#app .task-row:hover { background: var(--rl-surface-sunk); }
#app button.task-check {
  width: 20px; height: 20px; padding: 0; border-radius: var(--rl-r-xs);
  border: 1.5px solid var(--rl-line-control); background: var(--rl-surface); color: transparent;
  display: grid; place-items: center; cursor: pointer;
  transition: background var(--rl-d-fast) var(--rl-ease-standard), border-color var(--rl-d-fast) var(--rl-ease-standard);
}
#app button.task-check svg { width: 12px; height: 12px; display: block; }
#app button.task-check:hover { border-color: var(--rl-i-600); color: var(--rl-i-300); }
#app button.task-check.done { background: var(--rl-g-600); border-color: var(--rl-g-600); color: var(--rl-text-invert); }
#app button.task-check:focus-visible { outline: none; box-shadow: var(--rl-focus); }
#app .task-main { min-width: 0; }
#app .task-title { font-size: 14px; font-weight: 500; color: var(--rl-text); }
#app .task-link { font-size: 12.5px; color: var(--rl-text-2); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#app .task-who { font-size: 13px; color: var(--rl-text-2); display: flex; flex-direction: column; min-width: 0; }
#app .task-who .task-by { font-size: 12px; color: var(--rl-text-3); }
#app .task-row .task-due { font-size: 13px; text-align: right; color: var(--rl-text-2); font-variant-numeric: tabular-nums; }
#app .task-row .task-due.overdue { color: var(--rl-text-danger); font-weight: 500; }
#app .task-row .task-due.today { color: var(--rl-text-warning); font-weight: 500; }
#app .task-row.done .task-title { text-decoration: line-through; color: var(--rl-text-3); }
@media (max-width: 719px) {
  #app #tasksListWrap { padding: var(--rl-s-1) var(--rl-s-3) var(--rl-s-3); }
  #app .task-row { grid-template-columns: 24px minmax(0, 1fr) auto; row-gap: 2px; }
  #app .task-who { grid-column: 2; grid-row: 2; flex-direction: row; gap: var(--rl-s-2); }
  #app .task-row .task-due { grid-column: 3; grid-row: 1; }
}

/* ---- Appointments: a day schedule. */
#app .appt-day + .appt-day { margin-top: var(--rl-s-6); }
#app .appt-day-head {
  display: flex; align-items: baseline; gap: var(--rl-s-2); margin: 0 0 var(--rl-s-2);
  font-family: var(--rl-font-serif); font-size: 20px; line-height: 26px; font-weight: 400; color: var(--rl-text);
}
#app .appt-day-head span { font-family: var(--rl-font-sans); font-size: 14px; color: var(--rl-text-2); }
#app .appt-day-head em { margin-left: auto; font-family: var(--rl-font-sans); font-style: normal; font-size: 12.5px; color: var(--rl-text-3); }
#app .appt-list { padding: 0; }
#app .appt-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 110px auto; align-items: center; gap: var(--rl-s-4);
  padding-right: var(--rl-s-4); border-bottom: 1px solid var(--rl-line-soft);
}
#app .appt-row:last-child { border-bottom: 0; }
#app .appt-open {
  display: grid; grid-template-columns: 76px minmax(0, 1fr) minmax(150px, 220px); align-items: center; gap: var(--rl-s-4);
  padding: var(--rl-s-3) 0 var(--rl-s-3) var(--rl-s-4); min-width: 0;
  background: none; border: 0; font: inherit; color: inherit; text-align: left; cursor: pointer;
  border-radius: var(--rl-r-sm);
}
#app .appt-row:hover { background: var(--rl-surface-sunk); }
#app .appt-open:focus-visible { outline: none; box-shadow: var(--rl-focus-inset); }
#app .appt-time { display: flex; flex-direction: column; }
#app .appt-time b { font-size: 16px; font-weight: 600; color: var(--rl-text); font-variant-numeric: tabular-nums; }
#app .appt-time span { font-size: 12px; color: var(--rl-text-3); }
#app .appt-who { display: flex; flex-direction: column; min-width: 0; }
#app .appt-who b { font-size: 14px; font-weight: 500; color: var(--rl-text); }
#app .appt-who span { font-size: 12.5px; color: var(--rl-text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#app .appt-who .appt-note { color: var(--rl-text-3); }
#app .appt-staff { display: flex; align-items: center; gap: var(--rl-s-2); font-size: 13px; color: var(--rl-text-2); min-width: 0; }
#app .appt-av {
  flex: none; width: 24px; height: 24px; border-radius: var(--rl-r-full);
  display: grid; place-items: center; font-size: 10.5px; font-weight: 600;
  background: var(--rl-tint-accent-bg); color: var(--rl-tint-accent-fg);
}
#app .appt-unassigned { color: var(--rl-text-3); }
#app .appt-actions { display: flex; gap: var(--rl-s-1); justify-content: flex-end; }
#app .appt-row.is-cancelled .appt-who b, #app .appt-row.is-cancelled .appt-time b { color: var(--rl-text-3); text-decoration: line-through; }
@media (max-width: 1099px) {
  #app .appt-row { grid-template-columns: minmax(0, 1fr) auto; padding: 0 var(--rl-s-3) var(--rl-s-3) 0; }
  #app .appt-open { grid-template-columns: 64px minmax(0, 1fr); grid-column: 1 / -1; }
  #app .appt-staff { grid-column: 2; }
  #app .appt-status { padding-left: var(--rl-s-4); }
}

/* ---- Resident requests, Next year: one proportion bar with a key. */
#app .rb-head { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--rl-s-3); margin-bottom: var(--rl-s-4); }
#app .rb-head h3 { margin: 0 0 var(--rl-s-1); font-family: var(--rl-font-serif); font-size: 18px; font-weight: 400; }
#app .rb-head p { margin: 0; font-size: 13.5px; color: var(--rl-text-2); max-width: 70ch; }
#app .rb-bar { display: flex; gap: 2px; height: 12px; border-radius: var(--rl-r-xs); overflow: clip; background: var(--rl-surface-sunk); }
#app .rb-seg { flex-basis: 0; min-width: 4px; }
#app .rb-seg.is-yes, #app .rb-key.is-yes i, #app .rb-said.is-yes i { background: var(--rl-g-500); }
#app .rb-seg.is-maybe, #app .rb-key.is-maybe i, #app .rb-said.is-maybe i { background: var(--rl-a-500); }
#app .rb-seg.is-no, #app .rb-key.is-no i, #app .rb-said.is-no i { background: var(--rl-r-500); }
#app .rb-keys { display: flex; flex-wrap: wrap; gap: var(--rl-s-2) var(--rl-s-6); font-size: 13.5px; color: var(--rl-text-2); }
#app .rb-key, #app .rb-said { display: inline-flex; align-items: center; gap: var(--rl-s-2); }
#app .rb-key i, #app .rb-said i { width: 8px; height: 8px; border-radius: var(--rl-r-full); flex: none; }
#app .rb-key b { font-weight: 600; color: var(--rl-text); font-variant-numeric: tabular-nums; }
#app .rb-key em { font-style: normal; color: var(--rl-text-3); }

/* ---- Sequences: steps as a timeline. */
#app .seq-steps { list-style: none; margin: 0 0 var(--rl-s-4); padding: 0; position: relative; }
#app .seq-step {
  position: relative; display: grid; grid-template-columns: 28px minmax(0, 1fr) auto auto;
  align-items: center; gap: var(--rl-s-4); padding: var(--rl-s-3) 0;
}
#app .seq-step + .seq-step::before {
  content: ""; position: absolute; left: 13.5px; top: -10px; height: 20px; width: 1px; background: var(--rl-line);
}
#app .seq-node {
  width: 28px; height: 28px; border-radius: var(--rl-r-full); display: grid; place-items: center;
  font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums;
  background: var(--rl-surface); color: var(--rl-text-accent); box-shadow: inset 0 0 0 1px var(--rl-line-accent);
}
#app .seq-step-main { display: flex; flex-direction: column; min-width: 0; }
#app .seq-when { font-size: 12px; color: var(--rl-text-3); }
#app .seq-subject { font-size: 14px; font-weight: 500; color: var(--rl-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#app .seq-waiting { font-size: 12.5px; color: var(--rl-text-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
#app .seq-waiting.is-zero { color: var(--rl-text-3); }
#app .seq-step-actions { display: flex; gap: var(--rl-s-1); opacity: .55; transition: opacity var(--rl-d-fast) var(--rl-ease-standard); }
#app .seq-step:hover .seq-step-actions, #app .seq-step:focus-within .seq-step-actions { opacity: 1; }
#app .link-btn.is-danger { color: var(--rl-text-danger); }
@media (hover: none) { #app .seq-step-actions { opacity: 1; } }

/* ---- Automations: an empty state that teaches, with starting points. */
#app .auto-empty {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--rl-s-5);
  padding: var(--rl-s-8); margin-bottom: var(--rl-s-8);
  background: var(--rl-surface); border: 1px solid var(--rl-line); border-radius: var(--rl-r-md);
}
#app .auto-empty h3 { margin: 0 0 var(--rl-s-2); font-family: var(--rl-font-serif); font-size: 21px; line-height: 28px; font-weight: 400; }
#app .auto-empty p { margin: 0; font-size: 14px; line-height: 21px; color: var(--rl-text-2); max-width: 66ch; }
#app .auto-starters { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--rl-s-3); }
#app .auto-starter {
  display: flex; flex-direction: column; gap: var(--rl-s-2); text-align: left;
  padding: var(--rl-s-4); border: 1px solid var(--rl-line); border-radius: var(--rl-r-md);
  background: var(--rl-surface-sunk); font: inherit; color: var(--rl-text); cursor: pointer;
  transition: border-color var(--rl-d-fast) var(--rl-ease-standard), background var(--rl-d-fast) var(--rl-ease-standard), transform var(--rl-d-fast) var(--rl-ease-standard);
}
#app .auto-starter:hover { border-color: var(--rl-line-accent); background: var(--rl-surface); }
#app .auto-starter:active { transform: scale(.99); }
#app .auto-starter:focus-visible { outline: none; box-shadow: var(--rl-focus); }
#app .auto-starter-flow { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--rl-s-2); font-size: 12.5px; color: var(--rl-text-2); }
#app .auto-starter-flow b { font-weight: 600; color: var(--rl-text-accent); }
#app .auto-starter-name { font-size: 14px; font-weight: 500; }

/* ---- Public site: the editors in the middle, how the site connects in a
   side panel that stays put — on a wide screen, beside them. */
#app .site-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--rl-s-4); }
#app .site-aside > .card, #app .site-main > .card { margin: 0 0 var(--rl-s-4) !important; }
#app .site-aside #axoSyncReport.empty-note { padding: var(--rl-s-3) 0 0; max-width: none; text-align: left; font-size: 13.5px; }
@media (min-width: 1400px) {
  #app .site-layout { grid-template-columns: minmax(0, 1fr) minmax(320px, 400px); align-items: start; gap: var(--rl-s-6); }
  #app .site-aside { order: 2; position: sticky; top: calc(var(--rl-top-h) + var(--rl-s-4)); }
  #app .site-aside .settings-row { flex-direction: column; align-items: flex-start; gap: 2px; }
  #app .site-aside .settings-row .sr-label { text-align: left; }
}

/* ---- Letting pace. */
#app .pace-card { padding: var(--rl-s-6); }
#app .pace-card-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--rl-s-2) var(--rl-s-5); margin-bottom: var(--rl-s-3); }
#app .pace-card-head h3 { margin: 0; font-family: var(--rl-font-serif); font-size: 20px; font-weight: 400; }
#app .pace-card-head .pace-delta { margin: 0; font-size: 14px; font-weight: 600; letter-spacing: 0; }
#app .pace-card-head .pace-delta span { font-weight: 400; color: var(--rl-text-3); }
#app .pace-chart-wrap { position: relative; margin-top: var(--rl-s-2); overflow: visible; }
#app .pace-chart { width: 100%; height: auto; min-width: 0; display: block; }
#app .pace-grid { stroke: var(--rl-line-soft); stroke-width: 1; }
#app .pace-grid.is-base { stroke: var(--rl-line); }
#app .pace-tick { fill: var(--rl-text-3); font-size: 11.5px; font-family: var(--rl-font-sans); font-variant-numeric: tabular-nums; }
#app .pace-target { stroke: var(--rl-line-strong); stroke-width: 1; stroke-dasharray: none; }
#app .pace-target-label { fill: var(--rl-text-2); font-size: 12px; font-family: var(--rl-font-sans); }
#app .pace-line { stroke-width: 2; }
#app .pace-line.current { stroke: var(--rl-chart-1); }
#app .pace-line.prior { stroke: var(--rl-n-400); stroke-dasharray: 5 4; }
#app .pace-area { fill: var(--rl-chart-1); opacity: .1; }
#app .pace-now { stroke: var(--rl-line-strong); stroke-dasharray: 3 3; }
#app .pace-dot, #app .pace-hdot { fill: var(--rl-chart-1); stroke: var(--rl-surface); stroke-width: 2; }
#app .pace-value { fill: var(--rl-text); font-size: 13px; font-weight: 600; font-family: var(--rl-font-sans); paint-order: stroke; stroke: var(--rl-surface); stroke-width: 4px; }
#app .pace-cross { stroke: var(--rl-line-strong); stroke-width: 1; }
#app .pace-tip {
  position: absolute; pointer-events: none; z-index: 2;
  display: flex; flex-direction: column; gap: 2px; min-width: 150px;
  padding: var(--rl-s-2) var(--rl-s-3); font-size: 12.5px; color: var(--rl-text-2);
  background: var(--rl-surface-raised); border-radius: var(--rl-r-sm); box-shadow: var(--rl-e-2);
}
#app .pace-tip > b { color: var(--rl-text); font-size: 13px; }
#app .pace-tip b { font-variant-numeric: tabular-nums; color: var(--rl-text); }
#app .pace-legend .k.current { background: var(--rl-chart-1); }
#app .pace-legend .k.prior { background: var(--rl-n-400); }
#app .pace-note { margin: var(--rl-s-3) 0 0; font-size: 12.5px; line-height: 18px; color: var(--rl-text-3); max-width: 90ch; }
#app .pace-tip[hidden] { display: none; }
@media (min-width: 1100px) { #app .appt-row { grid-template-columns: minmax(0, 1fr) 96px 236px; } }
@media (max-width: 1099px) {
  #app .appt-row { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--rl-s-2); }
  #app .appt-status { grid-column: 1; grid-row: 2; }
  #app .appt-actions { grid-column: 2; grid-row: 2; flex-wrap: wrap; }
}
#app .site-aside .card > div:first-child { flex-wrap: wrap; }
#app .site-aside .btn, #app .pg-actions .btn { white-space: nowrap; }
#app .pg-actions a.btn { text-decoration: none; }
/* The settings cards used to be held to a prose measure (screens.css
   "#view-settings .card"); inside the centred frame they take its width. */
#app #view-settings .set-shell:not(.is-wide) .set-body > .card { max-width: none; }

/* =========================================================================
   FORMS (2026-10-14, js/forms.js) — the builder.
   ========================================================================= */
#app .fm-fields { list-style: none; margin: 0 0 var(--rl-s-3); padding: 0; display: flex; flex-direction: column; gap: var(--rl-s-3); }
#app .fm-field { padding: var(--rl-s-4); border: 1px solid var(--rl-line); border-radius: var(--rl-r-md); background: var(--rl-surface-sunk); }
#app .fm-field .field-block { margin-bottom: var(--rl-s-2); }
#app .fm-field-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); gap: 0 var(--rl-s-3); }
@media (max-width: 899px) { #app .fm-field-grid { grid-template-columns: minmax(0, 1fr); } }
#app .fm-field-tools { display: flex; align-items: center; flex-wrap: wrap; gap: var(--rl-s-1) var(--rl-s-2); }
#app .fm-field-tools .recon-check { margin: 0; }
#app .fm-action { padding: var(--rl-s-4) 0; border-top: 1px solid var(--rl-line-soft); }
#app .fm-action:first-of-type { border-top: 0; padding-top: 0; }
#app .fm-toggle { display: flex; gap: var(--rl-s-3); align-items: flex-start; cursor: pointer; margin-bottom: var(--rl-s-3); }
#app .fm-toggle input { width: 18px; height: 18px; margin: 2px 0 0; flex: none; }
#app .fm-toggle > span { display: flex; flex-direction: column; gap: 2px; }
#app .fm-toggle b { font-size: 14px; font-weight: 600; color: var(--rl-text); }
#app .fm-toggle > span > span { font-size: 13px; color: var(--rl-text-2); }
#app .fm-qr { display: flex; gap: var(--rl-s-5); align-items: flex-start; flex-wrap: wrap; margin-top: var(--rl-s-4); }
#app #fmQr { width: 180px; height: 180px; padding: var(--rl-s-2); background: var(--rl-n-0); border: 1px solid var(--rl-line); border-radius: var(--rl-r-md); }
#app #fmQr svg { width: 100%; height: 100%; display: block; }
