/* ==========================================================================
   Hanti-Dhowr Owner Portal / PWA — Design System
   Hand-maintained tokens + components, zero external/CDN dependencies
   (safe for production, no build toolchain — CLAUDE.md-equivalent
   discipline to apps.portal's own design-system.css). Deliberately its own
   token set (prefixed hd, not the Staff Portal's own navy/gold tokens),
   so the two surfaces can never accidentally drift into each other
   visually.
   ========================================================================== */

:root {
  /* Brand */
  --hd-navy: #0e1a30;
  --hd-navy-soft: #17294a;
  --hd-navy-softer: #22375e;
  --hd-gold: #c9973f;
  --hd-gold-soft: #e8c98a;

  /* Surfaces */
  --hd-background: #f5f4f1;
  --hd-surface: #ffffff;
  --hd-surface-sunken: #f0eee9;

  /* Text */
  --hd-text: #171c26;
  --hd-muted: #666c78;
  --hd-faint: #9297a1;
  --hd-on-navy: #f4f2ec;
  --hd-on-navy-muted: #aab2c4;

  /* Borders / elevation */
  --hd-border: #e3e0d8;
  --hd-border-soft: #ecebe6;
  --shadow-sm: 0 1px 2px rgba(14, 26, 48, 0.06);
  --shadow-md: 0 6px 20px rgba(14, 26, 48, 0.09);
  --shadow-lg: 0 16px 40px rgba(14, 26, 48, 0.14);

  /* Semantic status — ONE canonical palette (--status-*), professional
     medium-rich tones, never neon. Never using --hd-gold as a status color
     — gold stays reserved for brand/navigation/primary actions only. Every
     --hd-* status alias below just points at these, so the soft/tinted
     badge system and the full-color operational-card system (further
     down) can never drift apart onto two different palettes. */
  --status-green: #147a53;
  --status-orange: #c2660c;
  --status-cyan: #0f766e;
  --status-blue: #2159a6;
  --status-red: #b33131;
  --status-slate: #4b5563;

  --hd-success: var(--status-green);
  --hd-success-bg: #e4f4ec;
  --hd-warning: var(--status-orange);
  --hd-warning-bg: #fbf0da;
  --hd-danger: var(--status-red);
  --hd-danger-bg: #fbe8e8;
  --hd-info: var(--status-blue);
  --hd-info-bg: #e7effb;
  --hd-teal: var(--status-cyan);
  --hd-teal-bg: #e2f4f2;
  --hd-neutral: var(--status-slate);
  --hd-neutral-bg: #eceae4;

  /* Radius */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 18px;
  --radius-pill: 999px;

  /* Spacing scale */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;

  --sidebar-width: 260px;
  --topbar-height: 60px;
  --bottomnav-height: 64px;
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-top: env(safe-area-inset-top, 0px);

  --max-content-width: 1440px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--hd-background);
  color: var(--hd-text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
button { font-family: inherit; }

/* Defensive wrapping for real (unbounded-length) data — owner/property/
   tenant/agreement names — inside flex layouts. Flex items default to
   min-width:auto, so an unbroken long token (no spaces/hyphens) can force
   the row wider than its container even though the surrounding text
   wraps; this makes every such text node break instead of overflowing. */
.hcard-title, .hcard-meta, .field-value, .field-label,
.page-header h1, .page-header .page-subtitle, .kpi-label,
.auth-footnote, .empty-state p, .auth-card h1, .brand-word, .brand-sub {
  overflow-wrap: anywhere;
  min-width: 0;
}

h1, h2, h3, h4 { margin: 0; font-weight: 650; letter-spacing: -0.01em; color: var(--hd-text); }
/* Deliberate levels below page title (.page-header h1, 21px) and section
   heading (.section-heading h2, 16.5px): h3 is a card heading, h4 a
   sub-grouping inside a card — never left to each browser's own default
   h3/h4 size, which varied it inconsistently across cards. */
h3 { font-size: 15px; }
h4 { font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--hd-muted); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0; padding: 0; margin: -1px;
}

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

:focus-visible {
  outline: 2px solid var(--hd-gold);
  outline-offset: 2px;
}

