/* Hawthorne Patio Homes -- staff (admin) portal shell.
 *
 * Recreated from "HPH admin portal handoff v1.0". Staff do not get the resident
 * sidebar: a full-width Pine band carries the wordmark, a Staff marker and the
 * primary nav as on-brand tabs; content is a 1180px column on Paper 50. Same
 * tokens and components as the resident portal (components.css), visibly a
 * different tool. Dark mode is the same data-theme="dark" switch, toggled from
 * the band and remembered in a cookie so the first paint is already right.
 */
@import url("./components.css");

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

/* ---------------------------------------------------------------- band --- */

.band { background: var(--pine-800); padding: 20px 44px 0; display: flex; flex-direction: column; gap: 20px; }
.band__row { display: flex; align-items: center; justify-content: space-between; gap: 32px; }
.band__brand { display: flex; align-items: center; gap: 16px; min-width: 0; text-decoration: none; }
.band__brand img { height: 34px; width: auto; display: block; }
.band__wordmark {
  font: var(--weight-medium) 13px/1 var(--font-display);
  letter-spacing: var(--wayfinding-track);
  text-transform: uppercase;
  color: var(--paper-00);
  white-space: nowrap;
}
.band__sep { width: 1px; height: 20px; background: var(--pine-600); flex-shrink: 0; }
.band__staff {
  font: var(--weight-semibold) 11px/1 var(--font-sans);
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--paper-300);
}
.band__me { display: flex; align-items: center; gap: 20px; }
.band__who { display: flex; flex-direction: column; gap: 2px; text-align: right; min-width: 0; }
.band__who b { font: var(--weight-semibold) var(--body-sm-size)/1.3 var(--font-sans); color: var(--paper-00); }
.band__who span { font: var(--font-body-sm); color: var(--paper-300); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.band__out { display: flex; align-items: center; gap: 8px; font: var(--font-body-sm); color: var(--paper-300); text-decoration: none; }
.band__out:hover { color: var(--paper-00); }

/* Square icon-only control; never a primary action; always labelled. */
.iconbtn {
  width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-md); border: 1px solid transparent; background: transparent;
  color: var(--paper-00); cursor: pointer; padding: 0;
  transition: background-color var(--duration-fast) var(--ease);
}
.iconbtn:hover { background: var(--pine-600); }
.ico--sun { display: none; }
[data-theme="dark"] .ico--sun { display: block; }
[data-theme="dark"] .ico--moon { display: none; }
.band a:focus-visible, .band button:focus-visible { outline-color: var(--pine-300); }

/* ---------------------------------------------------------------- tabs --- */

/* Section switching: active is a 2px Pine underline plus 600 weight. The
   on-brand variant sits on the band; the plain one inside a screen. */
.tabs { display: flex; gap: 26px; border-bottom: 1px solid var(--color-border); margin: 0; padding: 0; list-style: none; overflow-x: auto; }
.tabs--brand { border-bottom-color: var(--pine-600); }
.tab {
  display: flex; align-items: center; gap: 7px;
  padding: 0 0 10px; margin-bottom: -1px;
  border: 0; border-bottom: 2px solid transparent;
  background: transparent; text-decoration: none; white-space: nowrap;
  font: var(--weight-regular) var(--body-size)/1.4 var(--font-sans);
  color: var(--color-text-secondary);
  transition: color var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease);
}
.tab:hover { color: var(--color-text-primary); }
.tab[aria-current="page"] { font-weight: var(--weight-semibold); color: var(--color-text-primary); border-bottom-color: var(--pine-800); }
[data-theme="dark"] .tab[aria-current="page"] { border-bottom-color: var(--pine-300); }
.tabs--brand .tab { color: var(--color-text-on-brand-muted); }
.tabs--brand .tab:hover { color: var(--paper-00); }
.tabs--brand .tab[aria-current="page"] { color: var(--paper-00); border-bottom-color: var(--pine-300); }
.tab__count {
  min-width: 20px; height: 18px; padding: 0 5px; border-radius: var(--radius-sm);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-neutral-tint); color: var(--color-text-secondary);
  font: var(--weight-semibold) 11px/1 var(--font-sans); font-variant-numeric: tabular-nums;
}
.tabs--brand .tab__count { background: var(--pine-600); color: var(--paper-00); }

