/* ============================================================================
 * Stradl — design system  (rebrand 2026-05-14)
 *
 * Brand palette:
 *   #0A2D4D  dark blue          surfaces & text in dark mode, navbar
 *   #0D6EFD  vivid blue         primary action / link / active state
 *   #00B2A9  teal               accent (charts, secondary highlights)
 *   #5CCB3B  green              success / positive
 *   #E6ECEF  light grey-beige   light-mode body background
 *
 * Modes are toggled by setting `data-theme="light" | "dark"` on <html>.
 * The contextual sub-nav (--color-subnav-*) was rebranded 2026-05-15
 * from the legacy LodgeForce cream to a muted Stradl teal that ties
 * back to the --color-accent (#00B2A9) without shouting. The orange
 * active accent (--color-active-accent) is intentionally preserved —
 * its high-contrast pop against the new teal still reads as the
 * "you are here" signal Hamish wanted.
 * ============================================================================ */

:root,
:root[data-theme='light'] {
  /* ─── Brand (Stradl primary blue) ─── */
  --color-primary:        #0D6EFD;
  --color-primary-hover:  #0A58CC;
  --color-primary-soft:   #E6F0FF;
  --color-primary-ring:   rgba(13, 110, 253, 0.18);
  --color-accent:         #00B2A9;

  /* ─── Surfaces ─── */
  --color-bg:             #E6ECEF;
  --color-surface:        #FFFFFF;
  --color-surface-alt:    #F2F5F8;

  /* ─── Text ─── */
  --color-text:           #0A2D4D;
  --color-text-muted:     #5A6B7E;
  --color-text-on-dark:   #FFFFFF;
  --color-text-on-primary:#FFFFFF;

  /* ─── Borders / dividers ─── */
  --color-border:         #CFD8E1;
  --color-border-strong:  #A9B7C4;
  --color-input-border:   #BCC8D5;

  /* ─── Status ─── */
  --color-success:        #3FA827;     /* darker shade of #5CCB3B for AA on white */
  --color-success-bg:     #ECF9E5;
  --color-success-border: #B8E5A7;
  --color-danger:         #B42318;
  --color-danger-bg:      #FFF1F0;
  --color-danger-border:  #F4B8B0;
  --color-warn:           #B54708;
  --color-warn-bg:        #FEF6E7;
  --color-warn-border:    #FBE1A1;

  /* ─── Top navigation bar ─── */
  /* Light-mode navbar = light gray surface (matches body) with dark
   * text. The active tab gets the slightly darker --color-nav-bg-alt
   * pill behind it; teal underline still fires off --color-nav-accent. */
  --color-nav-bg:         #E6ECEF;
  --color-nav-bg-alt:     #D8E0E6;
  --color-nav-border:     #CFD8E1;
  --color-nav-text:       #5A6B7E;
  --color-nav-text-active:#0A2D4D;
  --color-nav-accent:     #00B2A9;
  --color-nav-brand:      #0A2D4D;
  --color-nav-brand-sub:  #5A6B7E;

  /* ─── Active accent (LodgeForce orange) — preserved, the cream sub-nav
   *      uses this for the active item highlight. Untouched per instruction. */
  --color-active-accent:        #d97a3c;
  --color-active-accent-hover:  #c0682a;

  /* ─── Contextual sub-nav (Stradl muted-teal sidebar) ───
   *      Rebranded 2026-05-15 from the legacy cream. Bg is a
   *      desaturated #00B2A9 accent so the sidebar reads as part of
   *      the brand without competing with the primary blue.
   *      Active item: clean white surface so the orange accent pops. */
  --color-subnav-bg:            #B7D4D1;
  --color-subnav-border:        #9CC0BC;
  --color-subnav-text:          #0A2D4D;
  --color-subnav-text-muted:    #4F6B73;
  --color-subnav-icon:          #4F6772;
  --color-subnav-active-bg:     #FFFFFF;
  --color-subnav-active-text:   #0A2D4D;
}

/* ─── Dark mode ───
 *  Triggered by `data-theme="dark"` on <html>, set by the early-bootstrap
 *  inline script in nav-permissions.js (so there's no flash of the wrong
 *  theme before the page paints).
 *
 *  The cream sub-nav block above is deliberately omitted here — those
 *  variables stay at their light-mode values in BOTH modes per Hamish's
 *  "keep the sidebar exactly as is" instruction.
 */