/* Default size for every icon this app renders (see the `icon` templatetag
   — every call always carries this class). Without an explicit
   width/height, an <svg> with only a viewBox falls back to the browser's
   300x150px replaced-element default — this is the fix for that, applied
   once at the root instead of patched per call site. Context-specific
   selectors below (bottom-nav, sidebar nav, hcard-media, empty-state)
   override this via ordinary specificity where a different size is
   wanted. */
svg.icon { width: 20px; height: 20px; flex-shrink: 0; }

/* ---------- Brand mark ---------- */

.brand-mark {
  width: 38px; height: 38px; border-radius: var(--radius-sm);
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(155deg, var(--hd-navy-softer), var(--hd-navy));
  color: var(--hd-gold-soft);
  font-weight: 700; font-size: 15px; letter-spacing: 0.02em;
  flex-shrink: 0;
}

/* Flex items default to min-width:auto, which refuses to shrink below the
   text's own intrinsic width — under Android Chrome's font-boost text
   autosizing (which can inflate "Hanti-Dhowr"/"Owner Portal" well past
   their authored size on a narrow column, e.g. inside .auth-card), that
   forced the whole brand row wider than its container instead of
   wrapping/shrinking, pushing it past the card edge. min-width: 0 lets it
   shrink and wrap like any other flex child. */
.brand-text { min-width: 0; }

/* ==========================================================================
   App shell — mobile-first: single column, sticky top bar, fixed bottom nav.
   Desktop (>=1024px): fixed sidebar replaces the bottom nav.
   ========================================================================== */

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

/* Mobile-first default: the desktop sidebar is hidden below the 1024px
   breakpoint (see @media (min-width: 1024px) further down, which is the
   ONLY place that turns it into the visible flex column). Without this
   base rule, the <aside> — an ordinary block element by default — was
   rendering fully visible and completely unstyled at the top of every
   page below 1024px (including any desktop browser window narrower than
   1024 CSS px, e.g. with DevTools docked open) — this was the actual
   cause of the "essentially unstyled/raw HTML" appearance found during
   visual review, not a missing/broken stylesheet. */
.op-sidebar { display: none; }

/* Compact WHITE mobile header (approved design §21/§32/§41 — not navy):
   navy is reserved for the sidebar; the mobile workspace stays light,
   matching the desktop topbar's own white/bordered treatment below. */
.op-topbar {
  position: sticky; top: 0; z-index: 30;
  height: calc(var(--topbar-height) + var(--safe-top));
  padding-top: var(--safe-top);
  display: flex; align-items: center; justify-content: space-between;
  padding-left: var(--space-4); padding-right: var(--space-4);
  background: var(--hd-surface);
  color: var(--hd-text);
  border-bottom: 1px solid var(--hd-border-soft);
}

.op-topbar .brand-row { display: flex; align-items: center; gap: var(--space-3); }
.op-topbar .brand-word { font-weight: 650; font-size: 16px; color: var(--hd-navy); }
.op-topbar .brand-sub { font-size: 10.5px; color: var(--hd-muted); letter-spacing: 0.03em; text-transform: uppercase; }
.op-topbar .icon-btn {
  width: 38px; height: 38px; border-radius: var(--radius-pill); flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--hd-surface-sunken); color: var(--hd-navy);
  border: none; cursor: pointer;
}
.op-topbar .icon-btn svg { width: 20px; height: 20px; }

.op-main { flex: 1; width: 100%; }

.op-content {
  max-width: var(--max-content-width);
  margin: 0 auto;
  padding: var(--space-5) var(--space-4) calc(var(--bottomnav-height) + var(--safe-bottom) + var(--space-6));
  width: 100%;
}

/* ---------- Mobile bottom navigation ---------- */

.op-bottomnav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex;
  background: var(--hd-surface);
  border-top: 1px solid var(--hd-border);
  padding-bottom: var(--safe-bottom);
  box-shadow: 0 -4px 20px rgba(14, 26, 48, 0.08);
}

.op-bottomnav .op-navitem {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 9px 4px 8px; min-height: 56px;
  color: var(--hd-muted); font-size: 11.5px; font-weight: 600;
  border: none; background: none; cursor: pointer;
}
.op-bottomnav .op-navitem svg { width: 22px; height: 22px; }
.op-bottomnav .op-navitem.active { color: var(--hd-navy); }
.op-bottomnav .op-navitem.active .nav-icon-dot { background: var(--hd-gold); }
.op-bottomnav .op-navitem .nav-icon-wrap { position: relative; }

