/* ══════════════════════════════════════════════════════════════════════
   FRONTIER DESIGN TOKENS — refined operator
   ----------------------------------------------------------------------
   Single source of truth for the app's visual language: fonts, colors,
   geometry. All custom components should reference these tokens via
   var(--fr-...) so theme changes can be made in one place.

   Loaded at the top of custom.css so subsequent styles can reference
   the tokens. CSS @import statements MUST come before any other rule.
   ══════════════════════════════════════════════════════════════════════ */

@import url('https://api.fontshare.com/v2/css?f[]=general-sans@300,400,500,600,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500;600&display=swap');

:root {
  /* ── Surfaces — warm off-whites, not stark ─────────────────────── */
  --fr-bg:              #F6F5F1;
  --fr-surface:         #FFFFFF;
  --fr-hairline:        #ECEAE3;
  --fr-hairline-strong: #DAD7CD;

  /* ── Text — dark slate, not pure black ─────────────────────────── */
  --fr-ink:    #14181D;
  --fr-ink-2:  #4D525A;
  --fr-ink-3:  #8E9299;

  /* ── Brand accent — burnt amber ────────────────────────────────── */
  /* Shifted from red-leaning burnt orange (#C2410C) to amber/gold so it
     reads as clearly distinct from the negative-signal red. Same warm
     family, different enough hue that the page no longer feels "all
     red" at a glance. */
  --fr-accent:        #B45309;       /* primary brand action */
  --fr-accent-soft:   #FEF3C7;       /* tint for light backgrounds */
  --fr-accent-strong: #92400E;       /* hover/pressed state */
  --fr-accent-2:      #D97706;       /* lighter amber for gradients */

  /* ── Horizon brand orange — matches the marketing-site map ─────── */
  /* Brighter / more saturated than --fr-accent. Used only on Horizon-
     branded surfaces (the Executive Dashboard map area, legend pips,
     anywhere the corporate parent brand should read explicitly). The
     muted amber accent above is still the primary UI color. */
  --fr-horizon-orange:      #ED7B22;
  --fr-horizon-orange-soft: #FCE7CF;
  --fr-slate:               #3D3530;
  --fr-gold:                #C18B3F;

  /* ── Signal: positive (good news, "all clear") ─────────────────── */
  --fr-positive:        #1F7A4D;
  --fr-positive-deep:   #155C39;
  --fr-positive-tint:   rgba(31, 122, 77, 0.06);
  --fr-positive-tint-2: rgba(31, 122, 77, 0.11);

  /* ── Signal: negative (rent dropped, error) ────────────────────── */
  /* Brighter / cooler red so it reads as unambiguously red next to the
     warm-amber brand accent. */
  --fr-negative:        #B91C1C;

  /* ── Signal: warning (action needed, soft amber) ───────────────── */
  --fr-warning:         #B5701F;
  --fr-warning-deep:    #8C5618;
  --fr-warning-tint:    rgba(181, 112, 31, 0.08);
  --fr-warning-tint-2:  rgba(181, 112, 31, 0.14);

  /* ── Geometry ──────────────────────────────────────────────────── */
  --fr-r-sm:  6px;
  --fr-r-md:  10px;
  --fr-r-lg:  14px;

  /* ── Type stacks ───────────────────────────────────────────────── */
  --fr-font-sans:   'General Sans', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --fr-font-serif:  'Instrument Serif', "Times New Roman", serif;
  --fr-font-mono:   'JetBrains Mono', ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

/* ══════════════════════════════════════════════════════════════════════
   END FRONTIER DESIGN TOKENS
   ══════════════════════════════════════════════════════════════════════ */


/* ══════════════════════════════════════════════════════════════════════
   FRONTIER NAVBAR (Phase 2)
   Refined operator top bar — white surface, hairline rule, branded
   primary-action slot on the right.
   ══════════════════════════════════════════════════════════════════════ */

.fr-navbar {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 11px 16px;
    background: var(--fr-surface);
    border: 1px solid var(--fr-hairline);
    border-radius: var(--fr-r-md);
    margin: 4px 0 24px;
    box-shadow: 0 1px 0 rgba(20, 24, 29, 0.02);
    font-family: var(--fr-font-sans);
}

.fr-navbar-spacer { flex: 1; }

/* Menu icon button (top-left) */
.fr-icon-btn {
    width: 38px;
    height: 38px;
    border-radius: var(--fr-r-md);
    border: 1px solid var(--fr-hairline-strong);
    background: var(--fr-surface);
    color: var(--fr-ink);
    font-family: var(--fr-font-sans);
    font-size: 18px;
    line-height: 1;
    padding: 0;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 120ms ease, border-color 120ms ease;
}
.fr-icon-btn:hover {
    background: var(--fr-bg);
    border-color: #C9C5B8;
}

/* Frontier wordmark */
.fr-brand {
    font-family: var(--fr-font-serif);
    font-size: 22px;
    font-weight: 400;
    letter-spacing: 0.16em;
    color: var(--fr-ink);
    margin-left: 4px;
    user-select: none;
    line-height: 1;
}

/* Property selector wrapper — sized for navbar */
.fr-property-select {
    min-width: 220px;
    max-width: 260px;
}

/* Override react-select internals (used by dcc.Dropdown) so the
   selector matches the navbar aesthetic. The .Select-* classes are
   from older react-select; modern Dash still emits them. */
.fr-property-select-inner .Select-control {
    border: 1px solid var(--fr-hairline-strong) !important;
    border-radius: var(--fr-r-md) !important;
    background: var(--fr-surface) !important;
    height: 38px !important;
    font-family: var(--fr-font-sans) !important;
    font-size: 13.5px !important;
    transition: border-color 120ms ease;
    box-shadow: none !important;
}
.fr-property-select-inner .Select-control:hover {
    border-color: #C9C5B8 !important;
}
.fr-property-select-inner .Select-value-label,
.fr-property-select-inner .Select-placeholder,
.fr-property-select-inner .Select-input {
    line-height: 36px !important;
    font-weight: 500 !important;
    color: var(--fr-ink) !important;
}
.fr-property-select-inner .Select-arrow {
    border-color: var(--fr-ink-3) transparent transparent !important;
}
.fr-property-select-inner .is-focused:not(.is-open) > .Select-control {
    border-color: var(--fr-accent) !important;
    box-shadow: 0 0 0 3px rgba(180, 83, 9, 0.10) !important;
}

/* Primary action button (orange) — Publish Rates / Submit for Review.
   These !important rules override Bootstrap's .btn / .btn-primary /
   .btn-success defaults that ship with dbc.Button. */
.fr-action-btn,
.fr-action-btn.btn,
.fr-action-btn.btn-primary,
.fr-action-btn.btn-success {
    background-color: var(--fr-accent) !important;
    border-color: var(--fr-accent) !important;
    color: #FFFFFF !important;
    font-family: var(--fr-font-sans) !important;
    font-size: 13.5px !important;
    font-weight: 500 !important;
    height: 38px;
    padding: 0 16px !important;
    border-radius: var(--fr-r-md) !important;
    box-shadow: 0 1px 0 rgba(20, 24, 29, 0.04),
                0 1px 3px rgba(180, 83, 9, 0.22) !important;
    transition: transform 120ms ease, box-shadow 200ms ease,
                background-color 120ms ease, border-color 120ms ease;
    display: inline-flex !important;
    align-items: center;
    gap: 8px;
    line-height: 1;
}
.fr-action-btn:hover,
.fr-action-btn.btn:hover {
    background-color: var(--fr-accent-strong) !important;
    border-color: var(--fr-accent-strong) !important;
    transform: translateY(-1px);
    box-shadow: 0 2px 0 rgba(20, 24, 29, 0.04),
                0 4px 10px rgba(180, 83, 9, 0.28) !important;
}
.fr-action-btn:focus,
.fr-action-btn.btn:focus {
    box-shadow: 0 0 0 3px rgba(180, 83, 9, 0.20) !important;
    outline: none;
}
.fr-action-btn .fr-btn-icon {
    font-size: 16px;
    line-height: 1;
    display: inline-block;
}


/* ══════════════════════════════════════════════════════════════════════
   FRONTIER PROPERTY CARD (Phase 3)
   Three-zone scoreboard: Position · Demand Pipeline · Rent
   See mockups/property_card_v4.html for the design spec.
   ══════════════════════════════════════════════════════════════════════ */

/* Card shell */
.fr-property-card {
    background: var(--fr-surface);
    border: 1px solid var(--fr-hairline);
    border-radius: var(--fr-r-lg);
    overflow: visible;          /* required so the badge tooltip can escape */
    box-shadow: 0 1px 0 rgba(20, 24, 29, 0.02), 0 1px 2px rgba(20, 24, 29, 0.03);
    margin-bottom: 24px;
    font-family: var(--fr-font-sans);
    color: var(--fr-ink);
}

/* Card header strip (property name + subtitle + updated indicator) */
.fr-pc-header {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 14px;
    padding: 22px 32px 18px;
    border-bottom: 1px solid var(--fr-hairline);
}
.fr-pc-title {
    font-family: var(--fr-font-serif);
    font-size: 30px;
    font-weight: 400;
    letter-spacing: -0.01em;
    color: var(--fr-ink);
    line-height: 1;
    margin: 0;
}
.fr-pc-subtitle {
    color: var(--fr-ink-3);
    font-size: 13px;
    font-weight: 400;
}
.fr-pc-subtitle .fr-sep {
    display: inline-block;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--fr-ink-3);
    margin: 0 8px;
    vertical-align: middle;
    opacity: 0.6;
}
.fr-pc-header-spacer { flex: 1; }
.fr-updated {
    font-family: var(--fr-font-mono);
    font-size: 11px;
    color: var(--fr-ink-3);
    letter-spacing: 0.02em;
}
.fr-live-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--fr-positive);
    margin-right: 6px;
    vertical-align: middle;
    box-shadow: 0 0 0 0 rgba(31, 122, 77, 0.5);
    animation: fr-pulse 2.4s ease-out infinite;
}
@keyframes fr-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(31, 122, 77, 0.45); }
    70%  { box-shadow: 0 0 0 6px rgba(31, 122, 77, 0); }
    100% { box-shadow: 0 0 0 0 rgba(31, 122, 77, 0); }
}

/* Three-zone grid */
.fr-pc-zones {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
}
.fr-pc-zone {
    padding: 26px 32px 30px;
    border-right: 1px solid var(--fr-hairline);
    position: relative;
    opacity: 0;
    transform: translateY(6px);
    animation: fr-rise 600ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.fr-pc-zone:last-child { border-right: 0; }
.fr-pc-zone:nth-child(1) { animation-delay: 80ms; }
.fr-pc-zone:nth-child(2) { animation-delay: 160ms; }
.fr-pc-zone:nth-child(3) { animation-delay: 240ms; }
@keyframes fr-rise {
    to { opacity: 1; transform: translateY(0); }
}
.fr-zone-label {
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--fr-ink-3);
    font-weight: 500;
    margin-bottom: 22px;
    display: flex;
    align-items: center;
    gap: 10px;
}
.fr-zone-label::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--fr-hairline);
}

/* Hero stat block (one per zone) */
.fr-stat-hero {
    margin-bottom: 26px;
}
.fr-stat-hero-value {
    font-family: var(--fr-font-mono);
    font-feature-settings: 'tnum';
    font-variant-numeric: tabular-nums;
    font-size: 36px;
    font-weight: 500;
    color: var(--fr-ink);
    letter-spacing: -0.025em;
    line-height: 1;
    display: flex;
    align-items: baseline;
    gap: 8px;
}
.fr-stat-hero-value .fr-of,
.fr-stat-hero-value .fr-sub  {
    color: var(--fr-ink-3);
    font-size: 22px;
    font-weight: 400;
}
.fr-stat-hero-value .fr-delta {
    font-size: 13px;
    margin-left: 4px;
    font-weight: 500;
    font-family: var(--fr-font-mono);
}
.fr-stat-hero-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.13em;
    color: var(--fr-ink-3);
    margin-top: 8px;
    font-weight: 500;
}
/* Zone 1 hero variant: hero on left, publish badge on right */
.fr-stat-hero--with-badge {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}
.fr-stat-hero--with-badge .fr-hero-text { flex: 0 0 auto; }

/* Stat row (label : value pairs) */
.fr-stat-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 10px 0;
    border-top: 1px dashed var(--fr-hairline);
}
.fr-stat-row:first-of-type {
    border-top: 1px solid var(--fr-hairline);
    padding-top: 12px;
}
.fr-stat-label {
    color: var(--fr-ink-2);
    font-size: 12.5px;
    font-weight: 400;
}
.fr-stat-value {
    font-family: var(--fr-font-mono);
    font-feature-settings: 'tnum';
    font-variant-numeric: tabular-nums;
    font-size: 14px;
    font-weight: 500;
    color: var(--fr-ink);
}
.fr-stat-value .fr-unit {
    color: var(--fr-ink-3);
    font-size: 11px;
    margin-left: 3px;
    font-weight: 400;
}
.fr-delta {
    font-family: var(--fr-font-mono);
    font-size: 11.5px;
    font-weight: 500;
}
.fr-delta.fr-up   { color: var(--fr-positive); }
.fr-delta.fr-down { color: var(--fr-negative); }

/* ── Market position percentile bar (Zone 3) ──
   Used in render_z3_stats. The right side of the row holds a thin
   track with a colored fill from 0 to N% and the numeric value
   beside it, instead of a plain "39th pct" text value. */