:root[data-theme='dark'] {
  --color-primary:        #3D8BFF;     /* lifted from #0D6EFD for AA on dark surfaces */
  --color-primary-hover:  #5C9FFF;
  --color-primary-soft:   rgba(61, 139, 255, 0.16);
  --color-primary-ring:   rgba(61, 139, 255, 0.32);
  --color-accent:         #2DCDC4;

  --color-bg:             #0A2D4D;
  --color-surface:        #11365A;
  --color-surface-alt:    #173E68;

  --color-text:           #E6ECEF;
  --color-text-muted:     #8FA3B7;
  --color-text-on-dark:   #FFFFFF;
  --color-text-on-primary:#FFFFFF;

  --color-border:         #1F4D7A;
  --color-border-strong:  #2D5E91;
  --color-input-border:   #244F7C;

  --color-success:        #5CCB3B;
  --color-success-bg:     rgba(92, 203, 59, 0.14);
  --color-success-border: rgba(92, 203, 59, 0.36);
  --color-danger:         #FF6B5C;
  --color-danger-bg:      rgba(255, 107, 92, 0.12);
  --color-danger-border:  rgba(255, 107, 92, 0.36);
  --color-warn:           #FFB347;
  --color-warn-bg:        rgba(255, 179, 71, 0.14);
  --color-warn-border:    rgba(255, 179, 71, 0.36);

  /* Navbar deliberately matches body bg in dark mode so the chrome and
   * the page feel like one continuous surface. */
  --color-nav-bg:         #0A2D4D;
  --color-nav-bg-alt:     #103A60;
  --color-nav-border:     #1B4775;
  --color-nav-text:       #A9C0D6;
  --color-nav-text-active:#FFFFFF;
  --color-nav-accent:     #00B2A9;
  --color-nav-brand:      #FFFFFF;
  --color-nav-brand-sub:  #7B96B0;

  /* Dark-mode contextual sub-nav — a deeper navy than the body
   * (#0A2D4D) so the sidebar reads as a recessed panel rather than
   * blending into the page. Light text + icons sit on the deep
   * navy; the active item still pops as a white card with the
   * orange "you are here" stripe leading it, mirroring the
   * light-mode treatment. Rebranded 2026-05-15 from the legacy
   * LodgeForce cream that didn't belong in either mode. */
  --color-subnav-bg:            #062338;
  --color-subnav-border:        rgba(255,255,255,.08);
  --color-subnav-text:          #E6ECEF;
  --color-subnav-text-muted:    #8FA3B7;
  --color-subnav-icon:          #E6ECEF;
  --color-subnav-active-bg:     #FFFFFF;
  --color-subnav-active-text:   #0A2D4D;
}

/* Mode-independent design tokens (fonts, spacing, shape, shadow,
 * layout). Same values regardless of light/dark mode. */
:root {
  /* ─── Typography ─── */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-size-xs:   12px;
  --font-size-sm:   13px;
  --font-size-base: 14px;
  --font-size-md:   15px;
  --font-size-lg:   18px;
  --font-size-xl:   22px;
  --font-size-2xl:  28px;
  --line-height-tight: 1.15;
  --line-height-base:  1.45;

  /* ─── Spacing scale ─── */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;

  /* ─── Shape ─── */
  --radius-sm:  4px;
  --radius-md:  6px;
  --radius-lg:  10px;
  --radius-pill: 999px;

  /* ─── Shadow ─── */
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.05);
  --shadow-md: 0 6px 16px rgba(15, 23, 42, 0.08);
  --shadow-lg: 0 18px 48px rgba(29, 39, 51, 0.18);

  /* ─── Layout ─── */
  --content-max-width: 980px;
  --nav-height: 68px;
}

/* Optional: Inter font (progressive enhancement, no external block) */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: local('Inter'), local('Inter Variable');
}

/* ============================================================================
 * Base
 * ============================================================================ */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-sans);
  font-size: var(--font-size-base);
  line-height: var(--line-height-base);
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: var(--color-primary); text-decoration: none; }
a:hover { color: var(--color-primary-hover); text-decoration: underline; }

/* ============================================================================
 * Top navigation bar
 * ============================================================================ */

.app-nav {
  background: var(--color-nav-bg);
  border-bottom: 1px solid var(--color-nav-border);
  color: var(--color-nav-text);
  height: var(--nav-height);
  position: sticky;
  top: 0;
  z-index: 30;
}

.app-nav-inner {
  max-width: 1480px;
  margin: 0 auto;
  height: 100%;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: 0 var(--space-5);
}

.app-brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
  color: var(--color-nav-brand);
}
.app-brand:hover { text-decoration: none; color: var(--color-nav-brand); }

/* Stradl wordmark logo. Two variants live side-by-side in the navbar
 * markup; CSS toggles which one is visible based on the active theme
 * (data-theme on <html>). Light navbar → plain logo; dark navbar →
 * bordered variant whose white outline lifts the navy wordmark off
 * the dark-blue background. No flash because data-theme is set by
 * auth-gate.js before first paint. */
.app-brand-logo {
  height: 44px;
  width: auto;
  display: block;
}
/* Light mode (default): show the plain logo, hide the bordered one. */
.app-brand-logo-on-dark { display: none; }
/* Dark mode: swap. */
:root[data-theme='dark'] .app-brand-logo-on-light { display: none; }
:root[data-theme='dark'] .app-brand-logo-on-dark  { display: block; }

/* Legacy mark/text/sub spans — kept so any HTML page that still uses
 * the old shape (e.g. a future page added before its author saw the
 * rebrand) doesn't render with broken styling. */