/* ---------- "More" bottom sheet (mobile) ---------- */

.op-more-backdrop {
  position: fixed; inset: 0; background: rgba(14, 20, 33, 0.45);
  z-index: 49; opacity: 0; pointer-events: none; transition: opacity 0.18s ease;
}
.op-more-backdrop.open { opacity: 1; pointer-events: auto; }

.op-more-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  background: var(--hd-surface);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: var(--space-3) var(--space-4) calc(var(--safe-bottom) + var(--space-5));
  transform: translateY(100%);
  transition: transform 0.22s cubic-bezier(.2,.8,.2,1);
  box-shadow: var(--shadow-lg);
}
.op-more-sheet.open { transform: translateY(0); }
.op-more-sheet .sheet-handle {
  width: 40px; height: 4px; border-radius: var(--radius-pill);
  background: var(--hd-border); margin: var(--space-2) auto var(--space-4);
}
.op-more-sheet .sheet-item {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 13px var(--space-2); font-weight: 600; font-size: 15px;
  border-bottom: 1px solid var(--hd-border-soft);
}
.op-more-sheet .sheet-item:last-child { border-bottom: none; }
.op-more-sheet form.sheet-item-form { margin: 0; }
.op-more-sheet form.sheet-item-form button {
  display: flex; align-items: center; gap: var(--space-3); width: 100%;
  padding: 13px var(--space-2); font-weight: 600; font-size: 15px; color: var(--hd-danger);
  background: none; border: none; text-align: left; cursor: pointer; font-family: inherit;
}

/* ==========================================================================
   Desktop (>=1024px): sidebar replaces bottom nav; content gets a max width.
   ========================================================================== */

@media (min-width: 1024px) {
  .op-shell { flex-direction: row; }

  .op-sidebar {
    width: var(--sidebar-width); flex-shrink: 0;
    background: linear-gradient(180deg, var(--hd-navy), var(--hd-navy-soft));
    color: var(--hd-on-navy);
    display: flex; flex-direction: column;
    position: sticky; top: 0; height: 100vh; height: 100dvh;
    padding: var(--space-5) var(--space-4);
  }
  .op-sidebar .brand-row { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-7); }
  .op-sidebar .brand-word { font-weight: 650; font-size: 17px; }
  .op-sidebar .brand-sub { font-size: 11px; color: var(--hd-on-navy-muted); letter-spacing: 0.03em; text-transform: uppercase; }

  /* Deliberately NOT flex:1 on .primary-nav — that used to stretch it to
     fill all remaining sidebar height, shoving .secondary-nav all the way
     down and leaving a large empty gap between "Leases" and "Agreements".
     Nav groups now sit naturally together near the top; only
     .sidebar-footer (Sign out) is pushed to the bottom, via its own
     margin-top: auto below. */
  .op-sidebar .primary-nav, .op-sidebar .secondary-nav { display: flex; flex-direction: column; gap: 4px; }
  .op-sidebar .nav-link {
    position: relative;
    display: flex; align-items: center; gap: var(--space-3);
    min-height: 46px;
    padding: 12px var(--space-3) 12px calc(var(--space-3) + 3px);
    border-radius: var(--radius-md); border-left: 3px solid transparent;
    color: var(--hd-on-navy-muted); font-weight: 600; font-size: 14.5px;
    transition: background-color 0.12s ease, color 0.12s ease;
  }
  .op-sidebar .nav-link svg { width: 19px; height: 19px; flex-shrink: 0; }
  .op-sidebar .nav-link:hover { background: rgba(255,255,255,0.06); color: var(--hd-on-navy); }
  /* Active item: a lighter navy/charcoal pill (never a gold wash) with a
     gold left accent + gold icon + white text — gold marks the ONE active
     item, it never fills the whole pill. */
  .op-sidebar .nav-link.active {
    background: rgba(255,255,255,0.09); color: #ffffff;
    border-left-color: var(--hd-gold); font-weight: 650;
  }
  .op-sidebar .nav-link.active svg { color: var(--hd-gold); }
  .op-sidebar .nav-divider { height: 1px; background: rgba(255,255,255,0.1); margin: var(--space-4) 0; flex-shrink: 0; }

  .op-sidebar .sidebar-footer { margin-top: auto; padding-top: var(--space-4); border-top: 1px solid rgba(255,255,255,0.08); }
  .op-sidebar form.logout-form button {
    display: flex; align-items: center; gap: var(--space-3); width: 100%;
    padding: 11px var(--space-3); border-radius: var(--radius-md);
    color: var(--hd-on-navy-muted); font-weight: 600; font-size: 14.5px;
    background: none; border: none; text-align: left; cursor: pointer; font-family: inherit;
  }
  .op-sidebar form.logout-form button:hover { background: rgba(255,255,255,0.06); color: var(--hd-on-navy); }

  .op-topbar { display: none; }
  .op-bottomnav, .op-more-backdrop, .op-more-sheet { display: none; }

  .op-main { display: flex; flex-direction: column; }
  .op-content { padding: var(--space-5) var(--space-6) var(--space-6); }

  .op-desktop-topbar {
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--space-5) var(--space-6); max-width: var(--max-content-width); margin: 0 auto; width: 100%;
    border-bottom: 1px solid var(--hd-border-soft);
  }
  .op-desktop-topbar-title { font-size: 15px; font-weight: 650; color: var(--hd-text); }
}