.fr-stat-row--with-bar {
    align-items: center;  /* override 'baseline' so the bar lines up vertically */
}
.fr-pct-row-right {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    justify-content: flex-end;
    max-width: 70%;
}
.fr-pct-bar-wrap {
    flex: 1;
    min-width: 90px;
    max-width: 160px;
}
.fr-pct-bar-track {
    position: relative;
    width: 100%;
    height: 11px;
    background: var(--fr-hairline);
    border-radius: 6px;
    overflow: hidden;
}
.fr-pct-bar-fill {
    height: 100%;
    background: var(--fr-accent);
    border-radius: 6px;
    transition: width 0.25s ease-out;
}
/* Quartile segment markers — 1px-wide translucent overlays at 25/50/75
   that paint on top of both the fill and the track. Reads as faint
   joints dividing the bar into quartiles, like a fuel gauge. The
   semi-transparent black darkens whatever sits beneath: amber → darker
   amber over the fill, hairline → darker gray over the unfilled track.
   This sits in front of .fr-pct-bar-fill by source order. */
.fr-pct-bar-track::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image: linear-gradient(
        to right,
        transparent calc(25% - 0.75px),
        rgba(0, 0, 0, 0.36) calc(25% - 0.75px),
        rgba(0, 0, 0, 0.36) calc(25% + 0.75px),
        transparent calc(25% + 0.75px),
        transparent calc(50% - 0.75px),
        rgba(0, 0, 0, 0.36) calc(50% - 0.75px),
        rgba(0, 0, 0, 0.36) calc(50% + 0.75px),
        transparent calc(50% + 0.75px),
        transparent calc(75% - 0.75px),
        rgba(0, 0, 0, 0.36) calc(75% - 0.75px),
        rgba(0, 0, 0, 0.36) calc(75% + 0.75px),
        transparent calc(75% + 0.75px)
    );
}

/* ── Zone-level action button (Zone 3 "View Market Charts") ── */
.fr-zone-action-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    margin-top: 16px;
    padding: 9px 14px;
    background: transparent;
    border: 1px solid var(--fr-hairline-strong);
    border-radius: 6px;
    color: var(--fr-ink-2);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: all 0.15s ease-out;
}
.fr-zone-action-btn:hover {
    background: var(--fr-accent-soft);
    border-color: var(--fr-accent);
    color: var(--fr-accent-strong);
}
.fr-zone-action-btn:active {
    transform: translateY(1px);
}
.fr-zone-action-btn-arrow {
    font-size: 14px;
    line-height: 1;
    transform: translateY(-1px);
}

/* Forward-occupancy mini chart (Zone 1) */
.fr-occ-trajectory {
    margin-top: 18px;
    padding-top: 18px;
    border-top: 1px solid var(--fr-hairline);
}
.fr-occ-label {
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.13em;
    color: var(--fr-ink-3);
    font-weight: 500;
    margin-bottom: 14px;
}
.fr-occ-chart-wrap {
    position: relative;  /* anchors the .fr-occ-dot overlay */
    width: 100%;
    height: 160px;
    margin-bottom: 6px;
}
/* True-circle data points overlaid on the SVG line+area. The path
   inside the SVG stretches non-uniformly with the container, which
   would distort SVG circles into ovals — so we render the dots as
   HTML elements positioned at percentage coordinates instead. */
.fr-occ-dot {
    position: absolute;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #FFFFFF;
    border: 1.6px solid #B45309;
    transform: translate(-50%, -50%);
    pointer-events: none;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
}
/* Each cell is absolutely positioned at the same x% as its dot above
   (the percentages are computed in render_z1_occ_chart and applied as
   inline ``left: X%`` styles). ``transform: translateX(-50%)`` centers
   each label horizontally on its dot. */
.fr-occ-axis {
    position: relative;
    height: 30px;
    margin-top: 2px;
}
.fr-occ-axis-cell {
    position: absolute;
    top: 0;
    transform: translateX(-50%);
    text-align: center;
    font-family: var(--fr-font-mono);
    font-size: 11px;
    color: var(--fr-ink-2);
    font-weight: 500;
    white-space: nowrap;
}
.fr-occ-axis-cell .fr-axis-label {
    display: block;
    color: var(--fr-ink-3);
    font-size: 9.5px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    margin-top: 2px;
    font-family: var(--fr-font-sans);
    font-weight: 500;
}

/* Traffic funnel (Zone 2) */
.fr-funnel-wrap {
    margin-top: 24px;
    padding-top: 22px;
    border-top: 1px solid var(--fr-hairline);
}

/* Funnel header: title (+ info icon) on the left, 7D/30D toggle on the right */
.fr-funnel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}
.fr-funnel-title-group {
    display: inline-flex;
    align-items: center;
}
.fr-funnel-title {
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.13em;
    color: var(--fr-ink-3);
    font-weight: 500;
}

/* Small info icon (FontAwesome) — hover reveals the YoY tooltip */
.fr-info-icon {
    margin-left: 6px;
    font-size: 11px;
    color: var(--fr-ink-3);
    cursor: help;
    opacity: 0.6;
    transition: opacity 120ms ease, color 120ms ease;
}
.fr-info-icon:hover {
    opacity: 1;
    color: var(--fr-ink-2);
}

/* 7D / 30D segmented toggle */
.fr-funnel-toggle {
    display: inline-flex;
    border-radius: 6px;
    background: var(--fr-bg);
    padding: 2px;
    border: 1px solid var(--fr-hairline);
}
.fr-funnel-toggle-btn {
    padding: 3px 9px;
    border: 0;
    background: transparent;
    font-family: var(--fr-font-mono);
    font-feature-settings: 'tnum';
    font-size: 10.5px;
    font-weight: 500;
    color: var(--fr-ink-3);
    cursor: pointer;
    border-radius: 4px;
    letter-spacing: 0.04em;
    transition: background 120ms ease, color 120ms ease, box-shadow 120ms ease;
}
.fr-funnel-toggle-btn:hover { color: var(--fr-ink-2); }
/* Default: 30D is active. Toggle the active styling via the wrap class. */
.fr-funnel-wrap .fr-funnel-toggle-btn[data-period="30d"] {
    background: var(--fr-surface);
    color: var(--fr-ink);
    box-shadow: 0 1px 2px rgba(20, 24, 29, 0.06);
}
.fr-funnel-wrap.fr-funnel-show-7d .fr-funnel-toggle-btn[data-period="30d"] {
    background: transparent;
    color: var(--fr-ink-3);
    box-shadow: none;
}
.fr-funnel-wrap.fr-funnel-show-7d .fr-funnel-toggle-btn[data-period="7d"] {
    background: var(--fr-surface);
    color: var(--fr-ink);
    box-shadow: 0 1px 2px rgba(20, 24, 29, 0.06);
}

/* Two row groups, one per period — only one visible at a time */
.fr-funnel-rows--7d  { display: none; }
.fr-funnel-rows--30d { display: block; }
.fr-funnel-wrap.fr-funnel-show-7d .fr-funnel-rows--7d  { display: block; }
.fr-funnel-wrap.fr-funnel-show-7d .fr-funnel-rows--30d { display: none; }

.fr-funnel-row {
    display: grid;
    grid-template-columns: 56px 1fr 36px 56px;
    align-items: center;
    gap: 12px;
    padding: 7px 0;
}
.fr-funnel-label { font-size: 12.5px; color: var(--fr-ink-2); font-weight: 400; }
.fr-funnel-bar-track {
    height: 6px;
    background: var(--fr-hairline);
    border-radius: 99px;
    overflow: hidden;
}
.fr-funnel-bar-fill {
    height: 100%;
    border-radius: 99px;
    background: linear-gradient(90deg, var(--fr-accent) 0%, var(--fr-accent-2) 100%);
    transform-origin: left center;
    animation: fr-bar-grow 800ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
    transform: scaleX(0);
}
@keyframes fr-bar-grow { to { transform: scaleX(1); } }
.fr-funnel-rows .fr-funnel-row:nth-child(1) .fr-funnel-bar-fill { animation-delay: 240ms; }
.fr-funnel-rows .fr-funnel-row:nth-child(2) .fr-funnel-bar-fill { animation-delay: 320ms; }
.fr-funnel-rows .fr-funnel-row:nth-child(3) .fr-funnel-bar-fill { animation-delay: 400ms; }
.fr-funnel-rows .fr-funnel-row:nth-child(4) .fr-funnel-bar-fill { animation-delay: 480ms; }
.fr-funnel-value {
    font-family: var(--fr-font-mono);
    font-feature-settings: 'tnum';
    font-variant-numeric: tabular-nums;
    font-size: 13px;
    font-weight: 500;
    color: var(--fr-ink);
    text-align: right;
}

/* YoY delta column: green ▲ / red ▼ / muted — */
.fr-funnel-yoy {
    font-family: var(--fr-font-mono);
    font-feature-settings: 'tnum';
    font-variant-numeric: tabular-nums;
    font-size: 11px;
    font-weight: 500;
    text-align: right;
    white-space: nowrap;
}
.fr-funnel-yoy.fr-up        { color: var(--fr-positive); }
.fr-funnel-yoy.fr-down      { color: var(--fr-negative); }
.fr-funnel-yoy--neutral     { color: var(--fr-ink-3); }

/* Sparkline wrapper (Zone 3) */
.fr-sparkline-wrap {
    margin: 14px 0 22px;
    height: 64px;
}

/* Publish-status badge (Zone 1 hero) */
.fr-publish-badge {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 11px 14px;
    border-radius: var(--fr-r-md);
    cursor: pointer;
    transition: background 140ms ease;
    text-decoration: none;
    flex: 1 1 auto;
    max-width: 200px;
    align-self: stretch;
    justify-content: center;
}
.fr-publish-badge--clean {
    background: var(--fr-positive-tint);
}
.fr-publish-badge--clean:hover {
    background: var(--fr-positive-tint-2);
}
.fr-publish-badge--action {
    background: var(--fr-warning-tint);
}
.fr-publish-badge--action:hover {
    background: var(--fr-warning-tint-2);
}
.fr-pb-top {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: -0.005em;
}
.fr-publish-badge--clean .fr-pb-top  { color: var(--fr-positive-deep); }
.fr-publish-badge--action .fr-pb-top { color: var(--fr-warning-deep); }
.fr-pb-icon {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #FFFFFF;
    flex-shrink: 0;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
}
.fr-publish-badge--clean .fr-pb-icon  { background: var(--fr-positive); }
.fr-publish-badge--action .fr-pb-icon { background: var(--fr-warning); }
.fr-pb-detail {
    font-family: var(--fr-font-mono);
    font-feature-settings: 'tnum';
    font-size: 11px;
    color: var(--fr-ink-3);
    letter-spacing: 0.01em;
    padding-left: 24px;
    line-height: 1.3;
}

/* Tooltip for badge hover (action state only — shows per-unit-type breakdown) */
.fr-publish-badge[data-tooltip]::after,
.fr-publish-badge[data-tooltip]::before {
    opacity: 0;
    pointer-events: none;
    transition: opacity 160ms ease, transform 160ms ease;
    z-index: 20;
}
.fr-publish-badge[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    top: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%) translateY(-4px);
    background: var(--fr-ink);
    color: #FFFFFF;
    padding: 9px 12px;
    border-radius: 8px;
    font-family: var(--fr-font-mono);
    font-size: 11.5px;
    line-height: 1.5;
    white-space: pre;
    box-shadow: 0 8px 24px rgba(20, 24, 29, 0.18);
}
.fr-publish-badge[data-tooltip]::before {
    content: '';
    position: absolute;
    top: calc(100% + 2px);
    left: 50%;
    transform: translateX(-50%) translateY(-4px);
    width: 0;
    height: 0;
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-bottom: 6px solid var(--fr-ink);
}
.fr-publish-badge[data-tooltip]:hover::after,
.fr-publish-badge[data-tooltip]:hover::before {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

/* Zone 1/2/3 stack on smaller screens */
@media (max-width: 1100px) {
    .fr-pc-zones { grid-template-columns: 1fr; }
    .fr-pc-zone {
        border-right: 0;
        border-bottom: 1px solid var(--fr-hairline);
    }
    .fr-pc-zone:last-child { border-bottom: 0; }
}


/* ──────────────────────────────────────────────────────────────────────
   PROPERTY CARD — slim header mode (Leasing Hub & Settings)
   ----------------------------------------------------------------------
   Leasing agents jump straight to the unit table; settings users don't
   need property metrics either — the demand/rent zones are noise for
   both workflows. The card class is toggled by a callback in
   app/callbacks/navigation.py based on the active page.
   ────────────────────────────────────────────────────────────────────── */

.fr-property-card.fr-property-card-slim {
    background: transparent;
    border: none;
    box-shadow: none;
    margin-bottom: 16px;
}
.fr-property-card.fr-property-card-slim .fr-pc-header {
    border-bottom: none;
    padding: 14px 4px 4px;
}
.fr-property-card.fr-property-card-slim .fr-pc-zones,
.fr-property-card.fr-property-card-slim .fr-updated {
    display: none;
}


/* ──────────────────────────────────────────────────────────────────────
   PROPERTY CARD POPOVERS (Phase 5 / Task #8)
   Hover-revealed math breakdowns for the Leases Needed row and Demand
   Gap hero in Zone 2. Anchored to the new design language: warm white
   surface, hairline border, mono numerics, refined hierarchy.
   ────────────────────────────────────────────────────────────────────── */

.fr-popover.popover {
    border: 1px solid var(--fr-hairline) !important;
    border-radius: var(--fr-r-md) !important;
    background: var(--fr-surface) !important;
    box-shadow: 0 12px 32px rgba(20, 24, 29, 0.10),
                0 2px 4px rgba(20, 24, 29, 0.04) !important;
    font-family: var(--fr-font-sans) !important;
    max-width: 360px !important;
}
.fr-popover .popover-body {
    padding: 14px 16px !important;
    min-width: 280px;
    color: var(--fr-ink);
}
.fr-popover .popover-arrow::after,
.fr-popover .popover-arrow::before {
    border-bottom-color: var(--fr-hairline) !important;
}

.fr-popover-eyebrow {
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.13em;
    color: var(--fr-ink-3);
    font-weight: 600;
    margin-bottom: 10px;
}
.fr-popover-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 4px 0;
    font-size: 13px;
    line-height: 1.4;
}
.fr-popover-row-label {
    color: var(--fr-ink-2);
}
.fr-popover-row-value {
    font-family: var(--fr-font-mono);
    font-feature-settings: 'tnum';
    font-variant-numeric: tabular-nums;
    color: var(--fr-ink);
    font-weight: 500;
    margin-left: 12px;
    white-space: nowrap;
}
.fr-popover-row--emphasis .fr-popover-row-label {
    color: var(--fr-ink);
    font-weight: 500;
}
.fr-popover-row--emphasis .fr-popover-row-value {
    font-weight: 600;
    font-size: 14px;
}
.fr-popover-divider {
    height: 1px;
    background: var(--fr-hairline);
    margin: 8px 0;
}