.app-brand-mark {
  font-size: var(--font-size-lg);
  line-height: 1;
  color: var(--color-nav-accent);
}
.app-brand-text {
  font-size: var(--font-size-md);
  font-weight: 700;
  letter-spacing: 0.02em;
}
.app-brand-sub {
  font-size: var(--font-size-xs);
  font-weight: 500;
  color: var(--color-nav-brand-sub);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Auth-card variant (login + set-password). The card background is
 * white so the logo's natural colours read fine — no pill needed. */
.auth-brand {
  display: flex;
  justify-content: center;
  margin-bottom: var(--space-4);
}
.auth-brand-logo {
  height: 64px;
  width: auto;
  display: block;
}

.app-nav-links {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 100%;
}

.app-nav-link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: 100%;
  padding: 0 var(--space-4);
  color: var(--color-nav-text);
  font-size: var(--font-size-base);
  font-weight: 500;
  text-decoration: none;
  border-bottom: 3px solid transparent;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.app-nav-link svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}
.app-nav-link:hover {
  color: var(--color-nav-text-active);
  background: var(--color-nav-bg-alt);
  text-decoration: none;
}
.app-nav-link.active {
  color: var(--color-nav-text-active);
  border-bottom-color: var(--color-active-accent);
  background: var(--color-nav-bg-alt);
}

.app-nav-spacer { flex: 1; }

.app-nav-user {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-nav-text);
}
.app-nav-tenant {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--font-size-xs);
  font-weight: 600;
  color: var(--color-nav-brand-sub);
}
.app-nav-avatar {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  background: var(--color-nav-bg-alt);
  border: 1px solid var(--color-nav-border);
  color: var(--color-nav-text-active);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-sm);
  font-weight: 600;
}

/* ============================================================================
 * Page layout
 * ============================================================================ */

.app-container {
  max-width: var(--content-max-width);
  margin: 0 auto;
}

/* Two-column layout for module pages — LodgeForce-style cream contextual
 * sidebar on the left + main content on the right. The sidebar background
 * extends full-bleed within the 240px column; content stays on the
 * surface. */
.app-section {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 0;
  max-width: 100%;
  margin: 0;
  padding: 0;
}

.app-section > .app-container {
  /* Compact-density doctrine: entity edit + list pages fill the content
   * column rather than centring inside an 980px cap. The form-grid is
   * already a self-limiting 2-column responsive layout, so wider page
   * = more rows visible at once. Pages that want a narrower prose cap
   * can opt in locally. */
  max-width: none;
  padding: var(--space-3) var(--space-4);
  margin: 0;
}

.app-sidebar {
  position: sticky;
  top: var(--nav-height);
  align-self: stretch;
  background: var(--color-subnav-bg);
  /* No right border — the active item bleeds into the content area to
   * create the LodgeForce "connected tab" look. The cream-to-white
   * transition happens at the column edge naturally. */
  padding: var(--space-5) 0 var(--space-6);
  font-size: var(--font-size-base);
  min-height: calc(100vh - var(--nav-height));
}

.app-sidebar-header {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--color-subnav-text-muted);
  padding: 0 var(--space-5);
  margin: 0 0 var(--space-3);
}

.app-sidebar-group {
  margin-bottom: var(--space-4);
}

/* Section heading inside a module's submenu — small uppercase muted label
 * that groups related items underneath (only used when a module has
 * `sections` rather than flat `items`). */
.app-sidebar-section-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5) var(--space-1);
  color: var(--color-subnav-text-muted);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.app-sidebar-section-title .icon {
  display: none;
}

.app-sidebar-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 10px var(--space-5);
  color: var(--color-subnav-text);
  font-weight: 500;
  font-size: var(--font-size-base);
  text-decoration: none;
  position: relative;
  /* Reserve space for the active orange bar on the left so non-active
   * items don't shift horizontally when their state changes. */
  border-left: 3px solid transparent;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}

.app-sidebar-link .icon {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-subnav-icon);
  font-size: 15px;
  flex-shrink: 0;
}
.app-sidebar-link svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.app-sidebar-link:hover {
  color: var(--color-subnav-active-text);
  background: var(--color-subnav-active-bg);
  text-decoration: none;
}
.app-sidebar-link:hover .icon {
  color: var(--color-active-accent);
}

/* Active = white bg (matches the content surface) + orange left bar +
 * heavier label. The negative right margin pulls the white 1px past the
 * cream column so the item visually merges into the content area as a
 * connected tab — the LodgeForce signature. */
.app-sidebar-link.active {
  color: var(--color-subnav-active-text);
  background: var(--color-surface);
  border-left-color: var(--color-active-accent);
  border-left-width: 3px;
  font-weight: 600;
  margin-right: -1px;
  z-index: 1;
}
.app-sidebar-link.active .icon {
  color: var(--color-active-accent);
}
.app-sidebar-link.active:hover {
  background: var(--color-surface);
}

/* Dark-mode override: in dark mode --color-surface flips to a dark-
 * blue panel colour, which would turn the active sidebar item into a
 * dark blue strip that ruins the cream sidebar. Hamish wants the
 * sidebar IDENTICAL across modes, so we hardcode the active surface
 * to white here regardless of theme. The "connected tab" effect with
 * the main content is no longer truly connected in dark mode (main
 * is dark blue), but the sidebar itself looks right. */
:root[data-theme='dark'] .app-sidebar-link.active,
:root[data-theme='dark'] .app-sidebar-link.active:hover {
  background: #ffffff;
}