@media (max-width: 1023.98px) {
  .op-desktop-topbar { display: none; }
}

/* ---------- Account chip (desktop top bar) ---------- */

.op-account-chip {
  display: flex; align-items: center; gap: var(--space-3); max-width: 280px;
  padding: 6px var(--space-3) 6px 6px; border-radius: var(--radius-pill);
  background: var(--hd-surface-sunken); border: 1px solid var(--hd-border-soft);
}
.op-account-chip .op-avatar-name { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.op-account-chip .op-name, .op-account-chip .op-role {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.op-account-chip .op-name { font-weight: 650; font-size: 13.5px; }
.op-account-chip .op-role { font-size: 11.5px; color: var(--hd-muted); }

.op-avatar {
  width: 38px; height: 38px; border-radius: var(--radius-pill);
  background: var(--hd-navy); color: var(--hd-gold-soft);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 13.5px; flex-shrink: 0;
}

/* ==========================================================================
   Page furniture
   ========================================================================== */

.page-header { margin-bottom: var(--space-5); }
.page-header-top { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
/* 22px mobile / 28px desktop — within the approved 26-32px desktop range,
   mobile sizes proportionally reduced rather than repeating the desktop
   size (§28). */
.page-header h1 { font-size: 22px; }
.page-header .page-subtitle { color: var(--hd-muted); font-size: 14px; margin-top: 4px; }
@media (min-width: 1024px) { .page-header h1 { font-size: 28px; } }

.breadcrumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  font-size: 13px; color: var(--hd-muted); margin-bottom: var(--space-4);
}
.breadcrumbs a { color: var(--hd-muted); }
.breadcrumbs a:hover { color: var(--hd-navy); }
.breadcrumbs .sep { color: var(--hd-faint); }
.breadcrumbs .current { color: var(--hd-text); font-weight: 600; }

.alert { padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); margin-bottom: var(--space-4); font-size: 14px; }
.alert-error { background: var(--hd-danger-bg); color: var(--hd-danger); }
.alert-success { background: var(--hd-success-bg); color: var(--hd-success); }
.alert-info, .alert-warning { background: var(--hd-info-bg); color: var(--hd-info); }

/* ==========================================================================
   Cards
   ========================================================================== */

.card {
  background: var(--hd-surface); border: 1px solid var(--hd-border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}
.card-pad { padding: var(--space-5); }

.card-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-4); }
/* auto-fill (not a fixed column count) so 1-2 records take only the width
   they need instead of being forced to stretch across empty columns, while
   more records still wrap into a full, intentional grid. */
