/*
 * Echox Platform — design tokens.
 *
 * Ported deliberately from the marketing site (~/echox/web/src/app/globals.css) so the product and
 * the front door read as one company. Deep navy ground, warm ivory paper, brass accent, and small
 * radii throughout: this should read as a firm that handles other people's money, not as a startup.
 *
 * The site expresses these through Tailwind's @theme; the product is plain CSS custom properties.
 * The VALUES are the contract — if the palette moves there, move it here in the same commit.
 */

:root {
  --ink: #0f2033;
  --ink-deep: #0a1724;
  --ink-soft: #16293d;
  --ink-line: #26394d;

  --ivory: #faf7f1;
  --paper: #fffdf8;
  --white: #ffffff;

  --brass: #a5793a;
  --brass-light: #c9a063;

  --slate: #5c6773;
  --slate-2: #8a939d;
  --slate-3: #364a5e;
  --line: #e4ded2;
  --line-soft: #efeae0;

  /* on navy */
  --mist: #a9b4c0;
  --mist-bright: #e4e9ee;
  --mist-dim: #7d8b9b;
  --mist-faint: #55677c;

  --danger: #8c3b3b;
  --success: #4b7a5a;

  --font-display: "Newsreader", Georgia, "Times New Roman", serif;
  --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;

  --radius-xs: 2px;
  --radius-sm: 3px;
  --radius-md: 4px;
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  background: var(--ivory);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── Auth layout ───────────────────────────────────────────────────────────
   Split screen: navy identity panel, ivory working panel. The pattern every
   serious PM product uses (Buildium, AppFolio, Rentvine) because it gives the
   brand somewhere to live without crowding the one thing the user came to do.
   Collapses to the form alone on small screens — a tenant paying rent on a
   phone should not scroll past a marketing panel to reach the password field. */

.auth {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  min-height: 100vh;
}

.auth-brand {
  background: var(--ink);
  color: var(--mist-bright);
  padding: 3.5rem 4rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  position: relative;
  overflow: hidden;
}

/* A single hairline of brass along the seam. The logo's brass arm is the only
   other place the colour appears at this size — keep it rare. */
.auth-brand::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 3px;
  height: 100%;
  background: var(--brass);
}

.auth-brand-copy { max-width: 30rem; }

.auth-brand h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.85rem, 2.4vw, 2.6rem);
  line-height: 1.22;
  letter-spacing: -0.015em;
  color: var(--white);
  margin: 0 0 1.1rem;
}

.auth-brand p {
  color: var(--mist);
  font-size: 1.02rem;
  line-height: 1.65;
  margin: 0;
}

.auth-brand-foot {
  display: flex;
  gap: 1.75rem;
  font-size: 0.82rem;
  color: var(--mist-faint);
}

.auth-brand-foot a { color: var(--mist-dim); text-decoration: none; }
.auth-brand-foot a:hover { color: var(--mist-bright); }

.auth-panel {
  background: var(--ivory);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem 2rem;
}

.auth-form-wrap { width: 100%; max-width: 24rem; }

.eyebrow {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--brass);
  margin: 0 0 0.6rem;
}

.auth-form-wrap h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.85rem;
  letter-spacing: -0.01em;
  margin: 0 0 0.4rem;
  color: var(--ink);
}

.auth-sub {
  color: var(--slate);
  font-size: 0.94rem;
  margin: 0 0 2rem;
}

/* ── Form ───────────────────────────────────────────────────────────────── */

.field { margin-bottom: 1.15rem; }

.field label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--slate-3);
  margin-bottom: 0.4rem;
}