/* Coming-soon items show the planned shape of a module without being
 * navigable. Rendered as <span> so they can't be clicked; muted + a "Soon"
 * pill on the right. */
.app-sidebar-link-coming {
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: default;
  color: var(--color-text-muted);
  opacity: 0.65;
}
.app-sidebar-link-coming:hover {
  background: transparent;
  color: var(--color-text-muted);
}
.app-sidebar-soon {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 6px;
  border-radius: 999px;
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  margin-right: 8px;
}

/* Hub shortcut at the top of the sidebar — styled like a section title
 * (icon + bold) but clickable, so it visually stands apart from the
 * indented Capture/Edit sub-links below. */
.app-sidebar-link.app-sidebar-hub {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  margin: 0 0 var(--space-4);
  color: var(--color-text);
  font-weight: 700;
  font-size: var(--font-size-base);
  border-left: 2px solid transparent;
  border-radius: var(--radius-md);
}
.app-sidebar-link.app-sidebar-hub .icon {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-primary);
  font-size: 14px;
  flex-shrink: 0;
}
.app-sidebar-link.app-sidebar-hub:hover {
  background: var(--color-surface);
  color: var(--color-text);
}
.app-sidebar-link.app-sidebar-hub.active {
  background: var(--color-primary-soft);
  color: var(--color-primary);
  border-left-color: var(--color-primary);
}

@media (max-width: 900px) {
  .app-section {
    grid-template-columns: 1fr;
    padding: 0 var(--space-4);
  }
  .app-sidebar {
    position: static;
    padding: var(--space-3) 0 var(--space-4);
    border-bottom: 1px solid var(--color-border);
    margin-bottom: var(--space-4);
  }
  .app-sidebar-group { margin-bottom: var(--space-3); }
}

/* ── Compact density doctrine ────────────────────────────────────────────
 * Defaults across the app favour density over whitespace. Page headers,
 * cards and forms all use the smaller end of the spacing scale; inputs
 * are 32px tall, sections wrap content tightly, and the form bottom
 * padding is just enough for the sticky toolbar to clear comfortably.
 * If a screen needs more breathing room, opt in locally — the global
 * default is dense. */

.page-header {
  padding: var(--space-4) var(--space-5) var(--space-3);
}

.page-header h1 {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-xl);
  line-height: var(--line-height-tight);
  font-weight: 700;
  color: var(--color-text);
}

.header-note,
.page-header p {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  margin: 0;
}

.breadcrumb {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: var(--space-1);
}

/* ============================================================================
 * Sections / cards
 * ============================================================================ */

.section,
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-2);
  box-shadow: var(--shadow-sm);
}

.section-title,
.card-title {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-base);
  font-weight: 700;
  color: var(--color-text);
}

/* ============================================================================
 * Forms
 * ============================================================================ */

form {
  padding: 0 var(--space-5) var(--space-6);
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2) var(--space-3);
}
/* Drop to 2 columns on narrower laptops / tablets, 1 column on phones
 * (the phone breakpoint also lives in responsive.css with !important). */
@media (max-width: 1100px) {
  .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.form-group {
  margin: 0;
  position: relative; /* anchors any .search-results dropdown directly below the input */
}

.wide,
.form-group.wide { grid-column: 1 / -1; }

label {
  display: block;
  margin-bottom: 2px;
  font-weight: 600;
  font-size: var(--font-size-xs);
  color: var(--color-text);
  letter-spacing: 0.01em;
}

input,
select,
textarea {
  width: 100%;
  min-height: 32px;
  border: 1px solid var(--color-input-border);
  border-radius: var(--radius-sm);
  padding: 5px 10px;
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  background: var(--color-surface);
  color: var(--color-text);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

textarea {
  min-height: 64px;
  resize: vertical;
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-ring);
  outline: none;
}

input:disabled,
select:disabled,
textarea:disabled {
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  cursor: not-allowed;
}

.inline-check {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-text);
  min-height: 32px;
}

.inline-check input {
  width: 16px;
  min-height: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--color-primary);
}

/* Helper text below an input (used widely on capture/edit forms) */
.field-hint {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  margin-top: 2px;
  line-height: 1.3;
}

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

button,
.btn {
  min-height: 32px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  padding: 6px 14px;
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

button:hover,
.btn:hover {
  background: var(--color-surface-alt);
  border-color: var(--color-text-muted);
}

button:disabled,
.btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.primary-btn,
.btn-primary {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: var(--color-text-on-primary);
}

.primary-btn:hover,
.btn-primary:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
  color: var(--color-text-on-primary);
}

.danger-btn,
.btn-danger {
  border-color: var(--color-danger);
  background: var(--color-surface);
  color: var(--color-danger);
}
.danger-btn:hover,
.btn-danger:hover {
  background: var(--color-danger-bg);
}

/* ============================================================================
 * Sticky action bar
 * ============================================================================ */

.actions {
  position: sticky;
  bottom: 0;
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
  padding: var(--space-2) var(--space-5);
  border-top: 1px solid var(--color-border);
  background: rgba(246, 247, 249, 0.96);
  backdrop-filter: blur(6px);
  z-index: 10;
}