@media (min-width: 640px) {
  .card-grid.cols-2 { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
  .card-grid.cols-3 { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
}

.section-heading {
  display: flex; align-items: baseline; justify-content: space-between;
  margin: var(--space-6) 0 var(--space-3);
}
/* 18px mobile / 21px desktop — approved range is 20-22px desktop; kept
   just under that on mobile so it stays clearly subordinate to the 22px
   page title there. */
.section-heading h2 { font-size: 18px; }
.section-heading .see-all { font-size: 13.5px; font-weight: 650; color: var(--hd-navy); }
@media (min-width: 1024px) { .section-heading h2 { font-size: 21px; } }

/* ---------- KPI tiles ---------- */

/* 2x2 through mobile AND tablet; only true desktop (>=1024px) goes 4-across
   — a 640px breakpoint put a phone-in-landscape and a real tablet in the
   same "4 columns" bucket, cramping the KPI cards on both. */
.kpi-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
@media (min-width: 1024px) { .kpi-grid { grid-template-columns: repeat(4, 1fr); } }

/* Shared 7-color fill source — the ONE place a "filled" tile's background
   comes from, reused by KPI cards and the Portfolio Status mini-cards
   below (the .hcard-filled/.hcard-fill-* family for Property/Unit/Lease/
   Agreement cards keeps its own equivalent set — same --status-*/--hd-navy
   tokens underneath, just a separate class namespace since its internal
   structure, .hcard-title/.hcard-stat/etc, is genuinely different from
   .kpi-value/.kpi-label — not duplicated one-off overrides, two thin
   variant-class families sharing one real color source). */
.kpi-fill-navy   { --kpi-fill: var(--hd-navy); }
.kpi-fill-blue   { --kpi-fill: var(--status-blue); }
.kpi-fill-green  { --kpi-fill: var(--status-green); }
.kpi-fill-orange { --kpi-fill: var(--status-orange); }
.kpi-fill-cyan   { --kpi-fill: var(--status-cyan); }
.kpi-fill-red    { --kpi-fill: var(--status-red); }
.kpi-fill-slate  { --kpi-fill: var(--status-slate); }

.kpi-card {
  background: var(--kpi-fill, var(--hd-navy)); color: #ffffff;
  border-radius: var(--radius-lg); padding: var(--space-4);
  box-shadow: var(--shadow-md); position: relative; overflow: hidden;
}
.kpi-icon {
  width: 34px; height: 34px; border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.16); color: #ffffff;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: var(--space-3);
}
.kpi-icon svg { width: 17px; height: 17px; }
.kpi-value { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; color: #ffffff; line-height: 1.1; }
.kpi-label { font-size: 12px; color: rgba(255, 255, 255, 0.85); margin-top: 4px; font-weight: 600; }
.kpi-sub { font-size: 11.5px; color: rgba(255, 255, 255, 0.7); margin-top: 3px; }

/* ---------- Portfolio status: white container, full-color mini-cards ---------- */

.status-strip {
  background: var(--hd-surface); border: 1px solid var(--hd-border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  padding: var(--space-4);
}
.status-strip-title { font-size: 12.5px; font-weight: 650; color: var(--hd-muted); margin-bottom: var(--space-3); }
/* auto-fit rather than a hard repeat(3, 1fr): 3 mini-cards fit comfortably
   at almost any width this appears at, but this collapses to fewer
   columns instead of ever compressing on a very narrow phone. */
.status-strip-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: var(--space-3); }

.mini-status-card {
  background: var(--kpi-fill, var(--hd-navy)); color: #ffffff;
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
  padding: var(--space-3); display: flex; align-items: center; gap: var(--space-2);
}
.mini-status-icon {
  width: 28px; height: 28px; border-radius: var(--radius-sm); flex-shrink: 0;
  background: rgba(255, 255, 255, 0.18); color: #ffffff;
  display: flex; align-items: center; justify-content: center;
}
.mini-status-icon svg { width: 14px; height: 14px; }
.mini-status-value { font-size: 17px; font-weight: 700; line-height: 1.1; }
.mini-status-label { font-size: 11.5px; color: rgba(255, 255, 255, 0.85); font-weight: 600; }

/* ---------- Recent Activity — deliberately white, never status-colored ---------- */

.activity-list { display: flex; flex-direction: column; gap: var(--space-2); }
.activity-item {
  display: flex; align-items: center; gap: var(--space-3);
  background: var(--hd-surface); border: 1px solid var(--hd-border-soft);
  border-radius: var(--radius-md); padding: var(--space-3) var(--space-4);
  box-shadow: var(--shadow-sm);
}
.activity-icon {
  width: 32px; height: 32px; border-radius: var(--radius-sm); flex-shrink: 0;
  background: var(--hd-surface-sunken); color: var(--hd-navy);
  display: flex; align-items: center; justify-content: center;
}
.activity-icon svg { width: 16px; height: 16px; }
.activity-text { font-size: 13.5px; font-weight: 600; color: var(--hd-text); min-width: 0; overflow-wrap: anywhere; }
.activity-time { font-size: 11.5px; color: var(--hd-faint); margin-top: 1px; }

/* ---------- Property / Lease / Agreement cards (horizontal) ---------- */

.hcard {
  display: flex; gap: 18px; align-items: flex-start;
  background: var(--hd-surface); border: 1px solid var(--hd-border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  padding: 20px;
}
.hcard:hover { box-shadow: var(--shadow-md); border-color: var(--hd-border); }

/* Small, supportive icon block — never the dominant visual element. */
.hcard-media {
  flex-shrink: 0; width: 52px; height: 52px; border-radius: var(--radius-md);
  background: var(--hd-surface-sunken); border: 1px solid var(--hd-border-soft);
  display: flex; align-items: center; justify-content: center; color: var(--hd-navy);
}
.hcard-media svg { width: 22px; height: 22px; }

.hcard-body { flex: 1; min-width: 0; }

/* Title is the strongest text; status badge stays cleanly top-right and
   never competes with it, even if the title wraps to two lines. */
.hcard-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
/* The title/meta wrapper needs min-width:0 to actually be allowed to
   shrink below its content's intrinsic width in this flex row — without
   it, a long unbroken owner/property/tenant name can push the status
   badge out past the card edge instead of wrapping (the .hcard-title/
   .hcard-meta overflow-wrap rule alone isn't enough; that only controls
   how text inside the box breaks, not whether the box itself may shrink). */
.hcard-top > div:first-child { min-width: 0; }
.hcard-title { font-size: 16px; font-weight: 650; color: var(--hd-text); line-height: 1.3; }
.hcard-meta { font-size: 13px; color: var(--hd-muted); margin-top: 3px; }

/* A quieter secondary line for reference codes/numbers — deliberately
   never given the same visual weight as the title (spec: "codes must not
   compete with titles"). */
.hcard-secondary { font-size: 11.5px; color: var(--hd-faint); margin-top: var(--space-3); }

/* Metric blocks: muted label, strong value — grid with auto-fit so they
   reflow to fewer columns (down to one) as available width shrinks,
   instead of ever compressing into an unreadable single line. */
.hcard-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: var(--space-4); margin-top: var(--space-4);
  padding-top: var(--space-4); border-top: 1px solid var(--hd-border-soft);
}
.hcard-stat { font-size: 12px; color: var(--hd-muted); font-weight: 600; letter-spacing: 0.01em; }
.hcard-stat strong { color: var(--hd-text); font-size: 16px; font-weight: 650; display: block; margin-bottom: 2px; letter-spacing: normal; }

.hcard-footer { display: flex; justify-content: flex-end; margin-top: var(--space-4); }
.hcard-cta {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 13px; font-weight: 650; color: var(--hd-navy);
}
.hcard-cta svg { width: 16px; height: 16px; }

.hcard-list { display: flex; flex-direction: column; gap: var(--space-4); }
@media (min-width: 900px) {
  /* auto-fit (not auto-fill): with only one record, its own 1fr track can
     grow to use the freed row instead of leaving a dead empty column next
     to it — the max-width on the card itself (not the grid) is what then
     stops that single card from becoming a giant stretched shape. */
  .hcard-list.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--space-4); }
  .hcard-list.grid-2 > * { max-width: 560px; }
}

