/* Abland brand palette read out of the logo artwork: navy #023f88,
   yellow #ffcb05, grey #636466. The pages use assets/abland-logo.svg, the
   registered lockup from abland.co.za; assets/abland-logo.png is the same artwork
   rasterised for email, which can't rely on SVG. assets/icons/ holds the derived favicon/app-icon set (see index.html/login.html
   <head> and manifest.webmanifest) — regenerate all of them from Logos/*-v2.png
   if the artwork changes, don't hand-edit the PNGs.
   Stage colours are the Central Blue template's own key (swatches L2:L6), so the
   dashboard reads the same way as the spreadsheet the leasing team already uses. */
:root {
  --navy: #023f88;
  --navy-dark: #012a5c;
  --navy-mid: #0a55a8;
  --navy-050: #f2f6fc;
  --navy-100: #e3ecf8;
  --navy-200: #c3d6ee;
  --yellow: #ffcb05;
  --grey: #636466;
  --ink: #14181f;
  --ink-soft: #5a6270;
  --line: #dbe1ea;
  --line-soft: #eef1f6;
  --surface: #ffffff;
  --canvas: #f5f7fa;

  --stage-vacant: #ff0000;
  --stage-offer-sent: #ffff00;
  --stage-offer-received: #0070c0;
  --stage-unconditional: #ffc000;
  --stage-concluded: #92d050;

  --radius: 10px;
  --shadow-sm: 0 1px 2px rgba(16, 30, 54, .06), 0 1px 3px rgba(16, 30, 54, .05);
  --shadow-md: 0 2px 4px rgba(16, 30, 54, .05), 0 8px 24px rgba(16, 30, 54, .07);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: "Segoe UI", Arial, Helvetica, sans-serif;
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

[hidden] { display: none !important; }

/* Top bar ---------------------------------------------------------------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 24px;
  height: 68px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}
/* The SVG carries its own white panel and yellow slash, as on abland.co.za: at
   the bar's full height the slash runs top to bottom and doubles as the divider.
   The negative margin cancels the panel's built-in left padding (28.5 of 116
   units) so the mark sits on the bar's gutter. */
.topbar .logo { height: 100%; width: auto; display: block; margin-left: -16px; }
.topbar .product {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--navy);
}
.topbar .product span {
  display: block;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .04em;
  color: var(--grey);
  text-transform: none;
}
.topbar .spacer { flex: 1; }
.topbar .who {
  font-size: 12px;
  color: var(--ink-soft);
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Outline / solid pair mirrors the Brokers and Vacancies buttons on abland.co.za */
.btn {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 18px;
  border-radius: 4px;
  border: 1.5px solid var(--navy);
  background: var(--surface);
  color: var(--navy);
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s, color .12s, box-shadow .12s;
}
.btn:hover { background: var(--navy-100); }
.btn-primary { background: var(--navy); color: #fff; }
.btn-primary:hover { background: var(--navy-dark); }
.btn:focus-visible { outline: 3px solid var(--yellow); outline-offset: 1px; }
.btn:disabled { opacity: .5; cursor: default; }

/* Page shell -------------------------------------------------------------- */
main { max-width: 1560px; margin: 0 auto; padding: 24px; }

.page-head { display: flex; align-items: flex-end; gap: 20px; flex-wrap: wrap; margin-bottom: 20px; }
.page-head h1 {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--navy);
}
.page-head .produced { margin: 4px 0 0; font-size: 12px; color: var(--ink-soft); }
.page-head .rule { height: 3px; width: 56px; background: var(--yellow); margin-top: 10px; }
.page-head .spacer { flex: 1; }

.property-picker {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.property-picker select {
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: normal;
  text-transform: none;
  color: var(--navy);
  min-width: 220px;
  padding: 8px 12px;
  border: 1.5px solid var(--navy);
  border-radius: 4px;
  background: var(--surface);
  cursor: pointer;
}
.property-picker select:focus { outline: none; box-shadow: 0 0 0 3px var(--navy-100); }

/* Filter bar -------------------------------------------------------------- */
.filters {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px 14px;
  margin-bottom: 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.filters input[type="search"], .filters select {
  font: inherit;
  font-size: 13px;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
  color: var(--ink);
}
.filters input[type="search"] { min-width: 240px; flex: 1 1 240px; }
.filters input:focus, .filters select:focus {
  outline: none;
  border-color: var(--navy-mid);
  box-shadow: 0 0 0 3px var(--navy-100);
}
.filters label.toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  color: var(--ink-soft);
  cursor: pointer;
}
.filters .count { font-size: 12px; color: var(--ink-soft); margin-left: auto; }

/* KPI cards --------------------------------------------------------------- */
.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: 14px;
  margin-bottom: 24px;
}
.kpi {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 16px 14px;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.kpi::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 4px; background: var(--navy-200); }
.kpi .label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.kpi .value {
  font-size: 28px;
  font-weight: 700;
  line-height: 1.15;
  color: var(--navy);
  margin-top: 6px;
  font-variant-numeric: tabular-nums;
}
.kpi .sub { font-size: 12px; color: var(--ink-soft); margin-top: 2px; }
.kpi.accent::before { background: var(--yellow); }
.kpi.good::before { background: var(--stage-concluded); }
.kpi.warn::before { background: var(--stage-unconditional); }
.kpi.bad::before { background: var(--stage-vacant); }
.kpi.k-offer-received::before { background: var(--stage-offer-received); }
.kpi.k-offer-sent::before { background: var(--stage-offer-sent); }
.kpi.bad .value { color: #b91c1c; }

/* Property card ----------------------------------------------------------- */
.property {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  margin-bottom: 24px;
  overflow: hidden;
}
.property > header,
.summary-main > header {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 14px 18px;
  background: var(--navy);
  color: #fff;
  border-bottom: 3px solid var(--yellow);
}
.property > header h2, .summary-main > header h2 { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: .02em; }
.property > header .spacer, .summary-main > header .spacer { flex: 1; }
.property .meta { font-size: 12px; color: var(--navy-200); }
.chip {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .03em;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, .3);
}
.chip.soon { background: var(--yellow); color: #4a3a00; border-color: var(--yellow); }
.chip.past { background: #ffe2e2; color: #9b1c1c; border-color: #ffc9c9; }

/* Stage mix bar: the site's GLA by stage, most committed first. Area not yet
   captured as shops counts as vacant. Inset from the header so the amber
   segment doesn't run into the yellow rule above it. */
.stage-summary {
  padding: 14px 18px 10px;
  border-bottom: 1px solid var(--line);
  background: var(--navy-050);
}
.mix {
  display: flex;
  height: 12px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--line-soft);
}
.mix > span { display: block; height: 100%; }
.mix > span + span { box-shadow: inset 1px 0 0 rgba(255, 255, 255, .9); }
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  padding-top: 10px;
}
.legend span { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--ink-soft); }
.legend i { width: 11px; height: 11px; border-radius: 2px; border: 1px solid rgba(0, 0, 0, .18); }
.legend b { color: var(--ink); font-variant-numeric: tabular-nums; }
.legend em { font-style: normal; font-variant-numeric: tabular-nums; }