/* ============================================================================
 * Status messages
 * ============================================================================ */

.message {
  margin: 0 var(--space-5) var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-weight: 600;
  font-size: var(--font-size-base);
  display: none;
}

.message.success,
.success {
  display: block !important;
  color: var(--color-success);
  background: var(--color-success-bg);
  border: 1px solid var(--color-success-border);
}

.message.error,
.error {
  display: block !important;
  color: var(--color-danger);
  background: var(--color-danger-bg);
  border: 1px solid var(--color-danger-border);
}

.message.warn,
.warn {
  display: block !important;
  color: var(--color-warn);
  background: var(--color-warn-bg);
  border: 1px solid var(--color-warn-border);
}

/* Pills (used for selected-record indicators in edit screens) */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  background: var(--color-primary-soft);
  color: var(--color-primary);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

/* ============================================================================
 * Modal dialog
 * ============================================================================ */

.dialog-backdrop {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: rgba(15, 23, 42, 0.5);
  z-index: 50;
}

.dialog-backdrop.open {
  display: flex;
}

.dialog {
  width: min(440px, 100%);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-lg);
  padding: var(--space-5);
}

.dialog h2 {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-lg);
}

.dialog p {
  margin: 0 0 var(--space-5);
  color: var(--color-text-muted);
  line-height: var(--line-height-base);
}

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* ============================================================================
 * Search-as-you-type results dropdown
 * ============================================================================ */

.search-results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  max-height: 280px;
  overflow-y: auto;
  z-index: 5;
}

.search-result-item {
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-base);
}
.search-result-item:last-child { border-bottom: none; }
.search-result-item:hover {
  background: var(--color-primary-soft);
  color: var(--color-primary);
}

/* Highlight the matched substring inside search-as-you-type result rows
 * so users can see why an unexpected entry showed up. */
.search-hit {
  background: #fff3a3; /* soft yellow, deliberately neutral vs brand colour */
  color: inherit;
  padding: 0 1px;
  border-radius: 2px;
  font-weight: 600;
}
.search-result-item:hover .search-hit { background: #fde36a; }

/* ============================================================================
 * Tables (used in edit screens, dashboards, reports)
 * ============================================================================ */

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-base);
}

.data-table th,
.data-table td {
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.data-table th {
  background: var(--color-surface-alt);
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  font-size: var(--font-size-xs);
  letter-spacing: 0.04em;
}

.data-table tr:hover td {
  background: var(--color-primary-soft);
}

/* ============================================================================
 * Responsive
 * ============================================================================ */

@media (max-width: 640px) {
  .app-nav-links { display: none; }

  .app-container { max-width: none; }

  .page-header { padding: var(--space-5) var(--space-4) var(--space-3); }
  .page-header h1 { font-size: var(--font-size-xl); }

  form { padding: 0 var(--space-4) 112px; }

  .section { padding: var(--space-4); }

  .form-grid { grid-template-columns: 1fr; }

  .actions {
    flex-direction: column;
    padding: var(--space-3) var(--space-4);
  }
  .actions button { width: 100%; }

  .message { margin-left: var(--space-4); margin-right: var(--space-4); }

  .dialog-actions { flex-direction: column-reverse; }
  .dialog-actions button { width: 100%; }
}

/* ============================================================================
 * Print (used by site-report, face-report)
 * ============================================================================ */

@media print {
  .app-nav,
  .actions,
  .message { display: none !important; }
  body { background: #ffffff; }
}

/* ============================================================================
 * Photo panel (Phase 2) — reusable photos widget mounted via mountPhotoPanel().
 * Used on landlord/property/site/face edit screens. Self-contained — none of
 * its classes leak outside the .pp-root container.
 * ============================================================================ */

.pp-root {
  position: relative;
  margin-top: var(--space-4);
}

.pp-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.pp-title {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: 700;
  color: var(--color-text);
}
.pp-header-actions { display: flex; gap: var(--space-2); align-items: center; }

.pp-file-input { display: none; }

.pp-btn {
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text);
  border-radius: var(--radius-md);
  padding: 8px 14px;
  font-weight: 600;
  font-size: var(--font-size-base);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.pp-btn:hover { background: var(--color-surface-alt); border-color: var(--color-text-muted); }
.pp-btn-primary {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-text-on-primary);
}
.pp-btn-primary:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
  color: var(--color-text-on-primary);
}
.pp-btn-danger { border-color: #d14343; color: #d14343; background: var(--color-surface); }
.pp-btn-danger:hover { background: #fdecec; border-color: #b83434; }

/* ── Drop zone ───────────────────────────────────────────────────────────── */
.pp-dropzone {
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  text-align: center;
  margin-bottom: var(--space-3);
  background: var(--color-surface);
  transition: background 0.12s, border-color 0.12s;
}
.pp-root.pp-dragover .pp-dropzone {
  background: var(--color-primary-soft);
  border-color: var(--color-primary);
}
.pp-dropzone-inner { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); }
.pp-dropzone-icon  { font-size: 28px; line-height: 1; }
.pp-dropzone-text  { color: var(--color-text-muted); font-size: var(--font-size-sm); }
.pp-dropzone-text a { color: var(--color-primary); font-weight: 600; }

/* ── Upload queue ────────────────────────────────────────────────────────── */
.pp-queue { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--space-3); }
.pp-queue-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto 120px;
  gap: var(--space-2);
  align-items: center;
  padding: 8px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font-size: var(--font-size-sm);
}
.pp-queue-name { font-weight: 600; color: var(--color-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pp-queue-size { color: var(--color-text-muted); }
.pp-queue-status { color: var(--color-text-muted); text-transform: capitalize; }
.pp-queue-bar {
  background: var(--color-surface-alt);
  border-radius: 999px;
  overflow: hidden;
  height: 6px;
}
.pp-queue-bar-fill {
  background: var(--color-primary);
  height: 100%;
  width: 0%;
  transition: width 0.18s ease;
}
.pp-queue-done .pp-queue-bar-fill   { background: #2a9b2a; width: 100% !important; }
.pp-queue-error .pp-queue-bar-fill,
.pp-queue-error-row { background: #fdecec; }
.pp-queue-error-row { color: #b83434; grid-template-columns: 1fr; }
.pp-queue-error { grid-column: 1 / -1; color: #b83434; font-size: var(--font-size-xs); }

/* ── Thumbnail grid ──────────────────────────────────────────────────────── */
.pp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-3);
}
.pp-empty {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--color-text-muted);
  padding: var(--space-5);
  font-size: var(--font-size-sm);
}
.pp-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  overflow: hidden;
  cursor: pointer;
  transition: box-shadow 0.12s ease, border-color 0.12s ease, transform 0.12s ease;
}
.pp-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--color-text-muted);
  transform: translateY(-1px);
}
/* Square 1:1 thumbnails — uniform grid across portrait + landscape source mix.
 * Cover-fit centre-crops the source so the most relevant part stays visible. */
