/* app.css | the frame: rail, topbar, content column, and the shared card
 * vocabulary every screen draws with. Screen specific styling lives with the
 * screen, not here. */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--cream);
  color: var(--dark);
  font-family: Poppins, "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.45;
}

/* Buttons default to centred, bordered, background filled chrome. The rail and
 * every inline link are buttons rather than anchors, so that chrome is undone
 * once here rather than per element. */
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  text-align: left;
  cursor: pointer;
}

.app { display: flex; min-height: 100vh; }

/* ---------- rail ---------- */
.rail {
  width: var(--rail-w);
  flex: 0 0 var(--rail-w);
  background: var(--dark);
  min-height: 100vh;
  padding: 16px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* The supplied lockup, sized to the rail. width:100% with height:auto keeps the
 * aspect ratio from the intrinsic attributes on the element, so the rail does
 * not jump when the image lands. */
.rail .brand { padding: 4px 8px 16px; }

/* ---------- the rail folds (15 September 2026) ----------
   Benjamin: "Make the side main menu on the left collapsible." Folded it keeps
   its ICONS and loses its labels, so it stays navigable: a menu that vanishes
   makes an advisor unfold it to find out where they are, which is a worse trade
   than a narrow one.

   The class is on .app, not on .rail, because the content column has to know:
   the width it gives back is the point, and a class only the rail could see
   would leave the column laid out for a rail that is no longer there. */
.rail-fold {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 8px; padding: 6px 10px;
  background: none; border: 0; border-radius: 6px;
  color: rgba(255,255,255,.55); font: inherit; font-size: 11px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; cursor: pointer;
}
.rail-fold:hover { background: rgba(255,255,255,.07); color: #fff; }
.rail-fold .fold-ico { flex: 0 0 16px; transition: transform .12s ease; }
.app.rail-folded .rail { width: 56px; flex: 0 0 56px; padding-left: 6px; padding-right: 6px; }
.app.rail-folded .rail-fold { justify-content: center; padding-left: 0; padding-right: 0; }
.app.rail-folded .rail-fold .fold-ico { transform: rotate(180deg); }
/* The label of every row goes, the icon stays. The row keeps its full height and
   centres, so the hit target does not shrink with the text. */
/* ⚠️ `.railfilter`, NOT `.rf-wrap`, CORRECTED 15 September 2026. The fold shipped
   naming a class that exists nowhere in this estate, so the Filters card, a
   panel of selects, chip groups and date boxes laid out for a 240px column, went
   on drawing itself inside a 56px rail, overflowing it, while the mini dashboard
   beside it in the same selector list correctly disappeared. Benjamin's report
   was about the card above it ("when collapsing the left main menu, the
   Mini-dashboard in the menu should disappear"), and the mini dashboard was
   already hidden: what he was looking at was this one. A typo'd selector fails
   silently, which is why it survived a byte-verified deploy.
   ⚠️ AND THE DASHBOARD IS STILL REACHABLE FOLDED, which is the other half of the
   same instruction: hiding the mini dashboard took away the only door to
   #/dashboard, so nav.js put a Dashboard row in the Advisor folder. A row is an
   icon and survives the fold. */
.app.rail-folded .rail .nav > span:not(.ico):not(.ext),
.app.rail-folded .rail .nav-parent > span:not(.ico),
.app.rail-folded .rail .section,
.app.rail-folded .rail .minidash,
.app.rail-folded .rail .railfilter,
.app.rail-folded .rail .nav-parent .chev { display: none; }
.app.rail-folded .rail .nav, .app.rail-folded .rail .nav-parent { justify-content: center; padding: 8px 0; }
/* ⚠️ THE CHILDREN OF A FOLDED FOLDER STAY VISIBLE AND KEEP THEIR ICONS. Hiding
   them would make a folded rail unable to reach Buyer Representation at all,
   which is the "menu that vanishes" this design is avoiding; the indent goes
   because there is no parent label to indent from. */
.app.rail-folded .rail .nav-children { margin-left: 0; }
.app.rail-folded .rail .nav-child { padding-left: 0; }
.app.rail-folded .rail .brand { padding: 4px 0 12px; }
.app.rail-folded .rail .brand .brand-logo { width: 100%; }
/* A count badge still has to be legible on a 56px rail: it sits on the icon
   rather than after a label that is no longer drawn. */
.app.rail-folded .rail .rail-count { position: absolute; top: 2px; right: 6px; }
.app.rail-folded .rail .nav { position: relative; }
/* ⚠️ HALF WIDTH SINCE 26 Aug 2026, on instruction. The lockup is wide and was
   filling the rail; height follows from the aspect ratio, and the intrinsic
   width/height on the <img> still prevents a reflow when it loads. */
.rail .brand .brand-logo { display: block; width: 50%; height: auto; }

.rail .section {
  color: var(--lime);
  font-size: 9.5px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  padding: 14px 10px 5px;
  font-weight: 600;
}

.rail .nav {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 10px; border-radius: 7px;
  color: #c8d3da; font-size: 13px; width: 100%;
}
.rail .nav:hover { background: rgba(255,255,255,.07); color: #fff; }
.rail .nav.active { background: var(--green); color: #fff; font-weight: 600; }
.rail .nav .ico { width: 15px; height: 15px; flex: 0 0 15px; opacity: .9; }
.rail .nav .stub-dot {
  margin-left: auto; width: 5px; height: 5px; border-radius: 50%;
  background: var(--slate); flex: 0 0 5px;
}
/* The open client-request count, 13 September 2026. Deliberately unlike the
   stub dot beside it: that one says a destination is unbuilt, this one says
   there is work waiting, and a reader who confused the two would take a busy
   board for a broken page. Lime on the dark rail is the same "this is live"
   colour the mini dashboard uses. */
.rail .nav .rail-count {
  margin-left: auto; flex: none; min-width: 18px; text-align: center;
  font-size: 10px; font-weight: 800; line-height: 16px; border-radius: 9px;
  padding: 0 5px; background: var(--lime); color: var(--dark);
}
.rail .nav.active .rail-count { background: #fff; color: var(--green); }

/* ---------- the rail's second level, and rows that leave ----------
   15 September 2026, on Benjamin's instruction (nav.js says which). A folder
   row is a button that only unfolds: it has no active fill of its own, because
   a child is the page, and lights up (has-active) with the open chevron when a
   child is current. A child is indented under it. A link row is an anchor to
   another site and carries an arrow so the reader knows it leaves. The anchor
   takes the same rules as the button so the three kinds of row line up. */
.rail a.nav { text-decoration: none; }
.rail .nav.nav-parent .chev { margin-left: auto; width: 12px; height: 12px; flex: 0 0 12px; opacity: .7; transition: transform .15s ease; }
.rail .nav.nav-parent[aria-expanded="true"] .chev { transform: rotate(180deg); }
.rail .nav.nav-parent.has-active { color: #fff; font-weight: 600; }
.rail .nav.nav-child { padding-left: 34px; font-size: 12.5px; }
.rail .nav-children[hidden] { display: none; }
.rail .nav .ext { margin-left: auto; font-size: 11px; opacity: .7; }

/* ---------- mini dashboard ---------- */
.minidash {
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.09);
  border-radius: 10px;
  padding: 10px 12px 8px;
  margin: 0 2px 12px;
}
.minidash-head {
  display: flex; align-items: center; gap: 8px; width: 100%;
  color: #fff; font-weight: 600; font-size: 13px; padding-bottom: 6px;
}
.minidash-head.active { color: var(--lime); }
.md-sec {
  color: var(--lime); font-size: 9px; letter-spacing: 1.1px;
  text-transform: uppercase; margin: 8px 0 3px; font-weight: 600;
}
.md-row { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; }
.md-row span { color: #a9b7c0; font-size: 11.5px; }
.md-row b { color: #fff; font-size: 11.5px; font-weight: 600; }
.md-sub { color: #7f8f9a; font-size: 10px; }

/* ---------- collapse, on the mini dashboard and the filter ----------
   Ported from the mockup. The chevron rotates rather than swapping glyph, so
   there is one icon and one state, and the transition makes the direction of
   the change legible. */
.rf-head-row {
  display: flex; align-items: center; justify-content: space-between;
  margin: 0 0 8px; padding: 0 0 8px;
  border-bottom: 1px solid rgba(255,255,255,.1);
}
.rf-head-label {
  color: rgba(255,255,255,.55); font-size: 10px; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase;
}
.collapse-toggle {
  background: none; border: none; padding: 2px; cursor: pointer;
  color: rgba(255,255,255,.5); display: flex; align-items: center;
}
.collapse-toggle:hover { color: #fff; }
.collapse-chev { width: 13px; height: 13px; transition: transform .15s ease; }
/* ⚠️ THE HEAD STAYS, THE BODY GOES. Collapsing the mini dashboard hides its
   figures, not its own header row, or there would be nothing left to click to
   bring it back. */
.minidash.collapsed #minidashBody,
.railfilter.collapsed .rf-content { display: none; }
.minidash.collapsed .collapse-chev,
.railfilter.collapsed .collapse-chev { transform: rotate(-90deg); }

/* ---------- rail filter ----------
   Sits between the mini dashboard and the nav rows. Deliberately quieter than a
   nav row: it acts on the list to the RIGHT, and styling it like a destination
   would suggest it navigates. */
.railfilter { margin: 0 2px 10px; }
/* ⚠️ THE FILTER MARKUP SHIPPED WITHOUT ITS STYLING, 27 Aug 2026. The panel was
   ported from the mockup and these eight classes were not, so every control fell
   back to browser defaults: white select boxes on a dark rail, invisible labels,
   and .between-dates with no display:none, which left the two date inputs
   permanently on screen instead of appearing only for "Between". Reported from a
   screenshot; a suite that asserts markup cannot see any of it.

   Extracted from the mockup rather than retyped. .rf-head-row and .rf-head-label
   are ours already, shared with the mini dashboard so the two cards collapse
   identically, so those two were not taken.

   ⚠️ CORAL ON .fsel AND .fsearch IS CORRECT AND IS NOT AN EXCEPTION. The house
   rule is coral only for EDITABLE INPUT TEXT, and these are editable inputs. A
   value the advisor sets reads coral here for the same reason it does in the
   record forms. */
.rf-sec { color:var(--lime);font-size:9.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;padding:0 0 4px }
.rf-lb { color:rgba(255,255,255,.5);font-size:9.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;padding:6px 0 3px }
.fsel,.fsearch { width:100%;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.16);color:var(--coral);font-weight:600;font-family:inherit;font-size:12px;border-radius:8px;padding:7px 9px;margin:0 0 2px }
.fsearch::placeholder { color:rgba(255,255,255,.35);font-weight:400 }
.fsel option { color:var(--dark) }
.fchips { display:flex;flex-wrap:wrap;gap:5px;margin:0 0 2px }
.fchip { font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:rgba(255,255,255,.75);border:1px solid rgba(255,255,255,.2);border-radius:7px;padding:4px 8px;cursor:pointer }
.fchip.active { background:rgba(208,237,101,.16);border-color:var(--lime);color:var(--lime) }
.rf-note { color:rgba(255,255,255,.42);font-size:10px;line-height:1.5;padding-top:5px }
.between-dates { display:none;gap:6px;margin:2px 0 2px }
.between-dates.show { display:flex }
.between-dates input[type=date] { flex:1;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.16);color:var(--coral);font-weight:600;font-family:inherit;font-size:11.5px;border-radius:8px;padding:6px 7px;color-scheme:dark }

/* ---------- topbar ---------- */
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.topbar {
  background: var(--topbar);
  padding: 13px 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.topbar .crumb { color: #93a3ad; font-size: 10.5px; letter-spacing: .6px; text-transform: uppercase; }
.topbar .title { color: #fff; font-size: 17px; font-weight: 600; }
.topbar .search {
  background: rgba(255,255,255,.10); border: 1px solid rgba(255,255,255,.14);
  border-radius: 7px; padding: 6px 10px; color: #fff; min-width: 200px;
}
.topbar .search::placeholder { color: #8fa0ab; }
.uptick { height: 3px; background: var(--uptick); }

/* ---------- content ---------- */
/* ⚠️ THE SPACING RULE OF THE RECORD PAGE REDESIGN, 15 September 2026
   (EDGE_UIRedesign_Review_v1_0.md §3.4, Benjamin's brief: "The current method
   of panels and line by line info is wasting a lot of space"). Content
   16px 24px (was 22), cards 12px apart (was 16), heads and rows 8px 14px
   (were 10). On a fifteen card page that is about 100px for nothing; the
   density and the two columns below do the rest. The record pages widen the
   column to 1240 (.content-wide) so two columns fit at laptop width. */
.content { padding: 16px 24px 10px; max-width: var(--content-max); width: 100%; margin: 0 auto; flex: 1; }
/* ⚠️ 1240 TO 1560, PCR-2026-09-25-01, and this is the ONE number in the change.
   The advisor: "this whole page can be widened so that everything can fit". The
   Client panel's authorized contacts table is seven columns and is already in
   the WIDER of the two columns, so the room has to come from the page rather
   than from the split. Benjamin ruled 29 September 2026 that it comes from the
   ceiling and not from the right hand column, which is left at its share so the
   panels there are not squeezed.

   ⚠️ NOTHING MOVES ON A LAPTOP. Below 1560 the page was already using every
   pixel it had, so this only takes effect on a monitor that was previously
   showing grey either side. The prose argument that caps other screens does not
   apply to a table, which is scanned across rather than read down a measure:
   the same reasoning content-full records below. */
.content.content-wide { max-width: 1560px; }
/* ⚠️ THE WHOLE WINDOW, ONE SCREEN ONLY, 15 September 2026. Benjamin: "Make the
   business target page wide enough so I do not have to scroll side to side."
   That board is fifteen columns of grid and no reading-width argument applies to
   it: a table is scanned across, not read down a measure. Every other screen
   keeps its max-width, because prose at 1600px is worse, not better. Paired with
   the collapsible rail, which gives this page back another 184px when it is
   folded. */
.content.content-full { max-width: none; padding-left: 14px; padding-right: 14px; }
/* ⚠️ THE SELECTS ARE CAPPED ON A FULL WIDTH BOARD. In an auto layout table a
   select sizes to its WIDEST OPTION, so "Waiting for Information" in Move To set
   the width of a column whose cells mostly read "Reviewing". Capping them and
   letting the closed control ellipsize costs nothing (the open list is not
   clipped by this) and took the board under a 1440 window with the rail open,
   which folding it alone did not. */
.content-full .board-sel { max-width: 118px; }
.panel { display: none; }
.panel.active { display: block; }

.card {
  background: var(--paper); border: 1px solid var(--border);
  border-radius: 10px; margin-bottom: 12px; overflow: hidden;
}
.card-head {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap; row-gap: 2px;
  padding: 8px 14px; background: var(--tint); border-bottom: 1px solid var(--border);
}
/* Side-scoped card heads, 1 Sep 2026: a buy side card and a sell side card are
   told apart by their header, portal wide, using the same hues as the side
   pills below. The inset bar carries the distinction for anyone the tints
   alone do not reach. */
.card-head.head-buy { background: var(--buy-tint); box-shadow: inset 4px 0 0 var(--buy); }
.card-head.head-sell { background: var(--sell-tint); box-shadow: inset 4px 0 0 var(--sell); }
/* The third state, added 6 Sep 2026 with the Add New panels: a card that belongs
   to NEITHER side, which until now was simply an unstyled head. Same tint it
   already had, plus the inset bar, so a panel with no side reads as a deliberate
   third thing beside the other two rather than as one somebody forgot. */
.card-head.head-neutral { background: var(--tint); box-shadow: inset 4px 0 0 var(--slate); }
/* ⚠️ THE COLOUR RULE, 15 September 2026, Benjamin's answer to "what should
   the colour mean": THE SIDE OF THE RECORD. A record page sets ONE class on
   #screenHost from sideOf(record), tone-buy, tone-sell or tone-neutral, and
   every card head under it takes that tone: the three tints and bars above,
   unchanged, applied by a rule instead of by five hand placed classes. A
   contact or a company is neutral; a deal takes its engagement's side. No
   card decides its own colour, so the colour cannot drift from the record.
   The card that ENDS a record keeps a caution bar whatever the side, because
   leaving is not a side. Label colours are the two AA greens and blue of
   §2.16. Consulting: to be ruled on when it is drawn. */
.tone-buy .card-head { background: var(--buy-tint); box-shadow: inset 4px 0 0 var(--buy); }
.tone-sell .card-head { background: var(--sell-tint); box-shadow: inset 4px 0 0 var(--sell); }
.tone-neutral .card-head { background: var(--tint); box-shadow: inset 4px 0 0 var(--slate); }
.tone-sell .sec-label { color: var(--status-pass-text); }
.tone-buy .sec-label { color: var(--buy); }
.card.card-end .card-head { background: var(--status-caution-bg); box-shadow: inset 4px 0 0 var(--status-caution); }
.card.card-end .sec-label { color: var(--status-caution-text); }
/* The right-aligned roll-up on a totalled panel (Sold, Acquired, Won). */
.head-total { margin-left: auto; font-size: 11.5px; font-weight: 700; color: var(--dark); white-space: nowrap; }
.sec-label {
  color: var(--dark); font-size: 10px; letter-spacing: 1.1px;
  text-transform: uppercase; font-weight: 700;
}
.sub-note { color: var(--slate); font-size: 10.5px; }
/* ⚠️ AN EMPTY PANEL, COLLAPSED TO ITS HEADING, 13 September 2026. The typical
   company record fills almost none of its twelve panels (97% carry no
   financials, 46% no linked contact), so the page was a scroll of cards each
   saying it had nothing. The wording is kept and moved behind this toggle, and
   the [hidden] override is scoped here because an author display rule beats the
   browser's own [hidden] and the panel bodies are plain divs today only. */
.card.panel-empty { opacity: .82; }
.card.panel-empty [hidden] { display: none !important; }
.empty-toggle {
  margin-left: auto; background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--slate); font-size: 10.5px; text-decoration: underline;
  font-family: inherit;
}
.empty-toggle:hover { color: var(--dark); }
/* ⚠️ A FOLDED PANEL, 13 September 2026: the Lost card on Deals in Motion opens
   on a click and builds its list only then. The [hidden] override is scoped
   here for the same reason it is scoped everywhere else in this file, an author
   display rule beats the browser's own [hidden] and jsdom cannot see it. */
.fold-slot[hidden], .fold-foot[hidden], .card[hidden] { display: none !important; }
.fold-foot { margin: -8px 0 16px; text-align: right; }
.disclosure-toggle {
  margin-left: auto; background: none; border: 1px solid var(--border);
  border-radius: 6px; padding: 3px 10px; cursor: pointer;
  color: var(--slate); font-size: 10.5px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; font-family: inherit;
}
.disclosure-toggle:hover { color: var(--dark); border-color: var(--slate); }
.row { display: flex; align-items: center; gap: 10px; padding: 8px 14px; border-top: 1px solid var(--border); }
.row .grow { flex: 1; min-width: 0; }
.row-foot { padding: 9px 14px; color: var(--slate); font-size: 11px; background: var(--tint); border-top: 1px solid var(--border); }

/* Explicit colour on every value bearing class. See the note in tokens.css. */
.name, .money, .stat .n, .company-name, .contact-name, .eng-title, table.t td { color: var(--dark); }
.name { font-weight: 600; }
.meta { color: var(--slate); font-size: 11.5px; }

/* ---------- a control that cannot be used must LOOK like it ----------
   Found by browser measurement, 8 September 2026, and it is older and wider
   than the change that found it: this stylesheet had no `:disabled` rule at
   all, so every disabled control in the portal was painted exactly like a live
   one. That matters here more than in most estates, because the house pattern
   is deliberately to DRAW a control that is not yet usable, disable it and put
   the reason beside it, rather than hide it from the person trying to meet its
   precondition. The reason was beside it and the button still looked ready to
   click, which is the pattern half working: Record the fee before a fee is
   typed, Send the commission before a deal is Acquired, Assign an Engagement
   ID on a record that already has one.

   The harness cannot see this: jsdom has no box model and no computed paint,
   so nine hundred assertions passed over buttons asserting `.disabled === true`,
   which was true and invisible. */
.btn:disabled,
button:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; }
select:disabled,
input:disabled,
textarea:disabled { opacity: .55; cursor: not-allowed; }

/* ⚠️ EVERY LIST TABLE SITS IN THIS, and it does nothing until the screen sets a
   min-width on the table (listview.js `spec.minWidth`). A fixed-layout table's
   percentage columns have no floor, so at a narrow viewport a cell holding a
   select or a button gets less room than the control needs and CLIPS it: the
   leads table printed "Conver" at 768 wide from the day it shipped. A min-width
   plus this wrapper gives those columns their floor and moves the overflow into
   a scrollbar on the table, which is where the house rule wants wide content.
   The card is `overflow: hidden`, so the scrollbar belongs to the wrapper and
   the page body still never scrolls sideways. */
.t-scroll { overflow-x: auto; }
table.t { width: 100%; border-collapse: collapse; table-layout: fixed; }
table.t th {
  text-align: left; font-size: 10px; letter-spacing: .8px; text-transform: uppercase;
  color: var(--slate); padding: 8px 14px; border-bottom: 1px solid var(--border); background: var(--tint);
}
table.t td { padding: 9px 14px; border-bottom: 1px solid var(--border); font-size: 13px; }
table.t tr:last-child td { border-bottom: 0; }

.pill {
  display: inline-block; padding: 2px 8px; border-radius: 20px;
  font-size: 10px; font-weight: 600; letter-spacing: .3px;
}
/* ⚠️ A PILL THAT IS A BUTTON, PCR-2026-09-25-01. The client tools row used to
   carry a pill showing the state and a separate link doing the work; the pill is
   now the control. `.pill` was written for a span, so a <button> needs the UA's
   own border, background and font undone or it draws as a grey chip.

   ⚠️ THE COLOUR STILL COMES FROM .pill-pass AND .pill-tint, which is why
   `background` is reset to transparent here and not to a value: setting one
   would win against whichever tone class follows and every toggle would look
   the same. */
.pill.tool-toggle {
  border: 0; background: transparent; font-family: inherit; cursor: pointer;
  line-height: 1.6;
}
.pill.tool-toggle:disabled { opacity: .5; cursor: default; }
.pill.tool-toggle:focus-visible { outline: 2px solid var(--dark); outline-offset: 1px; }
/* ⚠️ A THUMB NEEDS MORE THAN SIXTEEN PIXELS. Benjamin, 29 September 2026:
   tablets happen, phones rarely. Below the width where the record page stops
   being two columns, the control grows to a comfortable tap size. A mouse loses
   nothing because this never applies on a laptop. */
@media (max-width: 1179px) {
  .pill.tool-toggle { min-height: 34px; min-width: 52px; padding: 6px 14px; font-size: 12px; }
}
.pill-pass { background: var(--status-pass-bg); color: var(--status-pass-text); }
.pill-caution { background: var(--status-caution-bg); color: var(--status-caution-text); }
.pill-error { background: var(--status-error-bg); color: var(--status-error-text); }
.pill-tint { background: var(--tint); color: var(--slate); }
.side-buy { background: var(--buy-tint); color: var(--buy); }
.side-sell { background: var(--sell-tint); color: var(--status-pass-text); }

.link { color: var(--green); font-weight: 600; cursor: pointer; }
.link:hover { text-decoration: underline; }
/* ⚠️ A LINK INSIDE GREY META IS CLICKABLE WITHOUT BEING A SECOND GREEN CLAIM,
   15 September 2026, and it is what lets two house rules both hold. Benjamin:
   "Clicking on a business, contact, engagement should open the record all
   throughout the portal." The standing rule from Incoming Leads is ONE green
   link per row, because "a row with three green claims reads as a wall of green
   and says nothing about what to click".

   Those collide the moment a row's meta line names people who should open. They
   stop colliding if the meta link keeps the meta's own colour and weight and
   earns its underline on hover: the row still has one green thing to click, and
   the names under it are still records you can reach. */
.meta .link, .board-sub .link {
  color: inherit; font-weight: inherit; text-decoration: underline;
  text-decoration-style: dotted; text-underline-offset: 2px;
}
.meta .link:hover, .board-sub .link:hover {
  color: var(--green); text-decoration-style: solid;
}

/* A value the system has not been told. Never rendered as zero, because a blank
 * money field means "not recorded" and zero is a real answer on some fields. */
.nr-cell { color: var(--slate); font-style: italic; font-size: 11.5px; }

/* ---------- data currency banner ----------
 * Not decoration. Every date derived signal in this portal computes against a
 * Firestore snapshot that stopped advancing, so staleness counts drift upward
 * on their own. Any screen that computes from a date states its as-of date. */
.as-of {
  display: flex; align-items: center; gap: 8px;
  background: var(--status-caution-bg); border: 1px solid var(--status-caution);
  color: var(--status-caution-text);
  border-radius: 8px; padding: 8px 12px; margin-bottom: 14px; font-size: 12px;
}

/* ---------- record detail header ----------
 * Transcribed from the mockup: avatar initials, name, one meta line, role pills. */
.rec-head { display: flex; align-items: center; gap: 14px; padding: 16px 14px; }
.contact-avatar {
  width: 46px; height: 46px; flex: 0 0 46px; border-radius: 50%;
  background: var(--green-tint); color: var(--status-pass-text);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 16px; letter-spacing: .5px;
}
/* ⚠️ ONE SIZE FOR EVERY PAGE TITLE, 16 September 2026. Benjamin's item 15:
 * "The header titles of the pages are sometimes in large text and sometimes in
 * small text. This should always be in large text."
 *
 * ⚠️ THE ESTATE HAD TWO TITLE ELEMENTS AND NEITHER KNEW ABOUT THE OTHER, which
 * is why they drifted. A page title is written one of two ways here:
 *
 *     div.contact-name     the record header (recordHeader in details.js), the
 *                          advisor's own page, the buyer review, an event, the
 *                          financial inputs page, the marketing kit pages
 *     h1.name              the buyer and seller profile pages, the acquisition
 *                          reports, the CIM review, a lead, the LOI generator
 *
 * Measured from the shipping stylesheets before this rule: the first rendered
 * at 19px/600 weight 700, the second at TWENTY EIGHT PIXELS, and the second
 * size was never chosen by anybody. `.name` sets a weight and no size, so an
 * <h1> carrying it fell through to the browser's own 2em heading default. Half
 * the portal's titles were an accident of an unstyled tag.
 *
 * ⚠️ THE NUMBER IS THE LARGER OF THE TWO THAT ALREADY SHIP, deliberately. He
 * asked for large, and the pages already at 28px are not the ones he is
 * complaining about, so adopting that size changes only the titles he called
 * small and leaves the rest exactly as they are. It is now a declared token
 * rather than a tag default, so it is one number to tune if he wants it
 * tighter, and it no longer moves when a browser changes its defaults.
 *
 * ⚠️ AND THE MARGIN IS SET HERE FOR A REASON. An <h1> also carries a 0.67em UA
 * margin, which `.rec-head` (align-items: center) turns into an off centre
 * title beside the avatar. jsdom does not apply UA margins at all, so no check
 * in this suite could have seen that; it is zeroed explicitly rather than left
 * to a harness that cannot measure it. */
h1.name, .contact-name {
  font-size: var(--title-size);
  font-weight: 700;
  line-height: 1.25;
  margin: 0;
  color: var(--dark);
}
/* ⚠️ AND IT STEPS DOWN ON A PHONE, WHICH WAS FOUND BY LOOKING RATHER THAN BY
 * REASONING. Rendered at 375px from the shipping stylesheets, the longest real
 * engagement title in the estate ("Acquisition of M&W Heating and Air, Inc.
 * for Kareem Jackson / K3 Generational LLC") ran to SIX lines at 28px and
 * filled the screen before the record began. The token is re-declared rather
 * than the rule repeated, so there is still one place that says how big a page
 * title is. The breakpoint is the one `.facts` already collapses to a single
 * column at, so the header changes shape all at once rather than in two steps. */
@media (max-width: 559px) { :root { --title-size: 21px; } }
.contact-meta { color: var(--slate); font-size: 12px; margin-top: 2px; }
.rec-pills { margin-left: auto; display: flex; gap: 5px; flex-wrap: wrap; }

/* ---------- timeline ---------- */
.tl-row { display: flex; gap: 11px; padding: 10px 14px; border-top: 1px solid var(--border); }
.tl-type {
  flex: 0 0 66px; font-size: 9.5px; font-weight: 700; letter-spacing: .7px;
  text-transform: uppercase; color: var(--slate); padding-top: 2px;
}
.tl-body { flex: 1; min-width: 0; }
.tl-subject { color: var(--dark); font-weight: 600; font-size: 13px; }
.tl-text { color: var(--slate); font-size: 12px; margin-top: 2px; }
/* PCR-2026-09-16-03. A clamped entry keeps a Show more beside it; the expanded
   state keeps the sender's own line breaks, which is what makes a forwarded
   email readable rather than one long paragraph. A short entry never draws
   either rule, so it renders exactly as it did before. */
/* The book strip at the top of a meeting agenda, 21 Sep 2026. The predecessor
   tool opened its Weekly Sales Meeting Agenda with these, generated, so the room
   did not spend its first ten minutes assembling them. Wraps to as many columns
   as fit, one per figure, and collapses to a single column on a narrow screen. */
/* The two meeting cards, part 2 of the agenda. Side by side on a laptop and
   stacked below tablet width, which is where the old tool's two column grid
   became unreadable rather than merely narrow. */
/* The Covered tick sits in a section heading, where the old tool put it: a
   facilitator scans the headings to see what is still owed, not the bodies. */
.agcov { float: right; display: inline-flex; align-items: center; gap: 6px;
  font-size: 10.5px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .04em; color: var(--slate); cursor: pointer; }
.agcov input[disabled] { cursor: default; }
.agcards { display: grid; gap: 14px; grid-template-columns: 1fr 1fr; margin-bottom: 14px; }
@media (max-width: 900px) { .agcards { grid-template-columns: 1fr; } }
.agmv { font-size: 14px; font-weight: 700; color: var(--dark); margin-bottom: 8px; }
.agcards .card { margin: 0; }
.agcam { margin-top: 10px; font-size: 10.5px; font-weight: 700; line-height: 1.4;
  color: var(--slate); }
.agcam-on { color: #4a6b1c; }
.agtally { float: right; font-size: 10.5px; font-weight: 800; color: var(--slate); }
.agatt { display: flex; align-items: center; gap: 8px; padding: 5px 0;
  font-size: 12px; font-weight: 600; color: var(--dark); cursor: pointer; }
.agatt input[disabled] { cursor: default; }
.agfigs { display: grid; gap: 12px 18px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.agfig { border-left: 3px solid var(--green); padding: 2px 0 2px 10px; }
.agfig-l { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--slate); }
.agfig-v { font-size: 19px; font-weight: 800; color: var(--dark); line-height: 1.2; }
.agfig-s { font-size: 11.5px; color: var(--slate); }
.tl-full { white-space: pre-wrap; }
.tl-more { display: inline; margin-left: 6px; padding: 0; border: none; background: none;
  font: inherit; font-size: 12px; font-weight: 600; color: var(--green); cursor: pointer; }
.tl-more:hover { text-decoration: underline; }
.tl-when { flex: 0 0 96px; text-align: right; color: var(--slate); font-size: 11px; }

/* ---------- stub screens ---------- */
.stub { padding: 30px 4px; }
.stub h2 { margin: 0 0 6px; font-size: 16px; color: var(--dark); }
.stub .why { color: var(--slate); font-size: 13px; max-width: 620px; }
.stub .badge {
  display: inline-block; margin-bottom: 10px; padding: 3px 9px; border-radius: 20px;
  background: var(--tint); color: var(--slate); font-size: 10px;
  letter-spacing: .8px; text-transform: uppercase; font-weight: 700;
}

/* ---------- sign in gate ---------- */
#gate {
  position: fixed; inset: 0; background: var(--cream);
  display: flex; align-items: center; justify-content: center; z-index: 50;
}
#gate .box {
  background: var(--paper); border: 1px solid var(--border); border-radius: 12px;
  padding: 28px 30px; max-width: 380px; text-align: center;
}
#gate h1 { font-size: 18px; margin: 0 0 6px; color: var(--dark); }
#gate p { color: var(--slate); font-size: 13px; margin: 0 0 16px; }
.btn {
  display: inline-block; padding: 8px 16px; border-radius: 7px;
  font-weight: 600; font-size: 13px; border: 1px solid var(--border); background: var(--paper);
}
.btn-primary { background: var(--coral); border-color: var(--coral); color: #fff; }

.footer-conf {
  padding: 14px 24px 22px; color: var(--slate); font-size: 11px;
  display: flex; align-items: center; gap: 7px; justify-content: center;
}

/* The way back from a deal to its engagement. A deal is only ever reached
   through its engagement, so the return path is part of the page rather than a
   reliance on the browser's back button. */
.backlink { margin-bottom: 10px; }
.backlink .link { font-size: 12px; font-weight: 600; }

/* Company Details tabs. A tab strip that swaps the panel body, matching the
   demo's Business Type / Staff / Clients / Suppliers tabs. */
.tabstrip { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin: 0 0 10px; flex-wrap: wrap; }
.tabstrip .tab {
  background: none; border: none; border-bottom: 2px solid transparent;
  padding: 8px 12px; font: inherit; font-weight: 600; color: var(--slate); cursor: pointer;
}
.tabstrip .tab.active { color: var(--dark); border-bottom-color: var(--green); }

/* Dark accent card (the Financial Inputs Export panel), matching the demo, with
   the lime call-to-action. Rounded like every other card. */
.card.dark { background: var(--dark); border-color: var(--dark); color: #fff; }
.card.dark .card-head { background: rgba(255,255,255,0.06); border-bottom: 1px solid rgba(255,255,255,0.14); }
.card.dark .sec-label { color: #fff; }
.card.dark .sub-note { color: rgba(255,255,255,0.75); }
.card.dark .row, .card.dark .exp-note { color: rgba(255,255,255,0.88); border-top-color: rgba(255,255,255,0.12); }
.btn-lime { background: var(--lime); border-color: var(--lime); color: var(--dark); font-weight: 700; }

/* Segmented control (Slot A / Slot B), matching the demo's toggle. */
.segmented { display: flex; gap: 8px; margin-bottom: 16px; }
.segmented .seg {
  flex: 1; padding: 13px; border-radius: 10px; border: 1px solid var(--border);
  background: var(--tint); font: inherit; font-weight: 700; color: var(--slate);
  cursor: pointer; text-align: center;
}
.segmented .seg.active { background: var(--dark); color: #fff; border-color: var(--dark); }

/* Topbar + Add quick-create menu (matches the demo). */
.topbar-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.quick-create { position: relative; }
.quick-create-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
  background: var(--paper); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12); min-width: 220px; padding: 6px;
}
/* ⚠️ THE DARK GREEN, NOT THE BRAND GREEN, AND CONTRAST IS WHY. These are 10px
   uppercase labels on white, and the obvious choice, var(--green) #7aac33,
   measures 2.70:1 against paper. That is WORSE than the slate they replaced at
   5.39:1, so "make them stand out" would have made them harder to read while
   looking more colourful. --status-pass-text #4c7317 is the token this palette
   already provides for green TEXT on a light ground and measures 5.57:1, which
   passes AA for small text and is the only green here that does.
   Coral was not a candidate: the house rule reserves it for editable input text,
   and it measures 2.55:1 besides. */
.qc-group { font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--status-pass-text); padding: 8px 10px 4px; }
.qc-item { display: block; width: 100%; text-align: left; background: none; border: none; font: inherit; font-size: 12.5px; font-weight: 600; color: var(--dark); padding: 8px 10px; border-radius: 6px; cursor: pointer; }
.qc-item:hover { background: var(--tint); }

/* ---------- Add New wizard ----------
   Ported from 12_portal/crm-log-contact.html, which is still live. The class
   names inside a step card are renamed from its terse .n/.m/.r and .k/.t to
   .type-n/.type-m/.type-r and .stepdot-n/.stepdot-l, because a single letter
   class in a shared stylesheet collides with anything; the old file could
   afford them because it was one self contained page. */
.steps { display: flex; gap: 6px; margin-bottom: 10px; flex-wrap: wrap; }
.stepdot { flex: 1 1 90px; min-width: 90px; border-radius: 8px; padding: 7px 10px;
  background: var(--paper); border: 1.5px solid var(--border);
  border-top: 4px solid var(--border); }
.stepdot.on { border-top-color: var(--green); background: var(--green-tint); }
.stepdot.done { border-top-color: var(--green); }
.stepdot-n { font-size: 9px; font-weight: 800; color: var(--slate);
  text-transform: uppercase; letter-spacing: 0.05em; }
.stepdot-l { font-size: 11.5px; font-weight: 800; color: var(--dark); margin-top: 1px; }

/* ⚠️ TWO COLUMNS, WRAPPING TO ONE. The old page set 1fr 1fr and then overrode it
   to a single column in its narrow breakpoint. auto-fit does the same thing
   without a media query and without a fixed count, so a sixth route later does
   not need this rule changed. */
.types { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 10px; padding: 0 14px 4px; }
.type { border: 1.5px solid var(--border); border-left: 5px solid var(--slate);
  border-radius: 10px; padding: 12px 14px; background: var(--paper);
  cursor: pointer; text-align: left; font-family: inherit; width: 100%; }
.type:hover { border-color: var(--green); }
.type.on { border-color: var(--green); border-left-color: var(--green);
  background: var(--green-tint); }
.type-n { font-size: 13px; font-weight: 800; color: var(--dark); }
.type-m { font-size: 11px; color: var(--slate); margin-top: 3px; line-height: 1.45; }
/* ⚠️ THE DARK GREEN, NOT THE BRAND GREEN, FOR THE SAME REASON .qc-group USES IT.
   This is a 9.5px uppercase bold label on white and var(--green) #7aac33
   measures 2.70:1 there, which fails AA at any size. --status-pass-text #4c7317
   is the token this palette provides for green TEXT on a light ground, at
   5.57:1. The tone rules below override it per panel, and both hues they use
   pass as well: --buy #3b6ea8 at 5.27:1 and --slate #596d7b at 5.39:1. */
.type-r { font-size: 9.5px; font-weight: 800; color: var(--status-pass-text);
  margin-top: 6px; text-transform: uppercase; letter-spacing: 0.04em; }

/* ⚠️ ONE COLOUR PER PANEL, AND EVERY ONE OF THEM ALREADY EXISTED. Benjamin,
   6 Sep 2026: "use different colors to distinguish the different groups." The
   Add New panels take the side hues the portal has used since 1 Sep, so the
   Buyer Representation panel is the same blue as .side-buy, .head-buy and every
   buy side header an advisor has already learned, rather than a fourth palette
   that only this screen speaks. Center of Influences takes slate, which is what
   a card belonging to neither side already looks like and is also what .type
   drew at rest before any of this.

   WHICH tone a panel gets is decided in addnew_model.js, not here: the class is
   painted from `group.tone` so the colour cannot drift from the grouping. */
.type.tone-buy { border-left-color: var(--buy); }
.type.tone-buy:hover { border-color: var(--buy); }
.type.tone-buy.on { border-color: var(--buy); border-left-color: var(--buy);
  background: var(--buy-tint); }
.type.tone-buy .type-r { color: var(--buy); }
.type.tone-sell { border-left-color: var(--sell); }
.type.tone-sell:hover { border-color: var(--sell); }
.type.tone-sell.on { border-color: var(--sell); border-left-color: var(--sell);
  background: var(--sell-tint); }
.type.tone-sell .type-r { color: var(--status-pass-text); }
.type.tone-neutral { border-left-color: var(--slate); }
.type.tone-neutral:hover { border-color: var(--slate); }
.type.tone-neutral.on { border-color: var(--slate); border-left-color: var(--slate);
  background: var(--tint); }
.type.tone-neutral .type-r { color: var(--slate); }

/* Create modal. */
.modal-overlay { position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,0.35); display: flex; align-items: flex-start; justify-content: center; padding: 60px 16px; overflow: auto; }
.modal-card { width: 100%; max-width: 520px; margin: 0; }

/* ---------- config-document content (Playbooks, Campaigns, EDGE Academy) ----------
   The typed blocks content.js renders, plus the playbook stage and fee layout.
   Ported from the old portal's content pages into the rebuild's own tokens so the
   text that was served the secure way is now rendered natively here. */
.ct-h { font-size: 13px; font-weight: 800; color: var(--dark); margin: 14px 0 4px; }
.ct-p { font-size: 13px; line-height: 1.6; color: var(--dark); margin: 8px 0; }
.ct-flag { font-size: 12.5px; line-height: 1.55; color: var(--dark); margin: 8px 0;
  background: var(--tint); border-left: 3px solid var(--coral); border-radius: 0 8px 8px 0; padding: 9px 12px; }
.ct-list { margin: 8px 0 8px 4px; padding-left: 18px; }
.ct-list li { font-size: 13px; line-height: 1.55; color: var(--dark); margin: 4px 0; }
.ct-tablewrap { overflow-x: auto; margin: 10px 0; }
.ct-script { position: relative; background: var(--dark); color: #fff; border-radius: 10px;
  padding: 12px 14px 12px 62px; margin: 8px 0; font-size: 13px; line-height: 1.55; }
.ct-script-text { white-space: pre-wrap; }
.ct-copy { position: absolute; left: 10px; top: 10px; font-size: 10px; font-weight: 700;
  border: 1px solid rgba(255,255,255,.35); background: rgba(255,255,255,.1); color: #fff;
  border-radius: 6px; padding: 3px 7px; cursor: pointer; }
.ct-copy:hover { background: rgba(255,255,255,.2); }

.pb-sub { color: var(--slate); font-size: 12.5px; font-style: italic; margin-top: 2px; }
.pb-flow { display: flex; flex-wrap: wrap; gap: 8px; }
.pb-fnode { flex: 1 1 140px; border: 1.5px solid var(--border); border-radius: 10px;
  padding: 9px 11px; background: var(--tint); text-decoration: none; }
.pb-fnode .k { font-size: 9.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--slate); }
.pb-fnode .t { font-size: 12.5px; font-weight: 700; color: var(--dark); margin-top: 2px; }
.pb-points { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.pb-point { border: 1.5px solid var(--border); border-radius: 10px; padding: 10px 12px; }
.pb-point .n { font-size: 12.5px; font-weight: 800; color: var(--dark); }
.pb-point .b { font-size: 12px; color: var(--slate); margin-top: 3px; line-height: 1.5; }
.pb-stage-head { display: flex; align-items: baseline; gap: 10px; }
.pb-stage-head .k { font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  color: #fff; background: var(--dark); border-radius: 9px; padding: 2px 9px; }
.pb-stage-head .t { font-size: 15px; font-weight: 800; color: var(--dark); }
.pb-purpose { font-size: 12.5px; font-style: italic; color: var(--slate); margin: 8px 0; }
.pb-lbl { font-size: 9.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--slate); margin: 12px 0 4px; }
.pb-obj { border: 1.5px solid var(--border); border-radius: 9px; padding: 8px 12px; margin: 6px 0; }
.pb-obj summary { font-size: 12.5px; font-weight: 700; color: var(--dark); cursor: pointer; }
.pb-obj .a { font-size: 12.5px; color: var(--slate); margin-top: 6px; line-height: 1.55; white-space: pre-wrap; }
.pb-fstep { display: flex; align-items: baseline; gap: 10px; padding: 7px 0; border-top: 1px solid var(--border); }
.pb-fstep .w { font-weight: 700; font-size: 12.5px; color: var(--dark); flex: 1; }
.pb-fstep .a { font-weight: 800; font-size: 12.5px; color: var(--green); }
.pb-fstep .n { font-size: 11.5px; color: var(--slate); flex-basis: 100%; }
@media (max-width: 720px) { .pb-points { grid-template-columns: 1fr; } }

/* ---------- stage boards (Business Targets, Buyer Review) ----------
   The demo's grouped-cards-per-stage layout: a filter row of colored stage
   chips, then one bounded card per stage with a colored key square, over a
   horizontally scrolling table. Colors are per stage and arrive inline. */
.stage-chips { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px 14px; }
.stage-chip { cursor: pointer; display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 11px; border-radius: 16px; font-size: 11px; font-weight: 700;
  border: 1.5px solid; background: #fff; }
.stage-chip .sq { width: 7px; height: 7px; border-radius: 2px; display: inline-block; }
.stage-card { padding: 0; overflow: hidden; }
.stage-card-head { display: flex; align-items: center; gap: 8px; padding: 13px 16px;
  background: var(--tint); border-bottom: 1px solid var(--border); }
.stage-card-head .sq { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.stage-card-head .nm { font-weight: 800; font-size: 12px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--dark); }
.stage-card-head .ct { color: var(--slate); font-size: 12px; }
.board-scroll { overflow-x: auto; }
.board-scroll table.t { margin: 0; table-layout: auto; }
.board-scroll table.t td { vertical-align: top; }
.board-sub { font-size: 11px; color: var(--slate); }
.deal-badge { font-size: 9px; vertical-align: middle; }
.board-sel { font-size: 11px; width: 100%; min-width: 108px; }
/* The typed figure cells on the board (real estate value). Right aligned and
   tabular so a column of money reads as a column, and narrower than a select
   because it holds digits rather than the widest of five labels. */
.board-num { font-size: 11px; width: 100%; min-width: 88px; text-align: right;
  font-variant-numeric: tabular-nums; }

/* ---------- a panel's READ view, compacted 8 September 2026 ----------
   Benjamin, on the engagement: "The engagement panel takes up too much space
   with so little info. Reduce the space by utilizing the panel more
   efficiently." Every read-only field was its own full width `.row`, so a
   dozen short facts (a state, a date, five percentages) cost a dozen rows of
   fifty pixels each and the panel scrolled for values that would fit on three
   lines.

   THE PATTERN IS THE ONE THE ESTATE ALREADY HAS. The engagement header's facts
   strip below is label-over-value, wrapping, several across; this is that,
   given the panel's own padding and a rule between blocks. A short fact joins
   the grid and a fact that needs the width (notes, a list of links, a table)
   still gets a row of its own, so nothing is squeezed into a column it cannot
   read in.

   `min-width` is what stops two long labels sharing a line and colliding, and
   `flex: 1 1 auto` with a max width is what stops one fact stretching across
   the whole card when it is alone in its block. */
/* ⚠️ A GRID SINCE 15 September 2026, THE DENSITY RULE (review §3.1, Benjamin:
   three facts per line on a laptop, two on a tablet, one on a phone). Flex
   wrap gave ragged columns, three facts on one line and two on the next, so
   the eye could not read down a column of labels; a grid lines the labels up.
   .facts (the header strip) and .p-facts (a panel's read view) take the SAME
   rule so the header and the panels cannot disagree. A fact that needs the
   width (notes, a list of links) says so with .fact-wide. */
.facts, .p-facts {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 22px; padding: 10px 14px; border-top: 1px solid var(--border);
}
.p-facts > .fact, .facts > .fact { min-width: 0; max-width: none; overflow-wrap: anywhere; }
.p-facts > .fact > .meta { margin-bottom: 1px; }
.fact.fact-wide { grid-column: 1 / -1; }
@media (max-width: 1023px) { .facts, .p-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 559px)  { .facts, .p-facts { grid-template-columns: 1fr; } }
/* the narrow column of a two column page reads two facts across */
.rec-grid > .col:last-child .p-facts, .rec-grid > .col:last-child .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* ⚠️ AND A LONG VALUE BREAKS RATHER THAN RUNNING OUT OF ITS COLUMN. This is
   the lesson the Incoming Leads table taught on 4 September, applied to the new
   container the day it is built rather than after somebody sees an email
   printed across the fact beside it: a long unbroken string (an address, a
   domain, an id) has no break opportunity of its own. */
.p-facts > .fact { overflow-wrap: anywhere; }

/* ---------- engagement header facts strip ----------
   The demo's at-a-glance fact grid under the engagement title: label over
   value, five across on a wide screen, wrapping below. */
.fact .lbl, .fact > .meta { font-size: 9.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--slate); }
.fact .val, .fact > .name { font-size: 13px; font-weight: 600; color: var(--dark); margin-top: 1px; }
.fact .val .nr-cell { font-size: 12px; }

/* ---------- the record header of the redesign, 15 September 2026 ----------
   Review §3.2, Benjamin's five answers: keep today's header facts, add the
   record's live work and its most common control. The header is a card like
   any other, with a toned head, so it stops being the one card with no head:
   type and pills in the head; the name and one meta line; a facts grid; an
   action row for the record's most common control. details.js recordHeader()
   is the one builder all five pages use. */
.rec-head { padding: 12px 14px; }
.rec-card .card-head .rec-pills { margin-left: auto; }
.rec-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  padding: 8px 14px; border-top: 1px solid var(--border); background: var(--tint);
}
.rec-actions select, .rec-actions input { font: inherit; font-size: 12.5px; padding: 4px 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--paper); }
.live-list { display: flex; flex-direction: column; gap: 3px; }
.live-list .live { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 12.5px; }
.live-list .live .money { margin-left: auto; font-weight: 700; white-space: nowrap; }

/* ---------- two columns at laptop width, 15 September 2026 ----------
   Review §3.4 and §1: six cards on every record page are the same six and are
   about the RECORD, not the work (Log activity, Timeline, Buyer and seller
   profiles, EDGE Engagement Team, Archive or delete, Change history); at
   1180px and wider they take the right column and the work takes the left.
   Below that the page is one column in today's order. Every card is still on
   the page, in the DOM order the suites walk. */
.rec-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 0 16px; align-items: start; }
.rec-grid > .col { min-width: 0; }
@media (max-width: 1179px) { .rec-grid { grid-template-columns: 1fr; } }

/* the explanation a panel carries opens on demand rather than costing every
   reader four lines on every visit; the words stay verbatim in the DOM */
.p-help { border-top: 1px solid var(--border); }
.p-help summary { cursor: pointer; list-style: none; padding: 6px 14px; color: var(--slate); font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.p-help summary::-webkit-details-marker { display: none; }
.p-help summary::before { content: '+ '; }
.p-help[open] summary::before { content: '- '; }
.p-help .help-text { padding: 0 14px 10px; color: var(--slate); font-size: 12px; line-height: 1.5; }

/* ---------- the financials spread review ----------
   EDGE_FinancialsSpread_Plan_v1_0.md section 4. A figure the spread filled is
   painted so the advisor can tell it from one that was typed, and the figure it
   replaced sits small beneath it until Save (decision 2). The tint is the buy
   blue the estate already uses for a highlighted control, never a new colour. */
.editable.spread-new { background: var(--buy-tint); border-color: var(--buy); }
.spread-old { color: var(--slate); font-size: 10.5px; text-align: right; text-decoration: line-through; }
.spread-list { margin: 0; padding: 0 14px 10px 28px; font-size: 12px; }
.spread-list li { margin: 3px 0; }
.spread-list .name { font-weight: 700; }
.spread-files li { list-style: none; }

/* ---------- the Marketing pages and the toolbar editor ----------
   EDGE_MarketingPublish_Plan_v1_0.md, 8 September 2026. The editor is a
   contenteditable surface the vendored site renderer fills, so its blocks are
   the site's own tags (h2, h3, p, ul, ol, blockquote, hr, table) and are styled
   here to read like a page rather than like a form. The preview under it is
   the same markup drawn from the text that will be saved. */
.rt { border: 1px solid var(--border); border-radius: 8px; background: var(--paper); overflow: hidden; }
.rt-bar { display: flex; flex-wrap: wrap; gap: 4px; padding: 6px 8px; background: var(--tint); border-bottom: 1px solid var(--border); }
.rt-tool {
  font: inherit; font-size: 11.5px; font-weight: 600; color: var(--dark);
  background: var(--paper); border: 1px solid var(--border); border-radius: 6px; padding: 4px 9px; cursor: pointer;
}
.rt-tool:hover { border-color: var(--slate); }
.rt-link { display: flex; gap: 8px; align-items: center; padding: 8px; background: var(--buy-tint); border-bottom: 1px solid var(--border); }
.rt-link input { flex: 1; }
.rt-surface {
  min-height: 260px; max-height: 70vh; overflow-y: auto; padding: 14px 16px; outline: none;
  color: var(--dark); font-size: 14px; line-height: 1.6;
}
.rt-surface:focus { box-shadow: inset 0 0 0 2px var(--buy-tint); }
.rt-surface:empty::before, .rt-surface > p:only-child:empty::before { content: attr(data-placeholder); color: var(--slate); }
.rt-surface h2, .rt-preview-body h2 { font-size: 19px; margin: 18px 0 8px; color: var(--dark); }
.rt-surface h3, .rt-preview-body h3 { font-size: 16px; margin: 16px 0 6px; color: var(--dark); }
.rt-surface h4, .rt-surface h5, .rt-surface h6, .rt-preview-body h4, .rt-preview-body h5, .rt-preview-body h6 { font-size: 14px; margin: 12px 0 4px; color: var(--dark); }
.rt-surface p, .rt-preview-body p { margin: 0 0 10px; }
.rt-surface ul, .rt-surface ol, .rt-preview-body ul, .rt-preview-body ol { margin: 0 0 10px; padding-left: 24px; }
.rt-surface blockquote, .rt-preview-body blockquote { margin: 0 0 10px; padding: 4px 14px; border-left: 3px solid var(--green); color: var(--slate); }
.rt-surface hr, .rt-preview-body hr { border: 0; border-top: 1px solid var(--border); margin: 14px 0; }
.rt-surface table, .rt-preview-body table { border-collapse: collapse; margin: 0 0 10px; }
.rt-surface th, .rt-surface td, .rt-preview-body th, .rt-preview-body td { border: 1px solid var(--border); padding: 4px 8px; font-size: 13px; }
.rt-surface a, .rt-preview-body a { color: var(--buy); }
.rt-preview { border-top: 1px dashed var(--border); background: var(--cream); }
.rt-preview-head { padding: 6px 16px 0; }
.rt-preview-body { padding: 8px 16px 14px; color: var(--dark); font-size: 14px; line-height: 1.6; }
.mk-hint { margin-top: 4px; }
.mk-count { margin-top: 3px; text-align: right; }
.mk-thumb { margin-top: 7px; border: 1px solid var(--border); border-radius: 7px; overflow: hidden; background: var(--tint); height: 104px; display: flex; align-items: center; justify-content: center; }
.mk-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mk-check { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--dark); }
.mk-check input { width: auto; }
.mk-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
/* An armed button is the second click of a two click publish; it is painted so
   the change of state is visible, not only the change of words. */
.btn.mk-armed { background: var(--status-caution-bg); border-color: var(--status-caution); color: var(--status-caution-text); }
/* A writing page's inputs take the room a sentence needs. Measured in the
   browser on 8 September 2026: a browser default input is about 147 pixels wide,
   which clipped a post title after four words. Scoped to the Marketing record
   pages and the event page card so no other panel's layout moves. */
[data-marketing-field] input.editable, [data-marketing-field] textarea, [data-marketing-field] select,
[data-marketing-form] .rt, input[data-event-field] { width: 100%; max-width: 760px; box-sizing: border-box; }
[data-marketing-field] textarea { min-height: 72px; }
[data-marketing-field] input[type="date"] { max-width: 200px; }
/* ⚠️ AN AUTHOR display RULE BEATS THE BROWSER'S [hidden], measured in the browser
   on 8 September 2026: the editor's link row is display flex and the Cancel
   button inline block, so both drew while carrying the hidden attribute. The
   attribute wins again here, for the editor and the Marketing action row. */
.rt [hidden], .mk-actions [hidden] { display: none !important; }

/* ---------- the Conference Room, 15 September 2026 ----------
   Benjamin: a month grid on a laptop and the grouped list below tablet width,
   both audiences badged. Both are in the DOM and the width chooses; jsdom
   asserts the structure of both. Public events take the sell tint the estate
   already reads as "on our website"; EDGE Team events take the neutral tint;
   an event with no audience yet and not launched takes caution, as its pill
   does on the Events list. No new colour. */
.cal-nav { display: flex; align-items: center; gap: 8px; padding: 8px 14px; border-top: 1px solid var(--border); }
.cal-nav .cal-title { flex: 1; text-align: center; font-weight: 700; color: var(--dark); }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 1px; background: var(--border); border-top: 1px solid var(--border); }
.cal-grid .cal-dow { background: var(--tint); padding: 6px 8px; font-size: 9.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--slate); }
.cal-grid .cal-day { background: var(--paper); min-height: 78px; padding: 4px 6px; min-width: 0; }
.cal-grid .cal-day.cal-out { background: var(--cream); }
.cal-grid .cal-n { font-size: 11px; color: var(--slate); }
.cal-grid .cal-today .cal-n { background: var(--green); color: #fff; border-radius: 10px; padding: 0 6px; font-weight: 700; }
.cal-ev { display: block; width: 100%; margin-top: 3px; padding: 2px 6px; border-radius: 6px; font-size: 11px; line-height: 1.3; font-weight: 600; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
.cal-ev.cal-public { background: var(--sell-tint); color: var(--status-pass-text); }
.cal-ev.cal-team { background: var(--tint); color: var(--dark); }
.cal-ev.cal-unset { background: var(--status-caution-bg); color: var(--status-caution-text); }
.cal-list .cal-group { padding: 8px 14px 2px; border-top: 1px solid var(--border); font-size: 10px; letter-spacing: 1.1px; text-transform: uppercase; font-weight: 700; color: var(--slate); }
@media (min-width: 1024px) { .cal-list { display: none; } }
@media (max-width: 1023px) { .cal-grid-host { display: none; } }
/* announcements: the body reads as text, the tools sit under it, the comments unfold */
.ann-body { color: var(--dark); font-size: 13px; margin-top: 3px; white-space: pre-wrap; }
.ann-tools { margin-top: 6px; font-size: 12px; }
.cmt-slot[hidden] { display: none; }
.cmt-slot { margin-top: 8px; padding: 8px 10px; background: var(--tint); border-radius: 8px; }
.cmt { padding: 6px 0; border-top: 1px solid var(--border); }
.cmt:first-child { border-top: 0; padding-top: 0; }
.cmt-text { color: var(--dark); font-size: 12.5px; white-space: pre-wrap; }
.cmt-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; margin-top: 8px; }
.cmt-form textarea { flex: 1 1 220px; min-width: 0; }

/* ---- The client-facing note on a Business Target, 17 September 2026. A second
   row rather than a thirteenth column: that grid is already at the width
   Benjamin asked not to scroll sideways. ---- */
.tgt-noterow > td { padding-top: 0; border-top: 0; }
/* PCR-2026-09-24-02. The board is twelve columns with no width on any cell, so
   the browser shares the space by content and the two columns with the shortest
   headers collapse: a row numbered 18 broke one digit per line and "Archive"
   broke to "Arch" / "ive". nowrap alone fixes it, because the content can no
   longer be broken and the width has to follow. Deliberately no fixed width:
   the row count runs into three digits on the busiest engagement. */
.tgt-num, .tgt-arch { white-space: nowrap; }

/* PCR-2026-10-02-02, Benjamin: "the left column of Business target should have
   much more column space." Names broke mid-word ("Thie" / "l"), the DEAL badge
   stacked a letter per line and Listed X printed one character per line. Measured in a browser at 1440 on
   2 October: the name column went from 110 to about 220px and the note box from
   72 to 260px.

   ⚠️ THE CAUSE WAS ONE GLOBAL RULE, NOT THESE COLUMNS. tokens.css lets every
   table.t cell wrap ANYWHERE, which is right for the fixed layout tables it was
   written for (an email address spilling into the next column). This board is
   table-layout auto, and there `anywhere` shrinks a column's minimum width to a
   single character, so the browser took the width from whichever columns had
   the shortest content and gave it to the selects. On this board only, words
   wrap between words again; a listing link keeps `anywhere`, because a long
   address with nowhere to break would otherwise set the column's width.

   The name column gets a floor rather than a fixed width, and the cell padding
   comes in from 14px to 8px, which across twelve columns pays for most of it. */
/* ⚠️ table.t.tgt-board, NOT .tgt-board: the global rule is `table.t td`, one
   type selector more specific than `.tgt-board td`, and it won silently. */
table.t.tgt-board th, table.t.tgt-board td { overflow-wrap: normal; padding-left: 8px; padding-right: 8px; }
.tgt-board td.tgt-name .board-sub a { overflow-wrap: anywhere; }
.tgt-board td.tgt-name > div { min-width: 190px; }
/* Listed X needs no nowrap once the cell stops wrapping anywhere: "5.00x" has no
   break in it, and "Not recorded" may fold at its space, which is 28px cheaper
   than holding it on one line. */
.tgt-board .deal-badge { white-space: nowrap; }
/* The shared Interest Priority over EDGE's private one, PCR-2026-10-02-01 */
/* and the client note box, which the row's other controls squeezed to five
   characters ("Nothi"): a floor wide enough to read a line and type one */
.tgt-board .tgt-notebox { flex: 1 1 280px; min-width: 260px; }
.board-pri .board-sel + .board-sub { margin-top: 3px; }
.board-pri .board-pri-label { margin-top: 8px; margin-bottom: 2px; }

/* PCR-2026-09-24-01, the Listing Broker Email Generator. It sits in a record
   page's narrow RIGHT column and was built with the wide board's `row` / `grow`
   pattern: `.row .grow` is `min-width: 0` so a label may shrink to nothing,
   while `.board-sel` is `min-width: 108px` and will not, so "Template" clipped
   to "Te". The controls now stack, label over field, which is what the message
   box in the same panel already did.

   ⚠️ AND THE [hidden] OVERRIDE IS THE OTHER HALF OF THE SAME DEFECT. Two
   controls here are hidden until earned, the buyer picker and Copy, and an
   author display rule beats the browser's own [hidden]: the picker sat on
   `.row` (flex) and Copy sits on `.btn` (inline-block), so neither was hiding
   and both crowded the box below. Same trap, and the same scoped fix, as the
   four places above. */
.brokergen [hidden] { display: none !important; }
.brokergen .brokersel-lab { padding: 10px 14px 0; }
.brokergen .brokersel { display: block; width: calc(100% - 28px); max-width: none;
  margin: 4px 14px 0; }
.brokergen .brokerarea { display: block; width: calc(100% - 28px); margin: 4px 14px 2px; }
.tgt-note { display: flex; align-items: flex-start; gap: 10px; padding: 0 0 10px; }
.tgt-notelab {
  flex: none; font-size: 10px; font-weight: 800; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--green); padding-top: 7px; min-width: 128px;
}
.tgt-notebox {
  flex: 1 1 auto; min-width: 0; font: inherit; font-size: 13px; line-height: 1.5;
  color: var(--dark); background: #fff; border: 1.5px solid var(--border);
  border-radius: 8px; padding: 6px 10px; resize: vertical; min-height: 34px;
}
.tgt-notebox:focus { outline: none; border-color: var(--green); }
.tgt-notebox:disabled { color: var(--slate); }
.tgt-notestate { flex: none; font-size: 11px; font-weight: 700; color: var(--slate); padding-top: 9px; min-width: 96px; }

/* The per business release switch, 18 Sep 2026. It shares the note's row because
   it is the same decision twice: what this client sees about this business.
   Coral, because what it opens is the widest thing a client ever reads about
   somebody else's company, and a switch that colour gets looked at twice. */
.tgt-release { display: flex; align-items: center; gap: 8px; flex: none; padding-top: 6px; cursor: pointer; }
.tgt-release input { accent-color: var(--coral); width: 15px; height: 15px; cursor: pointer; }
.tgt-releaselab { font-size: 11px; font-weight: 800; color: var(--slate); white-space: nowrap; }
.tgt-release input:checked + .tgt-releaselab { color: var(--coral); }
.tgt-release .tgt-notestate { padding-top: 0; min-width: 0; }
/* The progress checklist on a Business Target, 22 September 2026. Three ticks,
   of which only the middle one is clickable: the NDA and the LOI are owned by
   the row's stage, so they are shown and not offered. Green when done rather
   than coral, because unlike the release switch beside it none of these three
   discloses anything; they report progress the client is already part of. */
.tgt-chk { display: flex; align-items: center; gap: 10px; flex: 1 1 100%;
  flex-wrap: wrap; padding-top: 8px; }
.tgt-chklab {
  flex: none; font-size: 10px; font-weight: 800; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--slate); min-width: 128px;
}
.tgt-chkitem { display: flex; align-items: center; gap: 6px; flex: none;
  font-size: 11px; font-weight: 700; color: var(--slate); white-space: nowrap; }
.tgt-chkitem.on { color: var(--green); }
.tgt-chkbox { cursor: pointer; }
.tgt-chkbox input { accent-color: var(--green); width: 15px; height: 15px; cursor: pointer; }
/* The derived ticks get a drawn box so the three read as one list, but it is a
   span and not an input: there is nothing here for a click to do. */
.tgt-chkmark { display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; flex: none; border: 1.5px solid var(--border);
  border-radius: 4px; font-size: 10px; font-weight: 800; color: #fff; background: #fff; }
.tgt-chkitem.on .tgt-chkmark { background: var(--green); border-color: var(--green); }
.tgt-chk .tgt-notestate { padding-top: 0; min-width: 0; }
/* The CIM's address, beside its tick. Its own class rather than tgt-chkitem,
   because it is an input and not a step: sharing the class made the checklist
   count five items. 24 September 2026. */
.tgt-chkurl { display: flex; align-items: center; gap: 6px; flex: 1 1 260px; }
.tgt-chkurl input { flex: 1 1 auto; min-width: 0; }

/* Attaching the counter offer comparison. Closed by default: it is a paste box
   for a blob of JSON, and it belongs out of the way until somebody wants it. */
.tgt-attach { display: flex; align-items: center; gap: 8px; flex: none; padding-top: 6px; flex-wrap: wrap; }
.tgt-attachbtn { font-size: 11px; font-weight: 800; color: var(--slate); background: none;
  border: 1.5px solid var(--border); border-radius: 8px; padding: 5px 10px; cursor: pointer; white-space: nowrap; }
.tgt-attachbtn:hover { border-color: var(--green); color: var(--green); }
.tgt-attachbox { flex: 1 0 100%; display: flex; gap: 8px; align-items: flex-start; flex-wrap: wrap; margin-top: 8px; }
.tgt-attachbox textarea { flex: 1 1 320px; font-family: inherit; font-size: 12px; line-height: 1.6;
  border: 1.5px solid var(--border); border-radius: 8px; padding: 8px 10px; resize: vertical; }
.tgt-attachbox textarea:focus { outline: none; border-color: var(--green); }
.tgt-attachsave, .tgt-attachdrop { font-size: 11px; font-weight: 800; border-radius: 8px;
  padding: 6px 12px; cursor: pointer; border: 1.5px solid transparent; white-space: nowrap; }
.tgt-attachsave { background: var(--green); color: #fff; }
.tgt-attachdrop { background: none; border-color: var(--border); color: var(--slate); }
.tgt-attachdrop:hover { border-color: #d64545; color: #d64545; }
@media (max-width: 900px) {
  .tgt-note { flex-wrap: wrap; }
  .tgt-release, .tgt-attach { padding-top: 0; }
}

/* Conversations between a client and their advisors, 30 Sep 2026: the panel is
   comments_panel.js, shared with the client portal. cnv- was checked free in
   this sheet and every script; cmt- was not, it is the Office page's. */
.cnv-title { font-weight: 800; color: var(--dark); font-size: 13.5px; }
.cnv-sub { font-size: 11.5px; color: var(--slate); margin: 2px 0 8px; }
.cnv-input { font: inherit; font-size: 13px; width: 100%; box-sizing: border-box; border: 1px solid var(--border); border-radius: 8px; padding: 7px 9px; resize: vertical; }
.cnv-bar { display: flex; gap: 8px; margin: 6px 0 10px; }
.cnv-btn { font: inherit; font-size: 12px; font-weight: 700; border: 1px solid var(--border); background: #fff; color: var(--dark); border-radius: 7px; padding: 4px 10px; cursor: pointer; }
.cnv-primary { background: var(--green); border-color: var(--green); color: #fff; }
.cnv-btn:disabled { opacity: .5; cursor: default; }
.cnv-thread { border-top: 1px solid var(--border); padding: 8px 0; }
.cnv-item { margin: 0 0 6px; }
.cnv-reply { margin-left: 14px; padding-left: 10px; border-left: 3px solid var(--tint); }
.cnv-head { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; font-size: 12px; }
.cnv-name { font-weight: 800; color: var(--dark); }
.cnv-role { font-size: 10.5px; font-weight: 700; color: var(--slate); }
.cnv-role-edge { color: var(--green); }
.cnv-when { font-size: 11px; color: var(--slate); }
.cnv-body { font-size: 13px; white-space: pre-wrap; margin-top: 2px; color: var(--dark); }
.cnv-withdrawn { font-style: italic; color: var(--slate); }
.cnv-edited { font-size: 10.5px; color: var(--slate); }
.cnv-acts { display: flex; gap: 6px; margin-top: 3px; }
.cnv-msg { font-size: 12px; color: var(--coral); margin: 4px 0; }
.cnv-empty { font-size: 12.5px; color: var(--slate); padding: 6px 0; }

/* ---- A CIM's summary on a Business Target, 2 October 2026 (PCR-2026-10-02-08).
   The cims- classes are cim_summary.js's, the same names the client portal styles. ---- */
.tgt-cim { margin-top: 4px; }
.tgt-cimbtn { background: none; border: 0; padding: 0; color: var(--green); font: inherit;
  font-size: 11px; font-weight: 700; cursor: pointer; text-decoration: underline; }
.tgt-cimbtn:disabled { color: var(--slate); cursor: default; }
.tgt-cimrow > td { padding: 4px 14px 16px; background: #fbfaf7; }
.tgt-cimrow[hidden] { display: none !important; }
.cims { font-size: 13px; line-height: 1.55; color: var(--dark); max-width: 1100px; }
.cims-by { font-size: 11px; color: var(--slate); margin-bottom: 6px; }
.cims-head { font-size: 15px; font-weight: 700; margin: 4px 0; }
.cims-conf { font-size: 12px; color: var(--slate); margin-bottom: 8px; }
.cims-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 8px; margin: 8px 0; }
.cims-stat { background: var(--tint); border-radius: 8px; padding: 8px 10px; }
.cims-sl { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--slate); }
.cims-sv { font-size: 15px; font-weight: 800; }
.cims-ss, .cims-sub { font-size: 11px; color: var(--slate); }
.cims-h3 { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--green); margin: 14px 0 6px; }
.cims-t { width: 100%; border-collapse: collapse; font-size: 12px; }
.cims-t th, .cims-t td { text-align: left; padding: 4px 6px; border-bottom: 1px solid var(--border); }
.cims-src td { font-size: 11px; color: var(--slate); }
.cims-three { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; }
.cims-find { border-left: 3px solid var(--border); padding: 6px 10px; margin: 8px 0; }
.cims-find.cims-critical { border-color: #c0392b; }
.cims-find.cims-high { border-color: var(--coral); }
.cims-fh { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.cims-sev { font-size: 10px; font-weight: 800; text-transform: uppercase; color: var(--slate); }
.cims-imp { margin-left: auto; font-weight: 700; }
.cims-ev { font-size: 12px; color: var(--slate); }
.cims-ask span { font-weight: 700; }
.cims-list { margin: 4px 0; padding-left: 18px; }
.cims-fine { font-size: 11px; color: var(--slate); margin-top: 12px; }

/* ---- The Buyer Portal Licence, 2 October 2026 (PCR-2026-10-02-05): the panel
   on a licence's engagement page, the representation control on its board
   rows, and the request queue on Operations. ---- */
.lic-body { padding: 10px 14px 14px; }
.lic-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 8px 0; }
.lic-check { font-size: 12px; color: var(--slate); display: inline-flex; align-items: center; gap: 4px; }
.lic-facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px 16px; margin-bottom: 8px; }
.lic-fact > div:last-child { font-size: 13px; font-weight: 700; color: var(--dark); }
.lic-rep { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.lic-rep-state { font-weight: 800; color: var(--coral); }
.lic-rep-btn { font-size: 11px; padding: 3px 8px; }
.lic-qrow { align-items: flex-start; gap: 12px; }
.lic-qdone { opacity: .55; }

/* ---- The CIM's figures against the company record, 3 October 2026: the
   advisor ticks what to apply; nothing is written on its own. ---- */
.tgt-cimfig { margin: 4px 0 12px; }
.tgt-cimfig-panel { margin-top: 8px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; background: #fff; }
.tgt-cimfig-panel[hidden] { display: none !important; }
.tgt-cimfig-panel .btn { margin-top: 8px; }
.tgt-cimhint { color: #b7791f; font-weight: 700; }  /* amber, the standard's status colour; coral never signals status */

/* ---- the CIM screen (screens/cim.js), Phase 3a, 4 October 2026 ---- */
.cim-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-left: auto; align-items: center; }
.cim-status { margin: 4px 0 14px; }
.cim-src .row { display: flex; gap: 14px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.cim-k { flex: 0 0 170px; font-weight: 700; color: var(--slate); font-size: 13px; }
.cim-links { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 10px; }
.cim-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px 18px; margin-top: 10px; }
.cim-ws { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 16px; margin-top: 16px; align-items: start; }
.cim-rail { background: #fff; border: 1px solid var(--border); border-radius: 10px; padding: 6px; position: sticky; top: 12px; }
.cim-sec { display: flex; align-items: center; gap: 6px; padding: 2px 4px; border-radius: 7px; }
.cim-sec.on { background: var(--sell-tint); }
.cim-secname { flex: 1; text-align: left; background: none; border: 0; padding: 7px 6px; font: inherit; font-size: 13px; font-weight: 600; color: var(--dark); cursor: pointer; }
.cim-sec.on .cim-secname { font-weight: 800; }
.cim-req { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--slate); }
.cim-badge { background: var(--coral); color: #fff; border-radius: 999px; font-size: 11px; font-weight: 800; padding: 1px 7px; }
.cim-mid .card { margin-bottom: 14px; }
.cim-field { display: block; margin-bottom: 12px; }
.cim-fl { display: block; font-size: 12px; font-weight: 700; color: var(--slate); margin-bottom: 4px; }
.cim-field input[type=text], .cim-field textarea, .cim-field select { width: 100%; box-sizing: border-box; font: inherit; font-size: 14px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; }
.cim-sugg { border: 1.5px solid var(--coral); border-radius: 10px; padding: 10px 12px; margin-top: 12px; background: #fff8f5; }
.cim-sv { white-space: pre-wrap; font-size: 14px; margin: 6px 0 10px; }
.cim-blocks { font-size: 14px; line-height: 1.6; color: var(--dark); }
.cim-h { font-weight: 800; color: var(--green); margin: 14px 0 6px; font-size: 15px; }
.cim-p { margin: 0 0 10px; }
.cim-i { font-style: italic; }
.cim-sm { font-size: 12.5px; }
.cim-note { font-size: 12.5px; color: var(--slate); margin: 6px 0 10px; }
.cim-ul { margin: 0 0 10px; padding-left: 20px; }
.cim-faq { list-style: none; padding-left: 0; }
.cim-faq li { margin-bottom: 10px; }
.cim-q { font-weight: 700; }
.cim-kv { border-collapse: collapse; margin-bottom: 10px; }
.cim-kv td { padding: 4px 18px 4px 0; vertical-align: top; }
.cim-kv td.k { color: var(--slate); font-weight: 600; }
.cim-scroll { overflow-x: auto; margin-bottom: 10px; }
.cim-tb { border-collapse: collapse; width: 100%; font-size: 13px; }
.cim-tb th { background: var(--green); color: #fff; text-align: left; padding: 5px 8px; white-space: nowrap; }
.cim-tb td { border-bottom: 1px solid var(--border); padding: 4px 8px; white-space: nowrap; }
.cim-tb .n { text-align: right; }
.cim-tb tr.b td { font-weight: 800; }
.cim-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; margin-bottom: 10px; }
.cim-stat { background: var(--cream); border-radius: 8px; padding: 10px; }
.cim-stat .sv { font-weight: 800; font-size: 16px; }
.cim-stat .sl { font-size: 12px; color: var(--slate); }
.cim-cover-h { font-size: 22px; font-weight: 900; margin-bottom: 6px; }
.cim-pick { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; margin-top: 10px; }
@media (max-width: 860px) { .cim-ws { grid-template-columns: 1fr; } .cim-rail { position: static; } }

/* The authorized contact's ONE access list, 5 Oct 2026 (screens/details.js):
   a line each for the portal and the tool pages, what | state | Grant or
   Revoke, the three in fixed columns so nothing wraps letter by letter. */
.acc-list { display: grid; grid-template-columns: minmax(120px, 1fr) auto auto; column-gap: 10px; row-gap: 6px; align-items: center; min-width: 300px; }
.acc-line { display: contents; }
.acc-what { font-size: 13px; font-weight: 600; color: var(--dark); }
.acc-line .pill { white-space: nowrap; justify-self: start; }
.acc-act { justify-self: end; }
.acc-act .btn { white-space: nowrap; padding: 4px 12px; font-size: 12px; }
.acc-note { grid-column: 1 / -1; margin-top: 2px; }
.acc-remove { grid-column: 1 / -1; justify-self: start; padding: 2px 0; font-size: 12px; background: transparent; border: 0; color: var(--slate, #5b6770); text-decoration: underline; cursor: pointer; }
.acc-remove:disabled { opacity: .5; cursor: default; text-decoration: none; }

/* ---- Business Targets as cards, 5 Oct 2026 (screens/targets.js targetCard) ---- */
.tgt-cards { display: flex; flex-direction: column; gap: 12px; padding: 12px; }
.tgt-card { border: 1.5px solid var(--border); border-radius: 12px; background: var(--paper); overflow: hidden; }
.tgt-card-head { display: flex; gap: 12px; align-items: flex-start; padding: 12px 14px; border-bottom: 1px solid var(--border); }
.tgt-card-num { font-weight: 700; color: var(--slate); min-width: 22px; }
.tgt-card-name { flex: 1; min-width: 0; color: var(--dark); }
.tgt-card-side { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.tgt-card-stage { display: flex; align-items: center; gap: 8px; }
.tgt-card-grid { display: grid; grid-template-columns: 1.3fr 1fr 1fr; gap: 0; }
/* S6, 5 Oct 2026: a closed card is its head alone */
.tgt-card-body[hidden] { display: none; }
.tgt-card-toggle { white-space: nowrap; padding: 4px 10px; font-size: 12px; }
.tgt-card-sec { padding: 12px 14px; border-right: 1px solid var(--border); min-width: 0; }
.tgt-card-sec:last-child { border-right: 0; }
.tgt-card-sectitle { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--slate); margin-bottom: 8px; }
.tgt-card-pair { display: grid; grid-template-columns: minmax(110px, 1fr) minmax(120px, 1.2fr); gap: 8px; align-items: center; padding: 3px 0; }
.tgt-card-lab { font-size: 12px; color: var(--slate); }
.tgt-card-val { min-width: 0; color: var(--dark); text-align: right; white-space: nowrap; }
.tgt-card-val .board-num, .tgt-card-val .board-sel { width: 100%; max-width: 170px; }
.tgt-card-op { font-weight: 700; color: var(--dark); }
.tgt-card-cim, .tgt-card-client, .tgt-card-spread { padding: 12px 14px; border-top: 1px solid var(--border); }
.tgt-card-cimtop { display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: center; margin-bottom: 6px; }
.tgt-card-hint { font-size: 11.5px; color: var(--slate); margin-top: 6px; }
.tgt-card-client .tgt-notebox { width: 100%; }
.tgt-notewarn { font-size: 12px; color: #9a4a2f; background: rgba(251,126,88,0.10); border-radius: 8px; padding: 6px 10px; margin: 4px 0 6px; }
@media (max-width: 1100px) { .tgt-card-grid { grid-template-columns: 1fr; } .tgt-card-sec { border-right: 0; border-bottom: 1px solid var(--border); } }

/* S7, 5 Oct 2026: the top search's suggestions */
.gs-suggest { position: absolute; top: 100%; left: 0; right: 0; min-width: 320px; z-index: 60; margin-top: 4px;
  background: #fff; border: 1.5px solid var(--border); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.12); padding: 4px; }
.gs-suggest[hidden] { display: none; }
.gs-item { display: block; width: 100%; text-align: left; background: none; border: 0; border-radius: 8px; padding: 7px 10px; cursor: pointer; font: inherit; }
.gs-item:hover, .gs-item:focus-visible { background: var(--tint, #f0f3f5); outline: none; }
.gs-name { font-weight: 700; color: var(--dark); font-size: 13.5px; }
.gs-detail { font-size: 12px; color: var(--slate); }
.gs-all { padding: 6px 10px 4px; border-top: 1px solid var(--border); margin-top: 4px; }