/* Register table ---------------------------------------------------------- */
/* The register scrolls in both directions inside this box. app.js (fitRegister)
   sizes it to end at the bottom of the window, so the frozen header at its top
   and the horizontal scrollbar at its bottom stay on screen while the rows are
   scrolled. The sticky header below only works because this box is the thing
   that scrolls vertically. */
.table-scroll { overflow: auto; max-height: calc(100vh - 92px); }
table.register { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12.5px; }
table.register th, table.register td {
  padding: 8px 11px;
  text-align: left;
  border-bottom: 1px solid var(--line-soft);
  white-space: nowrap;
  vertical-align: top;
}
table.register thead th {
  position: sticky;
  top: 0;
  background: var(--navy-100);
  color: var(--navy-dark);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--navy-200);
  z-index: 2;
}
table.register thead tr.groups th {
  top: 0;
  background: var(--navy-200);
  text-align: center;
  font-size: 10.5px;
  letter-spacing: .09em;
  border-left: 1px solid #fff;
  border-right: 1px solid #fff;
}
/* The group row is 32px tall (8px padding, 10.5px type, 1px border); the column
   row sticks directly under it */
table.register thead tr.cols th { top: 32px; }
table.register tbody tr:nth-child(even) { background: #fafbfd; }
table.register tbody tr:hover { background: var(--navy-050); }
table.register td.wrap { white-space: normal; min-width: 240px; max-width: 320px; }
/* Sized so Shop No. to Comment fill a full-width card (1,512px); the rest scrolls */
@media screen { table.register { zoom: 1.2; } }
table.register td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.register .shop { font-weight: 700; color: var(--navy); }
table.register tr.attention td:first-child { box-shadow: inset 3px 0 0 var(--stage-unconditional); }

/* Stage and DocuSign pills ------------------------------------------------ */
.stage {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 600;
  padding: 2px 9px 2px 7px;
  border-radius: 3px;
  border: 1px solid transparent;
}
.stage i { width: 9px; height: 9px; border-radius: 2px; border: 1px solid rgba(0, 0, 0, .2); flex: none; }
.stage-vacant { background: #fdeaea; color: #9b1c1c; border-color: #f7cfcf; }
.stage-vacant i { background: var(--stage-vacant); }
.stage-offer_sent { background: #fdfac9; color: #6d5f00; border-color: #f0e79a; }
.stage-offer_sent i { background: var(--stage-offer-sent); }
.stage-offer_received { background: #e4f0fa; color: #04548f; border-color: #c2ddf2; }
.stage-offer_received i { background: var(--stage-offer-received); }
.stage-unconditional_offer_concluded { background: #fff3d8; color: #86560a; border-color: #f6dfae; }
.stage-unconditional_offer_concluded i { background: var(--stage-unconditional); }
.stage-lease_concluded { background: #edf8e0; color: #3d6b11; border-color: #d3ecb4; }
.stage-lease_concluded i { background: var(--stage-concluded); }
.stage-unknown { background: var(--line-soft); color: var(--ink-soft); border-color: var(--line); }
.stage-unknown i { background: var(--grey); }

.ds {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 3px;
  background: var(--line-soft);
  color: var(--ink-soft);
  border: 1px solid var(--line);
}
.ds-sent { background: #f3f4f6; color: #4b5563; }
.ds-delivered { background: #e4f0fa; color: #04548f; border-color: #c2ddf2; }
.ds-signed { background: #fff3d8; color: #86560a; border-color: #f6dfae; }
.ds-executed { background: #edf8e0; color: #3d6b11; border-color: #d3ecb4; }

.flag { font-weight: 700; }
.flag-yes { color: #3d6b11; }
.flag-no { color: #b91c1c; }
.flag-na { color: #aab1bd; font-weight: 400; }

.signage { font-weight: 700; white-space: nowrap; }
.signage-submitted { color: #86560a; }
.signage-approved { color: #3d6b11; }
.ti-type { font-weight: 700; white-space: nowrap; color: var(--ink); }
.ti-na { color: #aab1bd; font-weight: 600; }

.muted { color: #aab1bd; }

/* Empty and message states ------------------------------------------------ */
.empty {
  padding: 44px 24px;
  text-align: center;
  color: var(--ink-soft);
  font-size: 13.5px;
}
.empty strong { display: block; font-size: 15px; color: var(--ink); margin-bottom: 6px; }
.empty .mark { width: 46px; height: 3px; background: var(--yellow); margin: 0 auto 16px; }

.notice {
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid #f6dfae;
  background: #fff8e8;
  color: #86560a;
  font-size: 13px;
}
.notice.error { border-color: #f7cfcf; background: #fdeaea; color: #9b1c1c; }
.notice.warn { border-color: #f0c36d; background: #fff8e6; color: #7a4b00; }

/* Sign in ----------------------------------------------------------------- */
.signin-wrap { display: flex; justify-content: center; padding: 60px 20px; }
.signin {
  width: 100%;
  max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 4px solid var(--navy);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  padding: 32px;
}
/* Pulled up to the card's top edge so the slash drops from the navy rule, the
   same way it runs off the top bar. */
.signin img { height: 84px; width: auto; display: block; margin: -32px 0 12px -21px; }
.signin h2 { margin: 0 0 4px; font-size: 18px; color: var(--navy); }
.signin p.lead { margin: 0 0 20px; font-size: 13px; color: var(--ink-soft); }
.signin label { display: block; font-size: 12px; font-weight: 600; color: var(--ink-soft); margin-bottom: 6px; }
.signin input {
  width: 100%;
  font: inherit;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 4px;
  margin-bottom: 14px;
}
.signin input:focus { outline: none; border-color: var(--navy-mid); box-shadow: 0 0 0 3px var(--navy-100); }
.signin .btn { width: 100%; padding: 11px; }
.signin .status { font-size: 12.5px; margin: 14px 0 0; min-height: 18px; }
.signin .status.ok { color: #3d6b11; }
.signin .status.err { color: #b91c1c; }

footer.foot { text-align: center; font-size: 11.5px; color: #98a0ad; padding: 8px 0 32px; }

/* Print: the register is 21 columns wide, so landscape ---------------------- */
@media print {
  @page { size: A4 landscape; margin: 12mm; }
  body { background: #fff; font-family: Arial, Helvetica, sans-serif; font-size: 9pt; }
  .topbar { position: static; box-shadow: none; border-bottom: 2px solid var(--navy); }
  .filters, .btn, .topbar .who, footer.foot, .property-picker { display: none !important; }
  table.register th.actions, table.register td.actions { display: none !important; }
  .modal { display: none !important; }
  main { padding: 0; max-width: none; }
  .property { break-inside: auto; box-shadow: none; border-radius: 0; }
  .property > header, .summary-main > header { background: #fff; color: var(--navy); border-bottom: 2px solid var(--yellow); }
  .property .meta, .chip { color: var(--ink-soft); background: none; border-color: var(--line); }
  table.register thead th { position: static; }
  .table-scroll { max-height: none !important; overflow: visible; }
  table.register tbody tr { break-inside: avoid; }
  .kpi { box-shadow: none; }
  .mix > span, .legend i { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

@media (max-width: 720px) {
  .topbar { height: auto; padding: 12px 16px; flex-wrap: wrap; gap: 12px; }
  .topbar .logo { height: 48px; margin-left: -12px; }
  .topbar .product { display: none; }
  main { padding: 16px; }
  .filters .count { margin-left: 0; }
}

/* Sign-in page extras ---------------------------------------------------- */
body.signin-page { display: flex; flex-direction: column; min-height: 100vh; }
body.signin-page main { flex: 1; }
.signin label { margin-top: 12px; }
.signin section > form > label:first-of-type { margin-top: 0; }
.signin .hint { font-size: 11.5px; color: var(--ink-soft); margin: -8px 0 4px; line-height: 1.5; }
.signin .link-btn {
  background: none; border: 0; padding: 0; font: inherit;
  color: var(--navy-mid); font-weight: 600; cursor: pointer; text-decoration: underline;
}
.signin .link-btn:hover { color: var(--navy); }

/* Users panel ------------------------------------------------------------ */
.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 20px 22px;
  margin-bottom: 20px;
}
.panel h2 { margin: 0 0 14px; font-size: 15px; color: var(--navy); }
.form-grid { display: flex; flex-wrap: wrap; gap: 14px 18px; align-items: flex-end; }
.form-grid > label { display: block; font-size: 12px; font-weight: 600; color: var(--ink-soft); }
.form-grid input[type="text"], .form-grid input[type="email"] {
  display: block; font: inherit; margin-top: 6px; padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 4px; min-width: 240px;
}
.form-grid input:focus { outline: none; border-color: var(--navy-mid); box-shadow: 0 0 0 3px var(--navy-100); }
.form-grid label.toggle { display: inline-flex; align-items: center; gap: 7px; font-weight: 500; }
.form-grid fieldset { border: 1px solid var(--line); border-radius: 6px; padding: 12px 14px; flex: 1 1 100%; margin: 0; }
.form-grid legend { font-size: 12px; font-weight: 600; color: var(--ink-soft); padding: 0 6px; }
.form-grid .hint { font-size: 11.5px; color: var(--ink-soft); margin: 8px 0 0; line-height: 1.5; }
.checkbox-list { display: flex; flex-wrap: wrap; gap: 8px 18px; }
.checkbox-list label { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink); }
/* "All properties" sits above the per-property list, which shows once it is unticked. */
.access-picker label.access-all { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; color: var(--ink); }
.access-picker .access-all-hint { margin: 4px 0 0; }
.access-picker .access-list { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
#user-create-form fieldset:disabled { opacity: .55; }

.temp-password {
  margin-top: 14px; padding: 12px 14px;
  background: var(--navy-050); border: 1px solid var(--navy-200); border-radius: 6px;
}
.temp-password .label { display: block; font-size: 10px; font-weight: 700; letter-spacing: .06em; color: var(--ink-soft); text-transform: uppercase; }
.temp-password code { display: block; margin-top: 5px; font-family: Consolas, "Courier New", monospace; font-size: 15px; font-weight: 700; color: var(--navy); letter-spacing: .03em; }

.users-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.users-table th, .users-table td { border: 1px solid var(--line); padding: 8px 10px; text-align: left; vertical-align: top; }
.users-table thead th { background: var(--navy-050); font-size: 11.5px; letter-spacing: .03em; color: var(--ink-soft); text-transform: uppercase; }
.users-table tr.inactive td { color: var(--ink-soft); background: var(--line-soft); }
.users-table td.actions { white-space: nowrap; }
.btn-sm { padding: 4px 9px; font-size: 11.5px; }
.tag {
  display: inline-block; padding: 1px 6px; border-radius: 3px; font-size: 10.5px; font-weight: 600;
  background: var(--navy-100); color: var(--navy); border: 1px solid var(--navy-200);
}
#users-view .status { font-size: 12.5px; margin: 12px 0 0; min-height: 18px; }
#users-view .status.ok { color: #3d6b11; }
#users-view .status.err { color: #b91c1c; }

/* Add/edit shop modal -------------------------------------------------------
   .btn-sm was previously only used for the Users table; reused here for the
   Add shop / Edit buttons in the register so they stay hidden in print
   without a separate rule (`.btn` is already hidden under @media print). */
table.register th.actions, table.register td.actions { white-space: nowrap; }
.property > header .btn-sm, .summary-main > header .btn-sm { margin-left: 4px; }

.modal { padding: 0; border: 0; border-radius: var(--radius); box-shadow: var(--shadow-md); max-width: 720px; width: calc(100% - 32px); }
.modal::backdrop { background: rgba(10, 20, 40, .5); }
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 22px; border-bottom: 1px solid var(--line); position: sticky; top: 0;
  background: var(--surface); border-radius: var(--radius) var(--radius) 0 0;
}
.modal-head h2 { margin: 0; font-size: 16px; color: var(--navy); }
.modal-close { background: none; border: 0; font-size: 22px; line-height: 1; color: var(--ink-soft); cursor: pointer; padding: 2px 4px; }
.modal-close:hover { color: var(--ink); }
.modal-form { max-height: 82vh; overflow-y: auto; padding: 4px 22px 22px; }
.modal-form fieldset { border: 1px solid var(--line); border-radius: 6px; margin: 16px 0 0; padding: 14px 16px; }
.modal-form legend { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); padding: 0 6px; }
.modal-form .form-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px 16px; align-items: start; }
.modal-form .form-grid label { display: block; font-size: 12px; font-weight: 600; color: var(--ink-soft); }
.modal-form .form-grid label.full, .modal-form .form-grid div.full { grid-column: 1 / -1; }
.modal-form input[type="text"], .modal-form input[type="number"], .modal-form input[type="date"],
.modal-form select, .modal-form textarea {
  display: block; width: 100%; font: inherit; font-size: 13px; margin-top: 5px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 4px; background: #fff; color: var(--ink);
}
.modal-form textarea { resize: vertical; }
.modal-form input:focus, .modal-form select:focus, .modal-form textarea:focus {
  outline: none; border-color: var(--navy-mid); box-shadow: 0 0 0 3px var(--navy-100);
}
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }
.modal-form .status { font-size: 12.5px; margin: 14px 0 0; min-height: 18px; }
.modal-form .status.err { color: #b91c1c; }
.modal-form .status.ok { color: #15803d; }
.modal-form .hint { display: block; font-size: 11.5px; font-weight: 400; line-height: 1.5; color: var(--ink-soft); margin-top: 6px; }
.modal-narrow { max-width: 460px; }

/* Leasing layout: a near full-screen dialog, since the plans are A1 drawings. */
.btn-layout { display: inline-flex; align-items: center; gap: 6px; }
.btn-layout svg { display: block; }
.modal-layout { max-width: none; width: calc(100vw - 32px); height: calc(100vh - 32px); max-height: none; }
.modal-layout[open] { display: flex; flex-direction: column; }
.modal-layout .modal-head { position: static; align-items: flex-start; }
.layout-meta { margin: 4px 0 0; font-size: 12px; color: var(--ink-soft); overflow-wrap: anywhere; }
.layout-head-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.layout-drop {
  display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap;
  margin: 12px 22px 0; padding: 14px 16px; border: 2px dashed var(--line); border-radius: 6px;
  font-size: 12.5px; color: var(--ink-soft); text-align: center;
}
.layout-drop[hidden] { display: none; }
.layout-drop.dragging { border-color: var(--navy); background: #eef3fb; color: var(--navy); }
.layout-status { margin: 8px 22px 0; font-size: 12.5px; min-height: 18px; }
.layout-status.err { color: #b91c1c; }
.layout-status.ok { color: #15803d; }
.layout-viewer { flex: 1; min-height: 0; margin: 8px 22px 0; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; display: flex; position: relative; background: #f4f6f9; }
.layout-viewer > .empty { margin: auto; }
/* The plan is drawn at full size and scaled with a transform (js/app.js), so
   zoom and pan never redraw it. The overlay canvas carries the stage colours. */
.layout-stage { position: absolute; left: 0; top: 0; transform-origin: 0 0; touch-action: none; }
.layout-stage canvas { position: absolute; left: 0; top: 0; display: block; }
.layout-stage canvas.overlay-hidden { visibility: hidden; }
.layout-viewer.map-pan { cursor: grab; }
.layout-viewer.map-pick { cursor: crosshair; }
.layout-viewer.map-dragging { cursor: grabbing; }
.layout-loading { margin: auto; color: var(--ink-soft); font-size: 13px; }
.map-tools { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 8px 22px 0; }
.map-tools[hidden], .map-banner[hidden], .map-info[hidden], .map-foot[hidden] { display: none; }
.map-tools-group { display: flex; flex-wrap: wrap; gap: 6px; }
.map-tools .btn[aria-pressed="true"] { background: #eef3fb; border-color: var(--navy); color: var(--navy); }
.map-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 22px 0; padding: 8px 12px; border-radius: 6px; background: #fff8db; border: 1px solid var(--yellow); font-size: 13px; }
.map-banner > span { flex: 1 1 260px; }
.map-info { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 22px 0; font-size: 13px; }
.map-info > span { margin-right: 4px; }
.map-swatch, .map-key i { display: inline-block; width: 14px; height: 14px; border: 1px solid #2b2b2b; border-radius: 2px; vertical-align: -2px; }
.map-foot { margin: 8px 22px 18px; font-size: 12.5px; }
.map-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; align-items: center; }
.map-key { display: inline-flex; align-items: center; gap: 6px; }
.map-count { color: var(--ink-soft); margin-left: auto; }
.map-unset { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 8px 0 0; color: var(--ink-soft); }
.map-unset > span { margin-right: 4px; }
.modal-actions .btn-map { margin-right: auto; }

/* Gear on the property card: icon-only, same outline style as Add shop */
.btn-icon { display: inline-flex; align-items: center; justify-content: center; padding: 4px 7px; line-height: 0; }
.btn-icon svg { display: block; }
/* Reload in the top bar: a square the same height as Users and Sign out */
.topbar .btn-icon { padding: 0; width: 38px; height: 38px; }

/* Group tabs: one summary card per property, the whole card links to
   that property's register */
/* Trading centres / Upcoming centres tabs: a heading with the count, then that group's KPI row and cards. */
.property-group { margin-bottom: 32px; }
.group-title {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 0 0 14px;
  padding-bottom: 8px;
  border-bottom: 3px solid var(--yellow);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--navy);
}
.group-count { font-size: 12px; font-weight: 600; color: var(--ink-soft); letter-spacing: .03em; }
.group-empty { margin: 0; padding: 14px 18px; color: var(--ink-soft); font-size: 13px; }

a.property-summary {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: border-color .12s, box-shadow .12s;
}
a.property-summary:hover {
  border-color: var(--navy-mid);
  box-shadow: 0 4px 10px rgba(16, 30, 54, .08), 0 14px 32px rgba(16, 30, 54, .12);
}
a.property-summary:focus-visible { outline: 3px solid var(--yellow); outline-offset: 2px; }
.property-summary .open-hint {
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--navy-200);
  transition: color .12s;
}
a.property-summary:hover .open-hint { color: #fff; }
.summary-kpis { padding: 16px 18px; }
.summary-kpis .kpis { margin-bottom: 0; }
.summary-kpis .kpi { box-shadow: none; }

@media (max-width: 720px) {
  .summary-kpis { padding: 12px; }
  .summary-kpis .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
}

@media print {
  .property-summary .open-hint { display: none; }
  .property-summary { break-inside: avoid; }
}

@media (max-width: 720px) {
  .modal { width: calc(100% - 20px); }
  .modal-form { padding: 4px 16px 16px; }
  .modal-layout { height: calc(100vh - 20px); }
  .layout-drop, .layout-status { margin-left: 12px; margin-right: 12px; }
  .layout-viewer { margin: 8px 12px 0; }
  .map-tools, .map-banner, .map-info { margin-left: 12px; margin-right: 12px; }
  .map-foot { margin: 8px 12px 12px; }
  .map-count { margin-left: 0; }
  .layout-drop-text { display: none; }
}

/* Settings menu (top bar) ------------------------------------------------ */
.menu-wrap { position: relative; }
.menu-wrap .caret { font-size: 11px; margin-left: 2px; }
.menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
  min-width: 190px; padding: 6px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-md);
}
.menu button {
  display: block; width: 100%; text-align: left;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--navy);
  padding: 9px 12px; border: 0; border-radius: 4px; background: none; cursor: pointer;
}
.menu button:hover, .menu button:focus-visible { background: var(--navy-050); outline: none; }

/* Communication panel ---------------------------------------------------- */
#comms-view .hint { font-size: 12.5px; color: var(--ink-soft); margin: -6px 0 14px; line-height: 1.5; }
#comms-view .status { font-size: 12.5px; margin: 12px 0 0; min-height: 18px; }
#comms-view .status.ok { color: #3d6b11; }
#comms-view .status.err { color: #b91c1c; }
.actions-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.digest-table th.tick, .digest-table td.tick { text-align: center; width: 1%; white-space: nowrap; }
.digest-table td.tick input { width: 16px; height: 16px; cursor: pointer; }
.digest-table td.tick input:disabled { cursor: not-allowed; opacity: .35; }
.digest-table .sub, .runs-table .sub { font-size: 11px; color: var(--ink-soft); }
.runs-table .err { color: #b91c1c; }
.runs-table .muted { color: var(--ink-soft); }
.runs-table tr.has-failure td { background: #fdf3f3; }

/* Section tabs: Retail | Office | Industrial | Introductions ------------- */
/* Photo tiles after abland.co.za's sector tiles, using the website's own
   sector photos. The site multiplies them under navy; at this size that leaves
   them almost black, so a translucent navy wash is used instead. Hover and the
   open tab lighten the top, and the open tab carries the yellow rule. */
.section-tabs {
  display: flex; gap: 10px; flex-wrap: wrap;
  margin: -4px 0 22px;
}
.section-tabs a {
  --tile: none;
  display: flex; align-items: flex-end; flex: 0 0 190px; height: 64px;
  padding: 0 14px 9px;
  font-size: 15px; font-weight: 600; letter-spacing: .01em; color: #fff;
  text-decoration: none;
  background-color: var(--navy);
  background-image: linear-gradient(rgba(2, 63, 136, .72), rgba(2, 63, 136, .72)), var(--tile);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .45);
  background-size: auto, cover; background-position: 50% 50%;
  border-bottom: 3px solid transparent;
  border-radius: 3px 3px 0 0;
  box-shadow: var(--shadow-sm);
  transition: border-color .15s;
}
.section-tabs a[data-tab="retail"] { --tile: url("../assets/sectors/retail.webp"); }
.section-tabs a[data-tab="office"] { --tile: url("../assets/sectors/office.webp"); }
.section-tabs a[data-tab="industrial"] { --tile: url("../assets/sectors/industrial.webp"); }
.section-tabs a:hover,
.section-tabs a.active { background-image: linear-gradient(rgba(2, 63, 136, .25), rgba(2, 63, 136, .8)), var(--tile); }
.section-tabs a.active { border-bottom-color: var(--yellow); font-weight: 700; }
.section-tabs a:focus-visible { outline: 3px solid var(--yellow); outline-offset: 2px; }

/* Property photos (migration 0021). On the Upcoming/Trading cards the photo
   runs down the left of the card; the register header carries a thumbnail. */
a.property-summary { display: grid; grid-template-columns: 250px minmax(0, 1fr); }
.summary-main { min-width: 0; }
/* Beside the photo the seven summary cards are compact, one row on a wide screen. */
.summary-main .summary-kpis { padding: 14px 18px 16px; }
.summary-main .summary-kpis .kpis { gap: 10px; }
.summary-main .summary-kpis .kpi { padding: 11px 12px 10px; }
.summary-main .summary-kpis .kpi .label { font-size: 10px; letter-spacing: .05em; }
.summary-main .summary-kpis .kpi .value { font-size: 22px; margin-top: 4px; }
.summary-main .summary-kpis .kpi .sub { font-size: 11px; }
@media (min-width: 1200px) {
  .summary-main .summary-kpis .kpis { grid-template-columns: repeat(7, minmax(0, 1fr)); }
}
@media (max-width: 1100px) {
  a.property-summary { grid-template-columns: 190px minmax(0, 1fr); }
}
.summary-photo {
  position: relative;
  min-height: 180px;
  overflow: hidden;
  background: var(--navy-dark);
  border-bottom: 3px solid var(--yellow);
}
.summary-photo .photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
  transition: transform .35s ease;
}
a.property-summary:hover .summary-photo .photo { transform: scale(1.04); }
.summary-photo.no-photo {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  color: rgba(255, 255, 255, .35);
  background: linear-gradient(160deg, var(--navy) 0%, var(--navy-dark) 100%);
}
.no-photo-text { font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.photo-badge {
  position: absolute; top: 12px; left: 12px; right: 12px;
  padding: 5px 8px;
  background: rgba(99, 100, 102, .78);
  color: #fff;
  font-size: 12px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; text-align: center;
}
.site-photo-label { display: block; font-size: 12px; font-weight: 600; color: var(--ink-soft); margin-bottom: 6px; }
.site-photo-row { display: flex; gap: 14px; align-items: flex-start; }
.site-photo-preview {
  flex: none; width: 150px; height: 100px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 4px; background: var(--navy-050);
  font-size: 12px; color: var(--ink-soft);
}
.site-photo-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.site-photo-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.site-photo-actions .hint { flex-basis: 100%; margin-top: 2px; }
.site-photo .status { margin: 8px 0 0; }
.property > header .header-photo {
  width: 76px; height: 46px; flex: none;
  object-fit: cover; border-radius: 4px;
  border: 1px solid rgba(255, 255, 255, .35);
  margin: -4px 0;
}

/* Introductions ---------------------------------------------------------- */
.lead-stage { background: var(--line-soft); color: var(--ink); border-color: var(--line); }
.lead-won { background: #edf8e0; color: #3d6b11; border-color: #d3ecb4; }
.lead-lost { color: var(--ink-soft); }
table.intro-table td { vertical-align: top; }
table.intro-table tr.intro-row { cursor: pointer; }
table.intro-table tr.intro-row:focus-visible { outline: 2px solid var(--navy); outline-offset: -2px; }
/* One heading row, not the register's two, so it sticks at the top of the box. */
table.intro-table thead tr.cols th { top: 0; }
table.intro-table .sub { display: block; font-size: 11px; color: var(--ink-soft); margin-top: 2px; white-space: normal; }
table.intro-table .sub.overdue { color: #b91c1c; font-weight: 700; }
table.intro-table .lead-name { font-weight: 700; color: var(--navy); }
.intro-card > header .meta { margin-left: 4px; }
/* One card per building: the lead tables flow with the page instead of
   scrolling inside a fitted box like the register. */
.intro-scroll { max-height: none; }
.intro-none { margin: 0; padding: 14px 18px; color: var(--ink-soft); font-size: 13px; }

.modal-intro { max-width: 860px; }
.modal-form input[type="email"] {
  display: block; width: 100%; font: inherit; font-size: 13px; margin-top: 5px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 4px; background: #fff; color: var(--ink);
}
.modal-form .status.ok { color: #3d6b11; }
.modal-form fieldset:disabled input, .modal-form fieldset:disabled select, .modal-form fieldset:disabled textarea {
  background: var(--line-soft); color: var(--ink);
}
#intro-history-wrap { margin-top: 22px; }
.intro-links { display: flex; flex-direction: column; gap: 6px; }
.intro-links > label { margin: 0; }
.link-row { display: flex; gap: 8px; align-items: center; }
.link-row select { flex: 0 1 360px; min-width: 0; }
.link-chips { display: flex; flex-wrap: wrap; gap: 6px; min-height: 26px; align-items: center; }
.link-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 4px 3px 10px; border-radius: 999px;
  background: var(--navy-050); color: var(--navy); border: 1px solid var(--line); font-size: 12.5px; font-weight: 600; }
.link-chip button { border: 0; background: transparent; color: var(--ink-soft); font-size: 16px; line-height: 1;
  cursor: pointer; padding: 0 6px; border-radius: 999px; }
.link-chip button:hover { background: #fff; color: #b91c1c; }
fieldset:disabled .link-chip { padding-right: 10px; }
.note-box { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 14px; }
.note-box textarea { flex: 1; margin-top: 0 !important; }
.note-box[hidden] { display: none; }
.history { list-style: none; margin: 0; padding: 0; }
.history .ev { padding: 9px 0 9px 14px; border-left: 3px solid var(--navy-200); margin-left: 2px; }
.history .ev + .ev { border-top: 1px solid var(--line-soft); }
.history .ev-created { border-left-color: var(--navy); }
.history .ev-stage { border-left-color: var(--yellow); }
.history .ev-email { border-left-color: #92d050; }
.won-box { margin-top: 14px; padding: 12px 14px; border: 2px solid #92d050; border-radius: 8px; background: #f6fbef; }
.won-box h3 { margin: 0 0 4px; font-size: 13px; color: var(--navy); }
.won-box .hint { margin: 0 0 8px; }
.won-box .won-done { margin: 0; font-size: 13px; color: var(--ink); }
.email-warn { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin: 14px 0 0; }
.modal-form .send-check { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 14px 0 0; font-weight: 600; color: var(--ink); }
.modal-form .send-check input { width: auto; margin: 0; }
.modal-form .send-check .hint { flex-basis: 100%; font-weight: 400; margin-left: 24px; }
.history .ev-note { white-space: pre-wrap; margin: 0; }
.history .ev-when { font-size: 11.5px; color: var(--ink-soft); margin-bottom: 3px; }
.history .ev-what { font-size: 13px; color: var(--ink); }
.history .ev-what p { margin: 4px 0 0; }

@media print {
  .section-tabs { display: none !important; }
  table.intro-table th.actions, table.intro-table td.actions { display: none !important; }
}

@media (max-width: 720px) {
  .section-tabs { gap: 6px; }
  .section-tabs a { flex: 1 1 0; min-width: 0; height: 50px; padding: 0 10px 7px; font-size: 13px; }
  a.property-summary { grid-template-columns: minmax(0, 1fr); }
  .summary-photo { min-height: 140px; }
  .property > header .header-photo { width: 60px; height: 38px; }
  .note-box { flex-direction: column; align-items: stretch; }
  /* A long property name must not push the page sideways. */
  .property-picker { max-width: 100%; }
  .property-picker select { min-width: 0; max-width: 100%; flex: 1 1 auto; }
  .link-row select { flex: 1 1 auto; }
}
