/* Portal components: sign in, invitation, dashboard, admin.
 *
 * READ THIS BEFORE ADDING A COLOUR.
 *
 * The design system is `site.css`, copied verbatim from the main site. Every
 * token, every button, every card and the wordmark come from there. This file
 * adds only the handful of components the marketing site has no equivalent of,
 * and it adds them out of the same tokens.
 *
 * A hard-coded hex here breaks the paper theme silently, because paper is a
 * complete token override and a literal colour simply does not participate.
 * There are no literal colours in this file. Keep it that way.
 *
 * The material vocabulary is the main site's: hairline rules, solid surfaces,
 * near-square corners, no blur, no glow, no glass, no gradient-filled
 * headlines. The first draft of this portal had all five of those and looked
 * like a different company. The audience is the same lenders, CPAs and buyers,
 * and this is where they read their own numbers, so it should look like it came
 * from the same drawer as the offering memorandum.
 */

/* ═══ SHELL ═══
 *
 * The header and footer are the main site's, markup and all, injected by
 * mountChrome(). Everything about how they look already lives in site.css, so
 * there is nothing here for them. What is here is the space between them.
 *
 * site.css sets `main { padding-top: var(--h-head) }` because the header is
 * fixed. That still holds. Signed in pages drop the scorecard strip, so
 * mountChrome() retunes --h-head to the bar height alone rather than the two
 * stacked, which keeps the offset honest without a second rule here. */

/* ═══ SIGNED IN CHROME ═══
 *
 * Signed out pages wear the marketing header. Signed in, that nav is wrong:
 * every item in it leads away from the documents the client came for. So the
 * header becomes the portal's own, one row instead of two, with the places that
 * exist inside the portal and a way back out to the public site.
 *
 * There is no admin link in it. Admin is reached by typing /admin, and the gate
 * 404s anyone not on the allowlist. A control most people should never see does
 * not belong in the furniture. */

.pchrome {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  background: var(--header);
  border-bottom: 1px solid var(--bd);
}

.pchrome-in {
  max-width: 1080px; margin: 0 auto; padding: 0 32px;
  height: var(--h-nav);
  display: flex; align-items: center; gap: 28px;
}

.pnav { display: flex; align-items: center; gap: 4px; margin-right: auto; }

.pnav a {
  padding: 9px 13px; border-radius: var(--r-btn);
  color: var(--dim); font-size: var(--t-sm); font-weight: 500;
  transition: color .2s var(--ease), background .2s var(--ease);
}

.pnav a:hover { color: var(--hi); background: var(--inset); }

/* The page you are on, marked with the gold the rest of the brand uses for
   "this is us speaking" rather than with a heavier weight. */
.pnav a.is-here { color: var(--gold); background: var(--gold-wash); }

.pchrome-right { display: flex; align-items: center; gap: 14px; flex: none; }

.pchrome-out { color: var(--mute); font-size: var(--t-sm); white-space: nowrap; }
.pchrome-out:hover { color: var(--hi); }

.pchrome-foot {
  border-top: 1px solid var(--bd-soft);
  padding: 26px 32px 40px; text-align: center;
  font-size: var(--t-sm); color: var(--mute);
}

.pchrome-foot-fine { margin-top: 10px; font-size: var(--t-xs); color: var(--ghost); }

/* Below the point where the nav and the controls stop fitting on one line, the
   header grows to two rows rather than squeezing. --h-head is measured from the
   rendered header, so main follows it without a second breakpoint here. */
@media (max-width: 720px) {
  .pchrome-in {
    height: auto; padding: 12px 20px; gap: 10px;
    flex-wrap: wrap; justify-content: space-between;
  }
  .pnav { order: 3; width: 100%; margin-right: 0; }
  .pnav a { padding: 8px 10px; }
  .pchrome-out { display: none; }
}

.pmain {
  max-width: 980px; margin: 0 auto;
  padding-top: calc(var(--h-head) + 56px);
  padding-left: 32px; padding-right: 32px; padding-bottom: 96px;
}