.pp-card-imgwrap {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--color-surface-alt);
}
.pp-card-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
.pp-card-badges { position: absolute; top: 8px; left: 8px; display: flex; gap: 4px; flex-wrap: wrap; }
.pp-badge {
  background: rgba(0,0,0,0.78);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 7px;
  border-radius: 4px;
  line-height: 1.4;
  letter-spacing: 0.02em;
}
.pp-badge-primary { background: #f0ad14; color: #000; }
.pp-badge-before  { background: #1f7a8c; }
.pp-badge-private { background: #555; }

/* PDF tile (lease document gallery) — replaces image preview with a clear
 * red "PDF" badge + filename so users instantly recognise documents. */
.pp-card-pdf {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 12px;
  background: linear-gradient(180deg, #fff 0%, #f7f9fb 100%);
  border-bottom: 1px solid var(--color-border);
}
.pp-pdf-icon {
  background: #d93025;
  color: #fff;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.04em;
  padding: 14px 18px;
  border-radius: 6px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.18);
}
.pp-pdf-filename {
  font-size: var(--font-size-xs);
  color: var(--color-text);
  text-align: center;
  word-break: break-word;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-width: 100%;
}

/* Drawer PDF preview — vertical stack, prominent button */
.pp-drawer-pdf {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 24px 16px;
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
}
.pp-drawer-pdf-icon {
  background: #d93025;
  color: #fff;
  font-weight: 700;
  font-size: 24px;
  padding: 20px 28px;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.20);
}
.pp-drawer-pdf-name {
  font-size: var(--font-size-sm);
  color: var(--color-text);
  text-align: center;
  word-break: break-word;
}

.pp-card-meta    { padding: 10px 12px; display: flex; flex-direction: column; gap: 4px; min-height: 0; }
.pp-card-type    { font-weight: 600; font-size: var(--font-size-sm); color: var(--color-text); line-height: 1.3; }
.pp-card-caption {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── Edit drawer ─────────────────────────────────────────────────────────── */
.pp-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(440px, 100vw);
  background: var(--color-surface);
  border-left: 1px solid var(--color-border);
  box-shadow: -8px 0 24px rgba(0,0,0,0.15);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.18s ease;
  z-index: 1000;
}
.pp-drawer.open { transform: translateX(0); }
.pp-drawer-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  font-weight: 700;
  font-size: var(--font-size-lg);
}
.pp-drawer-close {
  border: none; background: transparent;
  font-size: 24px; line-height: 1;
  cursor: pointer; color: var(--color-text-muted);
  padding: 4px 8px;
}
.pp-drawer-close:hover { color: var(--color-text); }

.pp-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
/* Drawer preview shows the FULL uploaded image (no crop) so the user can
 * inspect what they've actually attached. Capped at 50vh so a tall portrait
 * doesn't push the form fields out of the drawer. */
.pp-drawer-preview {
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: var(--space-3);
  display: flex;
  align-items: center;
  justify-content: center;
  max-height: 50vh;
}
.pp-drawer-preview img {
  max-width: 100%;
  max-height: 50vh;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}

.pp-label   { font-weight: 600; font-size: var(--font-size-sm); margin-top: var(--space-2); }
.pp-input   {
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: 8px 10px;
  font-family: inherit;
  font-size: var(--font-size-base);
  width: 100%;
  background: var(--color-surface);
  color: var(--color-text);
}
.pp-input:focus { outline: 2px solid var(--color-primary); outline-offset: -1px; border-color: var(--color-primary); }
/* Drawer flag checkboxes: fixed-size, top-aligned with the label so multi-line
 * text doesn't push the checkbox to the visual middle of the row. accent-color
 * keeps the checked state on-brand instead of inheriting the OS default. */
.pp-checklabel {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: var(--font-size-sm);
  color: var(--color-text);
  padding: 6px 0;
  line-height: 1.4;
  cursor: pointer;
}
.pp-checklabel input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 2px 0 0 0;          /* nudge down 2px so it lines up with the first text line */
  flex-shrink: 0;
  accent-color: var(--color-primary);
  cursor: pointer;
}

