

  :root{
    --black:#FFFFFF;
    --panel:#FBF8F2;
    --panel-2:#F0F7F2;
    --gold:#1FAA59;
    --gold-deep:#0E7C4A;
    --cream:#111111;
    --taupe:#444444;
    --hair:rgba(31,170,89,0.22);
    --hair-strong:rgba(31,170,89,0.45);
  }
  *{box-sizing:border-box;margin:0;padding:0;}
  html{scroll-behavior:smooth;}
  body{
    background:var(--black);
    color:var(--cream);
    font-family:'Inter',sans-serif;
    font-weight:300;
    -webkit-font-smoothing:antialiased;
    min-height:100vh;
  }
  h1,h2,h3,.serif{font-family:'Cormorant Garamond',serif;font-weight:500;letter-spacing:0.01em;}
  .mono{font-family:'IBM Plex Mono',monospace;}
  a{color:inherit;text-decoration:none;}
  .eyebrow{
    font-family:'IBM Plex Mono',monospace;
    font-size:0.7rem;
    letter-spacing:0.28em;
    text-transform:uppercase;
    color:var(--gold-deep);
  }
  .rule{
    height:1px;
    background:linear-gradient(90deg, var(--gold) 0%, transparent 70%);
    width:64px;
  }
  .rule-full{height:1px;background:var(--hair);width:100%;}

  /* NAV */
  header{
    position:sticky;top:0;z-index:100;
    background:rgba(255,255,255,0.92);
    backdrop-filter:blur(10px);
    border-bottom:1px solid var(--hair);
  }
  /* Full-width header row — no hard max-width/auto-margin centering; the
     gutter itself grows past a comfortable reading cap (~2000px total
     content width) via max(), the same "fluid until it's wide enough to
     need a boundary" shape #employee-portal-wide below uses for the
     Employee Portal's own content, so the header row's left/right edges
     always land exactly where that content's edges do, at every viewport
     width — never a separate, only-approximately-matching cap. */
  .nav-inner{
    display:flex;align-items:center;justify-content:space-between;
    padding:16px max(28px, calc((100vw - 2000px) / 2));
  }
  .kw-logo{display:flex;flex-direction:column;align-items:center;line-height:1;}
  .kw-logo .kw-name{
    font-family:'Cormorant Garamond',serif;font-weight:700;
    color:var(--gold-deep);letter-spacing:0.14em;text-transform:uppercase;
  }
  .kw-logo .kw-diamond{color:var(--gold);margin:4px 0;}
  .kw-logo .kw-sub{
    font-family:'Cormorant Garamond',serif;font-weight:500;
    color:var(--taupe);letter-spacing:0.32em;text-transform:uppercase;
  }
  .kw-logo.kw-nav{flex-direction:row;align-items:center;gap:10px;}
  .kw-logo.kw-nav .kw-name{font-size:1.05rem;}
  .kw-logo.kw-nav .kw-diamond{margin:0;font-size:0.7rem;}
  .kw-logo.kw-nav .kw-sub{font-size:0.68rem;letter-spacing:0.2em;}
  /* The wordmark itself must never clip/overflow — since an authenticated
     header now also carries a Name+Role block on the right (previously
     just a bare avatar circle, which always left enough room), the
     wordmark shrinks first on a narrow viewport so both sides keep fitting
     without either one being cut off. */
  @media(max-width:480px){
    .kw-logo.kw-nav{gap:6px;}
    .kw-logo.kw-nav .kw-name{font-size:0.8rem;}
    .kw-logo.kw-nav .kw-sub{font-size:0.5rem;letter-spacing:0.08em;}
  }
  .kw-logo.kw-hero .kw-name{font-size:3.2rem;}
  .kw-logo.kw-hero .kw-diamond{font-size:1.1rem;}
  .kw-logo.kw-hero .kw-sub{font-size:1.15rem;}
  .kw-logo.kw-portal .kw-name{font-size:1.7rem;}
  .kw-logo.kw-portal .kw-diamond{font-size:0.8rem;}
  .kw-logo.kw-portal .kw-sub{font-size:0.75rem;}

  .brand{display:flex;align-items:center;gap:12px;cursor:pointer;}
  .navlinks{
    position:fixed;top:69px;left:0;right:0;background:var(--black);
    display:flex;flex-direction:column;align-items:flex-start;
    padding:20px 28px;gap:20px;border-bottom:1px solid var(--hair);
    z-index:9999;max-height:calc(100vh - 69px);overflow-y:auto;
    /* Moves the menu up by its own full height plus the 69px top offset, so
       its bottom edge always lands exactly at the viewport top (y:0) —
       robust regardless of how many nav items are visible. The previous
       fixed -120% figure only fully hid the menu when it was tall enough
       (~345px+); once an authenticated session hides Contact/Client
       Portal/Employee Login here via data-hide-when-authenticated, the
       menu shrinks below that threshold and its opaque, z-index:9999
       panel bled ~26px into the viewport, visually covering the header
       profile avatar beneath it. */
    transform:translateY(calc(-100% - 69px));transition:transform .3s ease;
  }
  .navlinks.open{transform:translateY(0);}
  .navlinks button{
    background:none;border:none;color:var(--taupe);
    font-family:'Inter',sans-serif;font-size:0.86rem;letter-spacing:0.04em;
    cursor:pointer;padding:6px 0;position:relative;transition:color .25s;
  }
  .navlinks button:hover, .navlinks button.active{color:var(--cream);}
  .navlinks button.active::after{
    content:'';position:absolute;bottom:-2px;left:0;right:0;height:1px;background:var(--gold);
  }
  .portal-btn{
    border:1px solid var(--gold-deep) !important;
    padding:8px 18px !important;color:var(--gold-deep) !important;
    letter-spacing:0.08em !important;text-transform:uppercase;font-size:0.72rem !important;
  }
  .portal-btn:hover{background:var(--gold-deep);color:#FFFFFF !important;}
  .mobile-toggle{display:block;background:none;border:none;color:var(--cream);font-size:1.4rem;cursor:pointer;}

  /* AUTHENTICATED HEADER — every authenticated role (Owner/Tenant/
     Employee alike) keeps the SAME logo-left / hamburger+avatar-right
     layout the logged-out header already uses; only the hamburger panel's
     own contents differ (Contact/Client Portal/Employee Login hidden via
     data-hide-when-authenticated — see setAuthenticatedHeaderNavState() in
     navigation.js) and the avatar becomes visible (see
     setEmployeeHeaderState()/setOwnerHeaderState()/setTenantHeaderState()).
     No separate grid/layout mode is needed for this — the default
     .nav-inner/.header-controls/.mobile-toggle/.navlinks rules already
     apply identically whether or not a session is active. */

  /* EMPLOYEE HEADER PROFILE */
  .header-controls{display:flex;align-items:center;gap:14px;}
  .header-profile{position:relative;display:none;align-items:center;}
  /* Invisible hover bridge over the visual gap between the trigger and the
     dropdown (below). Pseudo-elements count as part of their host element
     for pointer-event/hit-testing purposes, so this keeps the pointer
     "inside" .header-profile while crossing that gap — without it, moving
     the mouse from the icon down into the menu passes over page content
     that isn't a descendant of .header-profile, firing mouseleave and
     closing the menu before the pointer ever reaches it. This changes no
     visible pixel — it has no background/border/content. */
  .header-profile::before{
    content:'';position:absolute;top:100%;left:0;right:0;height:12px;
  }
  .header-profile-btn{
    background:none;border:none;padding:4px 8px 4px 4px;cursor:pointer;border-radius:24px;
    display:flex;align-items:center;gap:10px;transition:background .2s;
    min-width:0;max-width:min(220px, 38vw);
  }
  @media(max-width:480px){
    .header-profile-btn{max-width:min(150px, 34vw);gap:8px;}
  }
  .header-profile-btn:hover{background:var(--panel-2);}
  .header-profile-btn:focus-visible{outline:2px solid var(--gold-deep);outline-offset:3px;}
  .header-profile-avatar{
    width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;
    background:var(--gold-deep);color:#FFFFFF;border:1px solid var(--hair-strong);flex-shrink:0;
    font-family:'IBM Plex Mono',monospace;font-size:0.78rem;letter-spacing:0.02em;
    background-size:cover;background-position:center;
  }
  /* Name (bold) stacked above role label (muted, smaller) — set by each
     dashboard's own header-state setter (setEmployeeHeaderState()/
     setOwnerHeaderState()/setTenantHeaderState(), which call
     updateHeaderProfileIdentity()). The role line is the employee's own
     real tbl_user_roles.role_name ("Admin", "Staff", etc.) for the
     Employee Portal, or a fixed "Property Owner"/"Tenant" label for those
     two portals — never a generic "Employee" placeholder — matching the
     mockup's own name-then-role two-line layout exactly. */
  /* min-width:0 lets this shrink below its own text's natural width inside
     the flex row above — without it, a long name (e.g. "AndrewAdmin
     Accounts") pushes .header-profile-btn wider than its own max-width
     cap and overflows the page on a narrow viewport instead of eliding.
     Name and role each truncate independently with an ellipsis (and their
     own title="..." tooltip, set alongside textContent in
     updateHeaderProfileIdentity()) rather than wrapping to a second/third
     line, which would grow the header's own height. */
  .header-profile-textblock{display:flex;flex-direction:column;line-height:1.3;text-align:left;min-width:0;}
  .header-profile-name{font-family:'Inter',sans-serif;font-weight:600;font-size:0.9rem;color:var(--cream);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .header-profile-label{font-family:'Inter',sans-serif;font-size:0.78rem;color:var(--taupe);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .header-profile-chevron{color:var(--taupe);font-size:0.65rem;line-height:1;flex-shrink:0;}
  /* width:max-content lets the box grow to fit its content (nav labels,
     name/role/email) instead of collapsing to min-width — the old
     width:auto shrink-to-fit computation was landing right at min-width
     (230px) regardless of content, forcing long emails into many jagged
     mid-word breaks. min-width keeps it from looking cramped for short
     content; max-width caps growth and is itself capped by the viewport so
     it can never cause horizontal overflow on narrow screens. */
  .header-profile-menu{
    display:none;position:absolute;top:calc(100% + 12px);right:0;
    width:max-content;min-width:260px;max-width:min(360px, calc(100vw - 40px));
    max-height:calc(100vh - 90px);overflow-y:auto;overflow-x:hidden;
    background:#FFFFFF;border:1px solid var(--hair);box-shadow:0 16px 32px rgba(0,0,0,0.14);
    padding:8px;z-index:9999;
  }
  .header-profile.open .header-profile-menu{display:block;}
  .header-profile-menu button{
    display:block;width:100%;text-align:left;background:none;border:none;
    color:var(--taupe);font-family:'Inter',sans-serif;font-size:0.86rem;
    padding:10px 12px;cursor:pointer;border-radius:1px;transition:background .2s,color .2s;
  }
  .header-profile-menu button:hover,
  .header-profile-menu button:focus-visible,
  .header-profile-menu button.active{background:var(--panel-2);color:var(--gold-deep);}
  .header-profile-menu-divider{height:1px;background:var(--hair);margin:6px 4px;}
  .header-profile-menu-signout{color:var(--gold-deep);}
  .header-profile-menu-signout:hover,
  .header-profile-menu-signout:focus-visible{background:var(--panel-2);color:var(--gold-deep);}

  /* Non-interactive signed-in-user summary at the top of the dropdown. */
  .header-profile-summary{padding:6px 12px 10px;}
  .header-profile-summary-name{
    font-family:'Inter',sans-serif;font-weight:500;font-size:0.92rem;
    color:var(--cream);word-break:break-word;overflow-wrap:anywhere;
  }
  .header-profile-summary-meta{
    margin-top:4px;font-family:'IBM Plex Mono',monospace;font-size:0.68rem;
    letter-spacing:0.02em;color:var(--taupe);word-break:break-word;overflow-wrap:anywhere;
  }

  /* ADMIN CONSOLE — Client Accounts / Employees / Invitations */
  .admin-console-head{margin-bottom:24px;}
  .admin-console-head h2{font-size:clamp(1.7rem,2.8vw,2.3rem);margin-top:8px;color:var(--cream);}
  .admin-console-head p{color:var(--taupe);font-size:0.9rem;margin-top:8px;max-width:640px;line-height:1.55;}

  /* Flat underline sub-nav — same visual language as the outer .dtabs row
     (sans-serif, normal case, underline-only active state), just one size
     down, so the two navigation levels read as a coherent system rather
     than two different components. */
  .admin-nav{display:flex;gap:22px;margin-bottom:24px;flex-wrap:wrap;border-bottom:1px solid var(--hair);}
  .admin-nav button{
    background:none;border:none;color:var(--taupe);padding:12px 1px;
    font-family:'Inter',sans-serif;font-weight:400;font-size:0.88rem;letter-spacing:normal;text-transform:none;
    cursor:pointer;border-bottom:2px solid transparent;min-height:44px;transition:color .2s,border-color .2s;
  }
  .admin-nav button:hover{color:var(--cream);}
  .admin-nav button.active{color:var(--gold-deep);font-weight:600;border-bottom-color:var(--gold-deep);}
  .admin-nav button:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}

  /* "ADMIN ONLY" badge — the Admin Console's own page-head, right-aligned
     beside the title block via .properties-page-head. Purely
     informational — data-employee-access="admin" already gates the whole
     page-head, so a non-admin can never even reach the markup this sits
     in. */
  .admin-only-badge{
    display:flex;align-items:center;gap:8px;flex-shrink:0;
    background:var(--panel-2);border:1px solid var(--hair-strong);color:var(--gold-deep);
    padding:8px 16px;border-radius:999px;
    font-family:'IBM Plex Mono',monospace;font-size:0.72rem;letter-spacing:0.08em;text-transform:uppercase;white-space:nowrap;
  }
  .admin-only-badge-icon{width:15px;height:15px;flex-shrink:0;}

  .admin-view-head{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:16px;}
  .admin-view-head-left{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;}
  .admin-view-head h3{font-size:1.4rem;color:var(--cream);}
  .admin-count-pill{
    font-family:'IBM Plex Mono',monospace;font-size:0.7rem;letter-spacing:0.04em;
    color:var(--gold-deep);border:1px solid var(--hair);padding:4px 10px;border-radius:1px;white-space:nowrap;
  }
  .admin-view-head-actions{display:flex;gap:12px;flex-wrap:wrap;}

  /* Admin stat cards — the Employees/Invitations views' own summary row
     (Total/Administrators/Staff/Active, or Total/Pending/Accepted/
     Completed): an icon in a tinted circle, a label, a big number, and an
     optional caption line. Reused as-is by both views; only the icon
     color and whether a caption is passed differ per card (see
     buildAdminStatCardHtml() in employee-dashboard.js). */
  .admin-stat-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;margin-bottom:24px;}
  .admin-stat-card{
    display:flex;align-items:center;gap:16px;
    background:var(--black);border:1px solid var(--hair);border-radius:12px;padding:20px;
  }
  .admin-stat-icon{
    width:48px;height:48px;border-radius:50%;display:flex;align-items:center;justify-content:center;
    flex-shrink:0;
  }
  .admin-stat-icon svg{width:22px;height:22px;}
  .admin-stat-icon.is-green{background:rgba(14,124,74,0.12);color:var(--gold-deep);}
  .admin-stat-icon.is-amber{background:rgba(180,83,9,0.12);color:#B45309;}
  .admin-stat-icon.is-blue{background:rgba(37,99,235,0.12);color:#2563EB;}
  .admin-stat-icon.is-red{background:rgba(179,38,30,0.12);color:#B3261E;}
  .admin-stat-body{min-width:0;}
  .admin-stat-label{font-size:0.82rem;color:var(--taupe);}
  .admin-stat-number{font-family:'Cormorant Garamond',serif;font-weight:600;font-size:1.7rem;color:var(--cream);line-height:1.2;}
  .admin-stat-caption{font-size:0.76rem;color:var(--taupe);}

  /* Client Accounts two-pane layout — table+toolbar card on the left,
     "Account Summary" card on the right, same warm-panel-with-two-white-
     cards shape as the Properties tab's own .properties-layout. */
  .client-accounts-layout{
    display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,300px);gap:24px;
    background:var(--panel);border:1px solid var(--hair);border-radius:12px;padding:20px;
  }
  /* Leases' own two-pane layout — same shape/chrome as
     .client-accounts-layout, just a wider right column: a lease's own
     detail fields (property name + full address, tenant name, etc.) need
     more room than Client Accounts' narrower icon+number+label Account
     Summary rows do, and wrapped badly at that narrower width (each 2-up
     field column too narrow for "Test Property"/"Lamar Jackson" to sit on
     one line). */
  .leases-layout{
    display:grid;grid-template-columns:minmax(0,1fr) minmax(360px,440px);gap:24px;
    background:var(--panel);border:1px solid var(--hair);border-radius:12px;padding:20px;
  }
  @media(max-width:960px){
    .leases-layout{grid-template-columns:1fr;}
  }
  @media(max-width:900px){
    .client-accounts-layout{grid-template-columns:1fr;}
  }
  .client-accounts-main-card,.account-summary-card{
    background:var(--black);border:1px solid var(--hair);border-radius:10px;padding:20px;min-width:0;
  }
  .account-summary-card h3{font-family:'Cormorant Garamond',serif;font-size:1.2rem;color:var(--cream);margin-bottom:12px;}
  .account-summary-row{display:flex;align-items:center;gap:14px;padding:14px 0;border-bottom:1px solid var(--hair);}
  .account-summary-row:last-child{border-bottom:none;}
  .account-summary-number{font-family:'Cormorant Garamond',serif;font-weight:600;font-size:1.3rem;color:var(--cream);line-height:1.2;}
  .account-summary-label{font-size:0.78rem;color:var(--taupe);margin-top:2px;}

  /* Employees' "Contact" column — email + phone stacked in one cell, each
     with a small leading icon, instead of two separate table columns.
     Reused verbatim for Client Accounts' own "Contact Information" column
     (buildContactCellHtml() in employee-dashboard.js — one shared
     implementation for both tables). Each line's copy button stays in the
     DOM/tab order always (never display:none/visibility:hidden) so it's
     reachable by keyboard and announced by a screen reader regardless of
     mouse hover — it's only ever visually low-opacity until the line is
     hovered/focused-within, matching this app's existing "hover/focus
     reveal" convention elsewhere (e.g. .admin-row-actions' own kebab). */
  .admin-contact-cell{display:flex;flex-direction:column;gap:4px;}
  .admin-contact-line{display:flex;align-items:center;gap:6px;color:var(--cream);}
  .admin-contact-line svg{width:13px;height:13px;flex-shrink:0;color:var(--taupe);}
  /* Deliberately NOT overflow-wrap:anywhere (unlike .profile-value's own
     long-email fix) — that broke a long email into an illegible
     three-line stack of arbitrary character chunks the moment the
     Contact Information column got squeezed below full-screen width, the
     opposite of what a value this short should ever need. white-space:
     nowrap keeps each line (email, phone) intact on its own single row;
     .admin-fixed-table's own min-width plus .admin-directory-scroll's
     overflow-x:auto (already applied to every one of these tables) picks
     up the slack by scrolling horizontally instead, exactly like this
     table already does for every OTHER long, unbreakable-looking value. */
  .admin-contact-value{white-space:nowrap;}
  .admin-contact-copy-btn{
    display:inline-flex;align-items:center;justify-content:center;
    width:22px;height:22px;padding:0;margin-left:2px;flex-shrink:0;
    border:none;background:transparent;border-radius:4px;cursor:pointer;
    color:var(--taupe);opacity:0;transition:opacity 0.15s ease, background 0.15s ease, color 0.15s ease;
  }
  .admin-contact-copy-btn svg{width:12px;height:12px;color:inherit;}
  .admin-contact-line:hover .admin-contact-copy-btn,
  .admin-contact-copy-btn:focus-visible{opacity:1;}
  .admin-contact-copy-btn:hover{background:rgba(255,255,255,0.08);color:var(--cream);}
  .admin-contact-copy-btn.is-copied{opacity:1;color:#2E7D32;}

  /* LEASES — selected-lease details panel, reusing .account-summary-card's
     own card chrome (border/radius/padding) via the shared
     .lease-details-card-wrap modifier below, since it's the exact same
     "card beside the directory table" shape Client Accounts already
     established. */
  .lease-details-card-wrap{padding:24px;}
  .lease-detail-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:20px;}
  .lease-detail-code{font-family:'Cormorant Garamond',serif;font-size:1.3rem;font-weight:600;color:var(--cream);margin-bottom:6px;}
  .lease-detail-fields{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;margin-bottom:18px;}
  .lease-detail-field{display:flex;align-items:flex-start;gap:12px;min-width:0;}
  .lease-detail-field .profile-value{overflow-wrap:anywhere;}
  .lease-detail-sub{font-size:0.78rem;color:var(--taupe);margin-top:2px;overflow-wrap:anywhere;}
  .lease-detail-section{border-top:1px solid var(--hair);padding-top:16px;margin-top:16px;}
  .lease-detail-document-row{display:flex;align-items:center;gap:12px;margin-top:10px;flex-wrap:wrap;min-width:0;}
  .lease-detail-document-row .profile-value{min-width:0;overflow-wrap:anywhere;}

  /* Unified owner/tenant lease pages. */
  .lease-page-heading{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;margin-bottom:22px;}
  .lease-page-heading h2,.lease-review-overlay h2{font-family:'Cormorant Garamond',serif;color:var(--cream);font-size:1.9rem;margin:0 0 4px;}
  .lease-page-heading p{color:var(--taupe);font-size:.88rem;margin:0;}
  .owner-lease-workspace{background:var(--panel);border:1px solid var(--hair);border-radius:12px;padding:18px;}
  .owner-lease-toolbar{margin-bottom:14px;}

  /* "Your signature is needed" banner — same amber accent as
     .status-pill-filled.is-lease-pending/.admin-stat-icon.is-amber
     elsewhere in this app, just at banner scale. Built/shown only when
     there's at least one such lease (renderOwnerLeaseSignatureBanner(),
     owner-dashboard.js) — the container itself stays display:none, not
     merely empty, the rest of the time. */
  .owner-lease-signature-banner{
    background:rgba(180,83,9,0.08);border:1px solid rgba(180,83,9,0.3);border-radius:10px;
    padding:16px 20px;margin-bottom:20px;
  }
  .owner-lease-signature-head{display:flex;align-items:center;gap:12px;}
  .owner-lease-signature-icon{
    display:grid;place-items:center;width:40px;height:40px;border-radius:50%;flex:0 0 auto;
    background:rgba(180,83,9,0.12);color:#B45309;
  }
  .owner-lease-signature-icon svg{width:18px;height:18px;}
  .owner-lease-signature-heading{font-family:'Cormorant Garamond',serif;font-size:1.2rem;color:var(--cream);}
  .owner-lease-signature-count{
    display:inline-flex;margin-left:10px;background:rgba(180,83,9,0.14);color:#B45309;
    border-radius:999px;padding:2px 10px;font-size:0.72rem;vertical-align:middle;
  }
  /* One row per pending-signature lease — a hairline separates each row
     after the first, never the first one from the heading above it. */
  .owner-lease-signature-row{
    display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
    padding:14px 0 0;margin-top:14px;border-top:1px solid rgba(180,83,9,0.2);
  }
  .owner-lease-signature-banner-main{display:flex;flex-direction:column;gap:2px;min-width:0;}
  .owner-lease-signature-banner-main strong{color:var(--cream);font-size:0.92rem;}
  .owner-lease-signature-detail{color:var(--taupe);font-size:0.82rem;}
  .owner-lease-signature-status{display:flex;align-items:center;gap:8px;color:var(--gold-deep);font-size:0.85rem;}
  .owner-lease-signature-status svg{width:16px;height:16px;flex-shrink:0;}

  /* Inline filter tabs — replaces the old 4 summary cards + separate
     Filter Leases dialog. Single-select: exactly one tab (or none, for
     All) carries .is-active at a time. Accent colors reuse the exact same
     .status-pill-filled.is-lease-* palette used in the table's own Status
     column, so a tab and the rows it filters to always agree visually.
     See renderOwnerLeaseFilterTabs()/selectOwnerLeaseFilterTab() in
     owner-dashboard.js. */
  .owner-lease-filter-tabs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:18px;}
  .owner-lease-filter-tab{
    display:inline-flex;align-items:center;gap:8px;background:var(--panel);border:1px solid var(--hair);
    border-radius:999px;padding:8px 16px;font-size:0.85rem;color:var(--taupe);cursor:pointer;
  }
  .owner-lease-filter-tab:hover{border-color:var(--hair-strong);}
  .owner-lease-filter-tab.is-active{background:rgba(14,124,74,.1);border-color:var(--hair-strong);color:var(--cream);}
  .owner-lease-filter-tab-count{
    display:inline-flex;min-width:20px;justify-content:center;background:var(--panel-2);border-radius:999px;
    padding:1px 7px;font-size:0.72rem;color:var(--taupe);
  }
  .owner-lease-filter-tab.is-active .owner-lease-filter-tab-count{background:rgba(14,124,74,.16);color:var(--gold-deep);}

  /* Action column — the row itself is already fully clickable
     (openOwnerLeaseReview()), this is just the visible affordance text,
     never a second, separate click target. */
  .owner-lease-action-link{color:var(--gold-deep);font-size:0.85rem;font-weight:600;white-space:nowrap;}
  .tenant-lease-layout{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(280px,.65fr);gap:20px;align-items:start;}
  .tenant-lease-main,.tenant-lease-side{display:grid;gap:20px;}
  /* "Lease details" grouped-card grid — Tenant's own My Lease page and
     Owner's lease review drawer both build one .lease-feature-card per
     buildLeaseExtractionSections() (lease-helpers.js) group into this
     same grid, so the two stay visually identical for the same lease. */
  .lease-details-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:20px;}
  .lease-feature-card{background:var(--black);border:1px solid var(--hair);border-radius:10px;padding:22px;}
  .lease-card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:24px;}
  .lease-card-head h3{font-family:'Cormorant Garamond',serif;color:var(--cream);font-size:1.5rem;margin:6px 0 2px;}
  .lease-card-head p{color:var(--taupe);margin:0;font-size:.85rem;}
  .lease-money{display:flex;align-items:flex-end;justify-content:space-between;gap:14px;margin:18px 0;}
  .lease-money span,.lease-date-line span{color:var(--taupe);font-size:.82rem;}
  .lease-money strong{font-family:'Cormorant Garamond',serif;color:var(--cream);font-size:1.65rem;}
  .lease-date-line{display:flex;justify-content:space-between;gap:16px;padding:13px 0;border-bottom:1px solid var(--hair);font-size:.85rem;}
  .lease-date-line:last-child{border-bottom:0;}
  .lease-date-line strong{color:var(--cream);text-align:right;}
  .lease-progress-list{margin-top:12px;}
  .lease-progress-row{display:flex;gap:12px;align-items:center;padding:11px 0;}
  .lease-progress-row + .lease-progress-row{border-top:1px solid var(--hair);}
  .lease-progress-row div{display:flex;flex-direction:column;gap:2px;}
  .lease-progress-row strong{color:var(--cream);font-size:.88rem;}
  .lease-progress-row small{color:var(--taupe);font-size:.76rem;}
  .lease-progress-icon{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--panel-2);color:var(--taupe);font-weight:700;flex:0 0 auto;}
  .lease-progress-icon.is-complete{background:rgba(14,124,74,.12);color:var(--gold-deep);}
  .lease-document-action{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px;flex-wrap:wrap;color:var(--cream);font-size:.84rem;}
  .lease-document-action-name{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}

  /* Lease signing stepper — the hero card's own 4-milestone progress bar
     (Lease prepared -> Owner signed -> Your signature -> Lease active),
     purely a display derivation over tbl_leases.created_at/owner_signed_at/
     tenant_signed_at/tbl_lease_status — see buildTenantLeaseStepperHtml()
     in tenant-dashboard.js. Distinct from .lease-wizard-step (Add Lease's
     own form-step indicator, employee-dashboard.js/index.html), which never
     shows a checkmark for a "complete" step since a form step is never
     independently completable out of order. */
  .lease-signing-stepper{display:flex;align-items:flex-start;margin:20px 0 4px;}
  .lease-signing-step{display:flex;flex-direction:column;align-items:center;text-align:center;gap:6px;min-width:0;flex:0 0 auto;}
  .lease-signing-step-circle{
    width:32px;height:32px;border-radius:50%;flex-shrink:0;
    display:flex;align-items:center;justify-content:center;
    font-size:.82rem;font-weight:700;
    border:2px solid var(--hair);color:var(--taupe);background:var(--black);
  }
  .lease-signing-step-label{font-size:.78rem;font-weight:600;color:var(--cream);white-space:nowrap;}
  .lease-signing-step-date{font-size:.72rem;color:var(--taupe);white-space:nowrap;}
  .lease-signing-step.is-complete .lease-signing-step-circle{background:var(--gold-deep);border-color:var(--gold-deep);color:#FFFFFF;}
  .lease-signing-step.is-current .lease-signing-step-circle{background:#B45309;border-color:#B45309;color:#FFFFFF;}
  .lease-signing-step.is-current .lease-signing-step-date{color:#B45309;font-weight:600;}
  .lease-signing-step-line{flex:1 1 24px;height:2px;background:var(--hair);margin:15px 6px 0;min-width:16px;}
  .lease-signing-step-line.is-complete{background:var(--gold-deep);}
  @media(max-width:640px){.lease-signing-stepper{flex-wrap:wrap;row-gap:14px;}.lease-signing-step{min-width:70px;}.lease-signing-step-line{display:none;}}
  .lease-review-status{margin-bottom:18px;}
  .lease-review-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;}
  .lease-review-grid>div{display:flex;flex-direction:column;gap:5px;min-width:0;}
  .lease-review-grid span{color:var(--taupe);font-size:.72rem;text-transform:uppercase;letter-spacing:.06em;}
  .lease-review-grid strong{color:var(--cream);font-size:.9rem;overflow-wrap:anywhere;}
  .lease-review-section{border-top:1px solid var(--hair);padding-top:18px;margin-top:20px;}
  .lease-review-section p{color:var(--cream);font-size:.85rem;line-height:1.55;}
  @media(max-width:900px){.tenant-lease-layout{grid-template-columns:1fr;}}
  @media(max-width:560px){.lease-review-grid{grid-template-columns:1fr;}.owner-lease-workspace{padding:10px;}.lease-feature-card{padding:18px;}}

  /* Lease signatures — tenant + property owner, each their own row: a
     label, a status-pill-filled (reusing the exact same pill/color
     language the lease-status pill above already uses — is-lease-active
     for "Signed", is-lease-pending for "Awaiting"), and an admin-only
     "Mark Signed" action. See renderLeaseSignaturesSection()/
     markLeaseSignature() in employee-dashboard.js. */
  .lease-signature-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:8px 0;}
  .lease-signature-row:not(:last-child){border-bottom:1px solid var(--hair);}
  .lease-signature-label{flex:1 1 120px;font-family:'Inter',sans-serif;font-size:0.86rem;color:var(--cream);}

  /* Lease notes — separate, readable entries instead of one run-on block.
     See renderLeaseNotesHtml()/parseLeaseNotes() (lease-helpers.js) for
     the split/metadata rules. */
  .lease-note-empty{font-family:'Inter',sans-serif;font-size:0.86rem;color:var(--taupe);}
  .lease-note-entry{padding:10px 12px;background:var(--panel-2);border-radius:4px;}
  .lease-note-entry:not(:last-child){margin-bottom:8px;}
  .lease-note-meta{font-family:'IBM Plex Mono',monospace;font-size:0.68rem;letter-spacing:0.04em;text-transform:uppercase;color:var(--taupe);margin-bottom:4px;}
  .lease-note-body{font-family:'Inter',sans-serif;font-size:0.86rem;color:var(--cream);white-space:pre-wrap;overflow-wrap:anywhere;}

  /* Add/Edit Lease — step indicator (purely visual progress over one
     scrollable form, see setAddLeaseStep()'s own comment) and the
     document-upload dropzone-style area + Review step's read-only rows. */
  .lease-wizard-steps{display:flex;align-items:center;gap:10px;margin:8px 0 24px;flex-wrap:wrap;}
  .lease-wizard-step{display:flex;align-items:center;gap:8px;color:var(--taupe);font-size:0.84rem;}
  .lease-wizard-step-circle{
    width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;
    background:var(--panel-2);border:1px solid var(--hair-strong);font-size:0.78rem;flex-shrink:0;
  }
  .lease-wizard-step.active{color:var(--cream);font-weight:600;}
  .lease-wizard-step.active .lease-wizard-step-circle{background:var(--gold-deep);border-color:var(--gold-deep);color:#FFFFFF;}
  .lease-wizard-step-line{flex:1;height:1px;background:var(--hair);min-width:24px;}
  .lease-upload-area{
    display:flex;align-items:center;gap:16px;border:1px dashed var(--hair-strong);border-radius:8px;
    padding:18px;background:var(--panel);cursor:pointer;transition:border-color .15s,background .15s;
  }
  .lease-upload-area:hover{border-color:var(--gold);}
  .lease-upload-area:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}
  .lease-upload-area.is-dragover{border-color:var(--gold-deep);background:rgba(191,161,74,0.08);}
  .lease-upload-icon{font-size:1.6rem;flex-shrink:0;}

  /* Add Lease Step 0 — method-selection cards (DocuSign/Upload Lease/
     Manually Enter), all equally reachable via chooseAddLeaseMethod()
     (see #adl-method-docusign/-upload/-manual in index.html). */
  .adl-method-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;}
  @media(max-width:700px){ .adl-method-grid{grid-template-columns:1fr;} }
  .adl-method-card{
    position:relative;display:flex;flex-direction:column;gap:8px;text-align:left;
    border:1px solid var(--hair-strong);border-radius:10px;padding:20px;background:var(--panel);
    cursor:pointer;transition:border-color .15s,background .15s;
  }
  .adl-method-card:hover{border-color:var(--gold);}
  .adl-method-card:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}
  .adl-method-icon{font-size:1.6rem;}
  .adl-method-title{font-weight:600;color:var(--cream);}
  .adl-method-desc{font-size:0.82rem;color:var(--taupe);}

  /* Add Lease — subtly marks a field autofilled from an uploaded document
     (applyLeaseImportExtraction()/markAddLeaseFieldExtracted(),
     employee-dashboard.js). Cleared the instant the admin edits that
     value (oninput= on the input itself), so this always means "still
     exactly what the document said," never "was ever extracted." */
  .adl-field-extracted{position:relative;border-left:2px solid var(--gold-deep);padding-left:10px;margin-left:-12px;}
  .adl-field-extracted label::after{
    content:"Extracted";margin-left:8px;padding:1px 7px;border-radius:999px;
    font-size:0.64rem;text-transform:uppercase;letter-spacing:0.04em;font-weight:600;
    background:rgba(191,161,74,0.14);color:var(--gold-deep);vertical-align:middle;
  }

  /* Lease import review panel — one row per extracted field, a confidence
     badge (green = confident, amber = needs review — value present but
     below threshold, gray = nothing found), and the source snippet as a
     title tooltip when available. */
  .lease-import-review-list{display:grid;grid-template-columns:1fr 1fr;gap:10px 20px;margin-top:10px;}
  .lease-import-review-row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;padding:6px 0;border-bottom:1px solid var(--hair);font-size:0.86rem;}
  .lease-import-review-label{color:var(--taupe);flex-shrink:0;}
  .lease-import-review-value{text-align:right;overflow-wrap:anywhere;}
  .lease-import-confidence-badge{display:inline-block;margin-left:8px;padding:1px 7px;border-radius:999px;font-size:0.68rem;text-transform:uppercase;letter-spacing:0.04em;white-space:nowrap;}
  .lease-import-confidence-badge.is-ok{background:rgba(14,124,74,0.12);color:#0E7C4A;}
  .lease-import-confidence-badge.is-review{background:rgba(179,38,30,0.1);color:#B3261E;}
  .lease-import-confidence-badge.is-empty{background:var(--panel-2);color:var(--taupe);}
  .lease-import-conflict-banner{border:1px solid #B3261E;background:rgba(179,38,30,0.05);color:#B3261E;padding:10px 14px;border-radius:6px;font-size:0.84rem;margin-bottom:12px;}
  .lease-import-match-hint{font-size:0.82rem;color:var(--gold-deep);margin-top:6px;}
  .lease-import-match-hint.is-missing{color:#B3261E;font-weight:600;}
  .lease-import-match-hint.is-blocked{border-left:3px solid #B3261E;background:rgba(179,38,30,0.06);padding:8px 10px;margin:8px 0;line-height:1.45;}
  .lease-import-order-notice{border:1px solid rgba(179,38,30,0.35);background:rgba(179,38,30,0.06);color:var(--cream);padding:12px 14px;border-radius:6px;font-size:0.84rem;line-height:1.55;margin-bottom:14px;}
  .lease-import-order-notice strong{color:#B3261E;}
  .lease-import-order-notice span{display:block;color:var(--gold-deep);font-weight:600;margin:3px 0;}
  .lease-review-summary{display:grid;grid-template-columns:1fr 1fr;gap:16px;background:var(--panel);padding:20px;border-radius:8px;}
  .lease-review-row{min-width:0;}
  .lease-review-row .profile-value{overflow-wrap:anywhere;}
  @media(max-width:600px){
    .lease-detail-fields,.lease-review-summary{grid-template-columns:1fr;}
  }

  /* Add Lease's Property/Unit/Tenant selection — each a full-width row
     (never side-by-side in a grid) since the confirmed summary card
     (.property-manager-row, reused verbatim from Edit Property's own
     Assigned Account Manager/Property Owner display) needs room to wrap
     a full address and owner name without clipping. */
  .adl-selection-fields{display:flex;flex-direction:column;gap:18px;margin-bottom:18px;}
  .adl-selection-field{margin-bottom:0;}
  .adl-selection-field > .eyebrow{margin-bottom:8px;}
  .adl-selection-field .property-manager-row{background:var(--panel);border:1px solid var(--hair);border-radius:8px;padding:14px 16px;}

  /* Small round initials avatar beside a Name cell — Client Accounts and
     Employees rows alike. */
  .admin-row-name-cell{display:flex;align-items:center;gap:10px;white-space:normal;}
  .admin-row-avatar{
    width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;
    flex-shrink:0;font-family:'IBM Plex Mono',monospace;font-size:0.68rem;color:#FFFFFF;background:var(--gold-deep);
  }

  .admin-toolbar{
    display:flex;align-items:center;gap:16px;flex-wrap:wrap;
    background:var(--panel);border:1px solid var(--hair);padding:16px;margin-bottom:1px;
  }
  .admin-search-input{
    flex:1 1 260px;min-width:200px;
    background:var(--black);border:1px solid var(--hair);color:var(--cream);
    padding:11px 12px;font-family:'Inter',sans-serif;font-size:0.86rem;border-radius:1px;
  }
  .admin-search-input:focus{outline:none;border-color:var(--gold);}
  .admin-filter-group{display:flex;gap:6px;flex-wrap:wrap;}
  .admin-filter-btn{
    background:transparent;border:1px solid var(--hair-strong);color:var(--taupe);
    padding:9px 16px;font-family:'IBM Plex Mono',monospace;font-size:0.7rem;
    letter-spacing:0.06em;text-transform:uppercase;cursor:pointer;border-radius:1px;transition:all .2s;
  }
  .admin-filter-btn:hover{border-color:var(--gold);color:var(--gold-deep);}
  .admin-filter-btn.active{background:var(--gold-deep);border-color:var(--gold-deep);color:#FFFFFF;}
  .admin-filter-btn:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}
  .admin-filter-reset{
    background:transparent;border:1px solid transparent;color:var(--taupe);
    padding:9px 10px;font-family:'IBM Plex Mono',monospace;font-size:0.7rem;
    letter-spacing:0.06em;text-transform:uppercase;cursor:pointer;border-radius:1px;transition:all .2s;
  }
  .admin-filter-reset:hover{color:var(--gold-deep);text-decoration:underline;}
  .admin-filter-reset:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}
  .admin-filter-summary{color:var(--taupe);font-size:0.78rem;align-self:center;}

  /* Units filter pills — colored per status: All is solid forest green when
     selected; Occupied/Pending Lease Signing/Available/Maintenance/
     Unavailable show that same status's own colored dot (reusing
     .unit-status-dot's exact colors, so
     these can never disagree with the Units table's own Status column) and
     fill solid with that color when selected. Scoped to #units-filter-group
     only — the Client Accounts page's own .admin-filter-btn group
     (All/Tenants/Property Owners) keeps its existing plain style,
     untouched. */
  #units-filter-group{gap:8px;}
  #units-filter-group .admin-filter-btn{
    border-radius:999px;display:inline-flex;align-items:center;
    font-family:'Inter',sans-serif;text-transform:none;letter-spacing:normal;font-size:0.82rem;
    padding:8px 16px;
  }
  #units-filter-group .admin-filter-btn .unit-status-dot{margin-right:7px;}
  #units-filter-group .admin-filter-btn[data-filter="all"]{border-color:rgba(14,124,74,0.35);color:var(--gold-deep);}
  #units-filter-group .admin-filter-btn[data-filter="Occupied"]{border-color:rgba(14,124,74,0.35);color:var(--gold-deep);}
  #units-filter-group .admin-filter-btn[data-filter="Pending Lease Signing"]{border-color:rgba(124,58,237,0.35);color:#7C3AED;}
  #units-filter-group .admin-filter-btn[data-filter="Available"]{border-color:rgba(37,99,235,0.35);color:#2563EB;}
  #units-filter-group .admin-filter-btn[data-filter="Maintenance"]{border-color:rgba(180,83,9,0.35);color:#B45309;}
  #units-filter-group .admin-filter-btn[data-filter="Unavailable"]{border-color:rgba(185,28,28,0.35);color:#B91C1C;}
  #units-filter-group .admin-filter-btn.active{color:#FFFFFF;}
  #units-filter-group .admin-filter-btn[data-filter="all"].active{background:var(--gold-deep);border-color:var(--gold-deep);}
  #units-filter-group .admin-filter-btn[data-filter="Occupied"].active{background:var(--gold-deep);border-color:var(--gold-deep);}
  #units-filter-group .admin-filter-btn[data-filter="Pending Lease Signing"].active{background:#7C3AED;border-color:#7C3AED;}
  #units-filter-group .admin-filter-btn[data-filter="Available"].active{background:#2563EB;border-color:#2563EB;}
  #units-filter-group .admin-filter-btn[data-filter="Maintenance"].active{background:#B45309;border-color:#B45309;}
  #units-filter-group .admin-filter-btn[data-filter="Unavailable"].active{background:#B91C1C;border-color:#B91C1C;}
  #units-filter-group .admin-filter-btn.active .unit-status-dot{background:#FFFFFF;}
  select.admin-filter-select{
    background:var(--black);border:1px solid var(--hair);color:var(--cream);
    padding:11px 12px;font-family:'Inter',sans-serif;font-size:0.84rem;border-radius:1px;width:auto;
  }
  /* Lease Directory's own Property filter — a plain .admin-filter-btn,
     the exact same pill button its sibling status filters
     (#lease-filter-group) already use, deliberately never styled to look
     like a <select>/dropdown (no chevron, no select-mimicking chrome) —
     it opens the Select a Property modal instead. Gets the shared
     .active highlight whenever a property is actually applied — see
     openLeasePropertyPickerModal()/applyLeasePropertyPickerSelection() in
     employee-dashboard.js. No dedicated rule needed beyond .admin-filter-btn
     itself; kept as a hook for the shrink-to-fit-label sizing below only. */
  .lease-property-filter-btn{white-space:nowrap;}
  /* Made visibly larger/easier to hit than the sibling status pills — a
     bigger click target and more legible label, since this button (unlike
     the one-word status pills) carries a whole property name once applied.
     Still plain .admin-filter-btn underneath (no chevron, no <select>
     chrome) — sizing only, per the comment above. The Unit filter
     (.lease-unit-filter-btn) matches it for visual consistency. */
  .lease-property-filter-btn,.lease-unit-filter-btn{
    padding:13px 22px;font-size:0.8rem;border-width:2px;
    /* Once a Property/Unit is actually applied, this button's own label
       swaps from the short "All Properties"/"All Units" to that record's
       real name/address — capped and ellipsized rather than left to grow
       unbounded, which used to widen the whole toolbar row and visibly
       shove Clear Filters/the count pill sideways or onto another line
       purely because a long address had been selected. */
    max-width:200px;overflow:hidden;text-overflow:ellipsis;
  }

  /* Lease Directory's own toolbar — the search box, six status pills, the
     Property/Unit filter buttons, Clear Filters, and the count pill all
     used to sit as flat siblings in one flex-wrap row; depending on the
     left column's actual width (a fluid minmax(0,1fr) column — see
     .leases-layout) individual controls could each end up wrapping onto
     their own line in whatever order happened to fit, rather than a
     stable, predictable layout. Forcing the search input onto a full-width
     row of its own means every filter control below it always wraps
     together as one group, in one place, regardless of viewport width or
     how long the currently-applied Property/Unit label is. */
  .lease-directory-toolbar #lease-search-input{flex:1 1 100%;}

  /* Select a Property modal — each row reuses .assign-manager-row's own
     chrome (photo/icon + name + contact line, is-current for the
     selected state) plus its own trailing unit/occupied/active-lease
     counts and a radio dot, standing in for a real <input type="radio">
     so the whole row (not just a tiny circle) is the click/tap target —
     role="radio" on the row itself carries the actual semantics. */
  .lease-property-picker-row{cursor:pointer;justify-content:space-between;}
  .lease-property-picker-row:hover{border-color:var(--gold);}
  .lease-property-picker-row:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}
  .lease-property-picker-counts{display:flex;gap:18px;flex-shrink:0;}
  .lease-property-picker-count{font-size:0.76rem;color:var(--taupe);text-align:center;white-space:nowrap;}
  .lease-property-picker-count strong{display:block;font-family:'Cormorant Garamond',serif;font-size:1.1rem;color:var(--cream);}
  .lease-property-picker-radio{
    width:18px;height:18px;flex-shrink:0;border-radius:50%;border:2px solid var(--hair-strong);
    box-sizing:border-box;position:relative;
  }
  .lease-property-picker-row.is-current .lease-property-picker-radio{border-color:var(--gold-deep);}
  .lease-property-picker-row.is-current .lease-property-picker-radio::after{
    content:'';position:absolute;inset:3px;border-radius:50%;background:var(--gold-deep);
  }

  /* Filter by Type / Filter by Status (Invitations) — checkbox list inside
     the multi-select dialog. */
  .admin-filter-checkbox-list{display:flex;flex-direction:column;gap:2px;max-height:320px;overflow-y:auto;margin-top:8px;}
  .admin-filter-checkbox-row{display:flex;align-items:center;gap:10px;padding:9px 4px;font-size:0.86rem;color:var(--cream);cursor:pointer;}
  .admin-filter-checkbox-row input[type="checkbox"]{width:16px;height:16px;flex-shrink:0;accent-color:var(--gold-deep);}

  .admin-directory{border:1px solid var(--hair);border-top:none;margin-bottom:44px;}
  .admin-directory-scroll{max-height:520px;overflow-y:auto;}
  .admin-directory table{margin-top:0;}
  .admin-directory th{position:sticky;top:0;z-index:1;}
  .admin-directory tbody tr[data-clickable="true"]{cursor:pointer;transition:background .15s;}
  .admin-directory tbody tr[data-clickable="true"]:hover{background:var(--panel-2);}
  .admin-directory tbody tr[data-clickable="true"]:focus-visible{outline:2px solid var(--gold-deep);outline-offset:-2px;}

  /* Row action menu — replaces the old unlabeled "x" with a labeled,
     keyboard-reachable menu trigger + menu. */
  .admin-row-actions{position:relative;display:inline-block;}
  .admin-row-menu-btn{
    width:36px;height:36px;border-radius:1px;flex-shrink:0;
    background:transparent;border:1px solid var(--hair-strong);color:var(--taupe);
    font-size:1.1rem;line-height:1;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
    transition:border-color .2s,color .2s;
  }
  .admin-row-menu-btn:hover,.admin-row-menu-btn:focus-visible,.admin-row-menu-btn[aria-expanded="true"]{
    border-color:var(--gold-deep);color:var(--gold-deep);outline:none;
  }
  .admin-row-menu{
    display:none;position:absolute;top:calc(100% + 4px);right:0;min-width:170px;
    background:#FFFFFF;border:1px solid var(--hair);box-shadow:0 12px 24px rgba(0,0,0,0.16);z-index:30;padding:4px;
  }
  .admin-row-menu.open{display:block;}
  .admin-row-menu button{
    display:block;width:100%;text-align:left;background:none;border:none;
    color:var(--taupe);font-family:'Inter',sans-serif;font-size:0.85rem;
    padding:10px 12px;min-height:40px;cursor:pointer;border-radius:1px;
  }
  .admin-row-menu button:hover,.admin-row-menu button:focus-visible{background:var(--panel-2);color:var(--gold-deep);}
  .admin-row-menu button.destructive{color:#B3261E;}
  .admin-row-menu button.destructive:hover,.admin-row-menu button.destructive:focus-visible{background:rgba(179,38,30,0.08);color:#B3261E;}
  .admin-row-menu button:disabled{opacity:0.45;cursor:not-allowed;}

  /* "Invite Sent."/"Invite Resent." success modal — one shared component
     for both the Invite User creation flow and the Resend Invite flow
     (see showInviteSentAnimation()/closeInviteSentModal(),
     employee-dashboard.js). #invite-sent-toast itself is a real
     .admin-modal-overlay/.admin-modal (backdrop, centering, the same
     display:none <-> .open{display:flex} toggle, and the same Escape/
     click-outside-to-close wiring via modalCancelers every other modal
     in this app already gets) — only the icon/text below are this
     component's own. Never shown alongside a failure message: it's only
     ever opened after a create/resend call has already confirmed
     success. */
  .invite-sent-modal{text-align:center;}
  .invite-sent-toast-icon{display:flex;justify-content:center;margin:0 auto 14px;}
  .invite-sent-toast-icon svg{display:block;overflow:visible;}
  .invite-sent-toast-envelope{fill:var(--panel-2);stroke:var(--gold-deep);stroke-width:2;}
  .invite-sent-toast-flap{fill:none;stroke:var(--gold-deep);stroke-width:2;}
  .invite-sent-toast-check{
    fill:none;stroke:var(--gold-deep);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;
    stroke-dasharray:36;stroke-dashoffset:36;
  }
  #invite-sent-toast.open .invite-sent-toast-icon{animation:invite-sent-toast-fly .5s ease;}
  #invite-sent-toast.open .invite-sent-toast-check{animation:invite-sent-toast-check .35s ease .35s forwards;}
  .invite-sent-toast-text{font-family:'IBM Plex Mono',monospace;font-size:0.95rem;letter-spacing:0.04em;color:var(--cream);}
  @keyframes invite-sent-toast-fly{
    0%{transform:translate(-14px,5px) rotate(-8deg);opacity:0;}
    60%{transform:translate(2px,-2px) rotate(2deg);opacity:1;}
    100%{transform:translate(0,0) rotate(0);}
  }
  @keyframes invite-sent-toast-check{to{stroke-dashoffset:0;}}

  /* Right-side drawer — account/invitation details, and (via
     .admin-modal-overlay elsewhere) forms use a centered modal; both
     count as "modal or right-side drawer" per the layout spec. */
  .admin-drawer-overlay{
    display:none;position:fixed;inset:0;background:rgba(17,17,17,0.5);z-index:2100;
  }
  .admin-drawer-overlay.open{display:block;}
  .admin-drawer{
    position:fixed;top:0;right:0;bottom:0;width:min(440px, 100vw);
    background:#FFFFFF;border-left:1px solid var(--hair);box-shadow:-24px 0 48px rgba(0,0,0,0.2);
    padding:28px;overflow-y:auto;
    transform:translateX(100%);transition:transform .25s ease;
  }
  .admin-drawer-overlay.open .admin-drawer{transform:translateX(0);}
  .admin-drawer-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:20px;}
  .admin-drawer-close{background:none;border:none;color:var(--taupe);font-size:1.4rem;line-height:1;cursor:pointer;padding:4px 8px;min-width:44px;min-height:44px;}
  .admin-drawer-close:hover{color:var(--gold-deep);}
  .admin-drawer-field{margin-bottom:16px;}
  .admin-drawer-field .eyebrow{margin-bottom:6px;}
  .admin-drawer-field-value{font-size:0.94rem;color:var(--cream);}
  .admin-drawer-actions{display:flex;gap:12px;flex-wrap:wrap;margin-top:24px;padding-top:20px;border-top:1px solid var(--hair);}

  /* Step indicator for the Add Tenant / Add Property Owner wizards */
  .admin-steps{display:flex;gap:8px;margin-bottom:20px;font-family:'IBM Plex Mono',monospace;font-size:0.66rem;letter-spacing:0.05em;text-transform:uppercase;color:var(--taupe);}
  .admin-steps .admin-step{padding-bottom:8px;border-bottom:2px solid var(--hair);flex:1;text-align:center;}
  .admin-steps .admin-step.current{color:var(--gold-deep);border-bottom-color:var(--gold-deep);}
  .admin-steps .admin-step.done{color:var(--cream);border-bottom-color:var(--hair-strong);}

  .admin-review-summary{background:var(--panel);border:1px solid var(--hair);padding:16px;margin-bottom:16px;}
  .admin-review-row{display:flex;justify-content:space-between;gap:12px;padding:8px 0;border-bottom:1px solid var(--hair);font-size:0.88rem;}
  .admin-review-row:last-child{border-bottom:none;}
  .admin-review-row .lbl{color:var(--taupe);font-size:0.72rem;letter-spacing:0.06em;text-transform:uppercase;}
  .admin-review-row .val{color:var(--cream);text-align:right;}

  .admin-empty-state{padding:56px 20px;text-align:center;color:var(--taupe);background:var(--panel);}
  .admin-empty-state .admin-empty-title{font-family:'Cormorant Garamond',serif;font-size:1.3rem;color:var(--cream);margin-bottom:8px;}
  .admin-empty-state .admin-empty-sub{font-size:0.86rem;}

  /* Controls inside the Admin panel meet the 44px touch-target minimum on
     every breakpoint, not just mobile — scoped to #epanel-accounts so no
     other Employee Portal tab's forms/buttons are affected. Also scoped to
     #admin-drawer-overlay/#add-tenant-overlay directly: both used to live
     physically inside #epanel-accounts (and so inherited this rule for
     free) until they were moved out to be reachable by a non-admin
     session — #epanel-accounts itself is entirely admin-gated
     (display:none for staff), which would otherwise have hidden these two
     shared modals for every staff session regardless of their own
     individual gating. Listed explicitly here so they keep the exact same
     touch-target sizing post-move. */
  #epanel-accounts .btn,
  #epanel-accounts .field input,
  #epanel-accounts .field select,
  #epanel-accounts select,
  #admin-drawer-overlay .btn,
  #add-tenant-overlay .btn,
  #add-tenant-overlay .field input,
  #add-tenant-overlay .field select,
  #add-tenant-overlay select{min-height:44px;}

  @media(max-width:760px){
    /* Client/Employee/Invitation directory rows become cards. */
    .admin-directory table,.admin-directory thead,.admin-directory tbody,
    .admin-directory th,.admin-directory td,.admin-directory tr{display:block;width:100%;}
    .admin-directory thead{position:absolute;left:-9999px;top:-9999px;}
    .admin-directory tbody tr{border:1px solid var(--hair);margin-bottom:1px;padding:14px 16px;}
    .admin-directory td{border-bottom:none;padding:6px 0;background:none;text-align:left;}
    .admin-directory td[data-label]::before{
      content:attr(data-label);display:block;font-family:'IBM Plex Mono',monospace;font-size:0.64rem;
      letter-spacing:0.06em;text-transform:uppercase;color:var(--taupe);margin-bottom:2px;
    }
    /* Lease Directory's own desktop-width truncation-with-tooltip
       (.lease-directory-table above) has no reason to exist once a row is
       already a full-width, label-per-field card — reset back to normal
       wrapping so the full value is always plainly visible here, no hover
       required. */
    .lease-directory-table td{overflow:visible;text-overflow:clip;white-space:normal;}
    .admin-drawer{width:100vw;}
    .admin-toolbar{flex-direction:column;align-items:stretch;}
    .admin-toolbar .admin-filter-select{width:100%;}
    .admin-toolbar .btn{width:100%;justify-content:center;}
    .admin-view-head{align-items:flex-start;}
    /* Same flex-basis-becomes-height-basis issue as
       .property-directory-pane > .admin-search-input above, triggered
       here by .admin-toolbar itself switching to flex-direction:column at
       this breakpoint: .admin-search-input's shared flex:1 1 260px reads
       260px as a WIDTH basis in the toolbar's normal row layout, but as a
       HEIGHT basis the moment the toolbar goes column — a 260px-tall
       Units search box on phones. Scoped to the Properties tab's own
       Units toolbar rather than every .admin-toolbar search input
       app-wide, since only this one was reported/verified against the
       reference at these breakpoints. */
    #epanel-properties .admin-toolbar .admin-search-input{flex-basis:auto;}
  }

  .admin-disclosure{margin-top:1px;border:1px solid var(--hair);}
  .admin-disclosure-summary{
    cursor:pointer;list-style:none;user-select:none;
    background:var(--panel);
    padding:14px 20px;font-family:'IBM Plex Mono',monospace;font-size:0.72rem;
    letter-spacing:0.06em;text-transform:uppercase;color:var(--gold-deep);
    display:flex;align-items:center;gap:8px;
  }
  .admin-disclosure-summary::-webkit-details-marker{display:none;}
  .admin-disclosure-summary::before{content:'▸';display:inline-block;transition:transform .2s;}
  .admin-disclosure[open] .admin-disclosure-summary::before{transform:rotate(90deg);}
  .admin-table-scroll{max-height:360px;overflow-y:auto;}
  .admin-table-wrap{overflow-x:auto;overflow-y:visible;}
  /* table-layout:auto (not fixed) lets every column grow to fit its own
     content — full names, emails, "Property Owner", a property + unit
     label, 2-3 inline action buttons — so nothing ever wraps mid-word,
     truncates, or bleeds into a neighboring column; the per-column
     width:X% styles the JS still sets are honored only as a minimum
     hint, not a hard cap. The whole table simply grows wider than the
     viewport when content demands it, and .admin-directory-scroll's (or
     .admin-table-wrap's) own overflow-x:auto scrolls it horizontally
     rather than clipping anything — min-width is a floor for the
     loading/empty states, not a ceiling on real content. */
  .admin-fixed-table{table-layout:auto;width:100%;min-width:680px;}
  .admin-fixed-table th,.admin-fixed-table td{text-align:left;white-space:nowrap;}
  .admin-fixed-table th{position:sticky;top:0;z-index:1;}

  /* Lease Directory: deliberately DIFFERENT from admin-fixed-table's own
     shared auto-layout+horizontal-scroll convention just above (which
     every OTHER directory keeps, on purpose — see that rule's own
     comment for why truncation was rejected there). This table's own
     left-hand column sits beside a wide details panel (.leases-layout),
     so its available width at ordinary desktop sizes regularly lands
     right at/under admin-fixed-table's 680px floor, forcing horizontal
     scroll at widths that shouldn't need it. table-layout:fixed lets it
     always exactly fill its container instead; every truncatable cell
     carries a real title= attribute (set in renderLeaseList(),
     employee-dashboard.js) so the full value is still one hover away —
     the ellipsis-with-no-fallback concern that ruled out this same
     approach for Invitations doesn't apply here. Status/Actions never
     truncate — a pill and a single kebab button are already compact. */
  .lease-directory-table{table-layout:fixed;min-width:0;}
  .lease-directory-table th,.lease-directory-table td{overflow:hidden;text-overflow:ellipsis;}
  .lease-directory-table th:nth-child(1),.lease-directory-table td:nth-child(1){width:12%;}
  .lease-directory-table th:nth-child(2),.lease-directory-table td:nth-child(2){width:23%;}
  .lease-directory-table th:nth-child(3),.lease-directory-table td:nth-child(3){width:16%;}
  .lease-directory-table th:nth-child(4),.lease-directory-table td:nth-child(4){width:16%;}
  .lease-directory-table th:nth-child(5),.lease-directory-table td:nth-child(5){width:11%;}
  /* Status: overflow:hidden + the base rule's text-overflow:ellipsis
     only ever apply ellipsis to a cell's own direct text — the actual
     content here is a child <span class="status-pill-filled"> (a pill
     with its own padding/border-radius), which text-overflow simply
     can't add a "…" to. At 11% width that clipped the two genuinely long
     status labels ("Pending Signature"/"Expiring Soon" — see
     lease-helpers.js) mid-word with no ellipsis at all, confirmed via a
     real-browser screenshot at a 768px viewport (a common width where
     this table is squeezed beside the details panel but hasn't yet
     switched to the ≤760px mobile-card layout, where this cell resets
     via the same rule the Property/Unit/Tenant cells use above). Letting
     it wrap instead — never truncated, same as every other cell in this
     table now — is safe here specifically since a two-line pill in an
     11%-wide column doesn't visually compete with anything beside it. */
  .lease-directory-table th:nth-child(6),.lease-directory-table td:nth-child(6){width:11%;overflow:visible;white-space:normal;}
  /* All 7 columns' widths sum to exactly 100% (a fixed px width on just
     this last one, mixed with the other six's %, could over/under-fill a
     table-layout:fixed row depending on the pane's own width) — 11% is
     comfortably wider than the single kebab button it holds at every
     width this table renders at before switching to the card layout. */
  .lease-directory-table th:nth-child(7),.lease-directory-table td:nth-child(7){width:11%;overflow:visible;white-space:nowrap;}
  /* Re-asserts the ≤760px mobile-card reset (originally declared inside
     the @media(max-width:760px) block far above, around line 682) which
     this exact same `.lease-directory-table td` selector — same
     specificity, but declared LATER in the file, right above — was
     silently winning against and completely shadowing at every width
     ≤760px: a real, verified-in-a-real-browser bug (property/tenant/
     status text rendered as "Ba…"/"Pe…" etc. in the Lease Directory's own
     mobile card rows, confirmed via Playwright screenshot at a 375px
     viewport) that plain reading of the CSS didn't reveal, since both
     rules "looked correct" in isolation — only their relative source
     order, which determines the winner between two equal-specificity
     rules, was wrong. Kept here (not moved) so the fix sits immediately
     next to — and is guaranteed by source order to win over — the exact
     rule it needs to override, rather than depending on staying
     correctly ordered relative to a large, unrelated block far above.
     overflow-wrap:anywhere is a second addition beyond the original
     line-682 rule — white-space:normal alone lets text wrap at spaces,
     but a genuinely unbroken long value (a long tenant name/email with no
     spaces) still overflowed the fixed-width cell horizontally once
     ellipsis-clipping stopped hiding it; same fix already used for the
     lease detail panel's own .profile-value/.lease-detail-sub.

     A THIRD, more severe issue found the same way (real-browser
     screenshot, not just reading the CSS): the six unconditional
     `.lease-directory-table th/td:nth-child(N){width:X%}` rules above
     (each specificity 0,2,1 — two class/pseudo-class-level selectors)
     OUTRANK the mobile card layout's own `.admin-directory td{width:100%}`
     reset (specificity only 0,1,1), even though display:block IS
     correctly applied by that same mobile block. The net effect: every
     "card" field's value box stayed pinned to its old desktop
     percentage — as little as 11% of an already-narrow phone screen —
     so even completely ordinary short values ("Jane Doe", "LS-2026-002")
     wrapped one character per line, confirmed visually. `:nth-child(n)`
     (matching every position at once) carries the identical 0,2,1
     specificity as each individual `:nth-child(N)` rule it needs to beat,
     so declaring it here — after them, at equal specificity — wins on
     source order and hands the real 100% width back to every column. */
  /* Owner's own redesigned Leases table — 6 columns (Unit/Tenant/Term/
     Rent/Status/Action) instead of the Employee Lease Directory's 7 (no
     separate Lease or Document column — the lease code is dropped and the
     document action lives inside the review drawer that opening a row
     already shows, see buildOwnerLeaseRowHtml()'s own comment). Always
     paired with .lease-directory-table on the same <table> — reuses that
     class's table-layout/overflow/mobile-reset behavior verbatim (see its
     own extensively-documented, real-browser-verified fixes above);
     .owner-lease-table only ever overrides the per-column WIDTH
     percentages, at equal selector specificity, so declaring it after
     .lease-directory-table's own width rules (immediately above) but
     still before the shared ≤760px mobile reset (immediately below) is
     what makes it win on desktop while the mobile reset still wins on
     phones, for exactly the same source-order reason documented above. */
  .owner-lease-table th:nth-child(1),.owner-lease-table td:nth-child(1){width:14%;}
  .owner-lease-table th:nth-child(2),.owner-lease-table td:nth-child(2){width:22%;}
  .owner-lease-table th:nth-child(3),.owner-lease-table td:nth-child(3){width:22%;}
  .owner-lease-table th:nth-child(4),.owner-lease-table td:nth-child(4){width:14%;}
  .owner-lease-table th:nth-child(5),.owner-lease-table td:nth-child(5){width:14%;overflow:visible;white-space:normal;}
  .owner-lease-table th:nth-child(6),.owner-lease-table td:nth-child(6){width:14%;overflow:visible;white-space:nowrap;}

  @media(max-width:760px){
    .lease-directory-table td{overflow:visible;text-overflow:clip;white-space:normal;overflow-wrap:anywhere;}
    .lease-directory-table th:nth-child(n),.lease-directory-table td:nth-child(n){width:100%;}
  }

  /* Sortable column headers (Employees' Employee/first-name column,
     Client Accounts' Name column) — a plain button styled to look like
     the surrounding <th> text, so it stays a real, keyboard-focusable
     control rather than an onclick on a non-interactive element. The
     arrow is a plain glyph (no icon dependency), shown only once a sort
     direction is active. */
  .admin-sort-header{display:inline-flex;align-items:center;gap:4px;background:none;border:none;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;}
  .admin-sort-header:hover{text-decoration:underline;}
  .admin-sort-arrow{font-size:0.85em;}

  /* Invite Employee's role-selection step — separate clickable cards
     (role="radio" within a role="radiogroup"), never a dropdown. Reuses
     the same border/hover language as .admin-filter-btn, just larger and
     laid out as a row of equal-width cards rather than a compact pill
     group. */
  .invite-role-cards{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:20px;}
  .invite-role-card{
    flex:1 1 160px;background:transparent;border:1px solid var(--hair-strong);color:inherit;
    padding:18px 16px;font-family:'Inter',sans-serif;font-size:0.94rem;text-align:left;
    cursor:pointer;border-radius:2px;transition:all .15s;
  }
  .invite-role-card:hover{border-color:var(--gold);}
  .invite-role-card.selected{border-color:var(--gold-deep);background:rgba(191,161,74,0.08);}
  .invite-role-card-name{display:block;font-weight:600;}

  /* Invitations shares the exact same auto-layout+horizontal-scroll
     behavior as Client Accounts/Employees now — no cell is ever clipped
     with an ellipsis regardless of column width; a narrow viewport simply
     scrolls the table within .admin-directory-scroll's own overflow-x,
     same as the other two directories. (Previously used
     table-layout:fixed + ellipsis truncation to avoid horizontal scroll
     entirely — dropped because truncating real recipient/status content
     is worse than an occasional horizontal scroll.) */
  .admin-invites-table{min-width:760px;}

  /* Client Accounts / Employees / Invitations directories aren't wrapped
     in their own .admin-table-wrap (unlike Lease Directory) — the
     .admin-directory-scroll shell around them needs its own horizontal
     scroll so a narrow viewport (wider than the 760px mobile-card
     breakpoint, narrower than admin-fixed-table's own min-width) scrolls
     the table within its own box instead of overflowing the page. */
  .admin-directory-scroll{overflow-x:auto;}

  select:disabled{background:var(--panel-2);color:var(--taupe);cursor:not-allowed;}
  .combobox{position:relative;}
  .combobox input{
    width:100%;background:var(--black);border:1px solid var(--hair);color:var(--cream);
    padding:11px 12px;font-family:'Inter',sans-serif;font-size:0.86rem;border-radius:1px;
  }
  .combobox input:focus{outline:none;border-color:var(--gold);}
  .combobox-listbox{
    display:none;position:absolute;top:calc(100% + 4px);left:0;right:0;max-height:220px;overflow-y:auto;
    background:#FFFFFF;border:1px solid var(--hair);box-shadow:0 12px 24px rgba(0,0,0,0.14);z-index:20;
    list-style:none;padding:4px;margin:0;
  }
  .combobox-listbox.open{display:block;}
  .combobox-option{padding:10px 12px;font-size:0.86rem;color:var(--taupe);cursor:pointer;border-radius:1px;}
  .combobox-option:hover,.combobox-option.active{background:var(--panel-2);color:var(--gold-deep);}
  .combobox-empty{padding:10px 12px;font-size:0.82rem;color:var(--taupe);font-style:italic;}
  /* The listbox is position:absolute, so it doesn't push flow content down
     when open — an open Property listbox can visually cover the Unit
     field right below it in Add Tenant's Assignment step until a
     selection is made or it's dismissed; this is normal combobox overlay
     behavior, not a layout bug. */

  /* Add Tenant / Add Property Owner / Edit Tenant / Edit Property Owner —
     centered modal forms. */
  .admin-modal-overlay{
    display:none;position:fixed;inset:0;background:rgba(17,17,17,0.55);z-index:2000;
    align-items:flex-start;justify-content:center;padding:60px 20px;overflow-y:auto;
  }
  .admin-modal-overlay.open{display:flex;}
  .admin-modal{
    background:#FFFFFF;border:1px solid var(--hair);max-width:560px;width:100%;
    padding:28px;box-shadow:0 24px 48px rgba(0,0,0,0.25);
  }
  .admin-modal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;gap:16px;}
  .admin-modal-close{background:none;border:none;color:var(--taupe);font-size:1.4rem;line-height:1;cursor:pointer;padding:4px 8px;}
  .admin-modal-close:hover{color:var(--gold-deep);}
  .admin-modal .form-inline{background:none;padding:0;margin-bottom:0;}
  .admin-modal-actions{display:flex;gap:12px;flex-wrap:wrap;margin-top:20px;justify-content:flex-end;}
  .admin-field-note{font-size:0.78rem;color:var(--taupe);margin-top:10px;}
  .notif-detail-modal-time{font-family:'IBM Plex Mono',monospace;font-size:0.72rem;color:var(--taupe);margin-bottom:14px;}
  .admin-field-note-error{color:#B3261E;}

  main{max-width:1180px;margin:0 auto;padding:0 28px;}

  /* Every authenticated portal (Employee, Owner, Tenant) breaks out of
     <main>'s own 1180px cap to use the full viewport width — logged-out
     pages (home/services/about/contact/login) keep that cap untouched.
     Same "cancel the parent's centering, then re-gutter with the viewport
     itself" trick .owner-properties-page/.owner-properties-inner already
     use (for just its own one panel), just folded into a single rule via
     max() instead of a second wrapper element (there's no single wrapping
     child inside any of these three sections to add one to — each holds
     .dtabs plus every one of its own panels directly). Fluid right up to
     roughly a 2000px-wide viewport, then the gutter itself grows to hold
     the content at a comfortable ~2000px reading width instead of
     stretching indefinitely on an ultra-wide monitor — see .nav-inner's
     own identical formula above, which this is deliberately kept
     pixel-identical to so the header row and the page content below it
     always share the same left/right edges for every role, not just
     Employee — a shared global header/layout, never a role-specific one.
     (.owner-properties-page's own separate 1440px cap for the Owner
     Portal's "My Properties" panel specifically is untouched by this —
     it's a deliberately calmer, narrower treatment for that one panel,
     nested inside this now-wider #page-dash-owner.) */
  #page-dash-employee, #page-dash-owner, #page-dash-tenant{
    margin-left:calc(50% - 50vw);
    margin-right:calc(50% - 50vw);
    padding-left:max(28px, calc((100vw - 2000px) / 2));
    padding-right:max(28px, calc((100vw - 2000px) / 2));
  }
  section.page{display:none;animation:fade .5s ease;}
  section.page.active{display:block;}
  @keyframes fade{from{opacity:0;transform:translateY(6px);}to{opacity:1;transform:translateY(0);}}

  /* HERO */
  .hero{
    min-height:78vh;display:flex;flex-direction:column;justify-content:center;
    padding:80px 0 60px;position:relative;
  }
  .kw-logo.kw-hero{margin-bottom:36px;}
  .hero h1{
    font-size:clamp(2.4rem, 5.5vw, 4.4rem);
    line-height:1.05;max-width:820px;color:var(--cream);
  }
  .hero h1 em{font-style:italic;color:var(--gold);}
  .hero p.lead{
    max-width:520px;margin-top:22px;color:var(--taupe);font-size:1.05rem;line-height:1.65;
  }
  .cta-row{display:flex;gap:16px;margin-top:38px;flex-wrap:wrap;}
  .btn{
    display:inline-flex;align-items:center;gap:10px;
    padding:14px 28px;font-size:0.82rem;letter-spacing:0.08em;text-transform:uppercase;
    cursor:pointer;border-radius:1px;transition:all .25s;font-family:'Inter',sans-serif;
  }
  /* Any bare svgIcon() dropped into a button (e.g. "Message management")
     renders at its unconstrained intrinsic size without this — same
     underlying gotcha as .maint-visit-row svg above. */
  .btn svg{width:16px;height:16px;flex-shrink:0;}
  .btn-primary{background:var(--gold-deep);color:#FFFFFF;border:1px solid var(--gold-deep);}
  .btn-primary:hover{background:transparent;color:var(--gold-deep);}
  .btn-ghost{background:transparent;color:var(--cream);border:1px solid var(--hair-strong);}
  .btn-ghost:hover{border-color:var(--gold);color:var(--gold);}
  .btn:disabled{opacity:0.45;cursor:not-allowed;}
  .btn-primary:disabled:hover{background:var(--gold-deep);color:#FFFFFF;}
  .btn-ghost:disabled:hover{border-color:var(--hair-strong);color:var(--cream);}
  .btn-danger{background:#B3261E;color:#FFFFFF;border:1px solid #B3261E;}
  .btn-danger:hover{background:transparent;color:#B3261E;}
  .btn-danger:disabled:hover{background:#B3261E;color:#FFFFFF;}

  /* Danger Zone — irreversible-from-here admin actions (Delete Property
     Owner today). Red-accented, visually distinct from the rest of a
     modal/drawer so it never reads as an ordinary form field. */
  .danger-zone{
    border:1px solid #B3261E;background:rgba(179,38,30,0.05);
    padding:18px 20px;margin-bottom:4px;
  }
  .danger-zone-title{
    font-family:'IBM Plex Mono',monospace;font-size:0.72rem;letter-spacing:0.08em;
    text-transform:uppercase;color:#B3261E;margin-bottom:10px;
  }
  .danger-zone-text{font-size:0.86rem;color:var(--taupe);line-height:1.5;margin-bottom:12px;}
  .danger-zone-text:last-of-type{margin-bottom:16px;}
  .danger-zone-confirm-label{display:block;font-size:0.82rem;color:var(--cream);margin-bottom:8px;}

  /* LEDGER STAT BAR */
  .ledger{
    display:grid;grid-template-columns:repeat(4,1fr);
    border-top:1px solid var(--hair);border-bottom:1px solid var(--hair);
    margin:70px 0;
  }
  .ledger div{
    padding:26px 22px;border-right:1px solid var(--hair);
  }
  .ledger div:last-child{border-right:none;}
  .ledger .num{font-family:'Cormorant Garamond',serif;font-size:2.1rem;color:var(--gold);}
  .ledger .lbl{font-size:0.72rem;letter-spacing:0.08em;color:var(--taupe);text-transform:uppercase;margin-top:6px;}

  .section-head{margin-bottom:44px;}
  .section-head h2{font-size:clamp(1.8rem,3vw,2.6rem);margin-top:10px;color:var(--cream);}

  /* SERVICE CARDS */
  .grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--hair);margin-bottom:90px;}
  .card{background:var(--black);padding:34px 28px;transition:background .3s;}
  .card:hover{background:var(--panel);}
  .card .idx{font-family:'IBM Plex Mono',monospace;color:var(--gold-deep);font-size:0.78rem;}
  .card h3{font-size:1.5rem;margin:14px 0 10px;color:var(--cream);}
  .card p{color:var(--taupe);font-size:0.92rem;line-height:1.6;}

  /* LINE ITEMS (services page) */
  .lineitem{
    display:grid;grid-template-columns:80px 1fr 1fr;gap:24px;
    padding:30px 0;border-bottom:1px solid var(--hair);align-items:start;
  }
  .lineitem .code{font-family:'IBM Plex Mono',monospace;color:var(--gold-deep);font-size:0.85rem;padding-top:4px;}
  .lineitem h3{font-size:1.6rem;color:var(--cream);}
  .lineitem p{color:var(--taupe);font-size:0.92rem;line-height:1.65;margin-top:8px;}

  /* ABOUT */
  .about-wrap{display:grid;grid-template-columns:1fr 1fr;gap:60px;padding:70px 0;align-items:start;}
  .about-wrap p{color:var(--taupe);line-height:1.75;margin-bottom:18px;font-size:0.98rem;}
  .pillar{padding:20px 0;border-top:1px solid var(--hair);}
  .pillar h4{color:var(--gold-deep);font-family:'Cormorant Garamond',serif;font-size:1.3rem;margin-bottom:6px;}
  .pillar p{color:var(--taupe);font-size:0.88rem;margin:0;}

  /* CONTACT */
  main:has(#page-contact.active){max-width:none;padding:0;}
  #page-contact{--gold-deep:#07533f;--taupe:#414754;--hair:#cdd3da;--panel:#fff;--panel-2:#eff6f1;}
  #page-contact .contact-wrap{display:grid;grid-template-columns:61.3fr 38.7fr;gap:0;padding:0;align-items:stretch;}
  .contact-wrap > div:first-child{padding:56px 40px 28px max(28px,4vw);min-width:0;}
  .contact-heading{font-size:clamp(1.9rem,2.6vw,2.4rem);line-height:1.15;letter-spacing:-0.02em;margin:0 0 8px;}
  .contact-lead{color:var(--taupe);font-size:1.02rem;margin-bottom:26px;}
  .field{margin-bottom:22px;}
  .field label{display:block;font-size:0.72rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--taupe);margin-bottom:8px;}
  .field input, .field textarea{
    width:100%;background:var(--panel);border:1px solid var(--hair);color:var(--cream);
    padding:14px 16px;font-family:'Inter',sans-serif;font-size:0.96rem;line-height:1.4;border-radius:1px;
  }
  .field input::placeholder, .field textarea::placeholder{color:var(--taupe);opacity:0.7;}
  .field input:focus, .field textarea:focus{outline:none;border-color:var(--gold);}
  .field input:disabled{background:var(--panel-2);color:var(--taupe);cursor:not-allowed;}
  .contact-field-pair,.contact-property-options{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;}
  .contact-field-pair .field{min-width:0;}
  .contact-property-type{border:0;padding:0;min-width:0;margin:0 0 22px;}
  .contact-property-type legend{font-size:0.72rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--taupe);margin-bottom:4px;}
  .contact-property-hint{font-size:0.82rem;color:var(--taupe);margin-bottom:8px;}
  .contact-property-option{position:relative;cursor:pointer;}
  .contact-property-option input{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
  .contact-property-card{
    position:relative;display:flex;align-items:center;gap:12px;height:100%;
    padding:16px 38px 16px 16px;border:1px solid var(--hair);border-radius:3px;background:var(--panel);
    transition:border-color .2s,background .2s;
  }
  .contact-property-icon{width:26px;height:26px;flex-shrink:0;color:var(--gold-deep);}
  .contact-property-card strong{display:block;font-family:'Cormorant Garamond',serif;font-size:1.15rem;font-weight:500;}
  .contact-property-description{display:block;margin-top:3px;font-size:0.78rem;line-height:1.4;color:var(--taupe);}
  .contact-property-badge{
    position:absolute;top:14px;right:14px;width:20px;height:20px;border-radius:50%;
    border:1.5px solid #9299a6;background:transparent;
    display:flex;align-items:center;justify-content:center;
    transition:background .2s,border-color .2s;
  }
  .contact-property-check{width:11px;height:11px;flex-shrink:0;color:#FFFFFF;visibility:hidden;}
  .contact-property-option input:checked + .contact-property-card{border-color:var(--gold-deep);background:var(--panel-2);}
  .contact-property-option input:checked + .contact-property-card .contact-property-badge{background:var(--gold-deep);border-color:var(--gold-deep);}
  .contact-property-option input:checked + .contact-property-card .contact-property-check{visibility:visible;}
  .contact-property-option input:focus-visible + .contact-property-card{outline:2px solid var(--gold-deep);outline-offset:3px;}
  .contact-status{margin:14px 0 0;font-size:0.88rem;min-height:1.2em;}
  .contact-status.success{color:var(--gold-deep);}
  .contact-status.error{color:#B3261E;}
  .field input:read-only{background:var(--panel-2);color:var(--taupe);}
  .field textarea{min-height:130px;resize:vertical;}
  #page-contact .field input,#page-contact .field textarea{background:#fff;border-radius:3px;}
  #page-contact .field input:focus-visible,#page-contact .field textarea:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}
  #contact-submit-btn{min-height:48px;justify-content:center;border-radius:3px;letter-spacing:0.14em;}
  #contact-submit-btn::after{content:'⟶';font-size:1.1rem;line-height:1;margin-left:12px;}
  .contact-status:empty{display:none;}
  #page-contact .info-block{position:relative;overflow:hidden;isolation:isolate;background:#f0efea;border-radius:0;padding:56px max(28px,4vw) 200px;min-width:0;}
  #page-contact .info-block::after{content:'';position:absolute;z-index:-1;inset:auto 0 0;height:260px;background:url('../img/contact-building.svg') bottom right / cover no-repeat;opacity:0.4;pointer-events:none;}
  .info-block-heading{font-size:clamp(1.9rem,2.6vw,2.4rem);line-height:1.15;letter-spacing:-0.02em;margin:14px 0 16px;color:var(--cream);}
  .info-block-lead{color:var(--taupe);font-size:1.02rem;line-height:1.5;max-width:380px;}
  .info-block-rule{margin:26px 0 16px;background:#b9bbb5;}
  .info-row{padding:12px 0 18px;}
  .info-row .eyebrow{margin-bottom:6px;color:var(--taupe);letter-spacing:0.14em;}
  .info-row div.val{font-family:'Cormorant Garamond',serif;font-size:clamp(1.1rem,1.4vw,1.3rem);color:var(--cream);overflow-wrap:anywhere;}
  body:has(#page-contact.active) footer{margin-top:0;padding:26px max(28px,4.6vw);}
  body:has(#page-contact.active) .footer-inner{max-width:none;}
  body:has(#page-contact.active) .nav-inner{padding-inline:max(28px,4.6vw);}
  @media(max-width:1200px){
    .contact-wrap > div:first-child{padding:44px 28px;}
    #page-contact .info-block{padding:44px 28px 180px;}
    .contact-field-pair,.contact-property-options{gap:14px;}
  }
  @media(max-width:860px){
    #page-contact .contact-wrap{grid-template-columns:1fr;}
    .contact-wrap > div:first-child{padding:36px 28px;}
    #page-contact .info-block{padding:36px 28px 160px;}
    .info-block-heading{max-width:500px;}
  }
  @media(max-width:600px){
    .contact-field-pair,.contact-property-options{grid-template-columns:1fr;gap:14px;}
    .contact-field-pair{gap:0;}
    #contact-submit-btn{width:100%;}
  }

  /* PORTAL */
  .portal-wrap{
    min-height:70vh;display:flex;align-items:center;justify-content:center;padding:70px 0;
  }
  .portal-card{
    width:100%;max-width:480px;background:var(--panel);border:1px solid var(--hair);border-radius:14px;
    padding:52px 48px;box-shadow:0 28px 64px rgba(0,0,0,0.4);
  }
  @media(max-width:520px){.portal-card{padding:36px 26px;border-radius:10px;}}
  .portal-tabs{display:flex;border-bottom:1px solid var(--hair);margin-bottom:30px;}
  .portal-tabs button{
    flex:1;background:none;border:none;color:var(--taupe);padding:12px 0;
    font-family:'IBM Plex Mono',monospace;font-size:0.75rem;letter-spacing:0.06em;text-transform:uppercase;
    cursor:pointer;border-bottom:2px solid transparent;
  }
  .portal-tabs button.active{color:var(--gold-deep);border-bottom-color:var(--gold-deep);}
  .portal-card .field input{background:var(--black);}
  .portal-card .field input:disabled{background:var(--panel-2);}
  .forgot{display:block;text-align:right;font-size:0.78rem;color:var(--taupe);margin-top:-10px;margin-bottom:26px;}
  .forgot:hover{color:var(--gold-deep);}
  .portal-note{
    margin-top:26px;padding-top:20px;border-top:1px solid var(--hair);
    font-size:0.78rem;color:var(--taupe);line-height:1.6;text-align:center;
  }

  /* DASHBOARD PREVIEW — no top padding: with the old per-portal "Welcome"
     banner removed (identity/Sign Out now live only in the shared global
     header), .dtabs is the first thing inside every one of these three
     sections, and its own button padding already provides the visual gap
     below the header's bottom border — matching the mockup's own tight
     header-to-nav spacing, not the old banner's ~60px of empty space
     above a heading that no longer exists. */
  .dash{display:none;padding:0 0 100px;}
  .dash.active{display:block;}
  .dash-top{display:flex;justify-content:space-between;align-items:flex-end;margin-bottom:40px;flex-wrap:wrap;gap:20px;}
  /* Owner Portal's own compact info row (Building Name + Account Manager)
     — real portal content kept after removing the "Welcome"/eyebrow
     banner above it, so it needs its own top/bottom spacing rather than
     inheriting .dash-top's (now-unused-here) margin-bottom:40px. */
  .owner-info-row{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:20px;padding:20px 0;border-bottom:1px solid var(--hair);margin-bottom:1px;}
  .dash-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--hair);margin-bottom:1px;}
  .dcard{background:var(--panel);padding:28px;}
  .dcard .eyebrow{margin-bottom:10px;}
  .dcard .val{font-family:'Cormorant Garamond',serif;font-size:2rem;color:var(--cream);}
  .dcard .sub{font-size:0.8rem;color:var(--taupe);margin-top:4px;}
  .status-pill{display:inline-block;padding:4px 12px;font-size:0.68rem;letter-spacing:0.06em;text-transform:uppercase;font-family:'IBM Plex Mono',monospace;border:1px solid var(--gold-deep);color:var(--gold-deep);border-radius:999px;}
  /* Color-coded .status-pill variants — account type (Employee/Tenant/
     Property Owner), employee role (Admin/Staff), and invitation status
     (Pending/Accepted/Completed/Revoked) each get their own outline color,
     reusing the exact hues already established for unit status elsewhere
     (.unit-status-dot) so the palette stays consistent app-wide rather
     than inventing a second color language. */
  .status-pill.is-tenant{border-color:#2563EB;color:#2563EB;}
  .status-pill.is-owner{border-color:#7C3AED;color:#7C3AED;}
  .status-pill.is-employee,.status-pill.is-admin{border-color:var(--gold-deep);color:var(--gold-deep);}
  .status-pill.is-staff{border-color:var(--hair-strong);color:var(--taupe);}
  .status-pill.is-pending{border-color:#B45309;color:#B45309;}
  .status-pill.is-accepted{border-color:var(--gold-deep);color:var(--gold-deep);}
  .status-pill.is-completed{border-color:#2563EB;color:#2563EB;}
  .status-pill.is-revoked,.status-pill.is-expired{border-color:#B91C1C;color:#B91C1C;}
  /* Filled "Active" pill — a pale, borderless fill rather than the outline
     shape above, matching the mockup's own distinct treatment for a plain
     lifecycle Active/Inactive flag (as opposed to a type/role/status
     classification, which stays outlined). */
  .status-pill-filled{
    display:inline-block;padding:4px 12px;border-radius:999px;
    font-size:0.68rem;letter-spacing:0.04em;text-transform:none;font-family:'Inter',sans-serif;font-weight:500;
    background:rgba(14,124,74,0.12);color:var(--gold-deep);
  }
  .status-pill-filled.is-inactive{background:var(--panel-2);color:var(--taupe);}
  /* Client Accounts' own "Pending" status (an on-the-fly-created tenant/
     property owner who hasn't completed login setup yet — see
     buildClientAccountRows()'s own header) — same amber the Invitations
     tab's "Pending" pill already uses (.status-pill.is-pending/
     inviteStatusPillClass()), so the identical underlying state reads
     identically in both places. */
  .status-pill-filled.is-pending{background:rgba(180,83,9,0.12);color:#B45309;}
  /* Lease status pills (Draft/Pending Signature/Active/Expiring Soon/
     Expired) — all DERIVED display labels, never new stored values, see
     lease-helpers.js's own header for the full real-column mapping. */
  .status-pill-filled.is-lease-active{background:rgba(14,124,74,0.12);color:var(--gold-deep);}
  .status-pill-filled.is-lease-pending{background:rgba(180,83,9,0.12);color:#B45309;}
  .status-pill-filled.is-lease-expiring{background:rgba(185,28,28,0.12);color:#B91C1C;}
  .status-pill-filled.is-lease-draft{background:rgba(37,99,235,0.12);color:#2563EB;}
  .status-pill-filled.is-lease-expired{background:var(--panel-2);color:var(--taupe);}
  /* Notification delivery-channel status chips (tbl_notification_deliveries
     .status) — 'queued'/'processing' deliberately share the muted/amber
     "not done yet" look with lease-pending, never the completed-looking
     gold/green 'sent' uses, so a Sent-history reader can never mistake an
     in-flight delivery for a finished one at a glance. */
  .status-pill-filled.is-queued{background:var(--panel-2);color:var(--taupe);}
  .status-pill-filled.is-processing{background:rgba(180,83,9,0.12);color:#B45309;}
  .status-pill-filled.is-sent{background:rgba(37,99,235,0.12);color:#2563EB;}
  .status-pill-filled.is-delivered{background:rgba(14,124,74,0.12);color:var(--gold-deep);}
  .status-pill-filled.is-failed{background:rgba(185,28,28,0.12);color:#B91C1C;}
  /* Maintenance request status/priority/urgency pills — see
     maintenance-helpers.js's own color maps for which state gets which. */
  .status-pill-filled.is-maint-blue{background:rgba(37,99,235,0.12);color:#2563EB;}
  .status-pill-filled.is-maint-amber{background:rgba(180,83,9,0.12);color:#B45309;}
  .status-pill-filled.is-maint-green{background:rgba(14,124,74,0.12);color:var(--gold-deep);}
  .status-pill-filled.is-maint-red{background:rgba(185,28,28,0.12);color:#B91C1C;}
  .status-pill-filled.is-maint-gray{background:var(--panel-2);color:var(--taupe);}
  table{width:100%;border-collapse:collapse;margin-top:1px;}
  th{text-align:left;font-family:'IBM Plex Mono',monospace;font-size:0.68rem;letter-spacing:0.06em;text-transform:uppercase;color:var(--taupe);padding:16px 20px;background:var(--panel);border-bottom:1px solid var(--hair);}
  td{padding:18px 20px;background:var(--panel);border-bottom:1px solid var(--hair);font-size:0.9rem;color:var(--cream);}
  .signout{font-size:0.78rem;color:var(--taupe);cursor:pointer;}
  .signout:hover{color:var(--gold-deep);}

  /* Owner Portal header Account Manager block — name, then each contact
     line stacked and right-aligned, Sign out visually separated by its own
     top margin but still inside the same block. */
  .owner-am-block{text-align:right;}
  .owner-am-name{font-family:'Cormorant Garamond',serif;font-size:1.05rem;color:var(--cream);margin-top:4px;}
  .owner-am-link{display:block;font-size:0.72rem;color:var(--taupe);margin-top:2px;text-decoration:none;}
  .owner-am-link:hover,.owner-am-link:focus-visible{color:var(--gold-deep);text-decoration:underline;}
  .owner-am-link:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}
  .owner-am-block .signout{margin-top:10px;}

  .dtabs{display:flex;gap:16px;margin-bottom:1px;flex-wrap:wrap;border-bottom:1px solid var(--hair);padding:0 2px;}
  .dtabs button{
    background:transparent;border:none;color:var(--taupe);padding:16px 1px;
    font-family:'Inter',sans-serif;font-weight:400;font-size:0.84rem;letter-spacing:normal;text-transform:none;
    cursor:pointer;border-bottom:2px solid transparent;white-space:nowrap;
  }
  .dtabs button:hover{color:var(--cream);}
  .dtabs button.active{color:var(--cream);font-weight:600;border-bottom-color:var(--gold-deep);background:transparent;}
  .dtabs button:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}
  .dpanel{display:none;padding-top:1px;}
  .dpanel.active{display:block;}

  .subtabs{display:flex;gap:2px;margin:0 0 1px;flex-wrap:wrap;}
  .subtabs button{
    background:var(--panel);border:none;color:var(--taupe);padding:12px 20px;
    font-family:'IBM Plex Mono',monospace;font-size:0.7rem;letter-spacing:0.06em;text-transform:uppercase;
    cursor:pointer;border-bottom:2px solid transparent;
  }
  .subtabs button.active{color:var(--gold-deep);border-bottom-color:var(--gold-deep);background:var(--panel-2);}
  .obpanel{display:none;padding-top:20px;}
  .obpanel.active{display:block;}

  .building-photo{width:56px;height:56px;border:1px solid var(--hair);background:var(--panel);background-size:cover;background-position:center;flex-shrink:0;}
  .am-photo{width:48px;height:48px;border-radius:50%;border:1px solid var(--hair);background:var(--panel);background-size:cover;background-position:center;flex-shrink:0;}

  /* OWNER PORTAL — My Properties. Breaks out of <main>'s 1180px cap (only
     for this panel) to a wider, still-responsive container, per this
     page's own "reduce excessive empty space" requirement — every other
     page keeps <main>'s existing width untouched. Restrained shadows,
     8-12px radii, no dense outlined boxes, no excessive uppercase — a
     deliberately calmer treatment than the Admin console's own
     .admin-* components it otherwise borrows tokens/patterns from. */
  .owner-properties-page{margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw);}
  .owner-properties-inner{max-width:1440px;margin:0 auto;padding:0 clamp(20px,4vw,56px) 60px;}
  .owner-properties-head{margin:28px 0 32px;}
  .owner-properties-head h2{font-size:clamp(1.8rem,3vw,2.3rem);margin-top:8px;color:var(--cream);}
  .owner-properties-head p{color:var(--taupe);font-size:0.92rem;margin-top:10px;max-width:640px;line-height:1.6;}
  .owner-properties-note{font-size:0.76rem;color:var(--taupe);opacity:0.75;margin:10px 0 28px;max-width:640px;line-height:1.5;}
  .owner-properties-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:24px;}

  .owner-property-card{background:var(--panel);border:1px solid var(--hair);border-radius:10px;overflow:hidden;box-shadow:0 2px 14px rgba(0,0,0,0.05);}
  .owner-property-card-header{display:flex;align-items:center;gap:16px;padding:20px 22px;border-bottom:1px solid var(--hair);}
  .owner-property-photo{width:64px;height:64px;border-radius:8px;background:var(--panel-2);background-size:cover;background-position:center;flex-shrink:0;}

  /* Unit Details' own Property Name/Property Details fields, plus that
     property's picture — reuses .owner-property-photo verbatim (see its
     own comment above) just laid out beside a narrower two-field column
     instead of a full property card. */
  .unit-detail-property-row{display:flex;gap:14px;align-items:flex-start;}
  .unit-detail-property-row-fields{display:flex;flex-direction:column;gap:14px;flex:1;min-width:0;}
  .owner-property-card-headline{flex:1;min-width:0;}
  .owner-property-card-name{font-family:'Cormorant Garamond',serif;font-size:1.3rem;color:var(--cream);line-height:1.25;}
  .owner-property-card-address{color:var(--taupe);font-size:0.82rem;margin-top:3px;}
  .owner-property-card-badge{margin-top:8px;}
  .owner-property-card-body{padding:22px;}
  .owner-property-section{margin-top:22px;}
  .owner-property-section:first-child{margin-top:0;}
  .owner-property-section-title{font-family:'IBM Plex Mono',monospace;font-size:0.68rem;letter-spacing:0.04em;text-transform:uppercase;color:var(--gold-deep);margin-bottom:12px;}
  .owner-property-field-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:16px;}
  .owner-property-field-label{font-size:0.76rem;color:var(--taupe);}
  .owner-property-field-value{font-size:0.92rem;color:var(--cream);margin-top:3px;line-height:1.4;}
  .owner-property-notes{font-size:0.88rem;color:var(--cream);line-height:1.6;white-space:pre-wrap;}

  .owner-unit-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid var(--hair);border-radius:8px;margin-bottom:8px;}
  .owner-unit-row:last-child{margin-bottom:0;}
  .owner-unit-number{font-size:0.9rem;color:var(--cream);}
  /* Neutral for most statuses (Occupied, Maintenance, Unavailable — all
     "business as usual" from the owner's view); the accent color is
     reserved for Available, the one status that's actually actionable. */
  .owner-unit-status.status-pill{border-color:var(--hair-strong);color:var(--taupe);}
  .owner-unit-status.status-pill.is-available{border-color:var(--gold-deep);color:var(--gold-deep);}

  @media(max-width:640px){
    .owner-property-card-header{flex-wrap:wrap;}
  }

  /* PROPERTIES TAB — property details card. Image top-left, headline
     beside it on wide screens; both stack (image above headline) below the
     640px breakpoint. No property-specific styling here — the image itself
     falls back to the plain --panel box (the same generic-placeholder
     mechanism .building-photo already uses) whenever property_photo_url is
     empty or fails to load, since a failed CSS background-image simply
     doesn't paint over the background-color. */
  /* Matches .admin-review-summary's card treatment (border+background+
     padding) — the same visual weight every other bordered content block
     on the Admin page carries, replacing what used to be an unbordered,
     merely-indented block here. Shared by both Property Details and Unit
     Details (#unit-details-card also carries this class). */
  .property-details-card{
    margin-top:20px;background:var(--black);border:1px solid var(--hair);border-radius:10px;padding:20px;
  }
  .property-detail-photo-row{display:flex;align-items:flex-start;gap:24px;flex-wrap:wrap;}
  .property-detail-photo{
    position:relative;width:220px;height:150px;border:1px solid var(--hair);border-radius:10px;background:var(--panel);
    background-size:cover;background-position:center;flex-shrink:0;
  }
  /* Same interaction as .profile-photo-edit-overlay (Employee Profile's
     own photo-change control) — hidden until Edit Property's own
     .editing class is toggled onto the frame, shown as a full-frame
     hover/focus target the whole time edit mode is open — just
     rectangular (border-radius:10px, matching .property-detail-photo
     itself) instead of that one's circular avatar shape. */
  .property-photo-edit-overlay{
    display:none;position:absolute;inset:0;align-items:center;justify-content:center;
    background:rgba(17,17,17,0.55);color:#FFFFFF;border:none;border-radius:10px;
    font-family:'IBM Plex Mono',monospace;font-size:0.72rem;letter-spacing:0.08em;text-transform:uppercase;
    cursor:pointer;width:100%;height:100%;
  }
  .property-detail-photo.editing .property-photo-edit-overlay{display:flex;}
  .property-photo-edit-overlay:hover,.property-photo-edit-overlay:focus-visible{background:rgba(17,17,17,0.72);}
  .property-detail-headline{display:flex;flex-direction:column;gap:10px;}
  .property-detail-name{font-family:'Cormorant Garamond',serif;font-size:1.5rem;color:var(--cream);}
  @media(max-width:640px){
    .property-detail-photo-row{flex-direction:column;align-items:flex-start;}
  }

  /* Property/Unit Details field grid — same responsive auto-fit behavior
     as .form-inline. Each editable cell holds a .profile-value (view) and
     a .profile-input/<select> (edit) pair, toggled by setPropertyEditMode()
     in employee-dashboard.js; Unit Details has no edit mode and only ever
     renders the .profile-value side. */
  .property-detail-fields{
    display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:14px;
    margin-top:18px;
  }

  /* PROPERTIES PAGE HEAD — title block, side by side with its own
     right-aligned actions on wide screens, stacked on narrow ones. */
  .properties-page-head{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;flex-wrap:wrap;margin-bottom:24px;}

  /* PROPERTIES TWO-PANE LAYOUT — a warm off-white canvas (this tab only;
     every other Employee Portal tab keeps the plain white page
     background) with two WHITE cards floating on it: a searchable,
     scrollable property directory on the left, and the selected
     property's full details + Units on the right. Stacks to a single
     column below 960px — the directory keeps a bounded scroll height on
     both layouts rather than growing to match whatever the details pane
     happens to need. */
  .properties-layout{
    display:grid;grid-template-columns:minmax(0,340px) minmax(0,1fr);gap:24px;
    background:var(--panel);border:1px solid var(--hair);border-radius:12px;padding:20px;
  }
  @media(max-width:960px){
    .properties-layout{grid-template-columns:1fr;}
  }

  .property-directory-pane{
    background:var(--black);border:1px solid var(--hair);border-radius:10px;padding:18px;
    display:flex;flex-direction:column;gap:12px;min-width:0;
    box-shadow:0 2px 14px rgba(0,0,0,0.05);
  }
  /* .admin-search-input's shared flex:1 1 260px (styles.css above) is
     written for its normal home inside a ROW-direction .admin-toolbar,
     where 260px is a WIDTH basis. Used here as a direct child of this
     COLUMN-direction flex pane instead, that exact same flex-basis
     becomes a HEIGHT basis — a 260px-tall search box with a gap of empty
     space above the list. Reset back to a natural, content-based height
     in this one context only; every other .admin-search-input (Client
     Accounts, the Units toolbar below) is still inside a real
     .admin-toolbar and keeps the shared rule untouched. */
  .property-directory-pane > .admin-search-input{flex:none;}
  .property-directory-pane-head{display:flex;align-items:center;justify-content:space-between;gap:12px;}
  .property-directory-pane-head h3{font-family:'Cormorant Garamond',serif;font-size:1.15rem;color:var(--cream);}

  .property-directory-scroll{max-height:640px;overflow-y:auto;display:flex;flex-direction:column;gap:8px;}

  /* Each row is one <button> (image + name/address/counts) — the whole
     row is the click target, matching every other clickable-row
     convention in this app (.admin-directory tbody tr[data-clickable]).
     Re-rendered in place on every selection/search change
     (renderPropertyDirectoryList() in employee-dashboard.js) — the
     .property-directory-scroll element itself is never replaced, so its
     scrollTop (and the search <input>'s own typed text, a sibling
     element entirely untouched by this) survive a selection change. */
  .property-directory-row{
    display:flex;align-items:flex-start;gap:12px;text-align:left;width:100%;min-width:0;
    background:var(--black);border:1px solid var(--hair);border-left:3px solid transparent;border-radius:10px;
    padding:10px;cursor:pointer;font-family:'Inter',sans-serif;color:var(--cream);
  }
  .property-directory-row:hover{border-color:var(--hair-strong);}
  .property-directory-row:focus-visible{outline:2px solid var(--gold-deep);outline-offset:-2px;}
  .property-directory-row.selected{background:var(--panel-2);border-left-color:var(--gold-deep);border-color:var(--hair-strong);}
  .property-directory-thumb{
    width:88px;height:70px;flex-shrink:0;border:1px solid var(--hair);border-radius:8px;background:var(--panel);
    background-size:cover;background-position:center;
  }
  .property-directory-row-body{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1;}
  .property-directory-row-name{font-size:0.92rem;font-weight:500;word-break:break-word;}
  .property-directory-row-address{color:var(--taupe);font-size:0.78rem;}
  .property-directory-row-counts{display:flex;flex-wrap:wrap;gap:10px;margin-top:2px;font-size:0.72rem;color:var(--taupe);}
  .property-directory-unit-total{color:var(--cream);}
  .unit-status-badge{display:inline-flex;align-items:center;white-space:nowrap;}
  .property-directory-row-nounits{color:var(--taupe);font-size:0.72rem;font-style:italic;}

  /* Colored status dots — Occupied/Available/Maintenance/Unavailable,
     shared by the Property Directory list's counts, the Units filter
     pills, the Units table's own Status column, and the Unit Details side
     panel — one definition, never a second set of colors to keep in
     sync. Restrained, not neon: the same "small dot + label" convention
     as .status-pill elsewhere, just with a semantic color per status
     instead of the single gold-deep accent. */
  .unit-status-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;flex-shrink:0;}
  .unit-status-dot.is-occupied{background:var(--gold-deep);}
  .unit-status-dot.is-pending-lease-signing{background:#7C3AED;}
  .unit-status-dot.is-available{background:#2563EB;}
  .unit-status-dot.is-maintenance{background:#B45309;}
  .unit-status-dot.is-unavailable{background:#B91C1C;}

  .property-details-pane{min-width:0;}

  /* Property Owner — a compact photo+name row (never a full contact card
     like Assigned Account Manager below it, since this field is a single
     read-only line elsewhere in this same field grid) using tbl_property_owners'
     own photo_path/profile_photo_url columns (resolveEntityPhotoUrl(),
     the same helper Assigned Account Manager/Employee Profile already use)
     — .am-photo's own empty-circle styling is the fallback avatar when no
     photo is set, exactly like every other photo field in this app. */
  .property-owner-row{display:flex;align-items:center;gap:10px;min-width:0;}
  .property-owner-photo{width:32px;height:32px;flex-shrink:0;}

  /* Assigned Account Manager — one horizontal row (avatar + Name/Role/
     Email/Phone) at desktop widths; wraps only when the details pane is
     genuinely too narrow to hold it (tablet/mobile). Email is never
     clipped/ellipsized — it's real content, not a preview — it simply
     wraps onto additional lines at narrow widths instead (min-width:0 on
     .property-manager-field lets it actually shrink/wrap rather than
     forcing the row wider); renderPropertyManagerDisplay() in
     employee-dashboard.js still sets the matching `title` attribute
     regardless, which is harmless even though nothing is actually
     truncated. */
  .property-manager-divider{border-top:1px solid var(--hair);margin-top:18px;}
  .property-manager-row{display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap;}
  .property-manager-fields{display:flex;gap:14px;flex-wrap:wrap;flex:1;min-width:0;}
  .property-manager-field{min-width:0;}
  #property-manager-email{display:inline-block;max-width:100%;overflow-wrap:break-word;word-break:break-word;}

  /* The pin-line under the property name/status — a combined, at-a-glance
     summary of the same street/city/state/zip fields broken out
     individually in .property-detail-fields below; both read from the
     same property record, never a second source of truth. */
  .property-detail-address-line{display:flex;align-items:center;gap:6px;color:var(--taupe);font-size:0.88rem;}
  .property-detail-address-icon{font-size:0.85rem;}

  /* Units section — search + status filter pills (reusing .admin-toolbar/
     .admin-filter-btn/.admin-search-input from the Client Accounts
     directory verbatim), the table, and the selected-unit details box are
     three separate, independently-sized layout objects stacked vertically
     — never a shared grid/flex row — so selecting a unit (which toggles
     the details box between hidden and shown) can never resize or reflow
     the search input or filter pills above it, and the details box is
     always free to size to its own content rather than a fixed side-column
     width. The details box spans the full row and its height grows
     naturally with its content (see #unit-details-card below). */
  .units-section{border-top:1px solid var(--hair);margin-top:22px;padding-top:18px;}
  .units-section-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:14px;}
  .units-table-layout{display:flex;flex-direction:column;gap:20px;margin-top:16px;}
  .units-table-col{min-width:0;}
  .units-pagination{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-top:12px;font-size:0.8rem;color:var(--taupe);}
  .units-pagination-controls{display:flex;gap:8px;}
  .unit-details-side-card{margin-top:0;border-radius:10px;width:100%;}
  .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}

  /* Per-unit-row three-dot menu ("Assign Tenant") — reuses the existing
     .admin-row-actions/.admin-row-menu/.admin-row-menu-btn component
     (styled above, shared with Client Accounts/Employees/Invitations)
     verbatim; only the Actions column's own width needs a rule here. */
  .unit-row-menu-col{width:36px;}

  .assign-tenant-current-block{border:1px solid var(--hair);border-radius:8px;padding:16px;background:var(--panel);margin-top:14px;}
  /* The details BOX spans the full row (see .units-table-layout above),
     but its own label/value fields stay a compact vertical stack — the
     same content shape as before, just no longer squeezed into a narrow
     side column — rather than spreading out into extra grid columns just
     because more horizontal space is now available. */
  .unit-details-side-card .property-detail-fields{display:flex;flex-direction:column;gap:14px;max-width:360px;}
  .unit-details-side-card #unit-tenant-section{margin-top:14px;}

  /* Units table — a lighter table treatment than the shared
     .admin-fixed-table (which carries min-width:680px, written for a
     full-width directory page): this table sits in a narrower column
     beside the unit-details side panel, so a 680px floor would force
     horizontal scrolling far more aggressively than the reference calls
     for. Tighter padding + a much smaller min-width still guarantee
     .admin-directory-scroll's own overflow-x:auto kicks in rather than
     clipping anything if the column ever gets narrower than this. */
  .units-table{table-layout:auto;width:100%;min-width:400px;border-collapse:collapse;}
  .units-table th{
    position:sticky;top:0;z-index:1;text-align:left;white-space:nowrap;
    padding:10px 12px;background:var(--panel);border-bottom:1px solid var(--hair);
    font-family:'IBM Plex Mono',monospace;font-size:0.66rem;letter-spacing:0.05em;
    text-transform:uppercase;color:var(--taupe);
  }
  .units-table td{padding:10px 12px;border-bottom:1px solid var(--hair);background:var(--black);font-size:0.85rem;color:var(--cream);}
  /* Unit/Status/Lease End/Monthly Rent/Days Left/Updated are all short,
     fixed-shape values — safe to keep on one line. Assigned Tenant is
     deliberately the one column NOT forced to nowrap: a tenant's name is
     exactly the kind of "critical... tenant... information" that must
     never be truncated, so a long name wraps to a second line within its
     own cell instead. */
  .units-table td:nth-child(1),.units-table th:nth-child(1),
  .units-table td:nth-child(2),.units-table th:nth-child(2),
  .units-table td:nth-child(4),.units-table th:nth-child(4),
  .units-table td:nth-child(5),.units-table th:nth-child(5),
  .units-table td:nth-child(6),.units-table th:nth-child(6),
  .units-table td:nth-child(7),.units-table th:nth-child(7){white-space:nowrap;}
  .unit-th-sortable{cursor:pointer;}
  .unit-th-sortable:hover{color:var(--cream);}
  .unit-lease-expired{color:#B3261E;font-weight:600;}

  .btn-small{padding:8px 14px;font-size:0.72rem;}

  /* Property Name (Edit Property) — a free-text input sharing the
     headline's own grid cell, same view/edit-pair pattern as every other
     field in .property-detail-fields below, just living in the headline
     instead. Sized down from the 1.5rem serif heading it replaces while
     editing — a full-size serif input looks oversized/awkward — but kept
     wide enough to comfortably hold a real property name. */
  .property-detail-name-edit{font-size:1rem;max-width:420px;width:100%;}

  /* ASSIGN ACCOUNT MANAGER — search picker (admin-modal-wide: a bit more
     room than the default 560px modal for each result's name/role/
     contact-info row) + the reassignment-confirmation dialog's
     current-vs-new comparison. Both reuse .admin-modal-overlay/
     .admin-modal/.admin-modal-head/.admin-modal-actions verbatim for
     visual consistency with every other modal in this app. */
  .admin-modal-wide{max-width:640px;}
  /* Add/Edit Lease's own wider modal — its form-inline grid comfortably
     shows 3 columns at this width, matching the mockup's own proportions;
     a separate class from .admin-modal-wide so the existing Assign
     Account Manager/Property Owner pickers (tuned narrower, for a list of
     rows rather than a form grid) are unaffected. */
  .admin-modal-xwide{max-width:820px;}

  .assign-manager-list-scroll{max-height:420px;overflow-y:auto;display:flex;flex-direction:column;gap:8px;margin-top:16px;}
  .assign-manager-row{
    display:flex;align-items:center;gap:14px;padding:10px;
    background:var(--panel);border:1px solid var(--hair);border-radius:8px;
  }
  .assign-manager-row.is-current{border-color:var(--gold-deep);background:var(--panel-2);}
  .assign-manager-row-photo{width:44px;height:44px;flex-shrink:0;}
  .assign-manager-row-body{flex:1;min-width:0;}
  .assign-manager-row-name{font-size:0.9rem;font-weight:500;color:var(--cream);}
  .assign-manager-row-meta{font-size:0.72rem;color:var(--gold-deep);text-transform:uppercase;letter-spacing:0.04em;margin-top:2px;}
  .assign-manager-row-contact{font-size:0.78rem;color:var(--taupe);margin-top:2px;overflow-wrap:anywhere;}
  /* A recipient candidate with no linked Auth account (or an inactive
     account manager) — visible-but-blocked in the Notifications compose
     picker rather than hidden entirely, so the sender can see WHY someone
     they might expect to notify isn't selectable. */
  .assign-manager-row.is-unavailable{opacity:0.6;}

  /* ---------- Notifications: Compose / Inbox / Sent ----------
     Its own scoped palette/typography — approved design calls for a
     distinct warm-ivory/forest-green treatment here while the rest of the
     app (header, other dashboard tabs) keeps its existing gold/black
     theme untouched. Every rule below lives under .notify-shell so
     nothing here leaks into the surrounding page. */
  .notify-subsection{display:none;}
  .notify-subsection.active{display:block;}

  .notify-shell{
    --nf-bg:#FFFFFF; --nf-card:#FAF8F4; --nf-accent:#24714D; --nf-border:#DCE6DD;
    --nf-text:#253C31; --nf-text-2:#647267; --nf-danger:#B3261E;
    --nf-danger-bg:#FBEAE9; --nf-warn:#9A6B1E; --nf-warn-bg:#FBF3E4;
    background:var(--nf-bg); color:var(--nf-text); font-family:'Inter',sans-serif;
    padding:24px clamp(16px, 3vw, 32px); border-radius:8px;
  }
  .notify-page-title{
    font-family:'Cormorant Garamond',serif; font-weight:600; font-size:1.9rem;
    color:var(--nf-text); margin:0 0 20px;
  }

  .notify-tabs{display:flex;gap:28px;flex-wrap:wrap;border-bottom:1px solid var(--nf-border);margin-bottom:24px;}
  .notify-tabs.is-compact{gap:20px;margin-bottom:16px;}
  .notify-tabs.is-compact .notify-tab{font-size:0.84rem;padding-bottom:8px;}
  .notify-tab{
    background:none;border:none;padding:0 0 12px;font-family:'Inter',sans-serif;
    font-size:0.9rem;color:var(--nf-text-2);cursor:pointer;position:relative;
    border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s;
  }
  .notify-tab:hover{color:var(--nf-text);}
  .notify-tab.active{color:var(--nf-accent);border-bottom-color:var(--nf-accent);font-weight:600;}

  .notify-card{
    background:var(--nf-card);border:1px solid var(--nf-border);border-radius:8px;
    padding:24px;
  }
  .notify-section-title{
    font-family:'Inter',sans-serif;font-weight:600;font-size:0.82rem;letter-spacing:0.04em;
    text-transform:uppercase;color:var(--nf-accent);margin-bottom:18px;
  }
  .notify-subsection-title{
    font-family:'Inter',sans-serif;font-weight:600;font-size:0.78rem;letter-spacing:0.03em;
    text-transform:uppercase;color:var(--nf-text-2);margin:22px 0 12px;
  }

  .notify-compose-grid{display:grid;grid-template-columns:1fr 1fr;gap:20px;align-items:start;}
  @media(max-width:860px){ .notify-compose-grid{grid-template-columns:1fr;} }
  .notify-compose-col{display:flex;flex-direction:column;gap:20px;}

  .notify-shell .field{margin-bottom:16px;}
  .notify-shell .field label{
    display:block;font-size:0.72rem;letter-spacing:0.04em;text-transform:uppercase;
    color:var(--nf-text-2);margin-bottom:6px;
  }
  .notify-shell .field input,.notify-shell .field textarea{
    width:100%;background:#FFFFFF;border:1px solid var(--nf-border);color:var(--nf-text);
    padding:11px 12px;font-family:'Inter',sans-serif;font-size:0.9rem;border-radius:6px;
  }
  .notify-shell .field input:focus,.notify-shell .field textarea:focus{outline:none;border-color:var(--nf-accent);}
  .notify-shell .btn.btn-primary{
    background:var(--nf-accent);border:1px solid var(--nf-accent);border-radius:6px;color:#FFFFFF;
  }
  .notify-shell .btn.btn-primary:disabled{opacity:0.5;cursor:not-allowed;}
  .notify-shell .btn.btn-primary:not(:disabled):hover{background:#1D5C3D;}

  .notify-search-input{
    width:100%;max-width:420px;background:#FFFFFF;border:1px solid var(--nf-border);
    color:var(--nf-text);padding:10px 14px;font-family:'Inter',sans-serif;font-size:0.88rem;
    border-radius:6px;margin-bottom:14px;
  }
  .notify-search-input:focus{outline:none;border-color:var(--nf-accent);}
  .notify-property-list{max-height:320px;overflow-y:auto;}

  .notify-chip-btn{
    background:#FFFFFF;border:1px solid var(--nf-border);color:var(--nf-text);
    padding:9px 16px;border-radius:999px;font-family:'Inter',sans-serif;font-size:0.84rem;cursor:pointer;
  }
  .notify-recipient-type-row{display:flex;gap:10px;flex-wrap:wrap;}
  .notify-chip-btn.active{border-color:var(--nf-accent);color:var(--nf-accent);background:#EFF6F1;font-weight:600;}
  .notify-recipient-count{font-family:'IBM Plex Mono',monospace;font-size:0.78rem;color:var(--nf-text-2);margin:4px 0 12px;}
  .notify-channel-row{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:18px;}
  .notify-status-error{border-color:var(--nf-danger);color:var(--nf-danger);}
  #notify-compose-status.notify-status-error{color:var(--nf-danger);font-size:0.86rem;margin-top:10px;}
  #notify-compose-status.notify-status-success{color:var(--nf-accent);font-size:0.86rem;margin-top:10px;}
  .notify-unit-group{margin-bottom:14px;}
  .notify-unit-group .eyebrow{margin-bottom:6px;color:var(--nf-text-2);}
  .notify-recipient-checkbox-row{display:flex;align-items:center;gap:10px;padding:8px 4px;font-size:0.86rem;color:var(--nf-text);cursor:pointer;}
  .notify-recipient-checkbox-row input[type="checkbox"]{width:16px;height:16px;flex-shrink:0;accent-color:var(--nf-accent);}
  .notify-recipient-checkbox-row.is-unavailable{opacity:0.6;cursor:default;}
  .notify-select-all-row{margin-bottom:0;padding-bottom:0;}
  .notify-text-secondary{color:var(--nf-text-2);}

  /* ---- Compose: 02 unified recipient list (search + role chips + list) ---- */
  .notify-role-filter-row{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px;}
  .notify-select-all-bar{
    display:flex;align-items:center;gap:16px;flex-wrap:wrap;
    border-bottom:1px solid var(--nf-border);margin-bottom:8px;padding-bottom:12px;
  }
  .notify-select-all-bar .notify-recipient-count{margin:0;margin-left:auto;}
  .notify-recipient-list{max-height:340px;overflow-y:auto;}
  .notify-recipient-name{font-weight:600;color:var(--nf-text);}

  /* ---- Compose: 03 channel toggle pills (Email / Phone-SMS) ---- */
  .notify-channel-toggle{
    position:relative;flex:1 1 160px;display:flex;align-items:center;justify-content:center;gap:8px;
    background:#FFFFFF;border:1px solid var(--nf-border);border-radius:6px;padding:12px 16px;
    font-family:'Inter',sans-serif;font-size:0.9rem;color:var(--nf-text);cursor:pointer;transition:background .15s,border-color .15s,color .15s;
  }
  .notify-channel-toggle input[type="checkbox"]{position:absolute;opacity:0;width:1px;height:1px;}
  .notify-channel-toggle.is-active{background:var(--nf-accent);border-color:var(--nf-accent);color:#FFFFFF;font-weight:600;}

  /* ---- Compose: 03 recipient contact preview (per active channel) ---- */
  .notify-channel-recipients{margin-bottom:18px;}
  .notify-channel-recipients-title{font-family:'IBM Plex Mono',monospace;font-size:0.76rem;color:var(--nf-text-2);margin-bottom:10px;}
  .notify-channel-recipients-list{border:1px solid var(--nf-border);border-radius:8px;background:#FFFFFF;overflow:hidden;}
  .notify-channel-recipient-row{display:flex;align-items:center;gap:12px;padding:12px 14px;border-bottom:1px solid var(--nf-border);}
  .notify-channel-recipient-row:last-child{border-bottom:none;}
  .notify-channel-recipient-body{display:flex;flex-direction:column;gap:2px;min-width:0;}
  .notify-channel-recipient-name{font-size:0.88rem;font-weight:600;color:var(--nf-text);}
  .notify-channel-recipient-contact{font-size:0.8rem;color:var(--nf-text-2);overflow-wrap:anywhere;}
  .notify-channel-recipient-contact.notify-channel-recipient-missing{color:var(--nf-danger);}
  .notify-avatar{
    width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;
    flex-shrink:0;font-family:'IBM Plex Mono',monospace;font-size:0.68rem;font-weight:600;
    color:var(--nf-accent);background:#EFF6F1;
  }

  /* ---- Inbox: search/unread-count/mark-all toolbar + list/detail ---- */
  .notify-toolbar{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:18px;}
  .notify-toolbar .notify-search-input{margin-bottom:0;flex:1;min-width:200px;}
  .notify-unread-count{font-family:'IBM Plex Mono',monospace;font-size:0.76rem;color:var(--nf-text-2);white-space:nowrap;}
  .notify-text-btn{
    background:none;border:none;color:var(--nf-accent);font-family:'Inter',sans-serif;
    font-size:0.82rem;font-weight:600;cursor:pointer;padding:4px;white-space:nowrap;
  }
  .notify-text-btn:hover{text-decoration:underline;}

  .notify-inbox-layout{display:grid;grid-template-columns:minmax(260px,360px) 1fr;gap:20px;align-items:start;}
  .notify-detail-back{display:none;margin-bottom:14px;}
  /* Below the reference's 800px break, the list/detail pair collapses from
     side-by-side into a single-pane "screen": the list is the default view,
     selecting a row swaps in the detail pane (via .is-viewing-detail, set/
     cleared in JS by select*Notification()/close*NotificationMobileDetail()),
     and .notify-detail-back is the only way back. Desktop never sets or
     reads that class, so both panes stay visible there regardless. */
  @media(max-width:860px){
    .notify-inbox-layout{grid-template-columns:1fr;}
    .notify-inbox-layout:not(.is-viewing-detail) .notify-detail-panel{display:none;}
    .notify-inbox-layout.is-viewing-detail .notify-inbox-list{display:none;}
    .notify-inbox-layout.is-viewing-detail .notify-detail-back{display:inline-flex;align-items:center;}
  }

  .notify-inbox-list{
    display:flex;flex-direction:column;gap:8px;max-height:640px;overflow-y:auto;
    background:var(--nf-card);border:1px solid var(--nf-border);border-radius:8px;padding:10px;
  }
  .notify-row{
    display:block;width:100%;text-align:left;background:#FFFFFF;border:1px solid var(--nf-border);
    border-radius:6px;padding:12px 14px;cursor:pointer;transition:border-color .15s,background .15s;
  }
  .notify-row:hover{border-color:var(--nf-accent);}
  .notify-row.is-selected{border-color:var(--nf-accent);background:#EFF6F1;}
  .notify-row.is-unread .notify-row-title{font-weight:700;}
  .notify-row-top{display:flex;align-items:center;gap:8px;margin-bottom:6px;}
  .notify-row-time{font-family:'IBM Plex Mono',monospace;font-size:0.66rem;color:var(--nf-text-2);white-space:nowrap;margin-left:auto;}
  .notify-row-title{font-size:0.88rem;font-weight:500;color:var(--nf-text);margin-bottom:3px;}
  .notify-row-property{font-size:0.76rem;color:var(--nf-text-2);}
  .notify-unread-dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--nf-accent);flex-shrink:0;}

  .notify-detail-panel{
    background:var(--nf-card);border:1px solid var(--nf-border);border-radius:8px;
    padding:28px;min-height:200px;
  }
  .notify-detail-title{
    font-family:'Cormorant Garamond',serif;font-weight:600;font-size:1.4rem;
    color:var(--nf-text);margin:14px 0 6px;
  }
  .notify-detail-meta{font-family:'IBM Plex Mono',monospace;font-size:0.74rem;color:var(--nf-text-2);margin-bottom:18px;}
  .notify-detail-body{font-size:0.92rem;line-height:1.65;color:var(--nf-text);white-space:pre-wrap;overflow-wrap:anywhere;margin-bottom:18px;}
  .notify-detail-property{font-size:0.8rem;color:var(--nf-text-2);border-top:1px solid var(--nf-border);padding-top:14px;}

  .notify-category-badge{
    display:inline-flex;align-items:center;font-family:'Inter',sans-serif;font-size:0.68rem;
    font-weight:600;letter-spacing:0.03em;text-transform:uppercase;padding:3px 10px;
    border-radius:999px;background:#EFF6F1;color:var(--nf-accent);border:1px solid var(--nf-border);
  }
  .notify-category-badge.is-high{background:var(--nf-warn-bg);color:var(--nf-warn);border-color:#F0DEB8;}
  .notify-category-badge.is-urgent{background:var(--nf-danger-bg);color:var(--nf-danger);border-color:#EFC9C6;}

  /* ---- Sent: cards ---- */
  .notify-sent-list{display:flex;flex-direction:column;gap:12px;}
  .notify-sent-card{background:var(--nf-card);border:1px solid var(--nf-border);border-radius:8px;padding:18px 20px;}
  .notify-sent-card-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px;}
  .notify-sent-card-title{font-size:0.96rem;font-weight:600;color:var(--nf-text);margin:8px 0 6px;}
  .notify-sent-card-meta{font-family:'IBM Plex Mono',monospace;font-size:0.72rem;color:var(--nf-text-2);margin-bottom:12px;}
  .notify-sent-card-badges{display:flex;gap:8px;flex-wrap:wrap;}
  .notify-badge{
    display:inline-flex;align-items:center;font-family:'Inter',sans-serif;font-size:0.72rem;
    font-weight:600;padding:4px 10px;border-radius:999px;border:1px solid transparent;
  }
  .notify-badge.is-success{background:#E6F2EA;color:var(--nf-accent);border-color:#BFE0CC;}
  .notify-badge.is-fail{background:var(--nf-danger-bg);color:var(--nf-danger);border-color:#EFC9C6;}
  .notify-badge.is-pending{background:#F1F1EC;color:var(--nf-text-2);border-color:var(--nf-border);}

  @media(max-width:480px){
    .notify-toolbar{flex-direction:column;align-items:stretch;}
    .notify-toolbar .notify-text-btn{align-self:flex-start;}
  }

  /* Scoped re-skin for generic components reused as-is inside this shell
     (the property/manager/owner picker rows and the property list's own
     Select/Selected control) — same markup and behavior, just recolored
     to the forest-green palette instead of their usual gold/blue. */
  .notify-shell .assign-manager-row{background:#FFFFFF;border-color:var(--nf-border);}
  .notify-shell .assign-manager-row.is-current{border-color:var(--nf-accent);background:#EFF6F1;}
  .notify-shell .assign-manager-row-name{color:var(--nf-text);}
  .notify-shell .assign-manager-row-meta{color:var(--nf-accent);}
  .notify-shell .assign-manager-row-contact{color:var(--nf-text-2);}
  .notify-shell .row-save{border-color:var(--nf-accent);color:var(--nf-accent);border-radius:6px;}
  .notify-shell .row-save:hover{background:var(--nf-accent);color:#FFFFFF;}
  .notify-shell .status-pill.is-completed{border-color:var(--nf-accent);color:var(--nf-accent);}

  /* ---------- Notification bell ---------- */
  .notif-bell{position:relative;display:none;align-items:center;}
  .notif-bell::before{content:'';position:absolute;top:100%;left:0;right:0;height:12px;}
  .notif-bell-btn{
    position:relative;background:none;border:none;padding:8px;cursor:pointer;border-radius:50%;
    display:flex;align-items:center;justify-content:center;color:var(--cream);transition:background .2s;
  }
  .notif-bell-btn:hover{background:var(--panel-2);}
  .notif-bell-btn:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}
  .notif-bell-icon{width:22px;height:22px;}
  .notif-bell-badge{
    position:absolute;top:2px;right:2px;min-width:16px;height:16px;padding:0 4px;
    background:var(--gold-deep);color:#FFFFFF;border-radius:999px;
    font-family:'IBM Plex Mono',monospace;font-size:0.62rem;line-height:16px;text-align:center;
  }
  /* right:0 (not left:0) — the bell sits near the right edge of the
     header, right before the profile chip (#header-profile-menu uses this
     exact same right:0 pattern for the same reason). Anchoring the menu's
     LEFT edge to the bell's left edge let a 380px-wide panel run straight
     off the right side of the viewport on anything but the widest
     screens, clipping every item's text against the window edge — right:0
     grows the panel leftward, into the header's own open space, instead. */
  .notif-bell-menu{
    display:none;position:absolute;top:calc(100% + 12px);right:0;
    width:max-content;min-width:280px;max-width:min(380px, calc(100vw - 40px));
    max-height:calc(100vh - 90px);overflow-y:auto;overflow-x:hidden;
    background:#FFFFFF;border:1px solid var(--hair);box-shadow:0 16px 32px rgba(0,0,0,0.14);
    padding:10px;z-index:9999;
  }
  .notif-bell.open .notif-bell-menu{display:block;}
  .notif-bell-menu-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:4px 6px 10px;}
  .notif-bell-menu-foot{padding:10px 6px 4px;border-top:1px solid var(--hair);margin-top:6px;}
  .notif-bell-menu-action{background:none;border:none;color:var(--gold-deep);font-family:'Inter',sans-serif;font-size:0.78rem;cursor:pointer;padding:4px;}
  .notif-bell-menu-action:hover,.notif-bell-menu-action:focus-visible{text-decoration:underline;}
  .notif-bell-item{
    display:block;width:100%;text-align:left;background:none;border:none;border-radius:6px;
    padding:10px 8px;cursor:pointer;transition:background .2s;
  }
  .notif-bell-item:hover,.notif-bell-item:focus-visible{background:var(--panel-2);}
  .notif-bell-item-title{display:block;font-size:0.86rem;font-weight:500;color:var(--cream);}
  .notif-bell-item.is-unread .notif-bell-item-title{font-weight:600;}
  /* 2-line clamp, not a single-line ellipsis — a one-line cutoff left
     multi-line messages (e.g. a website contact-form lead, which starts
     with a generic sentence before the actual name/email/message) showing
     almost nothing useful in the dropdown; the full text is always one
     click away via openNotifBellItem()'s own detail modal either way. */
  .notif-bell-item-preview{
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
    overflow:hidden;font-size:0.78rem;color:var(--taupe);margin-top:3px;white-space:pre-line;
  }
  .notif-bell-item-time{display:block;font-family:'IBM Plex Mono',monospace;font-size:0.64rem;color:var(--taupe);margin-top:4px;}
  @media(max-width:480px){
    .notif-bell-menu{position:fixed;top:64px;left:12px;right:12px;width:auto;max-width:none;}
  }

  .confirm-manager-columns{display:grid;grid-template-columns:1fr auto 1fr;gap:16px;align-items:center;margin-top:8px;}
  .confirm-manager-col{
    background:var(--panel);border:1px solid var(--hair);border-radius:8px;padding:16px;
    display:flex;flex-direction:column;align-items:center;text-align:center;gap:8px;min-width:0;
  }
  .confirm-manager-arrow{font-size:1.3rem;color:var(--gold-deep);}
  .confirm-manager-photo{width:56px;height:56px;}
  .confirm-manager-name{font-family:'Cormorant Garamond',serif;font-size:1.1rem;color:var(--cream);word-break:break-word;}
  .confirm-manager-field{display:flex;flex-direction:column;gap:2px;font-size:0.82rem;color:var(--cream);width:100%;overflow-wrap:anywhere;}
  .confirm-manager-field .eyebrow{font-size:0.64rem;}
  @media(max-width:560px){
    .confirm-manager-columns{grid-template-columns:1fr;}
    .confirm-manager-arrow{transform:rotate(90deg);justify-self:center;}
  }

  /* PROPERTY PHOTO PICKER (Add Property) — circular camera-icon button,
     replaces the old plain-text Photo URL input entirely. A real <button>
     (not a styled <div>) so it's keyboard-activatable (Enter/Space) with
     no extra wiring, and gets a visible focus ring for free. A successful
     selection previews as the button's own circular background image
     (object URL, revoked on replace/close in employee-dashboard.js) —
     falls back to the plain camera glyph otherwise. */
  .property-photo-upload{display:flex;flex-direction:column;align-items:center;gap:10px;margin-bottom:24px;}
  .property-photo-picker{
    width:96px;height:96px;border-radius:50%;flex-shrink:0;
    background:var(--panel);background-size:cover;background-position:center;
    border:1px dashed var(--hair-strong);color:var(--taupe);cursor:pointer;
    display:flex;align-items:center;justify-content:center;transition:border-color .2s,color .2s;
  }
  .property-photo-picker:hover,.property-photo-picker:focus-visible{border-color:var(--gold-deep);color:var(--gold-deep);outline:none;}
  .property-photo-picker-icon{font-size:1.6rem;line-height:1;}
  .property-photo-picker-label{font-size:0.72rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--taupe);font-family:'IBM Plex Mono',monospace;}

  /* EMPLOYEE PROFILE TAB */
  /* Space between the tab row and the panel content, scoped to the Profile
     panel only (not every .dpanel) so other Employee Portal tabs are
     unaffected. A plain padding-top on the panel itself works regardless
     of how many lines the sibling .dtabs row wraps to, since the two are
     independent siblings in normal flow — the tab row's own position
     never moves. */
  #epanel-profile{padding-top:25px;}
  /* Same technique for the Admin panel: padding-top on the panel itself, not
     margin/positioning on the tab row, so the tab row never moves and the
     gap survives however many lines .dtabs wraps to. */
  #epanel-accounts{padding-top:24px;}

  /* Fixed-size frame matching .am-photo's dimensions exactly — the Edit
     overlay below is positioned absolutely *within* this frame, so it can
     never change the frame's own size (it isn't part of normal flow).
     Shared with the Owner Portal's own Profile tab (#owner-profile-photo-frame)
     at the base 96px size — the Employee identity card's larger 140px
     version is a separate modifier class (.profile-identity-photo-frame,
     below) layered on top, so Owner's own photo frame is never affected. */
  .profile-photo-frame{position:relative;width:96px;height:96px;border-radius:50%;overflow:hidden;}
  .profile-photo-edit-overlay{
    display:none;position:absolute;inset:0;align-items:center;justify-content:center;
    background:rgba(17,17,17,0.55);color:#FFFFFF;border:none;border-radius:50%;
    font-family:'IBM Plex Mono',monospace;font-size:0.72rem;letter-spacing:0.08em;text-transform:uppercase;
    cursor:pointer;
  }
  .profile-photo-frame.editing .profile-photo-edit-overlay{display:flex;}
  .profile-photo-edit-overlay:hover,.profile-photo-edit-overlay:focus-visible{background:rgba(17,17,17,0.72);}

  /* minmax(0,1fr), not a bare 1fr: a bare 1fr track's implicit minimum
     width is auto (the longest unbreakable content, e.g. a phone number
     like "914-462-9090"), which can grow the grid wider than its own
     container and overflow the page on a narrow viewport — minmax(0,1fr)
     lets the track shrink below that and wrap its content instead. */
  .profile-fields{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:24px;}
  .profile-field .eyebrow{margin-bottom:8px;}

  /* PROFILE PAGE — identity card (left) + Personal Information/Account
     Security cards (right). Originated on Employee's own Profile tab;
     Owner's Profile tab (#opanel-profile) now reuses the exact same
     classes (identity card + Security card in the left column via
     .profile-left-col, Contact information + Properties cards in the
     right column) rather than a second, parallel layout system — only
     .profile-properties-card is new, added to the shared card-shell
     selector below. */
  .profile-page-layout{display:grid;grid-template-columns:340px minmax(0,1fr);gap:24px;align-items:start;}
  @media(max-width:860px){ .profile-page-layout{grid-template-columns:1fr;} }

  .profile-identity-card,.profile-info-card,.profile-security-card,.profile-properties-card{
    background:var(--black);border:1px solid var(--hair);border-radius:12px;padding:28px;min-width:0;
  }
  .profile-identity-card{display:flex;flex-direction:column;align-items:center;text-align:center;}
  .profile-left-col,.profile-right-col{display:flex;flex-direction:column;gap:24px;min-width:0;}

  /* Properties card — a compact, clickable list (unlike the full "My
     Properties" page's own bigger cards), each row opening that exact
     same page (openOwnerPropertiesView()) rather than a second,
     parallel property-detail view. */
  .profile-property-row{
    display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;
    background:none;border:1px solid var(--hair);border-radius:8px;padding:13px 14px;
    color:var(--cream);font-size:0.86rem;text-align:left;cursor:pointer;transition:border-color .15s;
  }
  .profile-property-row:hover,.profile-property-row:focus-visible{border-color:var(--gold-deep);}
  .profile-property-row + .profile-property-row{margin-top:8px;}
  .profile-property-row-label{display:flex;align-items:center;gap:10px;min-width:0;overflow-wrap:anywhere;}
  .profile-property-row-chevron{color:var(--taupe);flex-shrink:0;}

  /* Profile completion ring — a plain conic-gradient donut (no SVG/JS
     charting dependency): the outer circle IS the progress arc, an inner
     circle sized/colored to match the card's own background punches the
     "donut hole" through it, with the percentage text layered on top. */
  .profile-completion-row{display:flex;align-items:center;gap:16px;border-top:1px solid var(--hair);margin-top:18px;padding-top:18px;}
  .profile-completion-ring{
    position:relative;width:52px;height:52px;border-radius:50%;flex-shrink:0;
    background:conic-gradient(var(--gold-deep) calc(var(--pct, 0) * 1%), var(--hair) 0);
  }
  .profile-completion-ring-inner{
    position:absolute;inset:6px;border-radius:50%;background:var(--black);
    display:flex;align-items:center;justify-content:center;
    font-family:'IBM Plex Mono',monospace;font-size:0.68rem;color:var(--cream);
  }
  .profile-completion-row p{margin:2px 0 0;color:var(--taupe);font-size:0.78rem;line-height:1.5;text-align:left;}
  .profile-completion-row strong{color:var(--cream);font-size:0.9rem;}
  .profile-info-card h3,.profile-security-card h3{font-family:'Cormorant Garamond',serif;font-size:1.25rem;color:var(--cream);margin-bottom:20px;}

  /* Card header with an inline pencil-icon edit trigger (Contact
     Information/Mailing Address on the redesigned Owner Profile page) —
     a second, equally-valid way into the exact same enterOwnerProfileEditMode()
     the card's own bottom "Edit Profile" button already calls, never a
     separate/parallel edit mode of its own. */
  .profile-card-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:20px;}
  .profile-card-head h3{margin-bottom:0;}
  .profile-mailing-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:24px 0 4px;}
  .profile-mailing-head h4{font-family:'Cormorant Garamond',serif;font-size:1.05rem;color:var(--cream);margin:0;}
  .profile-edit-icon-btn{
    width:30px;height:30px;border-radius:50%;flex-shrink:0;padding:0;
    display:flex;align-items:center;justify-content:center;
    border:1px solid var(--hair-strong);background:var(--panel);color:var(--taupe);cursor:pointer;transition:border-color .15s,color .15s;
  }
  .profile-edit-icon-btn svg{width:14px;height:14px;}
  .profile-edit-icon-btn:hover,.profile-edit-icon-btn:focus-visible{border-color:var(--gold);color:var(--gold-deep);}

  /* Label-left/value-right row, used inside the Contact Information/
     Mailing Address/Security/Property cards (as opposed to .profile-field's
     own label-above-value stacking, used by the denser Property/Unit Details
     edit grids) — reuses the exact same .eyebrow/.profile-value/.profile-input
     components, just laid out horizontally with a hairline divider between
     rows instead of a grid of stacked cells. */
  .profile-detail-row{display:flex;justify-content:space-between;align-items:baseline;gap:16px;padding:14px 0;border-bottom:1px solid var(--hair);}
  .profile-detail-row:last-child{border-bottom:none;}
  .profile-detail-row .eyebrow{flex-shrink:0;}
  .profile-detail-row .profile-value{padding:0;text-align:right;flex:1 1 auto;min-width:0;}
  .profile-detail-row .profile-input{max-width:260px;}
  .profile-detail-row textarea.profile-input{min-height:52px;resize:vertical;text-align:left;}

  .profile-security-head{display:flex;align-items:center;gap:10px;margin-bottom:20px;}
  .profile-security-head h3{margin-bottom:0;}
  .profile-security-head svg{width:18px;height:18px;color:var(--gold-deep);flex-shrink:0;}

  /* Larger avatar for the identity card specifically — layered on top of
     .profile-photo-frame's own base 96px (see that rule's own comment). */
  .profile-identity-photo-frame{width:140px;height:140px;margin-bottom:16px;}
  .profile-identity-photo-frame .am-photo{width:140px;height:140px;}

  /* Initials fallback for an identity-card avatar with no photo —
     Tenant has no photo column/upload path at all (always shows this), and
     Owner falls back to it exactly when no photo is on file, mirroring
     .header-profile-avatar's own initials fallback but at identity-card
     size. Applied as an added class (never redefines base .am-photo),
     matching .am-photo's own background/border so it reads as the same
     component, just filled in. */
  .am-photo.am-photo-initials{
    display:flex;align-items:center;justify-content:center;
    background:var(--gold-deep);color:#FFFFFF;
    font-family:'IBM Plex Mono',monospace;letter-spacing:0.02em;
  }
  .profile-identity-photo-frame .am-photo-initials{font-size:2.4rem;}

  .profile-account-type-badge{
    display:inline-flex;align-items:center;gap:6px;background:var(--panel-2);border:1px solid var(--hair-strong);
    color:var(--gold-deep);padding:6px 14px;border-radius:999px;font-size:0.78rem;margin-bottom:14px;white-space:nowrap;
  }
  .profile-account-type-badge svg{width:14px;height:14px;flex-shrink:0;}
  .profile-identity-name{font-family:'Cormorant Garamond',serif;font-weight:600;font-size:1.4rem;color:var(--cream);margin-bottom:10px;overflow-wrap:anywhere;}
  .profile-identity-divider{width:100%;height:1px;background:var(--hair);margin:20px 0;}
  .profile-identity-contact{display:flex;flex-direction:column;gap:18px;width:100%;text-align:left;}
  .profile-identity-contact-row{display:flex;align-items:center;gap:14px;min-width:0;}
  .profile-identity-contact-row .eyebrow{margin-bottom:2px;}
  .profile-identity-contact-value{font-size:0.9rem;color:var(--cream);overflow-wrap:anywhere;}

  .profile-security-card p{color:var(--taupe);font-size:0.86rem;line-height:1.6;margin-bottom:18px;}
  .profile-security-note{
    display:flex;align-items:center;gap:10px;background:var(--panel);border:1px solid var(--hair);
    padding:14px 16px;border-radius:8px;font-size:0.85rem;color:var(--taupe);margin-bottom:20px;
  }
  .profile-security-note svg{width:16px;height:16px;flex-shrink:0;color:var(--taupe);}

  /* .profile-value (view) and .profile-input (edit) share identical
     padding, border-width, and font-size so swapping which one is
     display:none/block for a field never changes that field's box size —
     the border is just transparent in view mode instead of absent, which
     reserves the same space without looking like a boxed/disabled input. */
  .profile-value{
    font-size:0.94rem;color:var(--cream);
    padding:13px 14px;border:1px solid transparent;border-radius:1px;
    min-height:1.3em;
    /* A long unbreakable value (an email address, most often — see
       #profile-email-view/#owner-profile-email-view) must never overflow
       past its own field/column — every base .profile-value now wraps
       instead of clipping, the same treatment .profile-identity-contact-value/
       #property-manager-email/.lease-detail-field .profile-value already
       carry individually. This is the base rule every one of those
       overrides was layered on top of, so making it the default here
       closes the gap for every OTHER .profile-value field that never got
       its own override (nothing to clip, nothing left silently at risk). */
    overflow-wrap:anywhere;
  }
  .profile-input{
    width:100%;background:var(--panel);border:1px solid var(--hair);color:var(--cream);
    padding:13px 14px;font-family:'Inter',sans-serif;font-size:0.94rem;border-radius:1px;
  }
  .profile-input:focus{outline:none;border-color:var(--gold);}
  .profile-actions{display:flex;gap:12px;flex-wrap:wrap;margin-top:30px;align-items:center;}

  .form-inline{background:var(--panel);padding:24px;margin-bottom:1px;display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:16px;align-items:end;}
  .form-inline .field{margin-bottom:0;}
  .form-inline .field input,.form-inline .field select,.form-inline .field textarea{padding:11px 12px;font-size:0.86rem;}
  /* The due-date help text makes its grid cell taller. Align both storage
     fields at the top so their labels and inputs stay on the same row. */
  .adl-storage-rent-fields{grid-template-columns:repeat(2,minmax(0,1fr));align-items:start;}
  select{width:100%;background:var(--panel);border:1px solid var(--hair);color:var(--cream);padding:13px 14px;font-family:'Inter',sans-serif;font-size:0.94rem;}
  select:focus{outline:none;border-color:var(--gold);}
  .row-save{background:transparent;border:1px solid var(--gold-deep);color:var(--gold-deep);padding:10px 16px;font-size:0.72rem;letter-spacing:0.06em;text-transform:uppercase;cursor:pointer;white-space:nowrap;}
  .row-save:hover{background:var(--gold-deep);color:#FFFFFF;}

  /* Small circular "x" — Employee Accounts row delete. Muted by default,
     only reads as destructive on hover/focus so the table doesn't look
     alarming at rest. */
  .row-delete-btn{
    width:28px;height:28px;border-radius:50%;flex-shrink:0;
    background:transparent;border:1px solid var(--hair-strong);color:var(--taupe);
    font-size:1rem;line-height:1;cursor:pointer;
    display:inline-flex;align-items:center;justify-content:center;
    transition:border-color .2s,color .2s,background .2s;
  }
  .row-delete-btn:hover,.row-delete-btn:focus-visible{
    border-color:#B3261E;color:#B3261E;background:rgba(179,38,30,0.08);outline:none;
  }
  .row-delete-btn:disabled{opacity:0.45;cursor:not-allowed;}
  .resnotes{width:100%;background:var(--black);border:1px solid var(--hair);color:var(--cream);padding:8px 10px;font-size:0.84rem;font-family:'Inter',sans-serif;min-height:44px;}
  .banner{background:var(--panel);border:1px solid var(--hair-strong);padding:14px 18px;font-size:0.85rem;color:var(--taupe);margin-bottom:24px;}
  .banner strong{color:var(--gold-deep);}
  .empty-row{padding:26px 20px;color:var(--taupe);font-size:0.86rem;background:var(--panel);text-align:center;}
  .loading{padding:40px 0;text-align:center;color:var(--taupe);font-family:'IBM Plex Mono',monospace;font-size:0.8rem;letter-spacing:0.06em;text-transform:uppercase;}
  .status-select{background:var(--black);border:1px solid var(--hair);color:var(--gold-deep);padding:6px 8px;font-family:'IBM Plex Mono',monospace;font-size:0.72rem;text-transform:uppercase;}
  .req-desc{max-width:260px;font-size:0.85rem;color:var(--cream);line-height:1.5;}
  .unit-tag{font-family:'IBM Plex Mono',monospace;color:var(--gold-deep);font-size:0.8rem;}

  footer{border-top:1px solid var(--hair);margin-top:40px;padding:40px 28px;}
  .footer-inner{max-width:1180px;margin:0 auto;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:16px;}
  .footer-inner .eyebrow{color:var(--taupe);}

  @media(max-width:860px){
    .ledger{grid-template-columns:1fr 1fr;}
    .ledger div:nth-child(2){border-right:none;}
    .grid-3{grid-template-columns:1fr;}
    .about-wrap,.contact-wrap{grid-template-columns:1fr;gap:36px;padding:50px 0;}
    .lineitem{grid-template-columns:1fr;gap:6px;}
    .dash-cards{grid-template-columns:1fr;}
    table{font-size:0.8rem;}
  }
  @media(prefers-reduced-motion:reduce){
    .navlinks{transition:none;}
    section.page{animation:none;}
    #invite-sent-toast.open .invite-sent-toast-icon,#invite-sent-toast.open .invite-sent-toast-check{animation:none;}
    .invite-sent-toast-check{stroke-dashoffset:0;}
  }

  /* MAINTENANCE — tenant/owner/employee tabs share this one set of
     classes; role differences (edit controls, internal notes, filters)
     are handled by which markup each role's JS actually builds inside
     these containers, not by separate per-role CSS. */
  .maint-layout{
    display:grid;grid-template-columns:minmax(0,1fr) minmax(340px,420px);gap:24px;
    background:var(--panel);border:1px solid var(--hair);border-radius:12px;padding:20px;
  }
  .maint-list-col-wide{grid-column:1;}
  @media(max-width:960px){ .maint-layout{grid-template-columns:1fr;} }
  .maint-list-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;}
  .maint-list-tabs{display:flex;gap:6px;}
  .maint-list-tab{
    background:transparent;border:1px solid var(--hair-strong);color:var(--taupe);
    padding:6px 14px;border-radius:20px;font-size:0.78rem;letter-spacing:0.02em;cursor:pointer;
  }
  .maint-list-tab.active{background:var(--gold-deep);border-color:var(--gold-deep);color:#FFFFFF;}
  .maint-row{
    display:flex;align-items:center;justify-content:space-between;gap:12px;
    padding:14px 16px;border:1px solid var(--hair);border-radius:8px;margin-bottom:10px;
    cursor:pointer;background:var(--black);transition:border-color .15s,background .15s;
  }
  .maint-row:hover,.maint-row:focus-visible{border-color:var(--gold-deep);}
  .maint-row.selected{border-color:var(--gold-deep);background:var(--panel-2);}
  /* Explicit resets (not just "no other rule sets this") — the list
     container starts life as <div class="loading"> in the static HTML and
     some render paths never strip that class off once real rows replace
     the placeholder, so without these every row would silently inherit
     .loading's uppercase/mono styling instead of reading as plain text. */
  .maint-row-code{font-family:'IBM Plex Mono',monospace;font-size:0.72rem;letter-spacing:0.04em;text-transform:uppercase;color:var(--taupe);}
  .maint-row-title{font-family:'Inter',sans-serif;font-weight:600;font-size:0.95rem;text-transform:none;color:var(--cream);margin-top:2px;}
  .maint-row-sub{font-family:'Inter',sans-serif;font-size:0.8rem;text-transform:none;color:var(--taupe);margin-top:4px;}
  .maint-row-meta{text-align:right;font-size:0.78rem;color:var(--taupe);white-space:nowrap;}

  .maint-detail-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:6px;}
  .maint-detail-code{font-family:'IBM Plex Mono',monospace;font-size:0.72rem;letter-spacing:0.04em;text-transform:uppercase;color:var(--taupe);}
  .maint-detail-title{font-family:'Cormorant Garamond',serif;text-transform:none;font-size:1.5rem;margin-top:4px;color:var(--cream);}
  .maint-detail-sub{font-family:'Inter',sans-serif;text-transform:none;color:var(--taupe);font-size:0.86rem;margin-top:4px;}

  .maint-stepper{display:flex;align-items:center;margin:22px 0;}
  .maint-step{display:flex;flex-direction:column;align-items:center;gap:6px;flex:1;text-align:center;}
  .maint-step-dot{width:22px;height:22px;border-radius:50%;border:2px solid var(--hair-strong);display:flex;align-items:center;justify-content:center;background:var(--black);color:var(--taupe);font-size:0.7rem;}
  .maint-step.complete .maint-step-dot{background:var(--gold-deep);border-color:var(--gold-deep);color:#FFFFFF;}
  .maint-step.current .maint-step-dot{border-color:var(--gold-deep);color:var(--gold-deep);}
  .maint-step-label{font-family:'Inter',sans-serif;text-transform:none;font-size:0.7rem;color:var(--taupe);}
  .maint-step.complete .maint-step-label,.maint-step.current .maint-step-label{color:var(--cream);}
  .maint-step-line{flex:1;height:2px;background:var(--hair-strong);margin-bottom:20px;}
  .maint-step-line.complete{background:var(--gold-deep);}

  .maint-detail-section{margin-top:20px;}
  .maint-detail-section .eyebrow{margin-bottom:8px;}
  .maint-detail-desc{font-family:'Inter',sans-serif;text-transform:none;font-size:0.9rem;line-height:1.6;color:var(--cream);}
  .maint-detail-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px 24px;margin-top:14px;}
  .maint-detail-field{font-family:'Inter',sans-serif;text-transform:none;font-size:0.84rem;color:var(--cream);}
  /* Read-only stand-in for the Status/Priority <select> once a request is
     terminal (cancelled/closed) — a disabled <select> can only preselect
     one of its own <option>s, and "cancelled" isn't a status a request can
     be manually set to, so a disabled select had no way to show it and
     silently fell back to whichever option sorted first. Plain text sidesteps
     that entirely instead of adding a fake "Cancelled" option nothing can
     ever select. */
  .maint-detail-field-value{font-family:'Inter',sans-serif;font-size:0.86rem;color:var(--cream);padding:11px 0;}
  .maint-detail-field .eyebrow{margin-bottom:4px;}
  .maint-photo-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(90px,1fr));gap:8px;}
  .maint-photo-grid img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:8px;border:1px solid var(--hair);cursor:pointer;}

  /* Photo (left) + description/facts (right) split for the tenant detail
     panel, matching the mockup's own layout — a fixed-width photo column
     so it never crowds out the fact rows next to it. */
  .maint-detail-top-grid{display:grid;grid-template-columns:120px 1fr;gap:16px;margin-top:18px;}
  .maint-detail-photo-col img{border-radius:8px;}
  .maint-detail-photo-empty{
    width:100%;aspect-ratio:1;border-radius:8px;border:1px dashed var(--hair-strong);
    display:flex;align-items:center;justify-content:center;color:var(--taupe);font-size:0.72rem;text-align:center;
  }
  @media(max-width:600px){ .maint-detail-top-grid{grid-template-columns:1fr;} }

  /* Boxed "Latest update" callout — a distinct pale panel (vs. the plain
     text every other .maint-detail-section uses) so the most recent
     message reads as a highlighted summary, not just another paragraph. */
  .maint-callout{
    margin-top:20px;padding:14px 16px;border-radius:10px;
    background:var(--panel-2);border:1px solid var(--hair);
  }
  .maint-callout .eyebrow{margin-bottom:6px;}
  .maint-callout-body{font-family:'Inter',sans-serif;font-size:0.86rem;line-height:1.55;color:var(--cream);}

  .maint-tabs{display:flex;gap:4px;border-bottom:1px solid var(--hair);margin:20px 0 14px;}
  .maint-tab{background:transparent;border:none;border-bottom:2px solid transparent;color:var(--taupe);padding:8px 4px;margin-right:18px;font-size:0.82rem;cursor:pointer;}
  .maint-tab.active{color:var(--cream);border-bottom-color:var(--gold-deep);}
  /* Chat-window styling for the maintenance Conversation/Internal notes
     thread — used by both the employee's Conversation modal
     (maintLogCommentRowHtml(), employee-dashboard.js) and the tenant's own
     inline Conversation section (renderTenantMaintenanceDetail(),
     tenant-dashboard.js). .is-own bubbles (the reader's own "side" — every
     staff author from an employee's view, or the tenant's own messages
     from their view) sit right-aligned in the accent color; .is-other
     sits left-aligned and neutral, mirroring a normal text-message thread. */
  .maint-chat-row{display:flex;margin-bottom:12px;}
  .maint-chat-row:last-child{margin-bottom:0;}
  .maint-chat-row.is-own{justify-content:flex-end;}
  .maint-chat-row.is-other{justify-content:flex-start;}
  .maint-chat-bubble{max-width:78%;padding:10px 14px;border-radius:14px;background:var(--panel);border:1px solid var(--hair);}
  .maint-chat-row.is-own .maint-chat-bubble{background:var(--gold-deep);border-color:var(--gold-deep);color:#fff;border-bottom-right-radius:4px;}
  .maint-chat-row.is-own .maint-chat-bubble .maint-chat-meta{color:rgba(255,255,255,0.78);}
  .maint-chat-row.is-other .maint-chat-bubble{border-bottom-left-radius:4px;}
  .maint-chat-bubble.is-internal{background:rgba(180,83,9,0.12);border-color:rgba(180,83,9,0.35);}
  .maint-chat-meta{font-family:'IBM Plex Mono',monospace;text-transform:none;font-size:0.66rem;letter-spacing:0.02em;color:var(--taupe);margin-bottom:4px;}
  .maint-chat-body{font-family:'Inter',sans-serif;text-transform:none;font-size:0.86rem;line-height:1.5;color:var(--cream);white-space:pre-wrap;overflow-wrap:anywhere;}
  .maint-chat-row.is-own .maint-chat-body{color:#fff;}
  #maint-log-modal-body{max-height:360px;overflow-y:auto;margin:14px 0;padding-right:4px;}
  #tenant-maint-conversation{max-height:320px;overflow-y:auto;padding-right:4px;margin-top:8px;}
  .maint-reply-row{display:flex;gap:8px;margin-top:12px;}
  .maint-reply-row textarea{flex:1;min-height:56px;}
  .maint-internal-toggle{display:flex;align-items:center;gap:6px;font-size:0.78rem;color:var(--taupe);margin-top:8px;}

  /* Compact icon + label + value row (maintFactRowHtml(), tenant-dashboard.js) —
     "📅 Upcoming visit / Sep 15 · 9-11 AM" style facts in the tenant/owner
     detail panels, replacing the old plain eyebrow+value block. */
  .maint-fact-row{display:flex;align-items:flex-start;gap:8px;margin-top:12px;}
  .maint-fact-row svg{width:15px;height:15px;flex-shrink:0;color:var(--gold-deep);margin-top:2px;}
  .maint-fact-row-label{font-family:'IBM Plex Mono',monospace;font-size:0.68rem;letter-spacing:0.06em;text-transform:uppercase;color:var(--taupe);}
  .maint-fact-row-value{font-family:'Inter',sans-serif;text-transform:none;font-size:0.86rem;color:var(--cream);margin-top:2px;}

  /* Employee workspace's Assign to / Status / Priority — one row, three
     equal columns, committed together via a single "Save changes" button
     rather than each field auto-saving on its own change (see
     submitAdminMaintenanceManage() in employee-dashboard.js). */
  .maint-manage-row{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;margin-top:14px;}
  .maint-save-btn{width:100%;justify-content:center;margin-top:14px;}
  @media(max-width:600px){ .maint-manage-row{grid-template-columns:1fr;} }

  /* Status/Priority (admin) and Update entry permission (tenant) are the
     only plain native <select> elements in either detail panel — every
     other control here (.field input/textarea, .btn, .maint-select) has
     its own styling, but a bare <select> was left to render with the
     browser's own default chrome (flat, square-cornered, mismatched font)
     right next to those, reading as a dated, un-styled control. Matches
     .field input's own look (same background/border/radius/font) with a
     custom chevron replacing the native arrow appearance() hides. */
  #admin-maintenance-detail select,
  #tenant-maintenance-detail select{
    appearance:none;-webkit-appearance:none;-moz-appearance:none;
    width:100%;background-color:var(--panel);color:var(--cream);
    border:1px solid var(--hair);border-radius:1px;
    padding:14px 36px 14px 16px;font-family:'Inter',sans-serif;font-size:0.96rem;line-height:1.4;
    cursor:pointer;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23444444' d='M4 6l4 4 4-4z'/%3E%3C/svg%3E");
    background-repeat:no-repeat;background-position:right 14px center;background-size:11px;
  }
  #admin-maintenance-detail select:focus,
  #tenant-maintenance-detail select:focus{outline:none;border-color:var(--gold);}
  #admin-maintenance-detail select:disabled,
  #tenant-maintenance-detail select:disabled{background-color:var(--panel-2);color:var(--taupe);cursor:not-allowed;}

  /* "Staff only" badge next to an internal note, replacing the old plain
     tinted-background treatment for is-internal. */
  .maint-staff-only-badge{
    display:inline-block;margin-left:8px;padding:2px 8px;border-radius:999px;
    font-family:'IBM Plex Mono',monospace;font-size:0.62rem;letter-spacing:0.04em;text-transform:uppercase;
    background:var(--panel-2);color:var(--taupe);vertical-align:middle;
  }

  /* Employee's Maintenance requests table — a trailing chevron affordance
     and a left accent bar on the selected row, matching the mockup;
     admin-fixed-table itself has no selected-row styling at all
     elsewhere, so this is scoped to maint-req-table specifically rather
     than changing every other admin table's established look. The accent
     bar lives on the first cell, not the <tr> itself — a border-collapse
     table can't reliably render a border set on the row element. */
  .maint-req-table tbody tr{transition:background .15s;}
  .maint-req-table tbody tr:hover{background:var(--panel-2);}
  .maint-req-table tbody tr.selected{background:var(--panel-2);}
  .maint-req-table tbody tr:focus-visible{outline:2px solid var(--gold-deep);outline-offset:-2px;}
  .maint-req-table tbody td:first-child{border-left:3px solid transparent;}
  .maint-req-table tbody tr.selected td:first-child{border-left-color:var(--gold-deep);}
  .maint-row-chevron{color:var(--taupe);font-size:1.2rem;text-align:right;width:1%;}
  .maint-row-actions{text-align:right;width:1%;white-space:nowrap;}

  .maint-assign-row{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:14px;}
  /* A small fixed-size icon + one line of text (e.g. "Sep 15 · 9-11 AM") —
     svgIcon() returns a bare, unconstrained <svg> meant for a 48px stat
     circle elsewhere, so without an explicit cap here it renders at its
     intrinsic size (100+px) instead of a small inline glyph. */
  .maint-visit-row{display:flex;align-items:center;gap:8px;font-family:'Inter',sans-serif;text-transform:none;font-size:0.86rem;color:var(--cream);}
  .maint-visit-row svg{width:16px;height:16px;flex-shrink:0;color:var(--gold-deep);}
  .maint-actions-row{display:flex;gap:10px;margin-top:18px;flex-wrap:wrap;}

  /* Employee maintenance reference layout. Keep this scoped so tenant/owner
     maintenance screens retain their existing visual language. */
  #epanel-maintenance.employee-maint-panel,
  #epanel-maintenance{color:#202124;}
  #epanel-maintenance .employee-maint-heading{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-bottom:18px;}
  #epanel-maintenance .employee-maint-heading h2{font-family:'Cormorant Garamond',serif;font-size:2.35rem;line-height:1;margin:0;color:#151515;}
  #epanel-maintenance .employee-maint-heading p{margin:4px 0 0;color:#454545;font-family:Inter,sans-serif;font-size:.98rem;}
  #epanel-maintenance .employee-maint-create{padding:11px 18px;white-space:nowrap;}
  #epanel-maintenance .employee-maint-filters{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 12px;}
  #epanel-maintenance .maint-filter-control{position:relative;}
  #epanel-maintenance .maint-filter-button{min-width:190px;max-width:260px;text-align:left;background:#fff;border:1px solid #c9cdd0;color:#30353a;border-radius:6px;padding:9px 12px;cursor:pointer;font-family:Inter,sans-serif;font-size:.82rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  /* Property's own button runs wider than the rest — a chosen property's
     name/address is typically the longest label any of these filters
     ever shows, and was getting clipped at the shared 190px width. */
  #epanel-maintenance [data-filter-control="property"] .maint-filter-button{min-width:260px;max-width:340px;}
  #epanel-maintenance .maint-filter-menu{display:none;position:absolute;z-index:20;top:calc(100% + 4px);left:0;min-width:100%;max-height:260px;overflow:auto;background:#fff;border:1px solid #d5d9db;border-radius:6px;box-shadow:0 8px 22px rgba(0,0,0,.12);padding:4px;}
  #epanel-maintenance .maint-filter-control.open .maint-filter-menu{display:block;}
  #epanel-maintenance .maint-filter-menu button{display:block;width:100%;border:0;background:transparent;text-align:left;padding:8px 10px;border-radius:4px;color:#30353a;cursor:pointer;font-size:.8rem;white-space:nowrap;}
  #epanel-maintenance .maint-filter-menu button:hover{background:#eaf6f0;color:#0e7c4a;}
  /* Multi-select filter menus (Status, Priority) — a checkbox list plus a
     Select all/Clear row, rather than the single-select ones' plain
     option buttons; staying open across several toggles instead of
     closing on the first pick (see the outside-click handler in
     employee-dashboard.js that closes it instead). */
  #epanel-maintenance .maint-filter-menu-actions{display:flex;gap:4px;padding:2px 2px 6px;margin-bottom:4px;border-bottom:1px solid #e5e7e8;}
  #epanel-maintenance .maint-filter-menu-actions button{width:auto;flex:1;text-align:center;font-size:.72rem;letter-spacing:.02em;text-transform:uppercase;color:#0e7c4a;}
  #epanel-maintenance .maint-filter-menu-option{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:4px;cursor:pointer;font-size:.8rem;color:#30353a;white-space:nowrap;}
  #epanel-maintenance .maint-filter-menu-option:hover{background:#eaf6f0;color:#0e7c4a;}
  #epanel-maintenance .maint-filter-menu-option input[type="checkbox"]{margin:0;flex-shrink:0;}
  #epanel-maintenance .employee-maint-filters .admin-search-input{margin-left:auto;max-width:190px;}
  #epanel-maintenance .admin-stat-cards{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-bottom:12px;}
  #epanel-maintenance .admin-stat-card{background:#fff;border:1px solid #e4e5e6;border-radius:8px;padding:14px 16px;box-shadow:0 1px 2px rgba(0,0,0,.03);}
  #epanel-maintenance .admin-stat-icon{width:42px;height:42px;background:#e6f3ed;color:#0e7c4a;}
  #epanel-maintenance .admin-stat-number{font-family:Inter,sans-serif;font-size:1.7rem;color:#111;}
  #epanel-maintenance .admin-stat-label{color:#42464a;font-size:.82rem;}
  #epanel-maintenance .employee-maint-layout{grid-template-columns:minmax(0,1.35fr) minmax(320px,.75fr);gap:12px;background:transparent;border:0;padding:0;}
  #epanel-maintenance .maint-list-col,#epanel-maintenance .maint-detail-col{background:#fff;border:1px solid #e2e4e5;border-radius:8px;padding:10px 12px;box-shadow:0 1px 2px rgba(0,0,0,.03);}
  #epanel-maintenance .employee-maint-list-title{font-family:'Cormorant Garamond',serif;font-size:1.35rem;font-weight:600;color:#222;margin:0 0 8px 4px;}
  #epanel-maintenance .admin-table-wrap{border:1px solid #e1e4e5;border-radius:7px;overflow:hidden;}
  #epanel-maintenance .maint-req-table{min-width:0;background:#fff;}
  #epanel-maintenance .maint-req-table th{background:#f6f7f7;color:#394047;font-size:.72rem;padding:10px 12px;}
  #epanel-maintenance .maint-req-table td{color:#3f464c;border-bottom:1px solid #e5e7e8;padding:12px;font-size:.82rem;}
  #epanel-maintenance .maint-req-table tbody tr.selected{background:#eaf6f0;}
  #epanel-maintenance .maint-req-table tbody td:first-child{border-left-color:transparent;}
  #epanel-maintenance .maint-req-table tbody tr.selected td:first-child{border-left-color:#17804f;}
  #epanel-maintenance .employee-maint-row-title{color:#151515;font-size:.85rem;}
  #epanel-maintenance .maint-detail-title{color:#111;font-size:1.4rem;}
  #epanel-maintenance .maint-detail-code,#epanel-maintenance .maint-detail-sub,#epanel-maintenance .maint-detail-field{color:#394047;}
  #epanel-maintenance .maint-detail-col{min-height:276px;}
  @media(max-width:700px){#epanel-maintenance .admin-stat-cards{grid-template-columns:1fr;}#epanel-maintenance .employee-maint-heading{align-items:flex-start;flex-direction:column;}#epanel-maintenance .maint-filter-button{min-width:160px;}#epanel-maintenance .employee-maint-filters .admin-search-input{margin-left:0;max-width:none;width:100%;} }

  /* Property-owner maintenance reference layout. Owners intentionally have
     no property filter here: their existing owner-scoped view already
     represents the properties available to that account. */
  #opanel-maintenance.owner-maintenance-reference{color:#202124;}
  #opanel-maintenance.owner-maintenance-reference .lease-page-heading{margin-bottom:18px;}
  #opanel-maintenance.owner-maintenance-reference .lease-page-heading h2{font-family:'Cormorant Garamond',serif;font-size:2.35rem;line-height:1;margin:0;color:#151515;}
  #opanel-maintenance.owner-maintenance-reference .lease-page-heading p{margin:4px 0 0;color:#454545;font-family:Inter,sans-serif;font-size:.98rem;}
  #opanel-maintenance.owner-maintenance-reference .admin-stat-cards{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-bottom:12px;}
  #opanel-maintenance.owner-maintenance-reference .admin-stat-card{background:#fff;border:1px solid #e4e5e6;border-radius:8px;padding:14px 16px;box-shadow:0 1px 2px rgba(0,0,0,.03);}
  #opanel-maintenance.owner-maintenance-reference .admin-stat-icon{width:42px;height:42px;background:#e6f3ed;color:#0e7c4a;}
  #opanel-maintenance.owner-maintenance-reference .admin-stat-number{font-family:Inter,sans-serif;font-size:1.7rem;color:#111;}
  #opanel-maintenance.owner-maintenance-reference .admin-stat-label{color:#42464a;font-size:.82rem;}
  #opanel-maintenance.owner-maintenance-reference .maint-layout{grid-template-columns:minmax(0,1.35fr) minmax(320px,.75fr);gap:12px;background:transparent;border:0;padding:0;}
  #opanel-maintenance.owner-maintenance-reference .maint-list-col,#opanel-maintenance.owner-maintenance-reference .maint-detail-col{background:#fff;border:1px solid #e2e4e5;border-radius:8px;padding:10px 12px;box-shadow:0 1px 2px rgba(0,0,0,.03);}
  #opanel-maintenance.owner-maintenance-reference .eyebrow{font-family:'Cormorant Garamond',serif;text-transform:none;letter-spacing:0;font-size:1.35rem;font-weight:600;color:#222;margin:0 0 8px 4px;}
  #opanel-maintenance.owner-maintenance-reference .admin-table-wrap{border:1px solid #e1e4e5;border-radius:7px;overflow:hidden;}
  #opanel-maintenance.owner-maintenance-reference .admin-fixed-table{min-width:0;background:#fff;}
  #opanel-maintenance.owner-maintenance-reference .admin-fixed-table th{background:#f6f7f7;color:#394047;font-size:.72rem;padding:10px 12px;}
  #opanel-maintenance.owner-maintenance-reference .admin-fixed-table td{color:#3f464c;border-bottom:1px solid #e5e7e8;padding:12px;font-size:.82rem;}
  #opanel-maintenance.owner-maintenance-reference .admin-fixed-table tbody tr.selected{background:#eaf6f0;}
  #opanel-maintenance.owner-maintenance-reference .admin-fixed-table tbody td:first-child{border-left:3px solid transparent;}
  #opanel-maintenance.owner-maintenance-reference .admin-fixed-table tbody tr.selected td:first-child{border-left-color:#17804f;}
  #opanel-maintenance.owner-maintenance-reference .maint-detail-title{color:#111;font-size:1.4rem;}
  #opanel-maintenance.owner-maintenance-reference .maint-detail-sub,#opanel-maintenance.owner-maintenance-reference .maint-detail-field{color:#394047;}
  #opanel-maintenance.owner-maintenance-reference .maint-detail-col{min-height:276px;}
  @media(max-width:700px){#opanel-maintenance.owner-maintenance-reference .admin-stat-cards{grid-template-columns:1fr;}}
  #opanel-maintenance .owner-maintenance-filters{display:flex;gap:10px;flex-wrap:wrap;margin:0 0 12px;}
  #opanel-maintenance .owner-maint-filter{position:relative;}
  #opanel-maintenance .owner-maint-filter>button{min-width:190px;text-align:left;background:#fff;border:1px solid #c9cdd0;color:#30353a;border-radius:6px;padding:9px 12px;cursor:pointer;font-size:.82rem;}
  #opanel-maintenance .owner-maint-filter-menu{display:none;position:absolute;z-index:20;top:calc(100% + 4px);left:0;min-width:100%;background:#fff;border:1px solid #d5d9db;border-radius:6px;box-shadow:0 8px 22px rgba(0,0,0,.12);padding:4px;}
  #opanel-maintenance .owner-maint-filter.open .owner-maint-filter-menu{display:block;}
  #opanel-maintenance .owner-maint-filter-menu button{display:block;width:100%;border:0;background:transparent;text-align:left;padding:8px 10px;border-radius:4px;color:#30353a;cursor:pointer;font-size:.8rem;white-space:nowrap;}
  #opanel-maintenance .owner-maint-filter-menu button:hover{background:#eaf6f0;color:#0e7c4a;}
  #opanel-maintenance .owner-maint-filter-menu{max-height:260px;overflow:auto;}
  #opanel-maintenance .owner-maint-filter-menu-actions{display:flex;gap:4px;padding:2px 2px 6px;margin-bottom:4px;border-bottom:1px solid #e5e7e8;}
  #opanel-maintenance .owner-maint-filter-menu-actions button{width:auto;flex:1;text-align:center;font-size:.72rem;letter-spacing:.02em;text-transform:uppercase;color:#0e7c4a;}
  #opanel-maintenance .owner-maint-filter-option{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:4px;cursor:pointer;font-size:.8rem;color:#30353a;white-space:nowrap;}
  #opanel-maintenance .owner-maint-filter-option:hover{background:#eaf6f0;color:#0e7c4a;}
  #opanel-maintenance .owner-maint-filter-option input[type="checkbox"]{margin:0;flex-shrink:0;}

  /* Owner Billing → Tenant Billing → Status filter: same button+checkbox-
     popup pattern as the Maintenance workspace's Status/Priority filters
     (#epanel-maintenance .maint-filter-menu above) instead of a plain
     <select>, with Select all/Clear since more than one status can be
     picked at once. */
  #obpanel-tenant .billing-filter-control{position:relative;}
  #obpanel-tenant .billing-filter-button{min-width:170px;text-align:left;background:#fff;border:1px solid #c9cdd0;color:#30353a;border-radius:6px;padding:9px 12px;cursor:pointer;font-family:Inter,sans-serif;font-size:.82rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  #obpanel-tenant .billing-filter-menu{display:none;position:absolute;z-index:20;top:calc(100% + 4px);left:0;min-width:100%;max-height:260px;overflow:auto;background:#fff;border:1px solid #d5d9db;border-radius:6px;box-shadow:0 8px 22px rgba(0,0,0,.12);padding:4px;}
  #obpanel-tenant .billing-filter-control.open .billing-filter-menu{display:block;}
  #obpanel-tenant .billing-filter-menu-actions{display:flex;gap:4px;padding:2px 2px 6px;margin-bottom:4px;border-bottom:1px solid #e5e7e8;}
  #obpanel-tenant .billing-filter-menu-actions button{width:auto;flex:1;text-align:center;font-size:.72rem;letter-spacing:.02em;text-transform:uppercase;color:#0e7c4a;background:transparent;border:0;cursor:pointer;border-radius:4px;padding:6px 4px;}
  #obpanel-tenant .billing-filter-menu-actions button:hover{background:#eaf6f0;}
  #obpanel-tenant .billing-filter-menu-option{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:4px;cursor:pointer;font-size:.8rem;color:#30353a;white-space:nowrap;}
  #obpanel-tenant .billing-filter-menu-option:hover{background:#eaf6f0;color:#0e7c4a;}
  #obpanel-tenant .billing-filter-menu-option input[type="checkbox"]{margin:0;flex-shrink:0;}

  #opanel-overview.owner-overview-reference{color:#263238;}
  .owner-overview-heading{display:flex;justify-content:space-between;align-items:center;margin:28px 0 22px;}
  .owner-overview-heading h2{font-family:'Cormorant Garamond',serif;font-size:2.8rem;color:#12352e;margin:0;}
  .owner-overview-heading p{margin:4px 0;color:#6b7378;font-size:1.1rem;}
  .owner-overview-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;}
  .owner-overview-card{display:flex;gap:18px;align-items:flex-start;background:#fff;border:1px solid #dfe5e3;border-radius:7px;padding:18px 20px;min-height:108px;box-shadow:0 1px 2px rgba(0,0,0,.03);}
  .owner-overview-card .admin-stat-icon{width:48px;height:48px;display:flex;align-items:center;justify-content:center;border-radius:50%;font-size:1.5rem;flex-shrink:0;}
  .owner-overview-card>div>div{color:#35464f;font-size:.9rem;}.owner-overview-card strong{display:block;font-family:'Cormorant Garamond',serif;font-size:2rem;color:#102b28;line-height:1.2;margin:4px 0;}.owner-overview-card a,.overview-view-all{color:#087452;cursor:pointer;font-size:.85rem;}
  .owner-overview-grid{display:grid;grid-template-columns:1.6fr 1fr;gap:20px;margin-top:20px;}.owner-overview-grid section,.owner-overview-activity{position:relative;background:#fff;border:1px solid #dfe5e3;border-radius:7px;padding:18px;min-height:160px;}.owner-overview-grid h3,.owner-overview-activity h3{font-family:'Cormorant Garamond',serif;font-size:1.55rem;color:#172b3d;margin:0 0 14px;}.overview-view-all{position:absolute;right:18px;top:24px;}.owner-overview-property{display:grid;grid-template-columns:2fr 1fr repeat(3,.5fr);gap:14px;border-top:1px solid #e4e8e7;padding:12px 4px;font-size:.82rem;color:#40515c;}.owner-overview-property strong{color:#162b3d;font-family:'Cormorant Garamond',serif;font-size:1.05rem;}.owner-overview-property span{align-self:center;}.owner-overview-empty{color:#728087;font-size:.88rem;padding:20px 4px;}.owner-overview-activity{margin-top:20px;min-height:100px;}
  .owner-overview-table-head{display:grid;grid-template-columns:2fr 1fr 1fr 1.2fr 1fr 1fr;gap:12px;border-top:1px solid #e4e8e7;border-bottom:1px solid #e4e8e7;background:#f7f9f8;padding:9px 4px;color:#607079;font-size:.62rem;letter-spacing:.04em;font-weight:600;}.owner-overview-table-head span{white-space:nowrap;}.owner-overview-grid section:first-child{overflow:hidden;}.owner-overview-activity{min-height:108px;}
  .owner-overview-map-section{margin-top:20px;background:#fff;border:1px solid #dfe5e3;border-radius:7px;padding:18px;}.owner-overview-map-section h3{font-family:'Cormorant Garamond',serif;font-size:1.55rem;color:#172b3d;margin:0 0 14px;}.owner-overview-map{position:relative;min-height:260px;border-radius:6px;overflow:hidden;background:#eef3f1;background-image:linear-gradient(28deg,transparent 46%,rgba(255,255,255,.9) 47%,rgba(255,255,255,.9) 49%,transparent 50%),linear-gradient(112deg,transparent 46%,rgba(255,255,255,.85) 47%,rgba(255,255,255,.85) 49%,transparent 50%);background-size:180px 140px,220px 180px;}.owner-map-marker{position:absolute;width:32px;height:32px;border-radius:50% 50% 50% 0;transform:translate(-50%,-65%) rotate(-45deg);border:3px solid #fff;background:#087452;box-shadow:0 2px 7px rgba(0,0,0,.24);cursor:pointer;}.owner-map-marker span{display:block;color:#fff;font-weight:700;font-size:.8rem;transform:rotate(45deg);}.owner-map-legend{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:8px 20px;margin-top:14px;}.owner-map-legend>div{display:grid;grid-template-columns:24px 1fr;column-gap:8px;align-items:center;font-size:.8rem;color:#43535b;}.owner-map-legend strong{color:#162b3d;}.owner-map-legend>div>span:last-child{grid-column:2;}.owner-map-legend-number{width:20px;height:20px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:#087452;color:#fff;font-size:.7rem;font-weight:700;}
  @media(max-width:900px){.owner-overview-cards{grid-template-columns:repeat(2,1fr);}.owner-overview-grid{grid-template-columns:1fr;}}@media(max-width:600px){.owner-overview-heading{align-items:flex-start;flex-direction:column;gap:14px}.owner-overview-cards{grid-template-columns:1fr}.owner-overview-property{grid-template-columns:1fr 1fr;}}

  /* Tenant maintenance reference layout. */
  #tpanel-maintenance.tenant-maintenance-reference{color:#202124;}
  #tpanel-maintenance.tenant-maintenance-reference .lease-page-heading{margin-bottom:18px;}
  #tpanel-maintenance.tenant-maintenance-reference .lease-page-heading h2{font-family:'Cormorant Garamond',serif;font-size:2.35rem;line-height:1;margin:0;color:#151515;}
  #tpanel-maintenance.tenant-maintenance-reference .lease-page-heading p{margin:4px 0 0;color:#454545;font-family:Inter,sans-serif;font-size:.98rem;}
  #tpanel-maintenance.tenant-maintenance-reference .lease-page-heading .btn{padding:11px 18px;white-space:nowrap;}
  #tpanel-maintenance.tenant-maintenance-reference .admin-stat-cards{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-bottom:12px;}
  #tpanel-maintenance.tenant-maintenance-reference .admin-stat-card{background:#fff;border:1px solid #e4e5e6;border-radius:8px;padding:14px 16px;box-shadow:0 1px 2px rgba(0,0,0,.03);}
  #tpanel-maintenance.tenant-maintenance-reference .admin-stat-icon{width:42px;height:42px;background:#e6f3ed;color:#0e7c4a;}
  #tpanel-maintenance.tenant-maintenance-reference .admin-stat-number{font-family:Inter,sans-serif;font-size:1.7rem;color:#111;}
  #tpanel-maintenance.tenant-maintenance-reference .admin-stat-label{color:#42464a;font-size:.82rem;}
  /* Request details are a centered modal (.tenant-maint-detail-modal, the
     admin-modal-overlay component — see #tenant-maintenance-detail-modal-overlay
     in index.html), and the list below is a table (.maint-req-table, same
     component/markup as the employee queue) spanning the panel's full width. */
  #tpanel-maintenance.tenant-maintenance-reference .maint-list-col{background:#fff;border:1px solid #e2e4e5;border-radius:8px;padding:10px 12px;box-shadow:0 1px 2px rgba(0,0,0,.03);}
  #tpanel-maintenance.tenant-maintenance-reference .maint-list-head{align-items:flex-end;}
  #tpanel-maintenance.tenant-maintenance-reference .maint-list-head .eyebrow{font-family:'Cormorant Garamond',serif;text-transform:none;letter-spacing:0;font-size:1.35rem;font-weight:600;color:#222;margin:0 0 8px 4px;}
  #tpanel-maintenance.tenant-maintenance-reference .maint-list-tabs{gap:4px;}
  #tpanel-maintenance.tenant-maintenance-reference .maint-list-tab{background:#f1f3f4;border:0;color:#4b5359;border-radius:6px;padding:9px 20px;}
  #tpanel-maintenance.tenant-maintenance-reference .maint-list-tab.active{background:#087344;color:#fff;}
  #tpanel-maintenance.tenant-maintenance-reference .admin-table-wrap{border:1px solid #e1e4e5;border-radius:7px;overflow:hidden;}
  #tpanel-maintenance.tenant-maintenance-reference .maint-req-table{min-width:0;background:#fff;}
  #tpanel-maintenance.tenant-maintenance-reference .maint-req-table th{background:#f6f7f7;color:#394047;font-size:.72rem;padding:10px 12px;}
  #tpanel-maintenance.tenant-maintenance-reference .maint-req-table td{color:#3f464c;border-bottom:1px solid #e5e7e8;padding:12px;font-size:.82rem;}
  #tpanel-maintenance.tenant-maintenance-reference .maint-req-table tbody tr.selected{background:#eaf6f0;}
  #tpanel-maintenance.tenant-maintenance-reference .maint-req-table tbody td:first-child{border-left-color:transparent;}
  #tpanel-maintenance.tenant-maintenance-reference .maint-req-table tbody tr.selected td:first-child{border-left-color:#17804f;}
  #tpanel-maintenance.tenant-maintenance-reference .tenant-maint-row-title{color:#151515;font-size:.85rem;}
  @media(max-width:700px){#tpanel-maintenance.tenant-maintenance-reference .admin-stat-cards{grid-template-columns:1fr;}#tpanel-maintenance.tenant-maintenance-reference .lease-page-heading{align-items:flex-start;flex-direction:column;}}

  /* The tenant's maintenance request-details modal: a bit wider than the
     default .admin-modal (560px) since it carries a photo grid, stepper,
     and full conversation thread, and each info block gets its own card so
     the panel reads as organized sections rather than one long scroll of
     plain text — still a plain centered rectangle, just roomier. */
  .tenant-maint-detail-modal{max-width:640px;max-height:86vh;overflow-y:auto;}
  .tenant-maint-detail-modal.admin-modal .admin-modal-head{border-bottom:1px solid var(--hair);padding-bottom:16px;}
  .maint-detail-modal-actions{display:flex;align-items:center;gap:10px;flex-shrink:0;}
  .tenant-maint-detail-modal .maint-detail-top-grid,
  .tenant-maint-detail-modal .maint-detail-section{
    background:var(--panel-2);border:1px solid var(--hair);border-radius:10px;padding:14px 16px;margin-top:16px;
  }
  .tenant-maint-detail-modal .maint-detail-top-grid{margin-top:20px;}
  .tenant-maint-detail-modal .maint-callout{border-radius:10px;}
  .tenant-maint-detail-modal .maint-actions-row{margin-top:20px;}
  @media(max-width:600px){ .maint-detail-modal-actions .btn-small{padding:8px 12px;font-size:0.68rem;} }

  /* A plain rectangular card — .admin-modal's own base padding:28px is
     dropped here (double-padding on top of this section's own 26px sides
     was the main reason this modal used to feel oversized) in favor of one
     flex column (head / fields / actions). Deliberately UNCAPPED height
     (no max-height/inner scroll) so every field is always on screen at
     once rather than hidden behind a small internal scrollbar the
     employee's extra Tenant & unit field only made worse — the modal
     grows to fit its content, and .admin-modal-overlay's own
     overflow-y:auto scrolls the page if it's taller than the viewport. */
  .maintenance-request-modal{
    background:#fff;color:#202124;border-radius:0;padding:0;
    width:700px;max-width:94vw;display:flex;flex-direction:column;
  }
  .maintenance-request-modal .admin-modal-head{padding:22px 26px 12px;margin:0;border-bottom:0;flex:0 0 auto;}
  .maintenance-request-modal .admin-modal-head h3{font-family:'Cormorant Garamond',serif;color:#151515;font-size:1.9rem;margin:0;}
  .maintenance-request-modal .admin-modal-head p{color:#6b7378;margin:3px 0 0;font-size:.86rem;}
  .maintenance-request-modal form{display:flex;flex-direction:column;flex:1;min-height:0;}
  .maintenance-form-scroll{overflow-y:visible;padding:0 26px 6px;}
  .maintenance-form-section{border:1px solid #e3e7e6;border-radius:9px;padding:14px 16px;margin-top:12px;background:#fbfcfc;}
  .maintenance-form-section-title{font-weight:700;color:#0e533d;margin-bottom:10px;font-size:.92rem;}
  .maintenance-form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
  .maintenance-request-modal .field{margin-bottom:10px;}
  .maintenance-request-modal .field:last-child{margin-bottom:0;}
  .maintenance-request-modal label{color:#364047;font-size:.78rem;}
  .maintenance-request-modal input,.maintenance-request-modal select,.maintenance-request-modal textarea{background:#fff;color:#202124;border:1px solid #d6dcda;border-radius:5px;width:100%;box-sizing:border-box;}
  /* Fixed proper size, not user-resizable — every textarea in this form
     keeps the same shape regardless of how much (or little) the tenant
     types, rather than the page reflowing under them. */
  .maintenance-request-modal textarea{height:76px;resize:none;}
  #nm-description{height:96px;}
  .maintenance-request-modal .admin-modal-actions{border-top:1px solid #e2e5e4;margin:0;padding:14px 26px;flex:0 0 auto;}
  @media(max-width:650px){.maintenance-form-grid{grid-template-columns:1fr;}}

  /* Photos upload control — a <label for="nm-files"> styled as a dashed
     outline box (native click-to-open-picker behavior, no JS needed for
     that part) instead of the browser's own raw file input, with an
     unfilled/outline ("see-through") camera glyph rather than a solid icon. */
  .maint-photo-upload{
    display:flex;align-items:center;gap:10px;cursor:pointer;
    border:1px dashed #c9d0ce;border-radius:6px;padding:12px 14px;
    background:transparent;color:#5a6360;transition:border-color .15s,color .15s;
  }
  .maint-photo-upload:hover{border-color:#0e7c4a;color:#0e7c4a;}
  .maint-photo-upload-icon{width:22px;height:22px;flex-shrink:0;stroke-width:1.5;}
  .maint-photo-upload-text{font-size:.86rem;}

  /* Custom "window to select from" replacing every native <select> in the
     maintenance request form — a button that opens a popup list, matching
     the maint-filter-* popups (employee Maintenance workspace) rather than
     the browser's own default dropdown styling. Backed by a plain
     <input type="hidden"> (see renderMaintSelectMenu()/chooseMaintSelectOption()
     in tenant-dashboard.js) rather than an actual <select>, since a
     visually-hidden required <select> is exempt from native constraint
     validation and would silently let an empty value through. */
  .maint-select{position:relative;}
  .maint-select-button{
    display:flex;align-items:center;justify-content:space-between;gap:8px;
    width:100%;text-align:left;background:#fff;border:1px solid #d6dcda;border-radius:5px;
    padding:11px 12px;cursor:pointer;font-family:Inter,sans-serif;font-size:.86rem;color:#202124;
  }
  .maint-select-button:hover{border-color:#0e7c4a;}
  .maint-select-menu{
    display:none;position:absolute;z-index:30;top:calc(100% + 4px);left:0;right:0;
    max-height:220px;overflow-y:auto;background:#fff;border:1px solid #d5d9db;border-radius:6px;
    box-shadow:0 8px 22px rgba(0,0,0,.12);padding:4px;
  }
  .maint-select.open .maint-select-menu{display:block;}
  .maint-select-option{display:block;width:100%;border:0;background:transparent;text-align:left;padding:8px 10px;border-radius:4px;color:#30353a;cursor:pointer;font-size:.82rem;}
  .maint-select-option:hover{background:#eaf6f0;color:#0e7c4a;}
  .maint-select-option.selected{background:#eaf6f0;color:#0e7c4a;font-weight:600;}

  /* Property/Unit "choose from a window" pickers (employee/owner Create
     Request) — plain rectangular .admin-modal with a searchable list of
     .assign-manager-row cards (same component the Add Lease/Assign
     Manager pickers already use elsewhere; it's already light-themed —
     var(--panel) background, var(--cream) text — so it drops onto this
     white modal with no extra overrides needed). Picking a row proceeds
     immediately (no separate confirm step) since this is a lower-stakes,
     single-purpose pick, not an editable assignment. */
  .maint-picker-row{
    display:flex;align-items:center;gap:14px;padding:10px;width:100%;
    background:var(--panel);border:1px solid var(--hair);border-radius:8px;cursor:pointer;
    font:inherit;text-align:left;
  }
  .maint-picker-row:hover,.maint-picker-row:focus-visible{border-color:var(--gold-deep);}
  .maint-picker-row.selected{border-color:var(--gold-deep);background:var(--panel-2);}
  .maint-picker-row-body{flex:1;min-width:0;}
  .maint-picker-row-name{font-size:0.9rem;font-weight:500;color:var(--cream);}
  .maint-picker-row-meta{font-size:0.78rem;color:var(--taupe);margin-top:2px;}
  .maint-picker-row-detail{font-size:0.72rem;color:var(--taupe);margin-top:1px;}
  .maint-picker-row-arrow{color:var(--taupe);font-size:1.1rem;flex-shrink:0;}
  /* Property module photo — falls back to a plain building-icon glyph
     (svgIcon('home')) inside the same circle when no photo is set, rather
     than a blank/empty circle. */
  .maint-picker-row .maint-picker-row-photo{display:flex;align-items:center;justify-content:center;color:var(--taupe);}
  .maint-picker-row .maint-picker-row-photo svg{width:20px;height:20px;}
  #nm-property-picker-overlay .admin-search-input,
  #nm-unit-picker-overlay .admin-search-input,
  #admin-maint-property-filter-overlay .admin-search-input{margin-top:4px;}

  /* Read-only "known information" module shown once Property+Unit are
     resolved (via the pickers above) — reuses .property-manager-row/
     .property-manager-field verbatim (same "resolved selection" card the
     Add Lease wizard shows for Property/Unit/Tenant once each step is
     confirmed). */
  .maint-tenant-module{background:var(--panel);border:1px solid var(--hair);border-radius:8px;padding:14px 16px;margin-bottom:16px;}
  .maint-tenant-module .property-manager-row{margin-top:6px;}

  /* Pet on site — a small Yes/No segmented control (not a plain radio
     list) so it reads at a glance, matching this form's otherwise compact
     field sizing. */
  .maint-pet-toggle{display:inline-flex;border:1px solid #d6dcda;border-radius:6px;overflow:hidden;}
  .maint-pet-toggle label{margin:0;position:relative;}
  .maint-pet-toggle input{position:absolute;opacity:0;width:1px;height:1px;}
  .maint-pet-toggle span{display:block;padding:8px 22px;font-size:.84rem;color:#4a5158;cursor:pointer;user-select:none;}
  .maint-pet-toggle label:first-child span{border-right:1px solid #d6dcda;}
  .maint-pet-toggle input:checked + span{background:#0e533d;color:#fff;}
  .maint-pet-toggle input:focus-visible + span{outline:2px solid #0e533d;outline-offset:-2px;}

  @media(max-width:600px){
    .maint-detail-grid{grid-template-columns:1fr;}
    .maint-assign-row{grid-template-columns:1fr;}
  }

  /* TAX REPORT PRINT VIEW */
  #tax-report-print-overlay{
    display:none;position:fixed;inset:0;background:rgba(0,0,0,0.7);z-index:1000;
    overflow:auto;padding:40px 20px;
  }
  #tax-report-print-view{
    max-width:800px;margin:0 auto;background:#FFFFFF;color:#111111;padding:56px;
    font-family:'Inter',sans-serif;
  }
  #tax-report-print-view h2, #tax-report-print-view h3{font-family:'Cormorant Garamond',serif;color:#111111;}
  #tax-report-print-view table{width:100%;border-collapse:collapse;margin:10px 0 24px;}
  #tax-report-print-view th{text-align:left;font-family:'IBM Plex Mono',monospace;font-size:0.7rem;letter-spacing:0.06em;text-transform:uppercase;color:#555;padding:8px 10px;border-bottom:1px solid #ccc;}
  #tax-report-print-view td{padding:8px 10px;border-bottom:1px solid #eee;font-size:0.92rem;color:#111;}
  #tax-report-print-view td.tr-amount{text-align:right;font-family:'IBM Plex Mono',monospace;}
  #tax-report-print-view .tr-total-row td{font-weight:600;border-top:2px solid #111;border-bottom:none;}
  #tax-report-print-view .tr-header{text-align:center;margin-bottom:30px;padding-bottom:20px;border-bottom:2px solid #1FAA59;}
  #tax-report-print-view .tr-section-title{font-family:'IBM Plex Mono',monospace;font-size:0.75rem;letter-spacing:0.1em;text-transform:uppercase;color:#0E7C4A;margin:30px 0 6px;}
  #tax-report-print-view .tr-footer{margin-top:40px;padding-top:16px;border-top:1px solid #ccc;font-size:0.78rem;color:#666;text-align:center;}
  .tax-report-actions{max-width:800px;margin:20px auto;text-align:center;display:flex;gap:14px;justify-content:center;}
  @media print{
    body > *:not(#tax-report-print-overlay){display:none !important;}
    #tax-report-print-overlay{position:static;background:none;padding:0;overflow:visible;display:block;}
    #tax-report-print-view{max-width:100%;margin:0;padding:0;box-shadow:none;}
    .tax-report-actions{display:none !important;}
    @page{margin:0.75in;}
  }

/* Owner lease overview and readable profile contact details. */
#opanel-leases .lease-page-heading h2{font-size:2.6rem;}
.owner-all-leases-heading{font-family:'Cormorant Garamond',serif;font-size:1.8rem;font-weight:500;margin:26px 0 12px;color:var(--cream);}
.owner-lease-toolbar{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:18px;}
.owner-lease-toolbar .owner-lease-filter-tabs{margin:0;gap:4px;}
.owner-lease-filter-tab{border-color:transparent;background:transparent;padding:8px 12px;}
.owner-lease-filter-tab-count{background:transparent;padding:0;}
.owner-lease-search-controls{display:flex;align-items:center;gap:10px;flex:0 1 340px;}
.owner-lease-search-controls input{min-width:0;width:100%;}
.owner-lease-workspace{padding:0;border:0;background:transparent;}
.owner-lease-signature-heading{font-size:1.65rem;}
.owner-lease-signature-row:first-of-type{border-top:0;}
.owner-lease-document-note{font-size:.82rem;color:var(--taupe);margin-top:18px;}
.owner-lease-table td:nth-child(2),.owner-lease-table td:nth-child(3){white-space:normal;overflow-wrap:anywhere;}
.owner-lease-table{width:100%;}
#opanel-profile .profile-identity-contact-row > div:last-child,
#tpanel-profile .profile-identity-contact-row > div:last-child,
#epanel-profile .profile-identity-contact-row > div:last-child{min-width:0;flex:1;}
#opanel-profile .profile-identity-contact-value,
#tpanel-profile .profile-identity-contact-value,
#epanel-profile .profile-identity-contact-value{white-space:normal;overflow:visible;text-overflow:clip;overflow-wrap:anywhere;}
.owner-property-field-value{overflow-wrap:anywhere;}
@media(max-width:640px){
  .owner-lease-search-controls{flex:1 1 100%;}
  .owner-lease-signature-head{flex-wrap:wrap;gap:8px;}
  .owner-lease-signature-heading{font-size:1.35rem;}
  #opanel-profile .profile-detail-row,#tpanel-profile .profile-detail-row,#epanel-profile .profile-detail-row{flex-wrap:wrap;gap:6px;}
  #opanel-profile .profile-detail-row .profile-value,#tpanel-profile .profile-detail-row .profile-value,#epanel-profile .profile-detail-row .profile-value{flex-basis:100%;text-align:left;}
}

.owner-lease-unit{display:block;margin-top:4px;color:var(--taupe);font-size:.82rem;}
.owner-lease-table td:first-child{white-space:normal;overflow-wrap:anywhere;}
.owner-lease-review-drawer{width:min(680px,100vw);}
.owner-lease-review-drawer .lease-document-action{flex-wrap:wrap;gap:12px;}
.owner-lease-review-drawer .lease-document-action > span{flex:1 1 100%;overflow-wrap:anywhere;}
.owner-lease-filter-tab:focus-visible{outline:2px solid var(--gold-deep);outline-offset:2px;}

/* Keep owner/tenant contact values intact; narrow screens can scroll the
   focused value horizontally instead of losing text or splitting emails. */
#opanel-profile .profile-contact-line,
#tpanel-profile .profile-contact-line,
#epanel-profile .profile-contact-line{
  min-width:0;max-width:100%;white-space:nowrap;overflow-wrap:normal;
  overflow-x:auto;overflow-y:hidden;text-overflow:clip;line-height:1.6;
}
#opanel-profile .profile-contact-line:focus-visible,
#tpanel-profile .profile-contact-line:focus-visible,
#epanel-profile .profile-contact-line:focus-visible{
  outline:2px solid var(--gold-deep);outline-offset:3px;
}
@media(min-width:1000px){
  #opanel-profile .profile-page-layout,
  #tpanel-profile .profile-page-layout,
  #epanel-profile .profile-page-layout{grid-template-columns:minmax(340px,390px) minmax(0,1fr);}
}
@media(max-width:640px){
  #opanel-profile .profile-detail-row .profile-input,
  #tpanel-profile .profile-detail-row .profile-input,
  #epanel-profile .profile-detail-row .profile-input{flex-basis:100%;max-width:none;min-width:0;}
}