/* Sign in, signup and the landing page: a single column on an otherwise empty
   page.

   THIS USED TO CENTRE ITSELF IN THE VIEWPORT AND IT WAS WRONG.

   The old rule set min-height to the viewport less the header and centred the
   content inside it. On a laptop that looks deliberate. On a tall monitor it is
   a disaster: measured on Nolan's screen at 2335px tall, the panel was forced
   to 2222px to hold 615px of content, which put 731px of empty space above the
   heading and 763px below it. The form looked abandoned in the middle of a dark
   field and the header read as detached from the page.

   Vertical centring only works when you know the height of the viewport, and a
   web page never does. So it is top aligned now, a fixed distance under the
   header, and the page is as tall as its content. Short screens scroll, tall
   screens simply stop. Neither invents empty space.

   The padding-top still clears the fixed header, which is what --h-head is
   measured for. */
.pmain-narrow {
  max-width: 480px; margin: 0 auto;
  padding-top: calc(var(--h-head) + 44px);
  padding-left: 24px; padding-right: 24px; padding-bottom: 72px;
}

/* The portal's own column is narrower than the marketing site's, but the
   footer is the marketing footer and should keep its full width. */
footer .wrap { max-width: var(--maxw); }

/* ═══ TYPE ═══ */

.ptitle {
  font-family: var(--f-disp); font-weight: 600; color: var(--hi);
  font-size: var(--t-h2); line-height: 1.1; letter-spacing: -.005em;
  margin: 0 0 14px;
}

.psub {
  font-size: var(--t-lead); color: var(--body); line-height: 1.6;
  margin: 0 0 32px;
}

.pnote { font-size: var(--t-sm); color: var(--dim); line-height: 1.65; margin: 22px 0 0; }

/* What the portal is for, on the public landing page. Three lines, each a gold
   hairline and a claim. Not a feature grid: this is the one page a buyer who
   has never met Nolan might land on, and it should read like the firm talking
   rather than a product page. */
.pvalue { list-style: none; margin: 0 0 32px; padding: 0; }

.pvalue li {
  position: relative;
  padding: 0 0 0 22px;
  margin-bottom: 15px;
  font-size: var(--t-sm);
  line-height: 1.65;
  color: var(--body);
}

.pvalue li::before {
  content: '';
  position: absolute;
  left: 0; top: 11px;
  width: 12px; height: 1px;
  background: var(--gold);
}

.pvalue b { color: var(--tx); font-weight: 600; }

@media (max-width: 640px) {
  .ptitle { font-size: var(--t-h3); }
  .pheader-in, .pmain { padding-left: 20px; padding-right: 20px; }
}

/* ═══ FORMS ═══
   Square, hairline, inset fill. Matches the scorecard inputs on the main site
   rather than inventing a portal input. */

.field { margin-bottom: 20px; }

.field label {
  display: block; margin-bottom: 7px;
  font-size: var(--t-label); letter-spacing: .22em; text-transform: uppercase;
  font-weight: 600; color: var(--mute);
}

.field input,
.field select {
  width: 100%; padding: 13px 14px;
  border: 1px solid var(--bd); border-radius: var(--r-btn);
  background: var(--inset); color: var(--tx);
  font-family: var(--f-body); font-size: var(--t-body);
  transition: border-color .2s var(--ease);
}

.field input:focus,
.field select:focus { outline: none; border-color: var(--gold); }

/* The invitation page fills the email in and locks it. It is the address the
   link was issued to, and letting it be edited would let whoever holds the link
   claim an account in someone else's name. */
.field input[readonly] { color: var(--dim); background: var(--band); cursor: not-allowed; }

/* ═══ SHOW / HIDE A PASSWORD ═══
   Built by wirePasswordToggles() in portal.js, which wraps each password input
   and appends the button, so there is no markup for this on any page.

   The field gets right padding to match the button's width. Without it the
   caret runs underneath the word Show on a long password, which is the exact
   moment somebody wants to read what they typed. */
.pwwrap { position: relative; }

.pwwrap input { padding-right: 68px; }

.pwtoggle {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  padding: 6px 10px; border: 0; border-radius: var(--r-btn);
  background: none; cursor: pointer;
  font-family: var(--f-body); font-size: var(--t-xs); font-weight: 500;
  letter-spacing: .04em; color: var(--mute);
  transition: color .2s var(--ease), background .2s var(--ease);
}

.pwtoggle:hover { color: var(--hi); background: var(--inset); }