.field input[type="email"],
.field input[type="password"],
.field input[type="text"] {
  width: 100%;
  padding: 0.72rem 0.85rem;
  font-family: inherit;
  font-size: 0.97rem;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.field input:hover { border-color: #d6cfc0; }

.field input:focus {
  outline: none;
  border-color: var(--brass);
  box-shadow: 0 0 0 3px rgba(165, 121, 58, 0.14);
}

.field-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.field-row a {
  font-size: 0.8rem;
  color: var(--slate);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}
.field-row a:hover { color: var(--brass); border-bottom-color: var(--brass); }

.check {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.88rem;
  color: var(--slate);
  margin: 1.35rem 0 1.6rem;
  cursor: pointer;
}

.check input { accent-color: var(--brass); width: 15px; height: 15px; }

.btn {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.85rem 1.5rem;
  font-family: inherit;
  font-size: 0.97rem;
  font-weight: 500;
  color: var(--ivory);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.btn:hover { background: var(--ink-soft); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }

.auth-alt {
  margin-top: 1.9rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  font-size: 0.88rem;
  color: var(--slate);
}

.auth-alt a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--line); }
.auth-alt a:hover { border-bottom-color: var(--brass); color: var(--brass); }

/* ── Messages ───────────────────────────────────────────────────────────── */

.notice {
  padding: 0.8rem 0.95rem;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  margin-bottom: 1.5rem;
  border: 1px solid;
}

.notice-error {
  background: #fdf4f4;
  border-color: #e8d2d2;
  color: var(--danger);
}

/* Deliberately loud. This build cannot authenticate anyone, and the screen must
   not imply otherwise — a login that looks real and is not is worse than none. */
.notice-stub {
  background: #fbf6ec;
  border-color: #e6d9bf;
  color: #6b5324;
}

.validation-message { color: var(--danger); font-size: 0.82rem; display: block; margin-top: 0.35rem; }

/* ── Narrow ─────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {
  .auth { grid-template-columns: 1fr; min-height: 100dvh; }
  .auth-brand {
    padding: 2rem 1.75rem;
    gap: 1.75rem;
  }
  .auth-brand::after { width: 100%; height: 3px; top: auto; bottom: 0; }
  .auth-brand-copy h1 { font-size: 1.5rem; }
  .auth-brand-copy p, .auth-brand-foot { display: none; }
  .auth-panel { padding: 2.5rem 1.5rem 3.5rem; align-items: flex-start; }
}

/* ── Signed-in shell ────────────────────────────────────────────────────── */

.shell { min-height: 100vh; display: flex; flex-direction: column; }

.shell-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.1rem 2rem;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.shell-user { display: flex; align-items: center; gap: 1rem; font-size: 0.88rem; color: var(--slate); }

.linkish {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
  border-bottom: 1px solid var(--line);
}
.linkish:hover { color: var(--brass); border-bottom-color: var(--brass); }

.shell-body { padding: 3.5rem 2rem; max-width: 44rem; }

.shell-body h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 2rem;
  letter-spacing: -0.015em;
  margin: 0 0 0.75rem;
}

.lede { color: var(--slate); font-size: 1rem; max-width: 34rem; }

.lede code, .facts code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.88em;
  background: var(--line-soft);
  padding: 0.1em 0.35em;
  border-radius: var(--radius-xs);
}

.facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.5rem 1.5rem;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  font-size: 0.9rem;
}

.facts dt { color: var(--slate-2); text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.72rem; padding-top: 0.15rem; }
.facts dd { margin: 0; color: var(--ink); }

/* ── Shell navigation ───────────────────────────────────────────────────── */

.shell-left { display: flex; align-items: center; gap: 2.25rem; }
.shell-logo { display: inline-flex; line-height: 0; }

.shell-nav { display: flex; gap: 1.5rem; }

.shell-nav a {
  font-size: 0.9rem;
  color: var(--slate);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
}
.shell-nav a:hover { color: var(--ink); }
.shell-nav a.on { color: var(--ink); border-bottom-color: var(--brass); font-weight: 500; }

.shell-body { padding: 2.75rem 2rem 5rem; max-width: 68rem; width: 100%; }

/* ── Page furniture ─────────────────────────────────────────────────────── */

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 2rem;
  margin-bottom: 2rem;
}

.page-head h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.9rem;
  letter-spacing: -0.015em;
  margin: 0.1rem 0 0.3rem;
}

.page-head .eyebrow a { color: inherit; text-decoration: none; }
.page-head .eyebrow a:hover { border-bottom: 1px solid var(--brass); }