/* ---------- Status badges ---------- */

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 650; letter-spacing: 0.01em; white-space: nowrap;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge-success { background: var(--hd-success-bg); color: var(--hd-success); }
.badge-warning { background: var(--hd-warning-bg); color: var(--hd-warning); }
.badge-danger { background: var(--hd-danger-bg); color: var(--hd-danger); }
.badge-info { background: var(--hd-info-bg); color: var(--hd-info); }
.badge-teal { background: var(--hd-teal-bg); color: var(--hd-teal); }
.badge-neutral { background: var(--hd-neutral-bg); color: var(--hd-neutral); }
.badge-muted { background: var(--hd-surface-sunken); color: var(--hd-muted); }


/* ---------- Full-color operational status cards ----------
   Property/Unit/Lease/Agreement list & preview cards use the entire
   surface in a semantic status color (not just a border/tint) — applied
   via the `status_fill` templatetag as `hcard-filled hcard-fill-<color>`
   alongside the existing .hcard/.card structure, so every internal piece
   (title, meta, stats, secondary line, media block, CTA, badge) only
   needs ONE override block here regardless of which of the 6 colors is
   in play. Detail pages deliberately do NOT get this treatment (CLAUDE.md
   §33-equivalent: a whole detail page must never turn solid green/orange
   — only its status badge does), so this only ever appears on cards
   inside a list/grid. */