.pwtoggle:focus-visible { outline: 1px solid var(--gold); outline-offset: 1px; }

/* State and ZIP share a line, because a full width input for a two letter state
   reads as though something longer is expected. Collapses on a phone. */
.addrrow { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 480px) { .addrrow { grid-template-columns: 1fr; gap: 0; } }

.field .fieldnote { margin-top: 6px; font-size: var(--t-xs); color: var(--mute); }

/* Marks a field as optional in the label itself. A form where some fields are
   required and none say so makes every field feel required, and the phone
   number is the one people hesitate over. */
.opt {
  margin-left: 8px;
  font-size: var(--t-xs); letter-spacing: .12em; text-transform: uppercase;
  font-weight: 500; color: var(--ghost);
}

/* ═══ SMS CONSENT ═══
   A2P 10DLC. The box ships unticked and nothing here may change that.

   Set apart from the fields above it with a rule and a panel, because consent
   has to read as its own decision rather than as one more thing to fill in on
   the way to a password. Deliberately not styled to attract the eye either: a
   consent control that is designed to be clicked is a dark pattern, and this
   one should simply be legible. */
.consent {
  display: flex; align-items: flex-start; gap: 12px;
  margin: 26px 0 0; padding: 16px 18px;
  border: 1px solid var(--bd); border-radius: var(--r-card);
  background: var(--panel-deep);
  font-size: var(--t-xs); line-height: 1.65; color: var(--body);
  cursor: pointer;
}

/* Big enough to hit on a phone, and not shrunk by the flex row. The default
   13px checkbox next to two lines of legal text is a miss waiting to happen. */
.consent input {
  flex: none;
  width: 18px; height: 18px; margin-top: 1px;
  accent-color: var(--gold); cursor: pointer;
}

.consent strong { color: var(--tx); font-weight: 600; }
.consent a { color: var(--amber); text-decoration: underline; text-underline-offset: 2px; }
.consent a:hover { color: var(--hi); }

/* Full width variants of the site buttons. The site's .btn is inline-block
   because it sits in prose; in a form it should fill the column. */
.btn-block { display: block; width: 100%; text-align: center; }

button.btn { font-size: var(--t-sm); font-family: var(--f-body); }

.btn:disabled { opacity: .5; cursor: progress; }

.orline {
  display: flex; align-items: center; gap: 14px;
  margin: 24px 0;
  font-size: var(--t-label); letter-spacing: .22em; text-transform: uppercase;
  color: var(--mute); font-weight: 600;
}

.orline::before, .orline::after {
  content: ''; flex: 1; height: 1px; background: var(--bd-soft);
}

/* ═══ MESSAGES ═══ */

.msg {
  display: none;
  margin-bottom: 22px; padding: 13px 15px;
  border-radius: var(--r-btn); border-left: 2px solid;
  font-size: var(--t-sm); line-height: 1.55;
}

.msg.is-shown { display: block; }
.msg.error { border-color: var(--neg);  background: var(--inset); color: var(--neg); }
.msg.ok    { border-color: var(--gold); background: var(--gold-wash); color: var(--tx); }

/* ═══ DELIVERABLE LIST ═══
   A sheet per document. Solid fill, one hairline, gold rule on hover. No lift
   and no shadow: these are documents, not app tiles. */

.dlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }

.dlist a {
  display: block; padding: 26px 28px;
  border: 1px solid var(--bd); border-radius: var(--r-card);
  background: var(--panel); color: inherit;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}

.dlist a:hover { border-color: var(--bd-strong); background: var(--surface); color: inherit; }

/* Flex so the New pill sits on the label's line rather than pushing the title
   down by its own height on the cards that have one. */
.dlist .dkind {
  font-size: var(--t-label); letter-spacing: .22em; text-transform: uppercase;
  font-weight: 600; color: var(--kicker); margin-bottom: 9px;
  display: flex; align-items: center; gap: 10px;
}

.dlist .dtitle {
  font-family: var(--f-disp); font-weight: 600; color: var(--hi);
  font-size: var(--t-h4); line-height: 1.25; margin-bottom: 6px;
}

.dlist .dsum { font-size: var(--t-sm); color: var(--body); }

/* Figures and dates in the mono, per the main site's rule. */
.dlist .ddate {
  margin-top: 12px;
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: .04em; color: var(--mute);
}