.muted { color: var(--slate); margin: 0; }
.count { margin-top: 1rem; font-size: 0.85rem; }
.strong { color: var(--ink); font-weight: 500; text-decoration: none; }
a.strong:hover { color: var(--brass); }
.sub { display: block; font-size: 0.82rem; color: var(--slate-2); margin-top: 0.15rem; }
.opt { font-weight: 400; color: var(--slate-2); text-transform: none; letter-spacing: 0; }
.hint { font-size: 0.85rem; color: var(--slate); margin: 0.25rem 0 1.5rem; }

/* ── Search ─────────────────────────────────────────────────────────────── */

.searchbar { display: flex; gap: 0.6rem; margin-bottom: 1.5rem; max-width: 30rem; }

.searchbar input {
  flex: 1;
  padding: 0.6rem 0.8rem;
  font: inherit;
  font-size: 0.93rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
}
.searchbar input:focus { outline: none; border-color: var(--brass); box-shadow: 0 0 0 3px rgba(165,121,58,0.14); }

/* ── Tables ─────────────────────────────────────────────────────────────── */

.grid {
  width: 100%;
  border-collapse: collapse;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  font-size: 0.92rem;
}

.grid thead th {
  text-align: left;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--slate-2);
  font-weight: 600;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--line);
  background: var(--ivory);
}

.grid td { padding: 0.8rem 1rem; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
.grid tbody tr:last-child td { border-bottom: none; }
.grid tbody tr:hover { background: var(--ivory); }

/* Digits that line up in a column read as quantities; digits that wander read as text. */
.grid .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── Empty states ───────────────────────────────────────────────────────── */

.empty {
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
  padding: 3rem 2rem;
  text-align: center;
  color: var(--slate);
  background: var(--paper);
}
.empty.small { padding: 1.75rem; }
.empty p { margin: 0 0 0.75rem; }
.empty a { color: var(--ink); border-bottom: 1px solid var(--line); text-decoration: none; }
.empty a:hover { color: var(--brass); border-bottom-color: var(--brass); }

/* ── Panels ─────────────────────────────────────────────────────────────── */

.panel { margin-bottom: 2.75rem; }

.panel h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.25rem;
  margin: 0 0 0.9rem;
}

/* ── Forms ──────────────────────────────────────────────────────────────── */

.form-narrow { max-width: 34rem; }

.field-grid { display: grid; grid-template-columns: 2fr 0.7fr 1fr; gap: 1rem; }
.field-grid.two { grid-template-columns: 1fr 1fr; }

.sub-fields {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 1.25rem 1.25rem 0.5rem;
  margin: 1.75rem 0 1.5rem;
  background: var(--paper);
}

.sub-fields legend {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--slate-3);
  padding: 0 0.4rem;
}

.field select,
.field input[type="number"] {
  width: 100%;
  padding: 0.72rem 0.85rem;
  font: inherit;
  font-size: 0.97rem;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.field select:focus, .field input[type="number"]:focus {
  outline: none; border-color: var(--brass); box-shadow: 0 0 0 3px rgba(165,121,58,0.14);
}

.form-actions { display: flex; align-items: center; gap: 1.25rem; margin-top: 2rem; }

.btn-inline { width: auto; }

.btn-quiet {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 0.92rem;
  color: var(--slate);
  cursor: pointer;
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}
.btn-quiet:hover { color: var(--brass); border-bottom-color: var(--brass); }

.inline-form { margin-top: 1.25rem; }

.inline-fields {
  display: grid;
  grid-template-columns: 1.2fr 0.7fr 0.7fr 0.9fr 1.1fr auto;
  gap: 0.75rem;
  align-items: end;
}
.inline-fields .field { margin-bottom: 0; }
.inline-fields label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--slate-2); }

@media (max-width: 800px) {
  .shell-body { padding: 2rem 1.25rem 4rem; }
  .shell-left { gap: 1.25rem; }
  .field-grid, .field-grid.two { grid-template-columns: 1fr; }
  .inline-fields { grid-template-columns: 1fr 1fr; }
  .page-head { flex-direction: column; gap: 1rem; }
  .grid { font-size: 0.86rem; }
}

/* ── Reconciliation verdict ─────────────────────────────────────────────────
   The one place on the site that gets a coloured ground. It is the answer to
   the question the licence turns on, so it should be readable across a room —
   and semantic colour here is state, not decoration, which is why it does not
   reuse the brass accent. */