/* The cursor-help affordance lets the user know the element has more
   info available on hover. Applied to the popover anchors. */
.fr-popover-anchor {
    cursor: help;
}


/* ──────────────────────────────────────────────────────────────────────
   SECTION HEADER — page break between property card and unit-type list
   ────────────────────────────────────────────────────────────────────── */

.fr-section-header {
    margin: 8px 4px 18px;
}
.fr-section-title {
    font-family: var(--fr-font-serif);
    font-size: 32px;
    font-weight: 400;
    letter-spacing: -0.005em;
    color: var(--fr-ink);
    line-height: 1;
    margin: 0 0 6px;
}
.fr-section-description {
    font-family: var(--fr-font-serif);
    font-style: italic;
    font-size: 15px;
    color: var(--fr-ink-2);
    margin: 0;
    line-height: 1.4;
    letter-spacing: 0.005em;
}


/* Softer red for availability exposure "urgent" bar */
.bg-exposure-urgent {
  background-color: #e57373 !important;  /* Coral red - urgent but not alarming */
}

/* Renewals UI polish */
.renewals-summary-bar {
  gap: 8px;
}
.renewals-badge {
  display: inline-block;
  padding: 4px 8px;
  margin-right: 8px;
  border-radius: 12px;
  font-size: 12px;
  background: rgba(0,0,0,0.04);
}
.renewals-badge-current { color: #6c757d; }
.renewals-badge-new { color: #0dcaf0; }
.renewals-badge-base { color: #0d6efd; }
.renewals-badge-amenity { color: #20c997; }
.renewals-badge-increase { color: #198754; }
.renewals-badge-total { color: #0d6efd; font-weight: 600; }

.pill-override {
  background: #ffe8a1;
  color: #856404;
  padding: 2px 6px;
  border-radius: 10px;
  font-size: 11px;
}
/* Keep override input inline with badges, avoid wrapping early */
.override-inline { display: inline-block; vertical-align: middle; min-width: 140px; }

/* Renewals table terms collapse row styling */
.terms-collapse-row > td {
  background: #f6f8fb;
  border-top: 1px solid #dfe3e8;
  border-bottom: 1px solid #dfe3e8;
}

.terms-collapse-row .dash-table-container {
  margin: 0;
}

/* Custom CSS for Dash Property Management App */

/* ─────────────────────────────────────────────────────────────────────
   GLOBAL STYLES
   ───────────────────────────────────────────────────────────────────── */

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    background-color: #eef1f5;
}

/* ─────────────────────────────────────────────────────────────────────
   NAVBAR CUSTOMIZATION
   ───────────────────────────────────────────────────────────────────── */

.navbar-brand {
    font-weight: 700 !important;
    font-size: 1.3rem !important;
}

/* Logo and navbar layout */
.navbar .d-flex.align-items-center {
    flex-grow: 1;
}

.navbar .d-flex.align-items-center img {
    /* No filter needed - logo is already white */
    transition: all 0.2s ease;
    opacity: 0.9;
}

.navbar .d-flex.align-items-center img:hover {
    filter: drop-shadow(0 0 8px rgba(255,255,255,0.4));
    opacity: 1;
    transform: scale(1.05);
}

.navbar .d-flex.align-items-center span {
    margin-left: 0.75rem;
    letter-spacing: 0.5px;
}

/* ─────────────────────────────────────────────────────────────────────
   SIDEBAR STYLES
   ───────────────────────────────────────────────────────────────────── */

.offcanvas {
    background-color: #2c3e50 !important;
    color: white !important;
}

.offcanvas .form-control,
.offcanvas .form-select {
    background-color: #34495e !important;
    border-color: #5a6c7d !important;
    color: white !important;
}

.offcanvas .form-control:focus,
.offcanvas .form-select:focus {
    background-color: #3b4a5c !important;
    border-color: #3498db !important;
    box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25) !important;
}

.offcanvas .form-control::placeholder {
    color: #bdc3c7 !important;
}

.offcanvas .dropdown-menu {
    background-color: #34495e !important;
    border-color: #5a6c7d !important;
}

.offcanvas .dropdown-item {
    color: white !important;
}

.offcanvas .dropdown-item:hover {
    background-color: #3498db !important;
}

/* ─────────────────────────────────────────────────────────────────────
   SIDEBAR GROUPED NAVIGATION
   ───────────────────────────────────────────────────────────────────── */

.sidebar-nav-group-header {
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: rgba(255, 255, 255, 0.92);
    padding: 6px 10px;
    margin-top: 14px;
    background: rgba(255, 255, 255, 0.12);
    border-radius: 4px;
    border-left: 3px solid #3498db;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    padding-top: 8px;
}

/* First group header doesn't need the top divider/spacing */
.sidebar-nav-group-header:first-child {
    margin-top: 0;
    border-top: none;
    padding-top: 6px;
}

.sidebar-nav-item {
    padding: 7px 12px;
    border-radius: 6px;
    cursor: pointer;
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.9rem;
    transition: background-color 0.15s ease, color 0.15s ease;
    margin: 1px 0;
    user-select: none;
}

.sidebar-nav-item:hover {
    background-color: #34495e;
    color: #ffffff;
}

.sidebar-nav-item.active {
    background-color: #3498db;
    color: #ffffff;
    font-weight: 500;
}

/* ─────────────────────────────────────────────────────────────────────
   DASH DROPDOWN STYLES (for sidebar)
   ───────────────────────────────────────────────────────────────────── */

/* Style Dash dropdowns in the sidebar */
.offcanvas .Select-control {
    background-color: #34495e !important;
    border-color: #5a6c7d !important;
    color: white !important;
}

.offcanvas .Select-control:hover {
    border-color: #3498db !important;
}

.offcanvas .Select-control .Select-value {
    color: white !important;
}

.offcanvas .Select-control .Select-value-label {
    color: white !important;
}

.offcanvas .Select-control .Select-placeholder {
    color: #bdc3c7 !important;
}

/* Ensure the main dropdown control text is white */
.offcanvas .Select-control .Select-value .Select-value-label {
    color: white !important;
}

.offcanvas .Select-control .Select-value .Select-value-label * {
    color: white !important;
}

.offcanvas .Select-control .Select-input > input {
    color: white !important;
}

.offcanvas .Select-menu-outer {
    background-color: #34495e !important;
    border-color: #5a6c7d !important;
    color: white !important;
}

.offcanvas .Select-option {
    background-color: #34495e !important;
    color: white !important;
}

.offcanvas .Select-option:hover {
    background-color: #3498db !important;
    color: white !important;
}

.offcanvas .Select-option.is-focused {
    background-color: #3498db !important;
    color: white !important;
}

.offcanvas .Select-option.is-selected {
    background-color: #2980b9 !important;
    color: white !important;
}

/* ─────────────────────────────────────────────────────────────────────
   PROPERTY HEADER CARD
   ───────────────────────────────────────────────────────────────────── */

/* Dropdown menu must sit above unit type cards */
#property-header-card .Select-menu-outer {
    z-index: 1050 !important;
}

/* Executive Dashboard / Executed Rents tab — dropdowns must float over
   the Plotly chart, table, and KPI cards rendered below the filter strip.
   Plotly graphs create their own stacking context, so a z-index on the
   Select-menu-outer alone isn't enough — we have to lift the entire
   filter card AND each dropdown wrapper into a higher stacking context
   first. .executed-rents-dropdown is set on each dcc.Dropdown; the
   filter Card wears .executed-rents-filter-card. */
.executed-rents-filter-card,
.executed-rents-filter-card .card-body {
    position: relative;
    z-index: 1100;
    overflow: visible !important;  /* defeat any default Card / CardBody overflow:hidden */
}

.executed-rents-dropdown {
    position: relative;
    z-index: 1100;
}

.executed-rents-dropdown .Select-menu-outer,
.executed-rents-dropdown .VirtualizedSelectFocusedOption,
.executed-rents-dropdown .VirtualizedSelectOption {
    z-index: 9999 !important;
}

/* Make the selected property name bold and prominent */
#property-header-card .Select-value-label,
#property-header-card .Select-value .Select-value-label {
    font-weight: 700 !important;
    font-size: 1.4rem !important;
    color: #2c3e50 !important;
}

/* Match the dropdown control to the forecast pill style */
#property-header-card .Select-control {
    background-color: #f8f9fa !important;
    border: 1px solid #e9ecef !important;
    border-radius: 8px !important;
    height: auto !important;
    min-height: 46px !important;
}

#property-header-card .Select-control:hover {
    border-color: #3498db !important;
}

/* Style the search input */
#property-header-card .Select-input > input {
    font-size: 1.1rem !important;
    font-weight: 600 !important;
}

/* Style the dropdown placeholder */
#property-header-card .Select-placeholder {
    font-size: 1.1rem !important;
    line-height: 46px !important;
}

/* Vertically center the selected value within the control */
#property-header-card .Select-control .Select-value {
    top: 0 !important;
    bottom: 0 !important;
    display: flex !important;
    align-items: center !important;
}

/* Prevent the property header card from hovering/lifting */
#property-header-card:hover {
    transform: none !important;
    box-shadow: 0 4px 12px rgba(0,0,0,0.10), 0 2px 4px rgba(0,0,0,0.06) !important;
}

/* ─────────────────────────────────────────────────────────────────────
   CARD STYLES
   ───────────────────────────────────────────────────────────────────── */

.card {
    border: 1px solid rgba(0, 0, 0, 0.06) !important;
    box-shadow: 0 4px 12px rgba(0,0,0,0.10), 0 2px 4px rgba(0,0,0,0.06) !important;
    border-radius: 10px !important;
    transition: transform 0.2s ease, box-shadow 0.2s ease !important;
    background-color: #ffffff !important;
}

.card:hover {
    transform: translateY(-3px) !important;
    box-shadow: 0 8px 24px rgba(0,0,0,0.14), 0 4px 8px rgba(0,0,0,0.08) !important;
}