.hcard-fill-green  { --status-fill: var(--status-green); }
.hcard-fill-orange { --status-fill: var(--status-orange); }
.hcard-fill-cyan   { --status-fill: var(--status-cyan); }
.hcard-fill-blue   { --status-fill: var(--status-blue); }
.hcard-fill-red    { --status-fill: var(--status-red); }
.hcard-fill-slate  { --status-fill: var(--status-slate); }

.hcard-filled {
  background: var(--status-fill, var(--hd-navy));
  border-color: var(--status-fill, var(--hd-navy));
  box-shadow: var(--shadow-md);
}
.hcard-filled:hover { box-shadow: var(--shadow-lg); }
.hcard-filled .hcard-title { color: #ffffff; }
.hcard-filled .hcard-meta { color: rgba(255, 255, 255, 0.82); }
.hcard-filled .hcard-secondary { color: rgba(255, 255, 255, 0.65); }
.hcard-filled .hcard-stat { color: rgba(255, 255, 255, 0.75); }
.hcard-filled .hcard-stat strong { color: #ffffff; }
.hcard-filled .hcard-stats { border-top-color: rgba(255, 255, 255, 0.22); }
.hcard-filled .hcard-media {
  background: rgba(255, 255, 255, 0.16); border-color: rgba(255, 255, 255, 0.28); color: #ffffff;
}
.hcard-filled .hcard-cta { color: #ffffff; }
.hcard-filled .field-label { color: rgba(255, 255, 255, 0.75); }
.hcard-filled .field-value { color: #ffffff; }
.hcard-filled .field-row { border-bottom-color: rgba(255, 255, 255, 0.16); }
/* Badge harmonizes with the fill instead of clashing with its own
   unrelated soft color — specificity (2 classes) beats the plain
   .badge-success/.badge-warning/etc it's layered on top of, regardless of
   which one. Status is still communicated as visible text, never color
   alone (the badge label itself is unchanged). */
.hcard-filled .badge { background: rgba(255, 255, 255, 0.22); color: #ffffff; border: 1px solid rgba(255, 255, 255, 0.42); }
/* A .btn-outline action (e.g. property detail's "View full agreement")
   sitting inside a filled card needs its own outline recolored — the
   default navy-on-white outline is unreadable against a solid fill. */
.hcard-filled .btn-outline {
  background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.5); color: #ffffff;
}
.hcard-filled .btn-outline:hover { background: rgba(255, 255, 255, 0.22); border-color: #ffffff; }

/* ==========================================================================
   Tabs
   ========================================================================== */

.tabs { display: flex; gap: var(--space-1); overflow-x: auto; border-bottom: 1px solid var(--hd-border); margin-bottom: var(--space-5); }
.tabs::-webkit-scrollbar { display: none; }
.tab-link {
  padding: var(--space-3) var(--space-3); font-weight: 650; font-size: 14px;
  color: var(--hd-muted); border-bottom: 2px solid transparent; white-space: nowrap;
}
.tab-link.active { color: var(--hd-navy); border-bottom-color: var(--hd-gold); }

/* ==========================================================================
   Definition lists / detail rows
   ========================================================================== */

.detail-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-4); }
@media (min-width: 768px) { .detail-grid.cols-2 { grid-template-columns: 1fr 1fr; } }

.field-row { display: flex; justify-content: space-between; gap: var(--space-3); padding: 11px 0; border-bottom: 1px solid var(--hd-border-soft); }
.field-row:last-child { border-bottom: none; }
.field-row .field-label { color: var(--hd-muted); font-size: 13.5px; }
.field-row .field-value { font-weight: 600; font-size: 14px; text-align: right; }

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: 11px 18px; border-radius: var(--radius-md); font-weight: 650; font-size: 14.5px;
  border: 1px solid transparent; cursor: pointer; min-height: 44px;
}
.btn-primary { background: var(--hd-navy); color: var(--hd-on-navy); }
.btn-primary:hover { background: var(--hd-navy-soft); }
.btn-outline { background: var(--hd-surface); border-color: var(--hd-border); color: var(--hd-text); }
.btn-outline:hover { border-color: var(--hd-navy); }
.btn-gold { background: var(--hd-gold); color: var(--hd-navy); }
.btn-gold:hover { background: var(--hd-gold-soft); }
.btn-block { width: 100%; }
.btn-sm { padding: 8px 14px; min-height: 36px; font-size: 13.5px; }

.doc-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-3); }