.pp-drawer-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
}
.pp-drawer-foot .pp-btn-danger { margin-right: auto; }

@media (max-width: 720px) {
  .pp-queue-row { grid-template-columns: minmax(0,1fr) auto; }
  .pp-queue-bar { grid-column: 1 / -1; }
  .pp-queue-status { display: none; }
  .pp-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}

/* Inline percent-suffix on a number input. Wrap input in a div with this
 * class; the "%" appears inside the right edge of the input. */
.input-suffix-pct {
  position: relative;
  display: block;
}
.input-suffix-pct input { padding-right: 28px; }
.input-suffix-pct::after {
  content: '%';
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-muted);
  font-weight: 600;
  pointer-events: none;
}

/* ============================================================================
 * Module sidebar (cross-page) — icon-only nav strip auto-injected by
 * /module-sidebar.js on every page. Mirrors the Dashboard's inline sidebar
 * so users never have to bounce back to Dashboard to switch modules.
 *
 * .ms-* namespace; doesn't collide with the Dashboard's existing .sb-* or
 * the Portfolio Admin sub-sidebar's .app-sidebar-*.
 * ============================================================================ */

/* Note: the previous left icon-strip (.ms-sidebar / .ms-btn / .ms-label)
 * was removed in the LodgeForce redesign. Module navigation moved to the
 * top tabs (`.app-nav-link`) injected by module-sidebar.js into
 * `.app-nav-inner`; per-module submenus stay in the cream contextual
 * sidebar (`.app-sidebar*`) injected by sidebar.js. */

/* ============================================================================
 * Sticky entity-edit toolbar (.entity-toolbar)
 *
 * Reusable across landlord-edit, property-edit, site-edit and face-edit so
 * the user always has Save + key actions in one click without scrolling.
 * Status pills (.bar-pill) and toolbar buttons (.bar-btn) sit alongside the
 * record's identity badge + name + parent context.
 *
 * Hidden by default (`hidden` attribute on the markup) and revealed by
 * page-level JS once an entity has been selected.
 * ============================================================================ */

.entity-toolbar {
  position: sticky;
  top: var(--nav-height);
  z-index: 10;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: 12px var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: 0 1px 2px rgba(29, 39, 51, 0.04);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}
.entity-toolbar-info {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  flex: 1;
  min-width: 0;
}
.entity-toolbar-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.entity-code-badge {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--font-size-sm);
  color: var(--color-primary);
  background: var(--color-primary-soft);
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  font-weight: 600;
  white-space: nowrap;
}
.entity-name-text {
  font-size: var(--font-size-md);
  font-weight: 600;
  color: var(--color-text);
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.entity-context-text {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}
.entity-context-text a { color: var(--color-primary); font-weight: 600; }
.entity-context-text a:hover { color: var(--color-primary-hover); text-decoration: underline; }

.bar-pill {
  display: inline-block;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  font-weight: 600;
  text-transform: capitalize;
  white-space: nowrap;
}
.bar-pill.green { background: var(--color-success-bg); color: var(--color-success); }
.bar-pill.amber { background: var(--color-warn-bg);    color: var(--color-warn); }
.bar-pill.red   { background: var(--color-danger-bg);  color: var(--color-danger); }
.bar-pill.muted { background: var(--color-surface-alt); color: var(--color-text-muted); border: 1px solid var(--color-border); }

.bar-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: var(--color-surface);
  border: 1px solid var(--color-input-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  font-size: var(--font-size-sm);
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.12s, border-color 0.12s;
  font-family: inherit;
}
.bar-btn:hover {
  background: var(--color-surface-alt);
  border-color: var(--color-border-strong);
  color: var(--color-text);
  text-decoration: none;
}
.bar-btn.primary {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-text-on-primary);
}
.bar-btn.primary:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
  color: var(--color-text-on-primary);
}
.bar-btn.accent {
  background: var(--color-active-accent);
  border-color: var(--color-active-accent);
  color: var(--color-text-on-primary);
}
.bar-btn.accent:hover {
  background: var(--color-active-accent-hover);
  border-color: var(--color-active-accent-hover);
}
.bar-btn svg {
  width: 14px; height: 14px;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ============================================================================
 * Maintenance log panel (Phase 3) — list-style widget mounted via
 * mountMaintenancePanel(). Self-contained .ml-* namespace so styles
 * cannot leak.
 * ============================================================================ */

.ml-root {
  position: relative;
  margin-top: var(--space-4);
}

.ml-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.ml-title {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: 700;
  color: var(--color-text);
}
.ml-header-actions { display: flex; gap: var(--space-2); align-items: center; }

.ml-btn {
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text);
  border-radius: var(--radius-md);
  padding: 8px 14px;
  font-weight: 600;
  font-size: var(--font-size-base);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.ml-btn:hover { background: var(--color-surface-alt); border-color: var(--color-text-muted); }
.ml-btn-primary {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-text-on-primary);
}
.ml-btn-primary:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
  color: var(--color-text-on-primary);
}
.ml-btn-danger { border-color: #d14343; color: #d14343; background: var(--color-surface); }
.ml-btn-danger:hover { background: #fdecec; border-color: #b83434; }

/* ── List ───────────────────────────────────────────────────────────────── */
.ml-list { display: flex; flex-direction: column; gap: 8px; }

.ml-empty {
  text-align: center;
  color: var(--color-text-muted);
  padding: var(--space-5);
  font-size: var(--font-size-sm);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
}

.ml-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-3);
  align-items: flex-start;
  padding: 12px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
  transition: box-shadow 0.12s ease, border-color 0.12s ease;
}
.ml-row:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--color-text-muted);
}