.card-header {
    background: linear-gradient(135deg, #3498db, #2980b9) !important;
    color: white !important;
    border: none !important;
    border-radius: 10px 10px 0 0 !important;
    font-weight: 700 !important;
    padding: 14px 20px !important;
}

.card-header h5 {
    margin: 0 !important;
    font-size: 1.5rem !important;
    letter-spacing: 0.02em !important;
}

/* Zero-availability unit type cards - more subtle appearance */
.card-zero-availability {
    opacity: 0.8 !important;
    box-shadow: 0 2px 6px rgba(0,0,0,0.06) !important;
}

.card-zero-availability:hover {
    transform: translateY(-1px) !important;
    box-shadow: 0 4px 12px rgba(0,0,0,0.08) !important;
    opacity: 0.9 !important;
}

.card-zero-availability .card-header {
    background: linear-gradient(135deg, #6c8ea8, #5a7a94) !important;
}

.card-zero-availability .card-body {
    padding-bottom: 12px !important;
}

/* Legacy .unit-type-card styles removed — superseded by .ut-card vocabulary
   appended at the end of this file (search "UNIT TYPE PRICING CARD"). */

/* ─────────────────────────────────────────────────────────────────────
   BUTTON STYLES
   ───────────────────────────────────────────────────────────────────── */

.btn {
    border-radius: 6px !important;
    font-weight: 500 !important;
    transition: all 0.2s ease !important;
}

.btn-primary {
    background: linear-gradient(135deg, #3498db, #2980b9) !important;
    border-color: #2980b9 !important;
}

.btn-primary:hover {
    background: linear-gradient(135deg, #2980b9, #1f618d) !important;
    border-color: #1f618d !important;
    transform: translateY(-1px) !important;
}

.btn-success {
    background: linear-gradient(135deg, #27ae60, #229954) !important;
    border-color: #229954 !important;
}

.btn-success:hover {
    background: linear-gradient(135deg, #229954, #1e8449) !important;
    border-color: #1e8449 !important;
    transform: translateY(-1px) !important;
}

.btn-outline-primary {
    border-color: #3498db !important;
    color: #3498db !important;
}

.btn-outline-primary:hover {
    background-color: #3498db !important;
    border-color: #3498db !important;
    color: white !important;
    transform: translateY(-1px) !important;
}

/* ─────────────────────────────────────────────────────────────────────
   TABLE STYLES
   ───────────────────────────────────────────────────────────────────── */

.dash-table-container {
    border-radius: 8px !important;
    overflow: hidden !important;
    box-shadow: 0 2px 8px rgba(0,0,0,0.08) !important;
}

.dash-table-container .dash-spreadsheet-container {
    border-radius: 8px !important;
}

.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner {
    border-radius: 8px !important;
}

/* Table header styling */
.dash-table-container .dash-header {
    background: linear-gradient(135deg, #2c3e50, #34495e) !important;
    color: white !important;
    font-weight: 600 !important;
    border: none !important;
}

.dash-table-container .dash-header .column-header-name {
    color: white !important;
}

/* Table cell styling */
.dash-table-container .dash-cell {
    border: 1px solid #e3e6f0 !important;
    font-size: 0.9rem !important;
    text-align: center !important;
    padding: 12px 8px !important;
}

.dash-table-container .dash-selected-cell {
    background-color: rgba(52, 152, 219, 0.1) !important;
}

/* Actions column styling */
.dash-table-container .dash-cell[data-dash-column="Actions"] {
    background: linear-gradient(135deg, #3498db, #2980b9) !important;
    color: white !important;
    font-weight: 600 !important;
    border-radius: 4px !important;
    border: 1px solid #2980b9 !important;
    cursor: pointer !important;
    transition: all 0.2s ease !important;
}

.dash-table-container .dash-cell[data-dash-column="Actions"]:hover {
    background: linear-gradient(135deg, #2980b9, #1f618d) !important;
    transform: translateY(-1px) !important;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2) !important;
}

.dash-table-container .dash-cell[data-dash-column="Actions"]:active {
    transform: translateY(0) !important;
    box-shadow: 0 1px 2px rgba(0,0,0,0.2) !important;
}

/* ─────────────────────────────────────────────────────────────────────
   ALERT STYLES
   ───────────────────────────────────────────────────────────────────── */

.alert {
    border: none !important;
    border-radius: 8px !important;
    font-weight: 500 !important;
}

.alert-info {
    background: linear-gradient(135deg, #d6eaf8, #aed6f1) !important;
    color: #1b4f72 !important;
}

.alert-success {
    background: linear-gradient(135deg, #d5f4e6, #a3e4d7) !important;
    color: #0d5345 !important;
}

.alert-warning {
    background: linear-gradient(135deg, #fdeaa7, #f9e79f) !important;
    color: #7d6608 !important;
}

.alert-danger {
    background: linear-gradient(135deg, #fadbd8, #f5b7b1) !important;
    color: #922b21 !important;
}

/* ─────────────────────────────────────────────────────────────────────
   INPUT STYLES
   ───────────────────────────────────────────────────────────────────── */

.form-control {
    border-radius: 6px !important;
    border: 1px solid #d5dbdb !important;
    transition: all 0.2s ease !important;
}

.form-control:focus {
    border-color: #3498db !important;
    box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25) !important;
}

.input-group-text {
    background-color: #ecf0f1 !important;
    border-color: #d5dbdb !important;
    color: #2c3e50 !important;
    font-weight: 500 !important;
}

/* ─────────────────────────────────────────────────────────────────────
   PLOTLY CHART STYLES
   ───────────────────────────────────────────────────────────────────── */

.js-plotly-plot {
    border-radius: 8px !important;
    overflow: hidden !important;
    box-shadow: 0 2px 10px rgba(0,0,0,0.08) !important;
    border: 1px solid #e3e6f0 !important;
    background-color: white !important;
    height: 500px !important;
    max-height: 500px !important;
    min-height: 500px !important;
}

/* Force Plotly charts to maintain fixed height */
.js-plotly-plot .plotly {
    height: 500px !important;
    max-height: 500px !important;
    min-height: 500px !important;
}

.js-plotly-plot .plotly .main-svg {
    height: 500px !important;
    max-height: 500px !important;
    min-height: 500px !important;
}

/* Prevent any dynamic resizing of Plotly charts */
.js-plotly-plot,
.js-plotly-plot * {
    transition: none !important;
    animation: none !important;
}

/* Disable Plotly's auto-resize behavior */
.js-plotly-plot .plotly {
    resize: none !important;
}

/* Force fixed dimensions */
#expiration-chart,
#gpr-forecast-chart {
    height: 500px !important;
    max-height: 500px !important;
    min-height: 500px !important;
    width: 100% !important;
    max-width: 100% !important;
}

/* Chart container styling to match card theme */
.chart-container {
    background-color: white !important;
    border-radius: 10px !important;
    box-shadow: 0 2px 10px rgba(0,0,0,0.08) !important;
    border: 1px solid #e3e6f0 !important;
    padding: 20px !important;
    margin-bottom: 20px !important;
}

/* Chart title styling */
.chart-title {
    color: #2c3e50 !important;
    font-weight: 600 !important;
    font-size: 1.2rem !important;
    text-align: center !important;
    margin-bottom: 15px !important;
}

/* ─────────────────────────────────────────────────────────────────────
   ACCORDION STYLES
   ───────────────────────────────────────────────────────────────────── */

.accordion-button {
    background-color: #34495e !important;
    color: white !important;
    border: none !important;
    font-weight: 500 !important;
}

.accordion-button:not(.collapsed) {
    background-color: #2c3e50 !important;
    color: white !important;
    box-shadow: none !important;
}

.accordion-button:focus {
    box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25) !important;
}

.accordion-body {
    background-color: #2c3e50 !important;
    color: white !important;
    border-top: 1px solid #34495e !important;
}

/* ─────────────────────────────────────────────────────────────────────
   SIDEBAR TABLE STYLES (for Pricing Parameters)
   ───────────────────────────────────────────────────────────────────── */

/* Style tables within the sidebar accordion */
.offcanvas .accordion-body table {
    background-color: #34495e !important;
    border-color: #5a6c7d !important;
    color: white !important;
    border-radius: 6px !important;
    overflow: hidden !important;
    margin-bottom: 1rem !important;
}

.offcanvas .accordion-body table th {
    background-color: #2c3e50 !important;
    color: white !important;
    border-color: #5a6c7d !important;
    font-weight: 600 !important;
    padding: 8px 12px !important;
}

.offcanvas .accordion-body table td {
    background-color: #34495e !important;
    color: white !important;
    border-color: #5a6c7d !important;
    padding: 8px 12px !important;
}

.offcanvas .accordion-body table tr:hover td {
    background-color: #3b4a5c !important;
}

/* Style table headers specifically */
.offcanvas .accordion-body table thead th {
    background-color: #2c3e50 !important;
    color: white !important;
    border-bottom: 2px solid #5a6c7d !important;
    font-weight: 600 !important;
}

/* Style table cells */
.offcanvas .accordion-body table tbody td {
    background-color: #34495e !important;
    color: white !important;
    border-color: #5a6c7d !important;
}

/* Ensure all text in tables is white */
.offcanvas .accordion-body table * {
    color: white !important;
}

/* ─────────────────────────────────────────────────────────────────────
   LOADING ANIMATION
   ───────────────────────────────────────────────────────────────────── */

._dash-loading {
    margin: 20px auto !important;
}

._dash-loading-callback {
    position: fixed !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    z-index: 9999 !important;
}

/* ─────────────────────────────────────────────────────────────────────
   CURRENCY DISPLAY
   ───────────────────────────────────────────────────────────────────── */

.currency {
    font-weight: 600 !important;
    color: #27ae60 !important;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important;
}

.currency-large {
    font-size: 1.2rem !important;
    font-weight: 700 !important;
}

/* ─────────────────────────────────────────────────────────────────────
   RESPONSIVE DESIGN
   ───────────────────────────────────────────────────────────────────── */

@media (max-width: 768px) {
    .card {
        margin-bottom: 1rem !important;
    }
    
    .btn {
        width: 100% !important;
        margin-bottom: 0.5rem !important;
    }
    
    .dash-table-container {
        font-size: 0.8rem !important;
    }
}

/* ─────────────────────────────────────────────────────────────────────
   CUSTOM UTILITY CLASSES
   ───────────────────────────────────────────────────────────────────── */

.text-gradient {
    background: linear-gradient(135deg, #3498db, #2980b9) !important;
    -webkit-background-clip: text !important;
    -webkit-text-fill-color: transparent !important;
    background-clip: text !important;
    font-weight: 700 !important;
}

.shadow-soft {
    box-shadow: 0 2px 10px rgba(0,0,0,0.08) !important;
}

.shadow-hover:hover {
    box-shadow: 0 4px 20px rgba(0,0,0,0.12) !important;
    transform: translateY(-2px) !important;
    transition: all 0.2s ease !important;
}

.border-radius-lg {
    border-radius: 12px !important;
}

/* ─────────────────────────────────────────────────────────────────────
   ANIMATION CLASSES
   ───────────────────────────────────────────────────────────────────── */

.fade-in {
    animation: fadeIn 0.5s ease-in !important;
}

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

.slide-in {
    animation: slideIn 0.3s ease-out !important;
}

@keyframes slideIn {
    from { transform: translateX(-20px); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
}

/* ─────────────────────────────────────────────────────────────────────
   MODAL SCROLL PREVENTION
   ───────────────────────────────────────────────────────────────────── */

/* Prevent page from scrolling to top when modals close */
.modal {
    scroll-behavior: auto !important;
}

.modal-dialog {
    scroll-behavior: auto !important;
}

/* Prevent any automatic scrolling when modals are shown/hidden */
body.modal-open {
    scroll-behavior: auto !important;
}

/* Ensure the page maintains its scroll position */
html, body {
    scroll-behavior: auto !important;
}

/* ─────────────────────────────────────────────────────────────────────
   TOOLTIP STYLES
   ───────────────────────────────────────────────────────────────────── */

/* Simple tooltip styling - just black text, let Dash handle positioning */
.dash-tooltip,
.dash-table-tooltip,
.tooltip,
[role="tooltip"],
.tooltip-inner,
.popover,
.popover-body {
    color: #000000 !important;
    font-size: 14px !important;
    font-family: "Segoe UI", Arial, sans-serif !important;
    font-weight: 600 !important;
    white-space: pre-line !important;
    line-height: 1.6 !important;
    max-width: 400px !important;
    padding: 12px 16px !important;
    border-radius: 6px !important;
}

/* Override Bootstrap default black tooltip background */
.tooltip-inner {
    background-color: #ffffff !important;
    border: 1px solid #dee2e6 !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12) !important;
}

/* Fix tooltip arrow to match white background */
.tooltip .tooltip-arrow::before,
.bs-tooltip-top .tooltip-arrow::before {
    border-top-color: #dee2e6 !important;
}
.bs-tooltip-bottom .tooltip-arrow::before {
    border-bottom-color: #dee2e6 !important;
}

/* Target all child elements within tooltips */
.dash-tooltip *,
.dash-table-tooltip *,
.tooltip *,
[role="tooltip"] *,
.tooltip-inner *,
.popover *,
.popover-body * {
    color: #000000 !important;
    font-weight: 600 !important;
}

/* Market comparison popover needs more width for the Specials column */
.popover.market-comp-popover {
    max-width: 600px !important;
}

/* ─────────────────────────────────────────────────────────────────────
   BPO INPUT - HIDE SPINNER ARROWS
   ───────────────────────────────────────────────────────────────────── */

/* Hide spinner arrows on BPO number inputs (Chrome, Safari, Edge, Opera) */
.bpo-input-no-spinner::-webkit-outer-spin-button,
.bpo-input-no-spinner::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Hide spinner arrows on BPO number inputs (Firefox) */
.bpo-input-no-spinner {
    -moz-appearance: textfield;
}

/* ─────────────────────────────────────────────────────────────────────
   BEDROOM GROUP ACCORDION (New Leases grouped view, .ut-card vocabulary)
   Restyled to match the editorial Frontier aesthetic: 3px amber left
   border, serif name, mono availability count, chev-on-circle that
   rotates open. Override Bootstrap's default accordion-* classes.
   ───────────────────────────────────────────────────────────────────── */

.bedroom-group-accordion .accordion-item {
    background: var(--fr-surface) !important;
    border: 1px solid var(--fr-hairline) !important;
    border-left: 3px solid var(--fr-accent) !important;
    border-radius: var(--fr-r-md) !important;
    margin-bottom: 14px !important;
    overflow: hidden !important;
}
/* No hover state — same reasoning as .ut-card: scroll crossings would
   re-rasterize the soft shadow over a wide region per frame. */

.bedroom-group-accordion .accordion-button {
    background: var(--fr-surface) !important;
    color: var(--fr-ink) !important;
    font-family: var(--fr-font-serif) !important;
    font-size: 24px !important;
    font-weight: 400 !important;
    letter-spacing: -0.005em !important;
    padding: 18px 24px !important;
    line-height: 1 !important;
    box-shadow: none !important;
}
.bedroom-group-accordion .accordion-button:focus {
    box-shadow: none !important;
}

.bedroom-group-accordion .accordion-button:not(.collapsed) {
    background: var(--fr-surface) !important;
    color: var(--fr-ink) !important;
    box-shadow: 0 1px 0 rgba(20, 24, 29, 0.04), 0 8px 28px rgba(20, 24, 29, 0.05) !important;
}

/* Replace Bootstrap's default chev with an amber chev-on-circle. */
.bedroom-group-accordion .accordion-button::after {
    width: 30px !important;
    height: 30px !important;
    background-image: none !important;
    background: #FBF9F4 !important;
    border: 1px solid var(--fr-hairline) !important;
    border-radius: 50% !important;
    color: var(--fr-ink-2) !important;
    font-family: var(--fr-font-serif) !important;
    font-size: 18px !important;
    line-height: 28px !important;
    text-align: center !important;
    content: "›" !important;
    transform: rotate(0deg) !important;
    transition: transform 200ms ease, background 140ms ease, color 140ms ease, border-color 140ms ease !important;
}
.bedroom-group-accordion .accordion-button:not(.collapsed)::after {
    transform: rotate(90deg) !important;
    background: var(--fr-accent-soft) !important;
    color: var(--fr-accent-strong) !important;
    border-color: rgba(180, 83, 9, 0.20) !important;
}

.bedroom-group-accordion .accordion-body {
    background: #FBF9F4 !important;
    color: inherit !important;
    border-top: 1px solid var(--fr-hairline) !important;
    padding: 18px !important;
    font-family: var(--fr-font-sans) !important;
}

/* Style the title row inside the accordion-button: serif name, then a small-
   caps unit-types count, then the right-aligned availability count. The Python
   wraps these in a flex container with class `d-flex align-items-center`. */
.bedroom-group-accordion .accordion-button .text-muted {
    color: var(--fr-hairline-strong) !important;
}
.bedroom-group-accordion .accordion-button > div {
    width: 100%;
    font-family: var(--fr-font-sans);
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--fr-ink-3);
}
.bedroom-group-accordion .accordion-button > div > span:first-child {
    font-family: var(--fr-font-serif);
    font-size: 24px;
    font-weight: 400;
    text-transform: none;
    letter-spacing: -0.005em;
    color: var(--fr-ink);
}

/* ─────────────────────────────────────────────────────────────────────
   TRAFFIC PERIOD TOGGLE (per-card, default: 7d visible, 30d hidden)
   ───────────────────────────────────────────────────────────────────── */

.traffic-30d {
    display: none !important;
}
.traffic-7d {
    display: inline !important;
}

/* Per-card override: when wrapper has show-30d, swap visibility */
.traffic-show-30d .traffic-7d {
    display: none !important;
}
.traffic-show-30d .traffic-30d {
    display: inline !important;
}

/* ─────────────────────────────────────────────────────────────────────
   REPORTS PAGE
   ───────────────────────────────────────────────────────────────────── */

/* Override blue gradient card-header for the reports filter card */
.reports-filter-card > .card-header {
    background: #f8f9fa !important;
    color: #2c3e50 !important;
    padding: 8px 16px !important;
    border-bottom: 1px solid #dee2e6 !important;
}

/* Prevent hover-lift on the reports filter card */
.reports-filter-card:hover {
    transform: none !important;
    box-shadow: 0 4px 12px rgba(0,0,0,0.10), 0 2px 4px rgba(0,0,0,0.06) !important;
}

/* Normalize Dash DatePickerSingle to match other inputs in height */
.reports-date-picker .DateInput_input {
    height: 36px !important;
    padding: 4px 10px !important;
    font-size: 0.85rem !important;
    line-height: 36px !important;
}

.reports-date-picker .SingleDatePickerInput {
    border-radius: 4px !important;
    border: 1px solid #ccc !important;
}

.reports-date-picker .DateInput {
    width: 130px !important;
}


/* ══════════════════════════════════════════════════════════════════════
   LEASING HUB — Frontier vocabulary (Phase 1: visual shell)
   Editorial folder/card layout for the read-only site-team page.
   Uses the global --fr-* tokens; namespaced under .fr-leasing-*.
   Tier ramp + rate-change badge styles arrive in Phase 2/3.
   ══════════════════════════════════════════════════════════════════════ */

/* Page-width cap. Editorial layouts read better in a centered column than
   stretched edge-to-edge on ultrawide monitors. The expiration chart
   (defined separately in app/layouts/main.py) mirrors this width so the
   two regions stay visually aligned. */
.fr-leasing-page,
#leasing-hub-expiration-chart {
    max-width: 1500px;
    margin-left: auto;
    margin-right: auto;
}

/* property line + page title */
.fr-leasing-prop-line {
    display: flex;
    align-items: baseline;
    gap: 14px;
    margin-bottom: 4px;
}
.fr-leasing-prop-name {
    font-family: var(--fr-font-serif);
    font-size: 36px;
    line-height: 1;
    letter-spacing: -0.01em;
    color: var(--fr-ink);
}
.fr-leasing-prop-meta {
    font-family: var(--fr-font-sans);
    font-size: 13px;
    color: var(--fr-ink-3);
    letter-spacing: 0.02em;
}
.fr-leasing-prop-meta .dot {
    display: inline-block;
    width: 3px; height: 3px;
    border-radius: 50%;
    background: #B5B2A8;
    margin: 0 8px 2px;
    vertical-align: middle;
}

.fr-leasing-title {
    margin-top: 18px;
    display: flex;
    align-items: baseline;
    gap: 14px;
}
.fr-leasing-title h1 {
    font-family: var(--fr-font-serif);
    font-size: 30px;
    font-weight: 400;
    letter-spacing: -0.005em;
    color: var(--fr-ink);
    margin: 0;
}
.fr-leasing-title .updated {
    font-family: var(--fr-font-sans);
    font-size: 12px;
    color: var(--fr-ink-3);
    letter-spacing: 0.02em;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.fr-leasing-title .updated .live-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--fr-positive);
    box-shadow: 0 0 0 3px var(--fr-positive-tint);
}

.fr-leasing-sub {
    margin-top: 6px;
    font-family: var(--fr-font-sans);
    font-size: 13.5px;
    color: var(--fr-ink-2);
    max-width: 720px;
}

/* search + actions row */
.fr-leasing-controls {
    margin-top: 28px;
    display: flex;
    gap: 14px;
    align-items: center;
}
.fr-leasing-search {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 10px;
    height: 44px;
    background: var(--fr-surface);
    border: 1px solid var(--fr-hairline-strong);
    border-radius: var(--fr-r-md);
    padding: 0 14px;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}
.fr-leasing-search:focus-within {
    border-color: var(--fr-accent);
    box-shadow: 0 0 0 3px rgba(180, 83, 9, 0.10);
}
.fr-leasing-search-label {
    font-family: var(--fr-font-sans);
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--fr-ink-3);
    padding-right: 10px;
    border-right: 1px solid var(--fr-hairline);
}
.fr-leasing-search input,
.fr-leasing-search input.form-control {
    flex: 1;
    border: none !important;
    outline: none !important;
    background: transparent !important;
    font-family: var(--fr-font-sans);
    font-size: 14px;
    color: var(--fr-ink);
    box-shadow: none !important;
    padding: 0 !important;
    height: auto !important;
}
.fr-leasing-search input::placeholder {
    color: #B5B2A8;
    font-style: italic;
}

.fr-leasing-ghost-btn {
    height: 44px;
    padding: 0 16px;
    background: var(--fr-surface);
    border: 1px solid var(--fr-hairline-strong);
    border-radius: var(--fr-r-md);
    font-family: var(--fr-font-sans);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--fr-ink-2);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.fr-leasing-ghost-btn:hover {
    background: #FBF9F4;
    color: var(--fr-ink);
    border-color: #C9C5B8;
}
.fr-leasing-ghost-btn .chev {
    font-size: 14px;
    line-height: 1;
    transform: translateY(-1px);
}

/* Sort control — segmented pills inline with Search/Expand/Collapse.
   Soft amber active state matches the editorial palette without shouting. */
.fr-leasing-sort {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}
.fr-leasing-sort-label {
    font-family: var(--fr-font-sans);
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--fr-ink-3);
    margin-right: 4px;
}
.fr-leasing-sort-pill {
    height: 32px;
    padding: 0 14px;
    background: var(--fr-surface);
    border: 1px solid var(--fr-hairline-strong);
    border-radius: 100px;
    font-family: var(--fr-font-sans);
    font-size: 12px;
    font-weight: 500;
    color: var(--fr-ink-2);
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}
.fr-leasing-sort-pill:hover {
    background: var(--fr-bg);
    color: var(--fr-ink);
    border-color: #C9C5B8;
}
.fr-leasing-sort-pill.is-active {
    background: var(--fr-accent-soft);
    color: var(--fr-accent-strong);
    border-color: rgba(180, 83, 9, 0.30);
    box-shadow: inset 0 0 0 1px rgba(180, 83, 9, 0.08);
}
.fr-leasing-sort-pill .dir {
    font-size: 11px;
    line-height: 1;
    font-weight: 700;
    margin-left: 2px;
}

/* unit-type folders */
.fr-leasing-folders {
    margin-top: 28px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.fr-leasing-folder {
    background: var(--fr-surface);
    border: 1px solid var(--fr-hairline);
    border-left: 3px solid var(--fr-accent);
    border-radius: var(--fr-r-md);
    overflow: hidden;
    transition: border-color 140ms ease, box-shadow 140ms ease;
}
.fr-leasing-folder:hover {
    box-shadow: 0 1px 0 rgba(20, 24, 29, 0.04), 0 6px 18px rgba(20, 24, 29, 0.04);
}
.fr-leasing-folder.is-open {
    box-shadow: 0 1px 0 rgba(20, 24, 29, 0.04), 0 8px 28px rgba(20, 24, 29, 0.05);
}

.fr-leasing-folder-head {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 16px 22px;
    cursor: pointer;
    user-select: none;
}
.fr-leasing-folder-head .name {
    font-family: var(--fr-font-serif);
    font-size: 30px;
    line-height: 1;
    letter-spacing: -0.005em;
    color: var(--fr-ink);
    min-width: 70px;
}
.fr-leasing-folder-head .count {
    font-family: var(--fr-font-sans);
    font-size: 13.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--fr-ink-3);
}
.fr-leasing-folder-head .count strong {
    font-weight: 700;
    color: var(--fr-ink);
    margin-right: 6px;
}
/* Price range sits adjacent to the count, not pinned to the right edge.
   The chev (below) gets margin-left:auto instead, so any future badge
   between count and range slots in cleanly. */
.fr-leasing-folder-head .range {
    font-family: var(--fr-font-mono);
    font-size: 13px;
    color: var(--fr-ink-2);
    letter-spacing: -0.01em;
}
.fr-leasing-folder-head .range em {
    font-style: normal;
    color: var(--fr-ink-3);
    margin: 0 8px;
    font-size: 11px;
}
.fr-leasing-folder-head .chev {
    margin-left: auto;
    width: 28px; height: 28px;
    border-radius: 50%;
    background: #FBF9F4;
    border: 1px solid var(--fr-hairline);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--fr-ink-2);
    font-family: var(--fr-font-serif);
    font-size: 18px;
    line-height: 1;
    transition: transform 200ms ease, background 140ms ease, color 140ms ease;
}
.fr-leasing-folder.is-open .fr-leasing-folder-head .chev {
    transform: rotate(90deg);
    background: var(--fr-accent-soft);
    color: var(--fr-accent-strong);
    border-color: rgba(180, 83, 9, 0.20);
}

.fr-leasing-folder-body {
    background: #FBF9F4;
    border-top: 1px solid var(--fr-hairline);
    padding: 14px;
}

/* group meta strip */
.fr-leasing-group-meta {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 6px 8px 14px;
    flex-wrap: wrap;
}
.fr-leasing-group-meta .lbl {
    font-family: var(--fr-font-sans);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--fr-ink-3);
}
.fr-leasing-group-meta .v {
    font-family: var(--fr-font-mono);
    font-size: 12px;
    color: var(--fr-ink);
    margin-left: 4px;
}
.fr-leasing-group-meta .sep {
    width: 1px;
    height: 14px;
    background: var(--fr-hairline-strong);
}

/* unit cards */
.fr-leasing-units {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.fr-leasing-unit {
    display: grid;
    /* Unit | Available | Rent | Amenities | Status — rent sits next to the
       date so the eye scans unit → date → price as one cluster. Amenities
       (1fr) absorb any leftover width on the right; on properties with no
       amenities the empty space falls to the right of the data cluster
       instead of splitting it. */
    grid-template-columns: 130px 200px 170px 1fr 130px;
    align-items: start;
    gap: 22px;
    padding: 16px 18px;
    background: var(--fr-surface);
    border: 1px solid var(--fr-hairline);
    border-radius: var(--fr-r-md);
    transition: border-color 120ms ease, transform 140ms ease, box-shadow 140ms ease;
}
.fr-leasing-unit:hover {
    border-color: var(--fr-hairline-strong);
    transform: translateY(-1px);
    box-shadow: 0 4px 16px rgba(20, 24, 29, 0.04);
}

.fr-leasing-unit .id { padding-top: 4px; }
.fr-leasing-unit .id .num {
    font-family: var(--fr-font-serif);
    font-size: 28px;
    line-height: 1;
    letter-spacing: -0.005em;
    color: var(--fr-ink);
}
.fr-leasing-unit .id .sqft {
    margin-top: 4px;
    font-family: var(--fr-font-sans);
    font-size: 11px;
    color: var(--fr-ink-3);
    letter-spacing: 0.04em;
}

.fr-leasing-unit .avail { padding-top: 4px; }
.fr-leasing-unit .avail .when {
    font-family: var(--fr-font-sans);
    font-size: 14.5px;
    font-weight: 600;
    color: var(--fr-ink);
    letter-spacing: -0.005em;
}
.fr-leasing-unit .avail .when.is-soon { color: var(--fr-accent-strong); }
.fr-leasing-unit .avail .when.is-now  { color: var(--fr-positive); }
.fr-leasing-unit .avail .when.is-far  { color: var(--fr-ink-2); }
.fr-leasing-unit .avail .date {
    margin-top: 2px;
    font-family: var(--fr-font-mono);
    font-size: 11.5px;
    color: var(--fr-ink-3);
    letter-spacing: -0.01em;
}

/* pills (Phase 1 — uniform; tier ramp arrives in Phase 2) */
.fr-leasing-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    padding-top: 2px;
}
.fr-leasing-pill {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px 5px;
    background: #F2EEE3;
    color: var(--fr-ink-2);
    font-family: var(--fr-font-sans);
    font-size: 11.5px;
    font-weight: 500;
    border-radius: 100px;
    letter-spacing: 0.01em;
    white-space: nowrap;
}
.fr-leasing-pill .price {
    margin-left: 6px;
    padding-left: 6px;
    border-left: 1px solid rgba(0, 0, 0, 0.12);
    font-family: var(--fr-font-mono);
    font-size: 10.5px;
    font-weight: 600;
    opacity: 0.85;
    letter-spacing: -0.01em;
}

/* Upgrade-tier ramp — quiet → cool → warm → inverted.
   Each tier pill answers "what level of finish is this unit?" at a glance,
   without needing the agent to read the full label. */
.fr-leasing-pill.tier-modest {
    background: #EFE9DA;
    color: #6B5C3F;
}
.fr-leasing-pill.tier-modest .price { border-left-color: rgba(107, 92, 63, 0.30); }

.fr-leasing-pill.tier-silver {
    background: #DDDCD3;
    color: #3F4147;
}
.fr-leasing-pill.tier-silver .price { border-left-color: rgba(63, 65, 71, 0.30); }

.fr-leasing-pill.tier-premium {
    background: var(--fr-accent-soft);
    color: var(--fr-accent-strong);
    box-shadow: inset 0 0 0 1px rgba(180, 83, 9, 0.20);
}
.fr-leasing-pill.tier-premium .price { border-left-color: rgba(146, 64, 14, 0.30); }

.fr-leasing-pill.tier-platinum {
    background: var(--fr-ink);
    color: #F6F2E5;
}
.fr-leasing-pill.tier-platinum .price {
    border-left-color: rgba(255, 255, 255, 0.30);
    opacity: 0.95;
}

/* "+N additional features" expander chip.
   Looks like a pill but with a dashed outline + italic label, signalling
   it's interactive. Click toggles .is-expanded on the parent .amenities. */
.fr-leasing-pill.std-chip {
    background: transparent;
    color: var(--fr-ink-3);
    border: 1px dashed var(--fr-hairline-strong);
    padding: 3px 10px 4px;
    cursor: pointer;
    font-style: italic;
    transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
    user-select: none;
}
.fr-leasing-pill.std-chip:hover {
    color: var(--fr-ink-2);
    border-color: var(--fr-ink-3);
    background: rgba(255, 255, 255, 0.5);
}
.fr-leasing-pill.std-chip .chev {
    margin-left: 6px;
    font-size: 10px;
    font-style: normal;
    transition: transform 180ms ease;
    display: inline-block;
}
.fr-leasing-amenities.is-expanded .fr-leasing-pill.std-chip .chev {
    transform: rotate(180deg);
}

/* The dropped-in additional-features subtitle.
   Hidden by default; revealed when parent .amenities has .is-expanded. */
.fr-leasing-additional {
    display: none;
    margin-top: 8px;
    padding: 8px 12px;
    background: var(--fr-bg);
    border: 1px solid var(--fr-hairline);
    border-radius: var(--fr-r-sm);
    font-family: var(--fr-font-sans);
    font-size: 12px;
    color: var(--fr-ink-2);
    line-height: 1.6;
    letter-spacing: 0.01em;
}
.fr-leasing-amenities.is-expanded .fr-leasing-additional {
    display: block;
}
.fr-leasing-additional .sep {
    color: #B5B2A8;
    margin: 0 7px;
}

/* rent block (left-aligned now that it sits between date and amenities,
   so the price reads as the natural continuation of the data cluster) */
.fr-leasing-unit .rent {
    text-align: left;
}
.fr-leasing-unit .rent .price {
    font-family: var(--fr-font-serif);
    font-size: 26px;
    line-height: 1;
    color: var(--fr-ink);
    letter-spacing: -0.005em;
}
.fr-leasing-unit .rent .term {
    margin-top: 4px;
    font-family: var(--fr-font-sans);
    font-size: 11px;
    color: var(--fr-ink-3);
    text-transform: uppercase;
    letter-spacing: 0.14em;
}
.fr-leasing-unit .rent .term strong {
    color: var(--fr-ink-2);
    font-weight: 600;
}

/* status column */
.fr-leasing-unit .status {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
    padding-top: 6px;
}
.fr-leasing-status-dot {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--fr-font-sans);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.01em;
    color: var(--fr-ink-2);
}
.fr-leasing-status-dot::before {
    content: "";
    width: 7px; height: 7px;
    border-radius: 50%;
}
.fr-leasing-status-dot.is-live::before {
    background: var(--fr-positive);
    box-shadow: 0 0 0 3px var(--fr-positive-tint);
}
.fr-leasing-status-dot.is-pending::before {
    background: var(--fr-warning);
    box-shadow: 0 0 0 3px var(--fr-warning-tint);
}

.fr-leasing-matrix-link {
    font-family: var(--fr-font-sans);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--fr-ink-3);
    text-decoration: none;
    border: none;
    background: transparent;
    border-bottom: 1px solid var(--fr-hairline-strong);
    padding: 0 0 1px;
    transition: color 120ms ease, border-color 120ms ease;
    cursor: pointer;
}
.fr-leasing-matrix-link:hover {
    color: var(--fr-accent);
    border-color: var(--fr-accent);
}

/* legend */
.fr-leasing-legend {
    margin: 28px 4px 0;
    display: flex;
    flex-wrap: wrap;
    gap: 22px;
    font-family: var(--fr-font-sans);
    font-size: 11.5px;
    color: var(--fr-ink-3);
    letter-spacing: 0.01em;
}
.fr-leasing-legend .item {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}
.fr-leasing-legend .item::before {
    content: "";
    width: 7px; height: 7px;
    border-radius: 50%;
}
.fr-leasing-legend .item.live::before {
    background: var(--fr-positive);
    box-shadow: 0 0 0 3px var(--fr-positive-tint);
}
.fr-leasing-legend .item.pending::before {
    background: var(--fr-warning);
    box-shadow: 0 0 0 3px var(--fr-warning-tint);
}

/* compact layout for narrower screens */
@media (max-width: 1100px) {
    .fr-leasing-unit {
        grid-template-columns: 110px 170px 140px 1fr 110px;
        gap: 16px;
    }
    .fr-leasing-unit .id .num,
    .fr-leasing-unit .rent .price {
        font-size: 24px;
    }
}

/* empty state */
.fr-leasing-empty {
    margin-top: 28px;
    padding: 28px;
    background: var(--fr-surface);
    border: 1px dashed var(--fr-hairline-strong);
    border-radius: var(--fr-r-md);
    text-align: center;
    font-family: var(--fr-font-sans);
    color: var(--fr-ink-2);
    font-size: 13px;
}

/* ── PHASE 3: rate-change story ────────────────────────────────────── */

/* Page-level "what changed today" strip — only renders when something
   actually changed. Soft amber, sits above the folders. */
.fr-leasing-change-strip {
    margin-top: 18px;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 16px;
    background: var(--fr-accent-soft);
    border: 1px solid rgba(180, 83, 9, 0.20);
    border-radius: var(--fr-r-md);
    font-family: var(--fr-font-sans);
    font-size: 12.5px;
    color: var(--fr-accent-strong);
}
.fr-leasing-change-strip .ic {
    width: 22px; height: 22px;
    border-radius: 50%;
    background: rgba(180, 83, 9, 0.15);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
}
.fr-leasing-change-strip strong { font-weight: 600; }
.fr-leasing-change-strip .units {
    font-family: var(--fr-font-mono);
    font-size: 11.5px;
    margin-left: 6px;
    color: var(--fr-accent-strong);
}

/* Per-folder "N updated" badge in the folder head */
.fr-leasing-folder-head .changed-badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 9px 4px;
    background: var(--fr-accent-soft);
    color: var(--fr-accent-strong);
    border-radius: 100px;
    font-family: var(--fr-font-sans);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.10em;
    text-transform: uppercase;
}

/* Subtle amber outline on cards whose rate changed today */
.fr-leasing-unit.is-changed {
    border-color: rgba(180, 83, 9, 0.35);
    box-shadow: 0 0 0 3px rgba(180, 83, 9, 0.05);
}
.fr-leasing-unit.is-changed:hover {
    border-color: rgba(180, 83, 9, 0.50);
    box-shadow: 0 0 0 3px rgba(180, 83, 9, 0.07), 0 4px 16px rgba(20, 24, 29, 0.04);
}

/* Per-unit rate-change badge under the rent + term */
.fr-leasing-rate-change {
    margin-top: 8px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 9px 4px;
    border-radius: 100px;
    font-family: var(--fr-font-sans);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: help;
    position: relative;
}
.fr-leasing-rate-change.is-up {
    background: var(--fr-positive-tint);
    color: var(--fr-positive-deep, #155C39);
}
.fr-leasing-rate-change.is-down {
    background: rgba(185, 28, 28, 0.08);
    color: var(--fr-negative);
}
.fr-leasing-rate-change .arrow {
    font-size: 11px;
    line-height: 1;
}
.fr-leasing-rate-change .when {
    font-weight: 500;
    opacity: 0.78;
    margin-left: 3px;
    padding-left: 7px;
    border-left: 1px solid currentColor;
    border-color: rgba(0, 0, 0, 0.18);
}

/* Hover tooltip — full was/now/timestamp story.
   Anchored to the badge's left edge now that the rent block sits in the
   middle of the row (was right-anchored when rent was the rightmost column). */
.fr-leasing-rate-change .tooltip {
    position: absolute;
    bottom: calc(100% + 8px);
    left: 0;
    background: var(--fr-ink);
    color: #F6F2E5;
    font-family: var(--fr-font-sans);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 0.01em;
    padding: 8px 11px;
    border-radius: var(--fr-r-sm);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 140ms ease, transform 140ms ease;
    transform: translateY(4px);
    box-shadow: 0 6px 20px rgba(20, 24, 29, 0.18);
    z-index: 5;
}
.fr-leasing-rate-change .tooltip::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 14px;
    border: 5px solid transparent;
    border-top-color: var(--fr-ink);
}
.fr-leasing-rate-change .tooltip strong {
    font-family: var(--fr-font-serif);
    font-size: 13px;
    margin: 0 2px;
}
.fr-leasing-rate-change .tooltip .arrow-mid {
    color: #B5B2A8;
    margin: 0 5px;
}
.fr-leasing-rate-change:hover .tooltip,
.fr-leasing-rate-change:focus-within .tooltip {
    opacity: 1;
    transform: translateY(0);
}


/* ══════════════════════════════════════════════════════════════════════
   FRONTIER EXPIRATION CHART
   Editorial wrapper for the Expiration Curve vs Ideal Threshold chart
   on Leasing Hub, New Leases, and Renewals. Replaces the legacy blue
   dbc.Card chrome with the same eyebrow + serif title pattern used by
   the property cards and Executive Dashboard.
   ══════════════════════════════════════════════════════════════════════ */

.fr-exp-chart {
    background: var(--fr-surface);
    border: 1px solid var(--fr-hairline);
    border-radius: var(--fr-r-lg);
    padding: 24px 28px 18px;
    margin-bottom: 24px;
}

.fr-exp-chart__topbar {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 32px;
    padding-bottom: 18px;
    margin-bottom: 8px;
    border-bottom: 1px solid var(--fr-hairline);
}

.fr-exp-chart__head {
    flex: 1 1 auto;
    min-width: 0;
}

.fr-exp-chart__eyebrow {
    display: block;
    font-family: var(--fr-font-sans);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--fr-accent);
    margin-bottom: 8px;
}