/* ==========================================================================
   Forms (login)
   ========================================================================== */

.field { margin-bottom: var(--space-4); }
.field label { display: block; font-weight: 650; font-size: 13.5px; margin-bottom: 6px; color: var(--hd-text); }
.field input {
  width: 100%; padding: 12px 14px; border-radius: var(--radius-md);
  border: 1px solid var(--hd-border); background: var(--hd-surface); color: var(--hd-text);
  font-size: 16px; font-family: inherit;
}
.field input:focus { outline: none; border-color: var(--hd-navy); box-shadow: 0 0 0 3px rgba(14,26,48,0.08); }
.field.has-error input { border-color: var(--hd-danger); }
.field-error { display: block; color: var(--hd-danger); font-size: 12.5px; margin-top: 5px; }

.password-field { position: relative; }
.password-toggle {
  position: absolute; right: 6px; top: 6px; bottom: 6px;
  background: none; border: none; color: var(--hd-muted); font-size: 12.5px; font-weight: 650;
  padding: 0 10px; cursor: pointer; border-radius: var(--radius-sm);
}
.password-toggle:hover { color: var(--hd-navy); }

/* ==========================================================================
   Auth page (login)
   ========================================================================== */

.auth-page {
  min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center;
  padding: var(--space-5); background: radial-gradient(ellipse at top, var(--hd-navy-soft) 0%, var(--hd-navy) 60%);
}
.auth-card {
  width: 100%; max-width: 440px; margin-inline: auto; box-sizing: border-box;
  background: var(--hd-surface);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: var(--space-7) var(--space-6);
  border-top: 3px solid var(--hd-gold);
}
.auth-brand { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-6); }
.auth-brand .brand-word { display: block; font-weight: 700; font-size: 16px; color: var(--hd-text); }
.auth-brand .brand-sub { display: block; font-size: 11.5px; color: var(--hd-muted); letter-spacing: 0.03em; text-transform: uppercase; margin-top: 1px; }
.auth-card h1 { font-size: 19px; margin-bottom: var(--space-6); }
.auth-footnote { text-align: center; font-size: 12.5px; color: var(--hd-faint); margin-top: var(--space-6); }

/* ==========================================================================
   Empty states
   ========================================================================== */

.empty-state {
  text-align: center; padding: var(--space-7) var(--space-4);
  color: var(--hd-muted);
}
.empty-state .empty-icon {
  width: 52px; height: 52px; margin: 0 auto var(--space-4);
  border-radius: var(--radius-pill); background: var(--hd-surface-sunken);
  display: flex; align-items: center; justify-content: center; color: var(--hd-faint);
}
.empty-state .empty-icon svg { width: 24px; height: 24px; }
.empty-state h3 { font-size: 15.5px; color: var(--hd-text); margin-bottom: 4px; }
.empty-state p { font-size: 13.5px; max-width: 320px; margin: 0 auto; }

/* ==========================================================================
   Error pages (403 / 404)
   ========================================================================== */

.error-page {
  min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center;
  flex-direction: column; text-align: center; padding: var(--space-5);
  background: var(--hd-background);
}
.error-page .code { font-size: 13px; font-weight: 700; color: var(--hd-gold); letter-spacing: 0.08em; margin-bottom: var(--space-3); }
.error-page h1 { font-size: 21px; margin-bottom: var(--space-2); }
.error-page p { color: var(--hd-muted); max-width: 380px; margin-bottom: var(--space-5); }

/* ==========================================================================
   Utility
   ========================================================================== */

.op-pagination { display: flex; align-items: center; justify-content: space-between; margin-top: var(--space-5); font-size: 13.5px; }
.op-pagination-links { display: flex; gap: var(--space-2); }

.mt-0 { margin-top: 0; }
.text-muted { color: var(--hd-muted); }
.text-center { text-align: center; }
.stack { display: flex; flex-direction: column; gap: var(--space-3); }