.ml-row-l { display: flex; gap: var(--space-3); align-items: flex-start; min-width: 0; }
.ml-row-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ml-row-title { font-weight: 600; color: var(--color-text); font-size: var(--font-size-base); }
.ml-row-meta  { font-size: var(--font-size-xs); color: var(--color-text-muted); }
.ml-row-desc  {
  font-size: var(--font-size-sm); color: var(--color-text);
  margin-top: 4px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ml-row-r { display: flex; align-items: center; }

/* Severity badge — colour-coded so ops scan a long list quickly */
.ml-badge {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 4px 8px;
  border-radius: 4px;
  line-height: 1.4;
  white-space: nowrap;
  flex-shrink: 0;
}
.ml-badge-critical { background: #d14343; color: #fff; }
.ml-badge-high     { background: #f0801c; color: #fff; }
.ml-badge-medium   { background: #f0c14b; color: #1a1a1a; }
.ml-badge-low      { background: #999; color: #fff; }

/* Status pill */
.ml-status {
  font-size: 12px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  white-space: nowrap;
}
.ml-status-open         { background: #fdecec; color: #b83434; }
.ml-status-assigned     { background: #fff4e3; color: #b8651b; }
.ml-status-in-progress  { background: #e3edff; color: #1f4ab8; }
.ml-status-resolved     { background: #e3f5e3; color: #2a7a2a; }
.ml-status-cannot-fix   { background: #f0f0f0; color: #555; }
.ml-status-deferred     { background: #f0f0f0; color: #555; }

/* ── Drawer ─────────────────────────────────────────────────────────────── */
.ml-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(440px, 100vw);
  background: var(--color-surface);
  border-left: 1px solid var(--color-border);
  box-shadow: -8px 0 24px rgba(0,0,0,0.15);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.18s ease;
  z-index: 1000;
}
.ml-drawer.open { transform: translateX(0); }
.ml-drawer-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  font-weight: 700;
  font-size: var(--font-size-lg);
}
.ml-drawer-title { font-weight: 700; }
.ml-drawer-close {
  border: none; background: transparent;
  font-size: 24px; line-height: 1;
  cursor: pointer; color: var(--color-text-muted);
  padding: 4px 8px;
}
.ml-drawer-close:hover { color: var(--color-text); }

.ml-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.ml-label   {
  font-weight: 600;
  font-size: var(--font-size-sm);
  margin-top: var(--space-2);
  color: var(--color-text);
}
.ml-input   {
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: 8px 10px;
  font-family: inherit;
  font-size: var(--font-size-base);
  width: 100%;
  background: var(--color-surface);
  color: var(--color-text);
}
.ml-input:focus { outline: 2px solid var(--color-primary); outline-offset: -1px; border-color: var(--color-primary); }

.ml-checklabel {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: var(--font-size-sm);
  color: var(--color-text);
  padding: 6px 0;
  line-height: 1.4;
  cursor: pointer;
}
.ml-checklabel input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 2px 0 0 0;
  flex-shrink: 0;
  accent-color: var(--color-primary);
  cursor: pointer;
}

.ml-edit-only {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

/* Severity hint shown under the severity dropdown */
.ml-severity-hint {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  margin-top: 4px;
  min-height: 1em;
}
.ml-severity-hint-critical {
  color: #b83434;
  font-weight: 600;
}
.ml-severity-hint-warn {
  color: #b8651b;
}

.ml-drawer-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
}
.ml-drawer-foot .ml-btn-danger { margin-right: auto; }

/* Error banner — appears above the list when an action fails */
.ml-error-banner {
  padding: 10px 14px;
  margin-bottom: var(--space-3);
  border-radius: var(--radius-md);
  background: #fdecec;
  color: #b83434;
  font-size: var(--font-size-sm);
  font-weight: 600;
}