.fr-exp-chart__title {
    font-family: var(--fr-font-serif);
    font-size: 32px;
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.01em;
    color: var(--fr-ink);
    margin: 0;
}

.fr-exp-chart__sub {
    font-family: var(--fr-font-serif);
    font-style: italic;
    font-size: 15px;
    line-height: 1.3;
    color: var(--fr-ink-3);
    margin: 8px 0 0;
}

.fr-exp-chart__legend {
    display: flex;
    align-items: center;
    gap: 22px;
    flex: 0 0 auto;
    padding-bottom: 4px;
}

.fr-exp-chart__legend-item {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--fr-font-sans);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--fr-ink-2);
    white-space: nowrap;
}

.fr-exp-chart__swatch {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 2px;
    flex: 0 0 auto;
}

.fr-exp-chart__swatch--ideal {
    background: var(--fr-hairline-strong);
}

.fr-exp-chart__swatch--actual {
    background: var(--fr-accent);
}

/* Tighten the dcc.Graph reset so it sits flush inside the card. */
.fr-exp-chart .js-plotly-plot,
.fr-exp-chart .plot-container {
    background: transparent !important;
}


/* ══════════════════════════════════════════════════════════════════════
   UNIT TYPE PRICING CARD — editorial Frontier vocabulary
   ----------------------------------------------------------------------
   Replaces the legacy .unit-type-card blue-bordered Bootstrap chrome
   with a calmer surface where the per-section signal colors (gauge ring,
   occupancy %, rent delta, market dot) carry the at-a-glance message.
   The top-edge rule is always amber (brand chrome, not a signal).
   ══════════════════════════════════════════════════════════════════════ */