.pempty {
  border: 1px dashed var(--bd); border-radius: var(--r-card);
  padding: 32px 28px; text-align: center; color: var(--dim);
}

/* ═══ DASHBOARD SECTIONS ═══
   The dashboard holds two unrelated things: documents prepared for this client,
   and tools they can use themselves. A heading rule keeps them from reading as
   one list, which matters because an empty documents section next to a tool
   would otherwise look like the tool belongs to somebody else. */

/* site.css gives a bare `section` 96px of vertical padding and a top rule,
   because on the marketing site a section is a full band of the page. Here it
   is a group of cards, so both have to go: they were adding 192px of empty
   space inside every group and a stray hairline above each heading. */
.psection {
  margin-bottom: 52px;
  padding: 0;
  border-top: none;
}

.psectionhead {
  font-family: var(--f-disp); font-weight: 600; color: var(--hi);
  font-size: var(--t-h3); margin: 0 0 18px;
  padding-bottom: 12px; border-bottom: 1px solid var(--bd-soft);
}

/* A tool, as opposed to a document. Same sheet, but not a link, because there
   is nowhere to go yet. Dashed to say so without needing a label to explain. */
.tooltile {
  padding: 26px 28px;
  border: 1px dashed var(--bd); border-radius: var(--r-card);
  background: var(--panel-deep);
}

.tooltile .dkind { display: flex; align-items: center; gap: 10px; }
.tooltile .dtitle { color: var(--tx); }

/* ═══ ADMIN ═══
   Nolan only. Deliberately plain: it is a control panel, not a page anyone is
   being sold anything on. */

.acols { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; }
@media (max-width: 860px) { .acols { grid-template-columns: 1fr; } }

.apanel {
  border: 1px solid var(--bd); border-radius: var(--r-card);
  background: var(--panel); padding: 26px 24px;
}

.apanel h2 {
  font-family: var(--f-disp); font-size: var(--t-h4); color: var(--hi);
  margin: 0 0 4px;
}

.apanel .apanel-sub { font-size: var(--t-sm); color: var(--dim); margin: 0 0 22px; }

.clist { list-style: none; margin: 0; padding: 0; }

.clist li {
  padding: 16px 0; border-top: 1px solid var(--bd-soft);
  display: flex; justify-content: space-between; align-items: flex-start; gap: 14px;
}

.clist li:first-child { border-top: none; }

.cname { color: var(--tx); font-weight: 500; }
.cmail { font-family: var(--f-mono); font-size: var(--t-xs); color: var(--mute); }

.cgrants { margin-top: 7px; font-size: var(--t-xs); color: var(--dim); line-height: 1.7; }

.cactions { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; flex: none; }

.linkbtn {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: var(--f-body); font-size: var(--t-xs); color: var(--amber);
  text-decoration: underline; text-underline-offset: 3px;
}

.linkbtn:hover { color: var(--hi); }
.linkbtn.danger { color: var(--neg); }

.pill {
  display: inline-block; padding: 2px 9px; border-radius: var(--r-pill);
  border: 1px solid var(--bd); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; font-weight: 700; color: var(--mute);
}

.pill.is-active   { color: var(--pos);  border-color: var(--pos); }
.pill.is-invited  { color: var(--warn); border-color: var(--warn); }

/* Never contacted. Deliberately the quietest of the four: it is the resting
   state of a record Nolan has only just typed in, not a problem. */
.pill.is-built    { color: var(--mute); border-color: var(--bd); }
.pill.is-disabled { color: var(--neg);  border-color: var(--neg); }

/* Which household or partnership a client belongs to. Quiet, because most
   clients are not in one and it should not shout on the rows that are. */
.pill.is-group {
  color: var(--amber); border-color: var(--bd-strong);
  text-transform: none; letter-spacing: .06em; font-weight: 500;
}

/* What produced a document, on the document list. Fifteen rows of titles say
   nothing about which skill made which, and the kind is the answer. */
.pill.is-kind {
  color: var(--kicker); border-color: var(--bd-soft);
  text-transform: none; letter-spacing: .06em; font-weight: 500;
}