/* ---------------------------------------------------------------- page --- */

.wrap { flex: 1; min-width: 0; padding: 44px 44px 80px; }
.col { max-width: 1180px; margin: 0 auto; display: flex; flex-direction: column; gap: 28px; }
.col--dash { gap: 32px; }
.col--860 { max-width: 860px; margin: 0; }
.col--820 { max-width: 820px; margin: 0; gap: 32px; }
.col--720 { max-width: 720px; margin: 0; }
/* Narrow screens are left-aligned inside the 1180 column, as the design draws them. */
.col--inner { max-width: 1180px; margin: 0 auto; }

.phead { display: flex; align-items: flex-end; justify-content: space-between; gap: 32px; }
.phead--top { align-items: flex-start; gap: 26px; }
.phead__text { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.phead__end { display: flex; align-items: flex-end; gap: 26px; flex-shrink: 0; }
.phead__end .chip, .phead__end .pill { margin-bottom: 6px; }
.phead .engraving { height: 120px; margin-bottom: -6px; }
.phead .pills { padding-top: 8px; }
.phead__mark { height: 82px; width: auto; display: block; flex-shrink: 0; margin-bottom: -4px; }
.mark--reversed { display: none; }
[data-theme="dark"] .mark--pine { display: none; }
[data-theme="dark"] .mark--reversed { display: block; }

.section { display: flex; flex-direction: column; gap: 16px; }
.section__head { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.search { width: 280px; flex-shrink: 0; }

/* -------------------------------------------------------------- tables --- */

/* Grid rows styled to DataTable's metrics -- uppercase Plex labels, 1px Paper
   200 rules, 13/15px cells -- so cells can hold pills and buttons. */
.table { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 14px 8px 0; overflow-x: auto; }
.table__head, .trow { display: grid; align-items: center; }
.table__head { align-items: end; }
.th {
  padding: 0 14px 8px; border-bottom: 1px solid var(--color-border);
  font: var(--font-label); letter-spacing: var(--label-track); text-transform: uppercase; color: var(--color-text-muted);
}
.trow { border-bottom: 1px solid var(--color-border); color: inherit; text-decoration: none; }
a.trow, .trow--link { cursor: pointer; transition: background-color var(--duration-fast) var(--ease); }
a.trow:hover { background: var(--color-zebra); }
.td { padding: 13px 14px; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.td--tight { padding: 9px 14px; flex-direction: row; gap: 8px; align-items: center; }
.td b { font: var(--weight-semibold) var(--body-size)/1.35 var(--font-sans); color: var(--color-text-primary); }
.td span { font: var(--font-body-sm); color: var(--color-text-muted); }
.td .ell { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td .plain { font: var(--font-body); color: var(--color-text-primary); }
.td .sec { font: var(--font-body-sm); color: var(--color-text-secondary); }
.td .ref { font: var(--font-body-sm); font-family: var(--font-mono); color: var(--color-text-secondary); }
/* A column cell is a flex column, so chips would stretch to the cell width without this. */
.td > .chip, .td > .pill { align-self: flex-start; }
.table--queue .table__head, .table--queue .trow { grid-template-columns: 200px 1fr 100px 116px 132px 108px; min-width: 900px; }
.table--residents .table__head, .table--residents .trow { grid-template-columns: 1fr 180px 250px 120px 150px; min-width: 900px; }
.table--leases .table__head, .table--leases .trow { grid-template-columns: 1fr 180px 230px 120px 190px; min-width: 900px; }
.table__empty { padding: 22px 14px; font: var(--font-body-sm); color: var(--color-text-muted); }

.initials {
  width: 32px; height: 32px; flex-shrink: 0; border-radius: 999px;
  background: var(--color-selected-tint); color: var(--pine-800);
  display: inline-flex; align-items: center; justify-content: center;
  font: var(--weight-semibold) 12px/1 var(--font-sans);
}
[data-theme="dark"] .initials { color: var(--paper-100); }
.who { display: flex; align-items: center; gap: 12px; min-width: 0; }

.two { display: grid; grid-template-columns: 1.15fr 1fr; gap: 20px; align-items: start; }
.list { display: flex; flex-direction: column; }
.lrow {
  display: flex; align-items: center; gap: 14px; padding: 15px 20px; border-top: 1px solid var(--color-border);
  color: inherit; text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease);
}
.lrow:first-child { border-top: 0; }
.lrow--top { align-items: flex-start; }
a.lrow:hover { background: var(--color-zebra); }
.lrow__text { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
.lrow__kind { display: flex; align-items: center; gap: 6px; color: var(--color-text-muted); font: var(--font-label); letter-spacing: var(--label-track); text-transform: uppercase; }
.lrow__title { font: var(--weight-semibold) var(--body-size)/1.3 var(--font-sans); color: var(--color-text-primary); }
.lrow__plain { font: var(--font-body); color: var(--color-text-primary); text-decoration: none; }
a.lrow__plain:hover { color: var(--color-link); }
.lrow__meta { font: var(--font-body-sm); color: var(--color-text-muted); }
.lrow__chev { color: var(--color-text-muted); display: flex; flex-shrink: 0; }
.lrow__empty { padding: 22px 20px; font: var(--font-body-sm); color: var(--color-text-muted); }

/* ------------------------------------------------------- request detail --- */

.contact { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 22px; }
.contact__text { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.contact__text b { font: var(--weight-semibold) var(--body-size)/1.35 var(--font-sans); }
.contact__text span { font: var(--font-body-sm); color: var(--color-text-secondary); overflow-wrap: anywhere; }
.update { display: grid; grid-template-columns: 280px 1fr; gap: 20px; align-items: start; }

/* ------------------------------------------------------------ resident --- */


/* ----------------------------------------------------------- inquiries --- */

.inqs { display: flex; flex-direction: column; gap: 14px; }
.inq { padding: 22px; display: flex; flex-direction: column; gap: 14px; }
.inq__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; }
.inq__name { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.inq__name b { font: var(--weight-semibold) var(--title-size)/1.3 var(--font-sans); }
.inq__meta { font: var(--font-body-sm); color: var(--color-text-muted); overflow-wrap: anywhere; }
.inq__actions { display: flex; gap: 10px; flex-shrink: 0; align-items: center; }
.inq__body { font: var(--font-body); max-width: 34em; margin: 0; white-space: pre-line; }

/* ------------------------------------------------------------ settings --- */

.staff { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 16px 22px; border-top: 1px solid var(--color-border); }
.staff:first-child { border-top: 0; }
.staff__who { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; min-width: 0; overflow-wrap: anywhere; }
.staff__who > span:first-child { flex-basis: 100%; }
@media (max-width: 600px) { .staff { flex-wrap: wrap; gap: 8px; } .staff__who { flex-basis: 100%; } }
.staff__add { display: flex; align-items: center; gap: 12px; padding: 18px 22px; border-top: 1px solid var(--color-border); }
.staff__add .field { flex: 1; }
.notices { padding: 22px; display: flex; flex-direction: column; gap: 12px; }
.notices p { margin: 0; font: var(--font-body); max-width: 34em; }
.notices span { font: var(--font-body-sm); color: var(--color-text-muted); }

/* --------------------------------------------------------------- notice --- */

/* The bare pages (session expired, unknown address, error). */
.notice { max-width: 560px; margin: 0 auto; display: flex; flex-direction: column; gap: 20px; }

/* ---------------------------------------------------------- responsive --- */

@media (max-width: 1100px) {
  .two { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .band { padding: 16px 20px 0; }
  .band__who, .band__out span, .band__wordmark, .band__sep, .band__staff { display: none; }
  .wrap { padding: 28px 20px 60px; }
  .phead, .phead--top { flex-direction: column; align-items: flex-start; gap: 20px; }
  .phead__end { align-items: center; }
  .search { width: 100%; }
  .update { grid-template-columns: 1fr; }
  .contact, .inq__top, .section__head { flex-direction: column; align-items: flex-start; }
  .actions--split { flex-direction: column; align-items: flex-start; }
  .staff__add { flex-direction: column; align-items: stretch; }
}

/* ---- CUT-108 · tabs scroll strip (iOS) ------------------------------------

Both tab rows -- the Pine nav (.tabs--brand) and the queue's filter row -- are
horizontal scrollers on a narrow screen. iOS Safari paints a persistent
scrollbar strip under them, which reads as a stray rule under the nav. Hiding
the bar leaves the scrolling itself untouched: the row still swipes, and on a
pointer device nothing was visible there to begin with. Momentum scrolling and
proximity snapping are what make a hidden bar acceptable -- a swipe ends on a
tab rather than mid-word, so the row does not need a visible position hint. */
.tabs {
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs .tab { scroll-snap-align: start; }
/* ---- end CUT-108 ---- */

/* ---- CUT-107 · schedule a visit ------------------------------------------

The visit form is a date plus an optional two-input window, so it wants three
columns rather than the label/field split .update uses. Same gap and alignment
as .update so the two cards on the request page read as one form. */
.visit { display: grid; grid-template-columns: 200px 1fr 1fr; gap: 20px; align-items: start; }
@media (max-width: 760px) {
  .visit { grid-template-columns: 1fr; }
}
/* ---- end CUT-107 ---- */

/* ---- CUT-105 · name fields, preferred name, staff notes -------------------

Three even columns for first / middle / last, so the name row reads as one
field rather than three stacked ones. Same gap as .grid2 and it collapses at
the same width. */
.grid3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px; }
@media (max-width: 760px) {
  .grid3 { grid-template-columns: 1fr; }
}

/* ---- end CUT-105 ---- */

/* ---- CUT-109 · households and occupants ----------------------------------

The Residents table is grouped by home, so it needs a band between the rows
that is not itself a row: same 900px minimum as .trow so it stays aligned
while the table scrolls sideways, and the label metrics of .th because it is a
heading for the rows under it, not data. */
.table__group {
  display: flex; align-items: baseline; gap: 10px;
  min-width: 900px; padding: 14px 14px 7px;
  border-bottom: 1px solid var(--color-border); background: var(--color-page);
}
.table__group b { font: var(--weight-semibold) var(--body-size)/1.35 var(--font-sans); color: var(--color-text-primary); }
.table__group span { font: var(--font-body-sm); color: var(--color-text-muted); }
/* ---- end CUT-109 ---- */

/* Balances: a name on the left, a figure on the right, tabular so the columns
   of digits line up down the card. */
.mlist { display: flex; flex-direction: column; }
.mrow {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 14px 20px; border-bottom: 1px solid var(--color-border);
}
.mrow:last-child { border-bottom: 0; }
.mrow__name { font: var(--font-body); color: var(--color-text-primary); }
.mrow__value { font: var(--weight-semibold) var(--body-size)/1.35 var(--font-sans); font-variant-numeric: tabular-nums; }

/* The refresh button sits in a section head next to the heading, so the form
   must not add a block of its own height there. */
.section__head form { margin: 0; }

/* ----------------------------------------------- end CUT-103 · market card --- */

/* ------------------------------------- CUT-111 · page head on a phone --- */

/* .phead__end is a non-shrinking row, which is right at 1280 where it holds a
   chip or an engraving beside the title. On the maintenance queue it holds a
   button plus the 280px search field, and a non-shrinking row of those two set
   the width of the whole document at 390: the Pine band stopped at the
   viewport and the page panned sideways. Stacking it and letting it shrink
   makes the search a full-width field under the title, which is where a phone
   wants it anyway. */
@media (max-width: 760px) {
  .phead__end {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    min-width: 0;
    flex-shrink: 1;
  }
  /* Alignment set on the row does nothing once it stacks; a chip or pill still
     needs to sit at the start rather than stretch to the column. */
  .phead__end .chip, .phead__end .pill { align-self: flex-start; }
  .search { width: 100%; }
}

/* --------------------------------------- CUT-111 · tables on a phone --- */

/* Every staff table is a grid with a 900-1000px minimum inside an
   overflow-x: auto box. On a 390 screen that showed the first two columns and
   hid the rest with nothing to say they were there -- including the only
   controls on Accounts and on Home facts. Below the breakpoint each record
   becomes a stack of label/value pairs instead: the column head is hidden and
   each cell prints its own label from data-label, so nothing is off-screen and
   no horizontal scroller is needed. The labels are the same words as the
   .th they replace, in the same uppercase Plex label face. */
@media (max-width: 760px) {
  .table { padding: 0; overflow-x: visible; }
  .table__head { display: none; }
  .table--queue .trow,
  .table--residents .trow,
  .table--leases .trow,
  .table--facts .trow,
  .table--rent .trow,
  .table--accounts .trow,
  .table__group {
    grid-template-columns: 1fr;
    min-width: 0;
  }
  .table .trow { padding: 8px 0; }
  .table__group { padding: 14px 16px 10px; }
  .table .td { padding: 7px 16px; }
  /* A cell that renders nothing must not print a label for nothing. */
  .table .td:empty { display: none; }
  .table .td[data-label]::before {
    content: attr(data-label);
    font: var(--font-label);
    letter-spacing: var(--label-track);
    text-transform: uppercase;
    color: var(--color-text-muted);
  }
  /* .td--tight is a row of buttons. It stays a row and wraps; the label takes
     a line of its own above it. */
  .table .td--tight { flex-wrap: wrap; align-items: center; row-gap: 6px; }
  .table .td--tight[data-label]::before { flex: 0 0 100%; }
  /* Truncation is for a fixed column width. In a stacked card there is a whole
     line for the value, so it wraps instead. */
  .table .td .ell { white-space: normal; overflow: visible; }
  /* The accounts row's role form is the full width of the card here. */
  .table .mrole { width: 100%; }
  .table .mrole .control { width: 100%; }
}
/* ---- end CUT-111 ---- */

/* ------------------------------- CUT-110 · the statement review table --- */

/* The review step is one table of parsed rows: date, descriptor, amount,
   direction, and what will happen to it. Same grid shape as the rent roll, so
   it inherits the phone stacking above with nothing new -- .table--import is
   added to the stacking list below rather than getting rules of its own. */
.table--import .table__head, .table--import .trow { grid-template-columns: 130px 1fr 130px 120px 150px; min-width: 900px; }
.table--import .td .plain { font-variant-numeric: tabular-nums; }

@media (max-width: 760px) {
  .table--import .trow { grid-template-columns: 1fr; min-width: 0; }
}
/* ---- end CUT-110 statement review ---- */

/* ------------------- CUT-110 · money follow-ups (months, suggestions) --- */

/* The rent roll gained a Last payment column, so its grid is restated here
   rather than edited above -- and the phone stack has to be restated with it,
   because this rule sits below the shared max-width: 760px block and would
   otherwise win over it. Same shape as .table--import. */
.table--rent .table__head, .table--rent .trow {
  grid-template-columns: 1fr 190px 160px 190px 200px 110px;
  min-width: 1060px;
}

/* The month picker in the page head: label above the select, Show beside it.
   Same shape as .mtxn__form, which is the same control pair on the deposits. */
.mperiod { display: flex; align-items: flex-end; gap: 10px; }
.mperiod .control { width: 190px; }

/* Confirm and Not theirs sit side by side where a deposit's match form does. */
.mtxn__form form { display: flex; }
.mtxn__form .suggestion-confirm { flex-direction: column; align-items: flex-start; gap: 12px; max-width: 320px; }

@media (max-width: 760px) {
  .table--rent .trow { grid-template-columns: 1fr; min-width: 0; }
  .mperiod { flex-direction: column; align-items: stretch; }
  .mperiod .control { width: 100%; }
}
/* ---- end CUT-110 money follow-ups ---- */



/* ---- CUT-114 · SignWell sync ------------------------------------------- */
/* Signer addresses in a Needs-attention row have no break points; at 390px
   they must wrap rather than push the chip off the card. */
.signwell .row__meta { overflow-wrap: anywhere; }
/* ---- end CUT-114 ---- */

/* ---- comms · 0007 · Activity tab --------------------------------------- */
/* A filter bar, not a form: the fields sit in a row and wrap, and the buttons
   stay with the last one rather than being pushed to their own line. */
.filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
.filters .field { flex: 1 1 200px; max-width: 280px; }
.filters__end { display: flex; align-items: center; gap: 8px; margin-left: auto; }

/* Five columns in both views: when · who · what · outcome · where. "What" takes
   the slack because a subject line is the only cell that can be long. */
.table--activity .table__head, .table--activity .trow { grid-template-columns: 170px 240px 1fr 180px 190px; min-width: 980px; }
.table--activity .td a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

@media (max-width: 760px) {
  .table--activity .trow { grid-template-columns: 1fr; min-width: 0; }
  .filters__end { margin-left: 0; }
}
/* ---- end comms · 0007 ---- */