.ut-card {
    background: var(--fr-surface);
    border: 1px solid var(--fr-hairline-strong);
    border-top: 3px solid var(--fr-accent);
    border-left: 3px solid var(--fr-accent);
    border-radius: var(--fr-r-md);
    overflow: hidden;
    transition: border-color 120ms ease, box-shadow 140ms ease;
    position: relative;
    margin-bottom: 14px;
    box-shadow: 0 1px 2px rgba(20, 24, 29, 0.04);
    content-visibility: auto;
    contain-intrinsic-size: auto 320px;
}
.ut-card:hover {
    border-top-color: var(--fr-accent-strong);
    border-left-color: var(--fr-accent-strong);
    box-shadow: 0 1px 0 rgba(20, 24, 29, 0.04), 0 6px 18px rgba(20, 24, 29, 0.04);
}

/* zero-availability variant: drop the amber bracket, unify to hairline */
.ut-card.is-empty {
    background: var(--fr-bg);
    border-color: var(--fr-hairline-strong);
}


/* ── header strip ────────────────────────────────────────────────── */
.ut-head {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 24px 13px;
    background: var(--fr-bg);
    border-bottom: 1px solid var(--fr-hairline-strong);
    flex-wrap: wrap;
    font-family: var(--fr-font-sans);
}
.ut-head .ut-code {
    position: relative;
    font-family: var(--fr-font-sans);
    font-size: 24px;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--fr-ink);
    font-weight: 700;
    padding-left: 12px;
}
.ut-head .ut-code::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 1.05em;
    background: var(--fr-accent);
    border-radius: 2px;
}
.ut-head .ut-availability {
    display: flex;
    align-items: baseline;
    gap: 6px;
    padding-left: 14px;
    border-left: 1px solid var(--fr-hairline);
    margin-right: 6px;
}
.ut-head .ut-availability .v {
    font-family: var(--fr-font-sans);
    font-size: 14px;
    font-weight: 600;
    color: var(--fr-ink);
    letter-spacing: -0.005em;
}
.ut-head .ut-availability .l {
    font-family: var(--fr-font-sans);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--fr-ink-3);
    margin-left: 4px;
}