/* Where an offer stands. Only the two settled outcomes are coloured: a live
   negotiation spends most of its time at submitted or countered, and marking
   those as good or bad while they are still moving tells the client something
   that is not true yet. */
.pill.is-accepted { color: var(--pos); border-color: var(--pos); }
.pill.is-closed   { color: var(--mute); border-color: var(--bd); }

/* Changed since the client last looked. Gold, because it is the brand's mark
   for "this is us speaking", and filled rather than outlined so it reads at a
   glance down a list of otherwise identical cards. */
.pill.is-new {
  color: var(--gold); border-color: var(--gold); background: var(--gold-wash);
}

/* Screen reader only. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ═══ ADMIN: clients first ═══
   The client list is what Nolan works with. Adding a client and the full
   document list are both occasional, so both sit behind a disclosure and the
   clients get the page. */

.ahead {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding-bottom: 12px; margin-bottom: 8px;
  border-bottom: 1px solid var(--bd-soft);
}

/* Sort and search share the right hand side of the heading row, and wrap
   underneath it together rather than one at a time. */
.acontrols {
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; flex: 1 1 auto; justify-content: flex-end;
}

.asearch {
  flex: 0 1 300px;
  padding: 9px 12px;
  border: 1px solid var(--bd); border-radius: var(--r-btn);
  background: var(--inset); color: var(--tx);
  font-family: var(--f-body); font-size: var(--t-sm);
}

.asearch:focus { outline: none; border-color: var(--gold); }

.asummary {
  cursor: pointer; list-style: none;
  font-family: var(--f-disp); font-size: var(--t-h4); color: var(--hi);
  display: flex; align-items: center; gap: 10px;
}

.asummary::-webkit-details-marker { display: none; }

.asummary::before {
  content: '+';
  font-family: var(--f-body); font-size: 15px; color: var(--gold);
  width: 18px; text-align: center;
}

details[open] > .asummary::before { content: '\2212'; }

/* ═══ ADMIN: a client, opened ═══
   Each client is a disclosure holding their documents and their deals. The flat
   row it replaced put the granted titles on one line with a remove link after
   each, which fit and answered none of the questions actually being asked: when
   did they get this, has it been revised, what is happening on their deal.

   Deliberately plain inside. This is a control panel and every pixel spent
   making it handsome is a pixel not spent making the next row readable. */

.crows { list-style: none; margin: 0; padding: 0; }

.crows > li { border-top: 1px solid var(--bd-soft); }
.crows > li:first-child { border-top: none; }

.csummary {
  cursor: pointer; list-style: none;
  padding: 16px 0 16px 26px; position: relative;
}

.csummary::-webkit-details-marker { display: none; }

.csummary::before {
  content: '+';
  position: absolute; left: 0; top: 17px;
  font-family: var(--f-body); font-size: 15px; color: var(--gold);
  width: 18px; text-align: center;
}

details[open] > .csummary::before { content: '\2212'; }

.csummary:hover .cname { color: var(--hi); }

.csummary-meta { margin-top: 6px; font-size: var(--t-xs); color: var(--dim); }

.cbody { padding: 4px 0 24px 26px; }

.cbody-acts {
  display: flex; gap: 18px; flex-wrap: wrap;
  margin-top: 24px; padding-top: 16px;
  border-top: 1px solid var(--bd-soft);
}

/* Rows of things belonging to a client or a deal: granted documents, offers,
   dates. Same gold hairline as the dashboard's, so the two screens describe the
   same object the same way. */
.minirows {
  list-style: none; margin: 0 0 12px; padding: 0 0 0 14px;
  border-left: 1px solid var(--bd);
}

.minirows > li { padding: 10px 0; }
.minirows > li + li { border-top: 1px solid var(--bd-soft); }

.minirow-main { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }

.minirow-name { color: var(--tx); font-size: var(--t-sm); }
.minirow-name:hover { color: var(--gold); }

.minirow-kind {
  font-size: var(--t-label); letter-spacing: .18em; text-transform: uppercase;
  font-weight: 600; color: var(--mute);
}

.minirow-note { margin-top: 4px; font-size: var(--t-xs); color: var(--mute); }

.minifoot { font-size: var(--t-xs); color: var(--mute); margin: 0 0 12px; }