.verdict {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
  padding: 1.4rem 1.6rem;
  border-radius: var(--radius-sm);
  border: 1px solid;
  margin-bottom: 2.5rem;
}

.verdict.ok { background: #f2f6f3; border-color: #cfded4; }
.verdict.off { background: #fdf4f4; border-color: #e8d2d2; }

.verdict-label {
  font-family: var(--font-display);
  font-size: 1.3rem;
  margin: 0 0 0.2rem;
}
.verdict.ok .verdict-label { color: var(--success); }
.verdict.off .verdict-label { color: var(--danger); }

.verdict-detail { margin: 0; font-size: 0.92rem; color: var(--slate-3); max-width: 34rem; }

.verdict-figures {
  display: grid;
  grid-template-columns: max-content max-content;
  gap: 0.3rem 1.5rem;
  margin: 0;
  font-size: 0.9rem;
}
.verdict-figures dt { color: var(--slate-2); text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.7rem; padding-top: 0.2rem; }
.verdict-figures dd { margin: 0; font-variant-numeric: tabular-nums; font-weight: 500; }

.grid tfoot td { padding: 0.8rem 1rem; border-top: 1px solid var(--line); background: var(--ivory); }

/* ── Status pills ───────────────────────────────────────────────────────────
   State as form as well as text, so a list scans at a glance. Semantic colour,
   deliberately separate from the brass accent. */

.pill {
  display: inline-block;
  padding: 0.14rem 0.55rem;
  border-radius: 999px;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border: 1px solid;
}

.pill.active { background: #f2f6f3; border-color: #cfded4; color: var(--success); }
.pill.draft { background: var(--line-soft); border-color: var(--line); color: var(--slate); }
.pill.ended { background: var(--white); border-color: var(--line); color: var(--slate-2); }
.pill.cancelled { background: #fdf4f4; border-color: #e8d2d2; color: var(--danger); }

.searchbar select {
  padding: 0.6rem 0.8rem;
  font: inherit;
  font-size: 0.93rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
}

.facts.wide { grid-template-columns: 10rem 1fr; gap: 1rem 2rem; }
.facts.wide dd { line-height: 1.5; }
.inline-fields.narrow { grid-template-columns: 14rem auto; }

.inline-fields.tenant { grid-template-columns: 1.4fr 1.6fr 1fr auto; }

.monthbox {
  padding: 0.6rem 0.8rem;
  font: inherit;
  font-size: 0.93rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
}

/* A reversed charge stays visible — the row is history, not clutter — but reads as struck. */
.grid tr.reversed td { color: var(--slate-2); text-decoration: line-through; }
.grid tr.reversed td:last-child { text-decoration: none; font-size: 0.8rem; }

.inline-fields.owner-row { grid-template-columns: 1fr; max-width: 22rem; }

.grid tr.opening td { background: var(--ivory); color: var(--slate); }
.grid .num.neg { color: var(--danger); }

.inline-fields.wo { grid-template-columns: 1.3fr 2fr 1fr auto; }
.inline-fields.vendor { grid-template-columns: 1.4fr 1fr 1.4fr 1fr auto; }

.pill.p-low { background: var(--line-soft); border-color: var(--line); color: var(--slate); }
.pill.p-normal { background: var(--white); border-color: var(--line); color: var(--slate-3); }
.pill.p-urgent { background: #fbf6ec; border-color: #e6d9bf; color: #6b5324; }
.pill.p-emergency { background: #fdf4f4; border-color: #e8d2d2; color: var(--danger); }

.inline-fields.narrow3 { grid-template-columns: 14rem 12rem auto; }

.notice-ok { background: #f2f6f3; border-color: #cfded4; color: var(--success); }
.shell-user a { color: var(--slate); text-decoration: none; border-bottom: 1px solid var(--line); }
.shell-user a:hover { color: var(--brass); border-bottom-color: var(--brass); }

/* ── Tenant portal ──────────────────────────────────────────────────────────
   Mobile-first, and it stays narrow on a desktop rather than stretching a
   one-column page across 1400px. A tenant opens this standing up, on a phone,
   usually because something is wrong or something is due. */

.tenant-shell { min-height: 100vh; display: flex; flex-direction: column; background: var(--ivory); }

.tenant-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  background: var(--ink);
  border-bottom: 3px solid var(--brass);
}

.tenant-bar .linkish { color: var(--mist); border-bottom-color: var(--ink-line); }
.tenant-bar .linkish:hover { color: var(--mist-bright); border-bottom-color: var(--brass); }

.tenant-body { flex: 1; width: 100%; max-width: 34rem; margin: 0 auto; padding: 1.75rem 1.25rem 3rem; }

.tenant-foot {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 1.5rem 1.25rem 2.5rem;
  font-size: 0.8rem;
  color: var(--slate-2);
  border-top: 1px solid var(--line);
  max-width: 34rem;
  margin: 0 auto;
  width: 100%;
}
.tenant-foot a { color: var(--slate); }

.my-head { margin-bottom: 1.5rem; }
.my-head h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.75rem;
  letter-spacing: -0.015em;
  margin: 0.15rem 0 0.25rem;
}

/* The balance is why most people open the page: first, and largest. */
.balance {
  border: 1px solid;
  border-radius: var(--radius-sm);
  padding: 1.5rem 1.4rem;
  margin-bottom: 2.25rem;
}
.balance.owing { background: var(--paper); border-color: var(--line); }
.balance.clear { background: #f2f6f3; border-color: #cfded4; }

.balance-label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate-2);
  margin: 0 0 0.35rem;
}
.balance.clear .balance-label { color: var(--success); }

.balance-figure {
  font-family: var(--font-display);
  font-size: 2.6rem;
  line-height: 1;
  letter-spacing: -0.02em;
  margin: 0 0 0.6rem;
  font-variant-numeric: tabular-nums;
}

.balance-note { font-size: 0.88rem; color: var(--slate); margin: 0.35rem 0 0; }
.balance-note.quiet { color: var(--slate-2); font-size: 0.82rem; margin-top: 0.9rem; }

.tenant-body .panel h2 { font-size: 1.1rem; }
.tenant-body .field textarea {
  width: 100%;
  padding: 0.72rem 0.85rem;
  font: inherit;
  font-size: 0.97rem;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  resize: vertical;
}
.tenant-body .field textarea:focus,
.tenant-body .field select:focus {
  outline: none; border-color: var(--brass); box-shadow: 0 0 0 3px rgba(165,121,58,0.14);
}
.grid.spaced { margin-top: 1.75rem; }

/* ── Password fields ────────────────────────────────────────────────────── */

.pw-wrap { position: relative; display: block; }

.pw-wrap input { padding-right: 4.2rem; }

.pw-toggle {
  position: absolute;
  top: 50%;
  right: 0.6rem;
  transform: translateY(-50%);
  background: none;
  border: none;
  padding: 0.25rem 0.4rem;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--slate-2);
  cursor: pointer;
  border-radius: var(--radius-xs);
}
.pw-toggle:hover { color: var(--brass); }

.pw-match {
  display: block;
  font-size: 0.82rem;
  margin-top: 0.35rem;
}
.pw-match.ok { color: var(--success); }
.pw-match.bad { color: var(--danger); }

.verdict.credential { display: block; }
.credential-value {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.05rem;
  letter-spacing: 0.06em;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
  padding: 0.3rem 0.55rem;
  user-select: all;
}

.inline-fields.payment { grid-template-columns: 1.8fr 0.9fr 1fr 1fr 1fr auto; }

.verdict.warn { background: #fbf6ec; border-color: #e6d9bf; }
.verdict.warn .verdict-label { color: #6b5324; }
.verdict.deadlines { display: block; margin-bottom: 1.25rem; }
.grid .sub.overdue { color: var(--danger); font-weight: 600; }

.field input[type="file"] {
  width: 100%;
  padding: 0.55rem 0.6rem;
  font: inherit;
  font-size: 0.9rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
}

.owner-nav { display: flex; gap: 1.25rem; margin-left: auto; margin-right: 1.75rem; }
.owner-nav a {
  font-size: 0.88rem;
  color: var(--mist);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
}
.owner-nav a:hover { color: var(--mist-bright); }
.owner-nav a.on { color: var(--white); border-bottom-color: var(--brass); }

/* An owner reads tables, so give them more room than the tenant's single column. */
.owner-body { max-width: 46rem; }

.head-actions { display: flex; align-items: center; gap: 1.25rem; }

.inline-fields.area { grid-template-columns: 1.2fr 1fr 2fr auto; }

.pill.c-good { background: #f2f6f3; border-color: #cfded4; color: var(--success); }
.pill.c-fair { background: var(--white); border-color: var(--line); color: var(--slate-3); }
.pill.c-poor { background: #fbf6ec; border-color: #e6d9bf; color: #6b5324; }
.pill.c-damaged, .pill.c-missing { background: #fdf4f4; border-color: #e8d2d2; color: var(--danger); }

.photo-link { display: block; font-size: 0.82rem; color: var(--ink); margin-bottom: 0.2rem; }
.photo-link:hover { color: var(--brass); }
.photo-form { display: flex; gap: 0.4rem; align-items: center; margin-top: 0.4rem; }
.photo-form input[type="file"] { font-size: 0.75rem; max-width: 11rem; }

.grid tr.worsened td { background: #fdf9f9; }
.worse-flag {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--danger);
}

/* ── Public listings ────────────────────────────────────────────────────── */

.public-body { max-width: 46rem; }
.public-tag { color: var(--mist); font-size: 0.85rem; letter-spacing: 0.04em; }
.fair-housing { display: block; margin-top: 0.6rem; max-width: 34rem; line-height: 1.5; }

.listing-grid { display: grid; gap: 1rem; }

.listing-card {
  display: block;
  padding: 1.25rem 1.4rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: var(--ink);
  transition: border-color 0.15s ease;
}
.listing-card:hover { border-color: var(--brass); }

.listing-rent {
  font-family: var(--font-display);
  font-size: 1.55rem;
  margin: 0 0 0.3rem;
  font-variant-numeric: tabular-nums;
}
.listing-rent .per { font-size: 0.9rem; color: var(--slate-2); font-family: var(--font-sans); }
.listing-address { margin: 0 0 0.15rem; font-weight: 500; }
.listing-sub { margin: 0; font-size: 0.87rem; color: var(--slate); }

.inline-fields.listing { grid-template-columns: 1.6fr 1fr 1fr 1fr auto; }

.pill.received { background: var(--line-soft); border-color: var(--line); color: var(--slate); }
.pill.underreview { background: #fbf6ec; border-color: #e6d9bf; color: #6b5324; }
.pill.approved { background: #f2f6f3; border-color: #cfded4; color: var(--success); }
.pill.declined { background: #fdf4f4; border-color: #e8d2d2; color: var(--danger); }
.pill.withdrawn { background: var(--white); border-color: var(--line); color: var(--slate-2); }
.sub.overdue { color: var(--danger); font-weight: 600; }

.report-tabs { display: flex; gap: 1.5rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--line); }
.report-tabs a {
  padding-bottom: 0.6rem;
  font-size: 0.92rem;
  color: var(--slate);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.report-tabs a:hover { color: var(--ink); }
.report-tabs a.on { color: var(--ink); border-bottom-color: var(--brass); font-weight: 500; }

.photo-strip { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 0.8rem; }
.photo-strip img {
  width: 8rem;
  height: 8rem;
  object-fit: cover;
  border: 1px solid var(--line);
  border-radius: 2px;
  display: block;
  background: var(--paper-2, #f3f1ec);
}
.photo-strip a:hover img { border-color: var(--brass); }
.photo-strip.small img { width: 4.5rem; height: 4.5rem; }

.panel h2 .head-action { float: right; font-weight: 400; }

.w9-toggle {
  background: none;
  border: 1px dashed var(--line);
  border-radius: 2px;
  padding: 0.15rem 0.5rem;
  font: inherit;
  font-size: 0.8rem;
  color: inherit;
  cursor: pointer;
}
.w9-toggle:hover { border-color: var(--brass); border-style: solid; }

/* ---- Audit log ------------------------------------------------------------------------- */

/* The filter row is a GET form, so a filtered view stays a URL someone can send on. */
.audit-filters {
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
}

.sr-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.sr-field > span {
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted, #6b7280);
}

.audit-grid td {
    vertical-align: top;
}

.nowrap {
    white-space: nowrap;
}

.audit-grid .pill.ok {
    background: #e7f4ec;
    color: #1c6b3f;
}

.audit-grid .pill.bad {
    background: #fbeaea;
    color: #9b1c1c;
}

/* Each change is one line: field, what it was, what it became. Read down the column and the
   history of a record is legible without opening anything. */
.changes {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.changes li {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: baseline;
    font-size: 0.85rem;
}

.changes .field {
    font-weight: 600;
}

.changes .was {
    color: var(--muted, #6b7280);
    text-decoration: line-through;
}

.changes .arrow {
    color: var(--muted, #6b7280);
}

.changes .now {
    font-weight: 500;
}

.pager {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.pager-links {
    display: flex;
    gap: 0.5rem;
}

/* ---- Global search --------------------------------------------------------------------- */

.shell-search {
    display: flex;
    align-items: center;
}

.shell-search input {
    width: 12rem;
    max-width: 30vw;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--line, #d8d8d2);
    border-radius: 999px;
    font: inherit;
    font-size: 0.85rem;
    background: transparent;
}

.hit-group h2 {
    margin-bottom: 0.5rem;
}

.hits {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
}

/* One result per row: what it is on the left, what tells it apart underneath. Scanning the
   column should be enough to pick the right one without opening anything. */
.hit {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.5rem 0;
    border-top: 1px solid var(--line, #e8e8e2);
}

.hit:first-child {
    border-top: 0;
}

.hit-title {
    font-weight: 600;
}

.hit-sub {
    font-size: 0.85rem;
    color: var(--muted, #6b7280);
}

/* ---- Errors ---------------------------------------------------------------------------- */

/* Paths, type names and trace ids: things read character by character rather than as words. */
.mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.85em;
}

/* A stack trace is wide by nature. It scrolls inside its own box so the page never does. */
.stack {
    margin: 0;
    padding: 0.75rem;
    overflow-x: auto;
    max-height: 28rem;
    overflow-y: auto;
    background: #0f2033;
    color: #e8e8e2;
    border-radius: 4px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.78rem;
    line-height: 1.5;
    white-space: pre;
    tab-size: 4;
}

/*
 * Searchable pickers.
 *
 * The <select> these replace is still in the DOM and still the element that posts — picker-ui.js
 * hides it and drives its value. It is display:none rather than removed, and a display:none form
 * control still posts, which is the whole trick: model binding never learns this happened.
 *
 * No styles here for the text box itself. It is an input[type="text"] inside the same .field or
 * .searchbar the select sat in, so it already inherits the form styling above and matches its
 * neighbours by construction rather than by a second copy of the same rules.
 */
.picker { position: relative; }

.picker select { display: none; }

.picker-list {
    position: absolute;
    z-index: 30;
    left: 0;
    right: 0;
    margin: 0.25rem 0 0;
    padding: 0.25rem;
    list-style: none;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    box-shadow: 0 6px 20px rgba(15, 32, 51, 0.1);
    max-height: 17rem;
    overflow-y: auto;
}

.picker-option {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.5rem 0.6rem;
    border-radius: var(--radius-xs);
    cursor: pointer;
}

/* Hover and keyboard selection are the same state deliberately: two different highlights in one
   list makes it ambiguous which row Enter will take. */
.picker-option:hover,
.picker-option.active {
    background: var(--line-soft);
}

.picker-label { font-size: 0.94rem; color: var(--ink); }
.picker-hint { font-size: 0.8rem; color: var(--slate); }

.picker-empty,
.picker-more {
    padding: 0.55rem 0.6rem;
    font-size: 0.85rem;
    color: var(--slate);
}

/* Set off from the results because it is a statement about the list, not another thing to pick. */
.picker-more { border-top: 1px solid var(--line-soft); margin-top: 0.25rem; }

/*
 * The contractor portal.
 *
 * A job list, not a table: this is read on a phone held in one hand, usually outdoors. Each job is
 * one large tap target with the three things that decide whether to go now — what, where, and how
 * urgent.
 */
.joblist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }

.job a {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.9rem 1rem;
    background: var(--white);
    border: 1px solid var(--line);
    border-left: 3px solid var(--line);
    border-radius: var(--radius-sm);
    text-decoration: none;
    color: var(--ink);
}

.job a:hover { border-color: var(--brass-light); border-left-color: var(--brass); }

/* Emergency earns the one strong colour on this page and nothing else does. NC landlord-tenant
   law has views about habitability, so it must read as different at a glance, not just darker. */
.job.emergency a { border-left-color: var(--danger); }

.job-title { font-size: 1rem; font-weight: 500; }
.job-where { font-size: 0.86rem; color: var(--slate); }
.job-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; font-size: 0.8rem; }

/* Work-order status, in the contractor's terms. The staff screens colour by lease and application
   state; these are the work-order states, which had no pill variants because until now only staff
   read them, inside a table that said what the column meant. */
.pill.assigned { background: #fbf6ec; border-color: #e6d9bf; color: #6b5324; }
.pill.completed { background: var(--line-soft); border-color: var(--line); color: var(--slate-3); }
.pill.invoiced { background: #f2f6f3; border-color: #cfded4; color: var(--success); }
.pill.requested { background: var(--white); border-color: var(--line); color: var(--slate-2); }

/* Recurring maintenance: unit, job, interval, first due, contractor, then the button. */
.inline-fields.plan { grid-template-columns: 1.6fr 1.7fr 0.6fr 1fr 1.4fr auto; }

/* A stopped plan still belongs in the list — it is the record of a decision — but it must not
   read as live work. Dimmed rather than hidden, and the link stays at full strength so it can
   still be opened and started again. */
.muted-row td { color: var(--slate-2); }
.muted-row td a.strong { color: var(--slate); }

/* Notices -------------------------------------------------------------------
   .notice-doc is the frozen text of an issued notice. Note the name: .notice on
   its own is this stylesheet's alert box and has been since the first screen,
   so the document body deliberately does not reuse it. */

.notice-doc {
    white-space: pre-wrap;
    background: var(--white);
    border: 1px solid var(--line);
    padding: 1.75rem 2rem;
    line-height: 1.75;
    color: var(--ink);
    max-width: 44rem;
    margin-bottom: 1rem;
}

.merge-fields { list-style: none; padding: 0; margin: 0 0 0.5rem; max-width: 44rem; }

.merge-fields li {
    display: grid;
    grid-template-columns: 13rem 1fr;
    gap: 1rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--line-soft);
    font-size: 0.85rem;
}

.merge-fields li:last-child { border-bottom: none; }
.merge-fields code { color: var(--ink); font-size: 0.82rem; }
.merge-fields span { color: var(--slate); }

/* "Not recorded" is a real state, not a missing value: Echox produced the notice
   and nobody has said it reached anyone. It reads as unfinished on purpose. */
.undelivered { color: var(--slate-2); font-style: italic; }

.sub-head {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--slate-2);
    margin: 2rem 0 0.5rem;
    font-weight: 500;
}

.inline-fields.template-pick { grid-template-columns: 22rem auto; }

/* A notice is served on paper. Printing the page should produce the document and
   nothing else — not the nav, not the form that records delivery. */
@media print {
    .shell-bar, .page-head .eyebrow, .no-print, .pager, .btn, .btn-inline, .btn-quiet { display: none !important; }
    .shell-body { padding: 0; }
    .panel { margin-bottom: 1rem; }
    .notice-doc { border: none; padding: 0; max-width: none; }
}

/* The add-an-owner row on the ownership panel: the searchable picker beside the
   share it is being given. The share box is narrow on purpose — it holds at most
   "100.00", and a full-width one invites the idea that more belongs in it. */
.inline-fields.owner-add { grid-template-columns: 1fr 8rem; max-width: 30rem; align-items: end; }

/* The handful of tenancies named inside an obligation banner. Capped at five in
   the markup: the banner exists to prompt action, and a list of forty is a report,
   not a prompt. */
.owed-list { list-style: none; padding: 0; margin: 0.85rem 0 0; display: grid; gap: 0.5rem; }
.owed-list li { font-size: 0.9rem; }
.owed-list a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--line); }
.owed-list a:hover { color: var(--brass); border-bottom-color: var(--brass); }