/* sparkline pill — "+2.5% 30d base rents" */
.ut-spark-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 5px 11px 5px 8px;
    background: var(--fr-positive-tint-2);
    border: 1px solid rgba(31, 122, 77, 0.15);
    border-radius: 100px;
    font-family: var(--fr-font-sans);
    font-size: 11px;
    font-weight: 600;
    color: var(--fr-positive-deep);
    cursor: default;
}
.ut-spark-pill.is-down {
    background: rgba(185, 28, 28, 0.08);
    border-color: rgba(185, 28, 28, 0.18);
    color: var(--fr-negative);
}
.ut-spark-pill.is-flat {
    background: var(--fr-bg);
    border-color: var(--fr-hairline-strong);
    color: var(--fr-ink-3);
}
.ut-spark-pill svg { display: block; }
.ut-spark-pill .delta {
    font-family: var(--fr-font-sans);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: -0.005em;
}
.ut-spark-pill .lbl {
    font-family: var(--fr-font-sans);
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    opacity: 0.85;
}

/* needed / forecast pills */
.ut-stat-pill {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    padding: 5px 11px;
    background: #FBF9F4;
    border: 1px solid var(--fr-hairline-strong);
    border-radius: 100px;
}
.ut-stat-pill .l {
    font-family: var(--fr-font-sans);
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--fr-ink-3);
}
.ut-stat-pill .v {
    font-family: var(--fr-font-sans);
    font-size: 13px;
    font-weight: 600;
    color: var(--fr-ink);
    letter-spacing: -0.005em;
}
.ut-stat-pill .horizon {
    font-family: var(--fr-font-mono);
    font-size: 10px;
    color: var(--fr-ink-3);
    letter-spacing: -0.01em;
}

/* live indicator (right-pinned) */
.ut-head .ut-live-pip {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 5px 12px 5px 10px;
    background: var(--fr-positive-tint-2);
    border-radius: 100px;
    font-family: var(--fr-font-sans);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--fr-positive-deep);
}
.ut-head .ut-live-pip .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--fr-positive);
    box-shadow: 0 0 0 3px var(--fr-positive-tint);
}


/* ── body — 3 equal columns ──────────────────────────────────────── */
.ut-body {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    align-items: stretch;
}
.ut-col {
    padding: 18px 22px 20px;
    border-right: 1px solid var(--fr-hairline);
    display: flex;
    flex-direction: column;
    min-height: 200px;
    position: relative;
    font-family: var(--fr-font-sans);
}
/* Split col (COL 1) has half-eyebrows inside each half rather than a
   single outer .ut-col-eyebrow. The padding is the same; layout is identical. */
.ut-col:last-child { border-right: none; }

.ut-col-eyebrow {
    font-family: var(--fr-font-sans);
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.22em;
    color: var(--fr-ink-3);
    margin-bottom: 14px;
    display: flex;
    align-items: center;
    gap: 10px;
}


/* ── COL 1 — left strip: occupancy + gauge + traffic ────────────── */
.ut-left-strip {
    display: flex;
    align-items: stretch;
    flex: 1;
    width: 100%;
}
/* occupancy %s stacked */
.ut-occ-stack {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    min-width: 0;
}
.ut-occ-stack .stat {
    text-align: center;
}
.ut-occ-stack .stat .num {
    font-family: var(--fr-font-sans);
    font-size: 30px;
    line-height: 1;
    letter-spacing: -0.01em;
    color: var(--fr-ink);
    font-weight: 600;
}
.ut-occ-stack .stat .num.is-up   { color: var(--fr-positive-deep); }
.ut-occ-stack .stat .num.is-warn { color: var(--fr-warning-deep); }
.ut-occ-stack .stat .num.is-down { color: var(--fr-negative); }
.ut-occ-stack .stat .num .pct {
    font-family: var(--fr-font-sans);
    font-size: 14px;
    font-weight: 600;
    color: inherit;
    opacity: 0.65;
    margin-left: 2px;
    vertical-align: 0.18em;
}
.ut-occ-stack .stat .lbl {
    margin-top: 6px;
    font-family: var(--fr-font-sans);
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--fr-ink-3);
}

/* gauge — SVG ring + center numeral */
.ut-gauge-block {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    border-left: 1px solid var(--fr-hairline);
    padding: 0 12px;
    min-width: 0;
}
.ut-gauge {
    width: 116px;
    height: 116px;
    border-radius: 50%;
    position: relative;
    /* The inline `background` style holds the conic-gradient; padding here
       creates the ring thickness, the inner .center fills the hole. */
}
.ut-gauge .center {
    position: absolute;
    inset: 9px;
    border-radius: 50%;
    background: var(--fr-surface);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
}
.ut-gauge .center .num {
    font-family: var(--fr-font-sans);
    font-size: 30px;
    line-height: 1;
    letter-spacing: -0.01em;
    color: var(--fr-ink);
    font-weight: 600;
}
.ut-gauge .center .total {
    margin-top: 2px;
    font-family: var(--fr-font-mono);
    font-size: 10px;
    color: var(--fr-ink-3);
    letter-spacing: -0.01em;
}
.ut-gauge-caption {
    margin-top: 6px;
    font-family: var(--fr-font-sans);
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--fr-ink-3);
}

/* traffic compact (no bars) */
.ut-traffic-block {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    border-left: 1px solid var(--fr-hairline);
    padding: 12px 0 12px 18px;
    min-width: 0;
}
/* Half-section eyebrow used inside .ut-left-half — matches the
   .ut-traffic-head label so both halves of COL 1 line up. */
.ut-traffic-head {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-bottom: 8px;
    min-height: 22px;
}
.ut-traffic-head .lbl {
    font-family: var(--fr-font-sans);
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.20em;
    color: var(--fr-ink-3);
}
/* Editorial pill toggle for the dbc.ButtonGroup inside the traffic head.
   The callback continues to set outline=true/false and active=true/false on
   the buttons; we restyle Bootstrap's defaults to match the .ut-* vocabulary. */
.ut-traffic-head .ut-traffic-toggle {
    border-radius: 100px;
    overflow: hidden;
    background: #FBF9F4;
    border: 1px solid var(--fr-hairline);
    padding: 1px;
    box-shadow: none;
}
.ut-traffic-head .ut-traffic-toggle .btn {
    background: transparent !important;
    border: 0 !important;
    color: var(--fr-ink-3) !important;
    font-family: var(--fr-font-sans);
    font-size: 9px !important;
    font-weight: 600 !important;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    padding: 2px 9px !important;
    border-radius: 100px !important;
    box-shadow: none !important;
    transition: background 120ms ease, color 120ms ease;
    line-height: 1.3 !important;
}
.ut-traffic-head .ut-traffic-toggle .btn:hover {
    color: var(--fr-ink-2) !important;
}
.ut-traffic-head .ut-traffic-toggle .btn.active,
.ut-traffic-head .ut-traffic-toggle .btn:active {
    background: var(--fr-ink) !important;
    color: #F6F2E5 !important;
}

.ut-traffic-rows {
    display: flex;
    flex-direction: column;
    gap: 7px;
}
.ut-traffic-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    justify-content: center;
}
.ut-traffic-row .lbl {
    flex: 0 0 auto;
    min-width: 50px;
    font-family: var(--fr-font-sans);
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--fr-ink-2);
}
.ut-traffic-row .v {
    font-family: var(--fr-font-sans);
    font-size: 14px;
    font-weight: 600;
    color: var(--fr-ink);
    letter-spacing: -0.005em;
    line-height: 1;
    min-width: 18px;
    text-align: right;
}
.ut-traffic-row .delta {
    font-family: var(--fr-font-sans);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    min-width: 22px;
    text-align: right;
}
.ut-traffic-row .delta.is-up   { color: var(--fr-positive-deep); }
.ut-traffic-row .delta.is-down { color: var(--fr-negative); }
.ut-traffic-row .delta.is-flat { color: #B5B2A8; }

/* The legacy global rule .traffic-7d/.traffic-30d uses display:inline,
   which would force flex children inline and break the row layout.
   Override inside our new vocabulary so flex layout is preserved. */
.ut-traffic-row .traffic-7d,
.ut-traffic-row .traffic-30d {
    display: inline-block !important;
}
.ut-traffic-row .traffic-30d {
    display: none !important;
}
.traffic-show-30d .ut-traffic-row .traffic-7d {
    display: none !important;
}
.traffic-show-30d .ut-traffic-row .traffic-30d {
    display: inline-block !important;
}


/* ── COL 2 — RENT ────────────────────────────────────────────────── */
.ut-rent-hero-wrap {
    background: var(--fr-positive-tint-2);
    border: 1px solid rgba(31, 122, 77, 0.10);
    border-radius: var(--fr-r-md);
    padding: 6px 14px 7px;
    text-align: center;
    margin-bottom: 14px;
}
.ut-rent-hero-wrap.is-down,
.ut-card.is-negative .ut-rent-hero-wrap {
    background: rgba(185, 28, 28, 0.06);
    border-color: rgba(185, 28, 28, 0.15);
}
.ut-rent-hero-wrap.is-warn,
.ut-card.is-warning .ut-rent-hero-wrap {
    background: var(--fr-warning-tint);
    border-color: rgba(181, 112, 31, 0.15);
}
.ut-rent-hero-wrap.is-flat {
    background: var(--fr-bg);
    border-color: var(--fr-hairline-strong);
}

.ut-rent-hero {
    display: inline-flex;
    align-items: baseline;
    gap: 10px;
}
.ut-rent-hero .delta {
    font-family: var(--fr-font-sans);
    font-size: 30px;
    line-height: 1;
    letter-spacing: -0.015em;
    font-weight: 600;
}
.ut-rent-hero .delta.is-up   { color: var(--fr-positive-deep); }
.ut-rent-hero .delta.is-down { color: var(--fr-negative); }
.ut-rent-hero .delta.is-warn { color: var(--fr-warning-deep); }
.ut-rent-hero .delta.is-flat { color: var(--fr-ink-2); }
.ut-rent-hero .delta-trail {
    font-family: var(--fr-font-mono);
    font-size: 12px;
    color: var(--fr-ink-2);
    padding-bottom: 6px;
    letter-spacing: -0.01em;
}
.ut-rent-hero .delta-trail.is-up   { color: var(--fr-positive-deep); opacity: 0.85; }
.ut-rent-hero .delta-trail.is-down { color: var(--fr-negative); opacity: 0.85; }
.ut-rent-hero .delta-trail.is-warn { color: var(--fr-warning-deep); opacity: 0.85; }
.ut-rent-hero-sub {
    margin-top: 2px;
    font-family: var(--fr-font-sans);
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.20em;
    color: var(--fr-ink-3);
}

.ut-rent-stats {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 10px;
    margin-top: auto;
}
.ut-rent-stats .stat {
    text-align: center;
    padding: 0 4px;
    border-right: 1px solid var(--fr-hairline);
}
.ut-rent-stats .stat:last-child { border-right: none; }
.ut-rent-stats .stat .lbl {
    font-family: var(--fr-font-sans);
    font-size: 9px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--fr-ink-3);
    margin-bottom: 6px;
}
.ut-rent-stats .stat .v {
    font-family: var(--fr-font-sans);
    font-size: 18px;
    font-weight: 600;
    line-height: 1;
    color: var(--fr-ink);
    letter-spacing: -0.005em;
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
}
.ut-rent-stats .stat .v .delta-inline {
    font-family: var(--fr-font-sans);
    font-size: 11px;
    font-weight: 600;
}
.ut-rent-stats .stat .v .delta-inline.is-up   { color: var(--fr-positive-deep); }
.ut-rent-stats .stat .v .delta-inline.is-down { color: var(--fr-negative); }
.ut-rent-stats .stat .sub {
    margin-top: 4px;
    font-family: var(--fr-font-mono);
    font-size: 10px;
    color: var(--fr-ink-3);
    letter-spacing: -0.01em;
}