/* Wraps rather than scrolls. A deal has eight fields and this panel is already
   indented twice, so a fixed column count would either overflow or shrink each
   field past the point of being able to read what is in it. */
.minigrid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
}

.minigrid input,
.minigrid select,
.mininote,
.minigrant {
  width: 100%; padding: 8px 10px;
  border: 1px solid var(--bd); border-radius: var(--r-btn);
  background: var(--inset); color: var(--tx);
  font-family: var(--f-body); font-size: var(--t-sm);
}

.minigrid input:focus,
.minigrid select:focus,
.mininote:focus,
.minigrant:focus { outline: none; border-color: var(--gold); }

.mininote { margin-top: 8px; resize: vertical; line-height: 1.5; }

.minigrant { max-width: 340px; }

.miniacts {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 8px;
}

.minicheck {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--t-xs); color: var(--dim); cursor: pointer;
  white-space: nowrap;
}

.minicheck input { width: auto; accent-color: var(--gold); }

/* A deal inside a client. Boxed, because unlike the client's documents it holds
   editable fields and needs an edge to say where it starts and stops. */
.dealwrap {
  border: 1px solid var(--bd); border-radius: var(--r-card);
  background: var(--panel-deep);
  padding: 14px 16px; margin-bottom: 10px;
}

.dealsummary {
  cursor: pointer; list-style: none;
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
}

.dealsummary::-webkit-details-marker { display: none; }

.dealsummary-name { color: var(--tx); font-weight: 500; font-size: var(--t-sm); }
.dealsummary-meta { font-size: var(--t-xs); color: var(--mute); }

.dealsummary:hover .dealsummary-name { color: var(--gold); }

details[open] > .dealsummary { margin-bottom: 14px; }

.dealadmin { margin-bottom: 4px; }

/* The sentence somebody actually ticked, folded away. It is three lines of
   carrier boilerplate that is only wanted when a specific question is being
   asked of it, and inline it would bury the phone number and the date, which
   are what Nolan looks at. */
.consentwording { margin-top: 6px; }

.consentwording summary {
  cursor: pointer; list-style: none;
  font-size: var(--t-xs); color: var(--mute);
  text-decoration: underline; text-underline-offset: 3px;
}

.consentwording summary::-webkit-details-marker { display: none; }
.consentwording summary:hover { color: var(--gold); }

.consentwording p {
  margin: 8px 0 0; padding: 10px 12px;
  border-left: 1px solid var(--bd); background: var(--inset);
  border-radius: var(--r-btn);
  font-size: var(--t-xs); line-height: 1.6; color: var(--dim);
}

@media (max-width: 640px) {
  .cbody { padding-left: 12px; }
  .minirows { padding-left: 10px; }
}

/* ═══ DEAL TRACKING ═══
   A business being pursued, the offers made on it, and the dates that matter.
   Real rows since 2026-08-17; this was three dashed "coming soon" tiles before
   that.

   Solid, not dashed. The dashed border is this portal's way of saying "nothing
   here yet", and it is now wrong for a card carrying a client's actual asking
   price. Same sheet as a document, because a deal and the document about it are
   the same kind of object to the person reading them. */

.dealcard {
  padding: 26px 28px;
  border: 1px solid var(--bd); border-radius: var(--r-card);
  background: var(--panel);
}

.dealcard + .dealcard { margin-top: 12px; }

.dealhead {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
}

.dealpills { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }

/* ═══ NOT LIVE YET ═══
   A section that is finished enough to look at and not finished enough to
   trust. The client is shown the real component with invented numbers in it, so
   the labelling has to be impossible to miss: a buyer who reads an example
   asking price as their own has been actively misled, and "coming soon" in a
   heading is not enough on its own to stop that.

   Hence three marks, not one: the pill on the heading, this note above the
   cards, and an Example pill on every card. The dashed edge is the fourth,
   carrying the same meaning the empty states and the tool tiles already use on
   this site, which is "nothing real here yet". */

.previewnote {
  margin: -6px 0 18px;
  padding: 12px 15px;
  border-left: 2px solid var(--gold);
  background: var(--gold-wash);
  border-radius: var(--r-btn);
  font-size: var(--t-sm); line-height: 1.6; color: var(--body);
}

.previewnote b { color: var(--tx); font-weight: 600; }