/* ── COL 3 — MARKET ──────────────────────────────────────────────── */
/* Header row — eyebrow on the left, View Chart link on the right. */
.ut-mkt-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 18px;
}
.ut-mkt-header .ut-col-eyebrow {
    margin-bottom: 0;
    flex: 0 1 auto;
}
.ut-mkt-header .view-link {
    font-family: var(--fr-font-sans);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    color: var(--fr-accent);
    cursor: pointer;
    text-decoration: none;
    border: none;
    background: transparent;
    padding: 0;
    flex: 0 0 auto;
    white-space: nowrap;
    transition: color 120ms ease;
}
.ut-mkt-header .view-link:hover { color: var(--fr-accent-strong); }

/* Gradient row — $low endpoint | bar stack | $high endpoint.
   Endpoint labels anchor the range numbers to their visual position on
   the gradient instead of floating above it. Pushed to the bottom area
   of the column so the percentile chip lands underneath. */
.ut-mkt-gradient-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-top: auto;
    margin-bottom: 18px;
}
.ut-mkt-endpoint {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Match the gradient bar's height so align-items:center puts the
       value's visual midline exactly on the bar's centerline. The 16px
       glyph spills 1px above and 1px below symmetrically — the *middle*
       of the number lands on the *middle* of the bar. */
    height: 14px;
    min-width: 50px;
}
.ut-mkt-endpoint .val {
    font-family: var(--fr-font-sans);
    font-size: 16px;
    font-weight: 600;
    color: var(--fr-ink);
    letter-spacing: -0.005em;
    line-height: 1;
}

/* Bar stack — wraps the gradient bar and pins a YOU label below it
   at the same percentile position as the caret on the bar. The padding
   reserves space for the pin label without disrupting bar height. */
.ut-mkt-bar-stack {
    flex: 1 1 auto;
    position: relative;
    min-width: 0;
    padding-bottom: 30px;
}
.ut-mkt-you-pin {
    position: absolute;
    top: 22px;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    line-height: 1;
    white-space: nowrap;
    pointer-events: none;
}
.ut-mkt-you-pin .val {
    font-family: var(--fr-font-sans);
    font-size: 12px;
    font-weight: 600;
    color: var(--fr-ink);
    letter-spacing: -0.005em;
}
.ut-mkt-you-pin .lbl {
    font-family: var(--fr-font-sans);
    font-size: 8.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.20em;
    color: var(--fr-ink-3);
    margin-top: 3px;
}
.ut-mkt-bar {
    position: relative;
    height: 14px;
    border-radius: 100px;
    background: linear-gradient(
        to right,
        rgba(185, 28, 28, 0.30) 0%,
        rgba(181, 112, 31, 0.32) 40%,
        rgba(31, 122, 77, 0.32) 75%,
        rgba(31, 122, 77, 0.42) 100%
    );
    box-shadow: inset 0 0 0 1px var(--fr-hairline);
}
.ut-mkt-bar .comp {
    position: absolute;
    top: 50%;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--fr-surface);
    border: 1px solid rgba(20, 24, 29, 0.35);
    transform: translate(-50%, -50%);
    z-index: 3;
}
.ut-mkt-bar .you {
    position: absolute;
    top: 50%;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--fr-ink);
    border: 3px solid var(--fr-surface);
    box-shadow: 0 0 0 1px var(--fr-ink), 0 4px 10px rgba(20, 24, 29, 0.18);
    transform: translate(-50%, -50%);
    z-index: 5;
}
.ut-card.is-positive .ut-mkt-bar .you {
    background: var(--fr-positive-deep);
    box-shadow: 0 0 0 1px var(--fr-positive-deep), 0 4px 10px rgba(31, 122, 77, 0.30);
}
.ut-card.is-warning .ut-mkt-bar .you {
    background: var(--fr-warning-deep);
    box-shadow: 0 0 0 1px var(--fr-warning-deep), 0 4px 10px rgba(140, 86, 24, 0.30);
}
.ut-card.is-negative .ut-mkt-bar .you {
    background: var(--fr-negative);
    box-shadow: 0 0 0 1px var(--fr-negative), 0 4px 10px rgba(185, 28, 28, 0.30);
}

.ut-mkt-bar .you-caret {
    position: absolute;
    bottom: 100%;
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 6px solid var(--fr-ink);
    transform: translate(-50%, -2px);
    z-index: 6;
}
.ut-card.is-positive .ut-mkt-bar .you-caret { border-top-color: var(--fr-positive-deep); }
.ut-card.is-warning  .ut-mkt-bar .you-caret { border-top-color: var(--fr-warning-deep); }
.ut-card.is-negative .ut-mkt-bar .you-caret { border-top-color: var(--fr-negative); }

/* Percentile chip — the right-zone punchline. Same chip vocabulary as
   the +X% rent hero in the middle zone: rounded pill on warm-paper bg,
   a hairline border, big number leading a small ordinal and an eyebrow
   label. Left-aligned so it lands at a consistent x-anchor card-to-card. */
.ut-mkt-pct-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    padding: 8px 14px;
    background: #FBF9F4;
    border: 1px solid var(--fr-hairline-strong);
    border-radius: 100px;
    align-self: flex-start;
    font-family: var(--fr-font-sans);
}
.ut-mkt-pct-chip .num {
    font-size: 24px;
    font-weight: 700;
    color: var(--fr-ink);
    letter-spacing: -0.015em;
    line-height: 1;
}
.ut-mkt-pct-chip .ord {
    font-size: 11px;
    font-weight: 600;
    color: var(--fr-ink);
    line-height: 1;
    align-self: flex-start;
    margin-left: -2px;
    margin-top: 4px;
}
.ut-mkt-pct-chip .lbl {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--fr-ink-3);
    margin-left: 8px;
}

/* market column placeholder when no comps configured */
.ut-mkt-empty {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    font-family: var(--fr-font-serif);
    font-style: italic;
    font-size: 14px;
    color: var(--fr-ink-3);
    line-height: 1.5;
    padding: 20px 8px;
}


/* ── footer reveal — show units table ────────────────────────────── */
.ut-foot {
    border-top: 1px solid var(--fr-hairline);
    background: #FBF9F4;
    padding: 12px 24px;
    display: flex;
    align-items: center;
    gap: 16px;
    cursor: pointer;
    user-select: none;
    transition: background 120ms ease;
    font-family: var(--fr-font-sans);
}
.ut-foot:hover { background: #F4EFE2; }
.ut-foot .lbl {
    font-family: var(--fr-font-sans);
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--fr-ink-2);
}
.ut-foot .count {
    font-family: var(--fr-font-mono);
    font-size: 11.5px;
    color: var(--fr-ink-3);
    letter-spacing: -0.01em;
}
.ut-foot .spacer { flex: 1; }
.ut-foot .chev {
    font-family: var(--fr-font-serif);
    font-size: 16px;
    color: var(--fr-ink-2);
    transition: transform 200ms ease;
}
.ut-card.units-open .ut-foot { background: #F4EFE2; }
.ut-card.units-open .ut-foot .chev {
    transform: rotate(90deg);
    color: var(--fr-accent-strong);
}


/* responsive: collapse 3 columns to a stack on narrow viewports */
@media (max-width: 1100px) {
    .ut-body { grid-template-columns: 1fr; }
    .ut-col {
        border-right: none;
        border-bottom: 1px solid var(--fr-hairline);
    }
    .ut-col:last-child { border-bottom: none; }
}


/* ══════════════════════════════════════════════════════════════════════
   EXPANDED UNIT TABLE — appears below .ut-foot when "SHOW UNITS" is open.
   Designed to read as a quiet extension of the card chrome: the same
   warm-paper header tint as .ut-head, hairline row dividers, and the
   same fr-* button vocabulary used elsewhere. Most cells set their own
   inline styles (set in hover_table.py per-cell), so the rules below
   use !important sparingly to override the legacy DataTable defaults
   without rewriting every cell builder.
   ══════════════════════════════════════════════════════════════════════ */

.ut-units-table-wrap {
    font-family: var(--fr-font-sans);
    padding: 14px 18px 18px;
    background: var(--fr-surface);
    border-top: 1px solid var(--fr-hairline);
}

/* The bulk-action button rows above the table */
.ut-units-table-wrap > div:not(.ut-units-table-scroll) .btn {
    font-family: var(--fr-font-sans);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 6px 14px;
    border-radius: 6px;
    border: 1px solid var(--fr-hairline-strong);
    box-shadow: none;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}
.ut-units-table-wrap > div:not(.ut-units-table-scroll) .btn-secondary,
.ut-units-table-wrap > div:not(.ut-units-table-scroll) .btn-outline-secondary {
    background: var(--fr-surface);
    color: var(--fr-ink-2);
    border-color: var(--fr-hairline-strong);
}
.ut-units-table-wrap > div:not(.ut-units-table-scroll) .btn-secondary:hover,
.ut-units-table-wrap > div:not(.ut-units-table-scroll) .btn-outline-secondary:hover {
    background: var(--fr-bg);
    color: var(--fr-ink);
    border-color: var(--fr-ink-3);
}
.ut-units-table-wrap > div:not(.ut-units-table-scroll) .btn-primary {
    background: var(--fr-accent);
    color: #FFFFFF;
    border-color: var(--fr-accent);
}
.ut-units-table-wrap > div:not(.ut-units-table-scroll) .btn-primary:hover {
    background: var(--fr-accent-strong);
    border-color: var(--fr-accent-strong);
}

/* Outer scroll container — replaces the legacy gray border */
.ut-units-table-scroll {
    border: 1px solid var(--fr-hairline-strong);
    border-radius: var(--fr-r-sm, 4px);
    overflow: auto;
    max-height: 500px;
    /* Tells the browser this scroll container's paint can't escape its
       box, so it doesn't reconsider the whole page during local scrolls. */
    contain: content;
}

/* The table itself */
.ut-units-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--fr-surface);
    font-family: var(--fr-font-sans);
    font-variant-numeric: tabular-nums;
}

/* Header row — eyebrow style on warm-paper bg, matches .ut-head */
.ut-units-table thead th {
    background: var(--fr-bg) !important;
    color: var(--fr-ink-3) !important;
    font-family: var(--fr-font-sans) !important;
    font-size: 9.5px !important;
    font-weight: 600 !important;
    letter-spacing: 0.16em !important;
    text-transform: uppercase !important;
    text-align: center !important;
    padding: 10px 8px !important;
    border: none !important;
    border-bottom: 1px solid var(--fr-hairline-strong) !important;
    position: sticky;
    top: 0;
    z-index: 2;
}
.ut-units-table thead th [id*="sort-header"] {
    color: var(--fr-ink-3);
}

/* Body cells — keep their inline padding/font-size/color rules from
   hover_table.py (vacancy red, muted "last published", etc. are
   intentional signals) but neutralize the legacy 1px gray border so
   we get clean hairline row dividers from the table itself. */
.ut-units-table tbody td {
    border: none !important;
    border-bottom: 1px solid var(--fr-hairline) !important;
    font-family: var(--fr-font-sans) !important;
}
.ut-units-table tbody tr:last-child td {
    border-bottom: none !important;
}

/* Zone divider — separates the "reference" columns (Unit, Date, Sq Ft,
   Prior Rent, Current Advertised) from the "action" columns (Recommended,
   Override, Adjusted, Term, etc.). Applied via .ut-section-end class on
   both the header Th and the body Td so the line runs continuously
   from header through the last row. Higher specificity than the base
   .ut-units-table tbody td rule, so it wins despite the !important reset. */
.ut-units-table thead th.ut-section-end,
.ut-units-table tbody td.ut-section-end {
    border-right: 1px solid var(--fr-hairline-strong) !important;
}
/* Default text color — only applied where no inline color override exists.
   Cells that set their own color (vacancy red, "Last Published" mute) win. */
.ut-units-table tbody { color: var(--fr-ink); }

/* Zebra striping — subtle warm tint on even rows so the eye has a rail to
   follow across the 14-column width. Lighter than --fr-bg so hover still
   reads as a distinct elevation above the zebra. Inline cell tints
   (vacancy red, never-published) win at normal specificity; hover wins via
   !important and momentarily unifies the row. */
.ut-units-table tbody tr:nth-child(even) td {
    background-color: #FBFAF6;
}

/* Row hover — single quiet cue, layered above zebra. Note: this
   momentarily covers cell-level signal tints (e.g. red for never-published
   units, green for "Published Rate" in Leasing Hub). Acceptable trade-off:
   those signals still read clearly on non-hovered rows, and hover unifies
   the row for readability.
   No transition: at large row counts the per-row style observer adds
   measurable scroll cost for an effect users don't notice anyway. */
.ut-units-table tbody tr:hover td {
    background: var(--fr-bg) !important;
}

/* Inputs that live in cells (BPO, Review Override) — match fr palette */
.ut-units-table tbody td input[type="number"],
.ut-units-table tbody td input[type="text"] {
    font-family: var(--fr-font-sans);
    font-variant-numeric: tabular-nums;
    border-color: var(--fr-hairline-strong) !important;
    background: var(--fr-surface) !important;
    color: var(--fr-ink) !important;
}
.ut-units-table tbody td input[type="number"]:focus,
.ut-units-table tbody td input[type="text"]:focus {
    border-color: var(--fr-accent) !important;
    outline: none;
    box-shadow: 0 0 0 2px var(--fr-accent-soft);
}
/* Disabled inputs (e.g. Review Override on the analyst view) — solid gray fill so they read as locked */
.ut-units-table tbody td input[type="number"]:disabled,
.ut-units-table tbody td input[type="text"]:disabled {
    background: #d6d8db !important;
    border-color: #d6d8db !important;
    color: #495057 !important;
    cursor: not-allowed !important;
}