#deals.is-preview .dealcard {
  border-style: dashed;
  background: var(--panel-deep);
}

.pill.is-example {
  color: var(--gold); border-color: var(--gold); background: var(--gold-wash);
}

.dealmore {
  display: inline-block; margin-top: 20px;
  font-size: var(--t-sm); color: var(--amber);
  text-decoration: underline; text-underline-offset: 3px;
}

.dealmore:hover { color: var(--hi); }

/* ═══ A MATCHED BUSINESS ═══
   The write up on one company. Mocked up at /portal/listing/ ahead of the deal
   section being built, because what a buyer is told and what we ask of them is
   a judgement worth settling on paper before it is wired to a database. */

.backlink { margin: 0 0 20px; font-size: var(--t-sm); }
.backlink a { color: var(--mute); }
.backlink a:hover { color: var(--gold); }

.ptitle .pill { vertical-align: middle; margin-left: 10px; }

/* The financing arithmetic. A definition list in all but name: a label and a
   figure, one per line, hairline between. Not a real table, because there are
   two columns and a table would bring markup for a header row that does not
   exist and a caption nobody wants. */
.mathtable {
  border: 1px solid var(--bd); border-radius: var(--r-card);
  background: var(--panel); overflow: hidden;
}

.mathrow {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; padding: 13px 20px;
  border-top: 1px solid var(--bd-soft);
  font-size: var(--t-sm);
}

.mathrow:first-child { border-top: none; }

.mathrow > span:first-child { color: var(--body); }

.mathrow > span:last-child {
  font-family: var(--f-mono); color: var(--tx);
  letter-spacing: -.01em; text-align: right; white-space: nowrap;
}

/* The two lines a buyer actually reads: what is left, and whether the lender
   will say yes. Marked by weight and a heavier rule, not by a fill, because a
   filled row in this palette reads as a warning. */
.mathrow.is-total { border-top-color: var(--bd-strong); }
.mathrow.is-total > span:first-child { color: var(--tx); font-weight: 600; }
.mathrow.is-total > span:last-child { color: var(--gold); }

/* What we need the buyer to do. Numbered, because these are steps in an order
   and the third one is a rule rather than a suggestion. The counter is gold and
   mono to match the way figures are set everywhere else on the site. */
.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; }

.steps li {
  counter-increment: step;
  position: relative;
  padding: 0 0 0 42px;
  margin-bottom: 22px;
  font-size: var(--t-sm); line-height: 1.7; color: var(--body);
}

.steps li::before {
  content: counter(step);
  position: absolute; left: 0; top: 1px;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--gold); border-radius: var(--r-pill);
  font-family: var(--f-mono); font-size: var(--t-xs); color: var(--gold);
}

.steps b { color: var(--tx); font-weight: 600; }

@media (max-width: 640px) {
  .mathrow { padding: 12px 15px; }
  .steps li { padding-left: 36px; }
}

.dealname {
  font-family: var(--f-disp); font-weight: 600; color: var(--hi);
  font-size: var(--t-h4); line-height: 1.25; margin: 0;
}

.dealmeta {
  margin-top: 6px;
  font-size: var(--t-sm); color: var(--dim);
}

/* Figures in the mono, per the main site's rule for anything numeric. Auto fit
   rather than three fixed columns: a deal often has an asking price and nothing
   else yet, and two thirds of an empty row reads as missing data rather than as
   data that does not exist.

   Each cell carries its own border rather than the grid drawing them with a 1px
   gap over a coloured background. That trick needs every cell in the last row
   filled, and these wrap to two columns on a phone: three figures then leave a
   fourth slot empty, which paints as a grey block sitting next to the revenue
   figure. Per-cell borders cannot produce that whatever the count. */
/* auto-fill, not auto-fit. auto-fit collapses the tracks nothing landed in, so
   a deal with an asking price and no financials yet gets one cell stretched the
   full width of the card with the words "Asking" floating at the left of it.
   auto-fill keeps the empty tracks sized, which leaves the figure the same width
   it would have had next to two others. */
.figs {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px; margin-top: 20px;
}

.fig {
  padding: 14px 16px;
  background: var(--panel-deep);
  border: 1px solid var(--bd-soft); border-radius: var(--r-btn);
}

.figlab {
  font-size: var(--t-label); letter-spacing: .22em; text-transform: uppercase;
  font-weight: 600; color: var(--mute); margin-bottom: 6px;
}

.figval {
  font-family: var(--f-mono); font-size: var(--t-body);
  color: var(--tx); letter-spacing: -.01em;
}

/* Offers and dates hang off the deal, so they are indented behind a gold
   hairline rather than boxed again. A card inside a card is one border too
   many at this size. */
.dsub { margin-top: 22px; }

.dsubhead {
  font-size: var(--t-label); letter-spacing: .22em; text-transform: uppercase;
  font-weight: 600; color: var(--kicker); margin-bottom: 10px;
}

.drows { list-style: none; margin: 0; padding: 0 0 0 16px; border-left: 1px solid var(--gold); }

.drows li { padding: 9px 0; }
.drows li + li { border-top: 1px solid var(--bd-soft); }

.drow-main {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
}

.drow-label { color: var(--tx); font-size: var(--t-sm); }

.drow-figure {
  margin-left: auto;
  font-family: var(--f-mono); font-size: var(--t-sm); color: var(--body);
  letter-spacing: -.01em;
}

.drow-note { margin-top: 4px; font-size: var(--t-xs); color: var(--mute); }

/* A finished date is still worth showing, quietly. Struck through would read as
   deleted; dimmed reads as done. */
.drows li.is-done .drow-label,
.drows li.is-done .drow-figure { color: var(--mute); }

@media (max-width: 640px) {
  .dealcard { padding: 22px 20px; }
  .drow-figure { margin-left: 0; }
}

/* ═══ EDITING A DOCUMENT IN PLACE ═══
   Behind a disclosure, like the consent wording, because a list of fifteen
   documents that can be scanned stops being scannable when every row is
   carrying five fields. */
.docedit { margin-top: 8px; }

.docedit > summary {
  cursor: pointer; list-style: none;
  font-size: var(--t-xs); color: var(--mute);
  text-decoration: underline; text-underline-offset: 3px;
}

.docedit > summary::-webkit-details-marker { display: none; }
.docedit > summary:hover { color: var(--gold); }

.miniform {
  margin-top: 10px; padding: 12px 14px;
  border: 1px solid var(--bd); border-radius: var(--r-card);
  background: var(--inset);
}

/* The summary line is a sentence, not a field beside three others. */
.minigrid .wide { grid-column: 1 / -1; }

/* A document path that opens the document.
   Styled at rest, not only on hover. The first version inherited .cmail exactly
   and was indistinguishable from the paths beside it, which is a link nobody
   finds: the whole point is being able to read a document before sending it,
   and an invisible affordance leaves you back at typing the URL by hand. */
a.cmail {
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  text-decoration-color: var(--bd);
}

a.cmail:hover {
  color: var(--gold);
  text-decoration: underline solid;
  text-decoration-color: currentColor;
}

.minirow-name:hover { color: var(--gold); }

/* The "before you start" card on the dashboard. Built from the same tokens as
   the account form; it is the same three fields asked a week earlier. */
.whoami-form { display: grid; gap: 12px; max-width: 26rem; margin-top: 14px; }
.whoami-row { display: grid; gap: 4px; }
.whoami-row label { font-size: 13px; color: var(--muted); }
.whoami-opt { color: var(--muted); font-weight: 400; }
.whoami-actions { display: flex; gap: 8px; align-items: center; margin-top: 4px; }

/* Asking for access, on the sign in page. Folded shut: nearly everyone here is
   an existing client, and two open forms on a sign in page is a page where
   people fill in the wrong one. */
.reqbox { margin-top: 28px; border-top: 1px solid var(--bd); padding-top: 18px; }
.reqbox > summary { cursor: pointer; font-size: 14px; color: var(--muted); }
.reqbox > summary:hover { color: var(--gold); }
.reqbox[open] > summary { margin-bottom: 14px; color: var(--fg); }
.reqbox textarea {
  width: 100%; font: inherit; color: inherit; background: var(--surface);
  border: 1px solid var(--bd); border-radius: 2px; padding: 8px 10px; resize: vertical;
}

/* The signup honeypot. Off-screen rather than display:none, because some form
   fillers skip hidden fields and filling it in is the whole point. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
