/* PermitPipeline Portfolio, additive layer. v8.
   Built against DESIGN_DIRECTION_FIRM_PAGE_v1.0.md; section refs below.

   §3 COLOUR DISCIPLINE, restored from mockup_v2.1:
     - Orange = ACT, and nothing else. ONE orange object per screen inside <main>.
       On this page the orange belongs to the header action, the Select-Projects trial
       end-card, and the footer band. Nothing else may be filled orange.
     - Charts and data are steel-blue (--pf-data) with blue-green (--pf-data2) second series.
       Zero orange charts.
     - Navigation, tabs and chips are never orange: they tell you where you are, not what to do.
   Live tokens (--paper --card --ink --ink-soft --ink-faint --line --line-soft --accent
   --accent-dark --accent-soft --good) come from firm-intel.css and are used as-is. */

:root{
  --pf-data:#3d6b9e; --pf-data-deep:#2c4f78; --pf-data-soft:#e9eff6; --pf-data-line:#c6d5e6;
  --pf-data2:#2e8577; --pf-data2-soft:#e3f0ed; --pf-data2-line:#bcdcd5;
  --pf-serif:'Instrument Serif',Georgia,serif;
  --pf-mono:'JetBrains Mono',ui-monospace,Menlo,monospace;
}

/* ═══════════ §3 orange budget: neutralise the live page's orange data ═══════════ */
.fp2-bar,.fp2-bar span,.fp2-bar i{background:var(--pf-data)!important}
.fp2-bar:hover{background:var(--pf-data-deep)!important}
.fp2-dist .fp2-drow i,.fp2-dist .bar,.fp2-dist .fill{background:var(--pf-data2)!important}
/* .spx-hot2,.spx-gradedot were display:none here until 2026-08-10. Restoring them in
   the markup did nothing while this rule stood: the grade dot and the hot marker are
   live public signals and they render. */
/* tabs and chips are wayfinding, never calls to action */
.pf-tabs a,.pf-chip,.pf-chip-folio,.pf-prov{color:var(--ink-soft)}

/* ═══════════ §4 Act I, identity ═══════════ */
.pf-logo{float:left;width:56px;height:56px;margin:2px 16px 10px 0;border:1px solid var(--line);
  background:var(--card);display:flex;align-items:center;justify-content:center;
  font-family:var(--pf-serif);font-size:24px;color:var(--ink)}
.fp2-h1{font-family:var(--pf-serif)}
.pf-chip-folio{display:inline-block;margin-left:2px;padding:3px 9px;border:1px solid var(--line);
  background:var(--card);font-family:var(--pf-mono);font-size:9px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-faint);vertical-align:4px}
body[data-firm="unclaimed"] .pf-chip-folio,
body[data-firm="claimed"] .pf-chip-folio{display:none}
.pf-intro{clear:none;max-width:60em}
.pf-byline{clear:both;margin-top:8px;font-family:var(--pf-mono);font-size:9px;
  letter-spacing:.15em;text-transform:uppercase;color:var(--ink-faint)}
body[data-firm="unclaimed"] .pf-intro,body[data-firm="unclaimed"] .pf-byline,
body[data-firm="unclaimed"] .pf-logo{display:none}

/* freshness dot (§5.6): blue-green, static, no animation */
.pf-fresh{display:flex;align-items:center;gap:8px;margin:14px 0 0;
  font-family:var(--pf-mono);font-size:10px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--pf-data2)}
.pf-fresh i{width:7px;height:7px;border-radius:50%;background:var(--pf-data2);flex:none}

/* actions: exactly one filled orange, the rest quiet (§3) */
.pf-acts{display:flex;gap:9px;flex-wrap:wrap;margin-top:16px;clear:both}
.pf-btn-primary{display:inline-flex;align-items:center;padding:11px 20px;border-radius:3px;
  background:var(--accent);border:1px solid var(--accent-dark);color:#fff;font-weight:600;
  font-size:14px;text-decoration:none}
.pf-btn-primary:hover{background:var(--accent-dark)}
.pf-btn-quiet{display:inline-flex;align-items:center;padding:11px 18px;border-radius:3px;
  background:var(--card);border:1px solid var(--line);color:var(--ink);font-weight:600;
  font-size:14px;text-decoration:none}
.pf-btn-quiet:hover{border-color:var(--ink);}
body[data-owner="yes"] .pf-claim,body[data-owner="yes"] .pf-claim-link,
body[data-firm="folio"] .pf-claim,body[data-firm="folio"] .pf-claim-link,
body[data-firm="claimed"] .pf-claim,body[data-firm="claimed"] .pf-claim-link{display:none}
/* THIS RULE USED TO SAY `.pf-btn-primary:not(.pf-folio-cta)` with no scope, so in the
   default state it hid EVERY primary button on the page, including "Send the
   verification link" and every Continue in the Portfolio wizard. Both flows were
   unusable from the moment they shipped and the DOM checks could not see it, because
   the markup was correct. It is scoped to the identity row, which is all it ever meant.
   render_check.py now resolves the cascade and fails on exactly this. */
body[data-firm="unclaimed"] .pf-acts .pf-btn-primary{display:none}
/* the filled orange treatment is for BUTTONS. .pf-alink is a text link and was being
   turned into an orange box by this rule, which is why Claim did not match Share. */
body[data-firm="unclaimed"] .pf-claim:not(.pf-alink){display:inline-flex;
  background:var(--accent);border-color:var(--accent-dark);color:#fff}

/* ═══════════ §4 Act II, the work. The band is the wow (§5.3) ═══════════ */
.pf-band{margin:30px 0 0}
/* The Portfolio section itself always renders, because the tab points at it in every
   state. Only the firm-supplied contents are state-dependent; when they are absent the
   invitation takes their place. Hiding the whole band left the tab pointing at nothing
   and the scroll-spy measuring a zero-height element. */
body[data-firm="unclaimed"] .pf-band-grid,body[data-firm="claimed"] .pf-band-grid,
body[data-firm="unclaimed"] .pf-quote,body[data-firm="claimed"] .pf-quote,
body[data-firm="unclaimed"] .pf-strip,body[data-firm="claimed"] .pf-strip{display:none}
.pf-band-head{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;
  flex-wrap:wrap;padding-bottom:10px;border-bottom:1px solid var(--line)}
.pf-band-head h2{font-family:var(--pf-serif);font-size:27px;font-weight:400;margin:0}
.pf-band-note{font-size:12.5px;color:var(--ink-faint);max-width:430px;text-align:right}
@media(max-width:760px){.pf-band-note{text-align:left}}
.pf-band-grid{display:grid;grid-template-columns:2fr 1fr;grid-template-rows:auto auto;
  gap:12px;margin-top:16px}
@media(max-width:820px){.pf-band-grid{grid-template-columns:1fr 1fr}}
.pf-shot{position:relative;margin:0;overflow:hidden;background:var(--paper-2);
  border:1px solid var(--line)}
.pf-shot img{display:block;width:100%;height:100%;object-fit:cover}
.pf-shot-wide{grid-row:1 / span 2;aspect-ratio:16/11}
@media(max-width:820px){.pf-shot-wide{grid-column:1 / -1;grid-row:auto}}
.pf-band-grid .pf-shot:not(.pf-shot-wide){aspect-ratio:16/10}
/* caption chips: ink gradient, never orange */
.pf-chipcap{position:absolute;left:0;right:0;bottom:0;padding:22px 14px 10px;
  background:linear-gradient(to top,rgba(10,10,10,.78),rgba(10,10,10,0));
  color:#fff;font-family:var(--pf-mono);font-size:9.5px;letter-spacing:.11em;
  text-transform:uppercase}
.pf-quote{margin:18px 0 0;padding:0 0 0 18px;border-left:2px solid var(--pf-data2);
  font-family:var(--pf-serif);font-size:21px;line-height:1.45;color:var(--ink)}
.pf-quote cite{display:block;margin-top:9px;font-family:var(--pf-mono);font-size:9px;
  font-style:normal;letter-spacing:.15em;text-transform:uppercase;color:var(--ink-faint)}
.pf-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:12px}
@media(max-width:760px){.pf-strip{grid-template-columns:1fr}}
.pf-shot-sm{aspect-ratio:16/10}

/* THE PROJECT RAIL IS NOT OURS TO RESTYLE. Removed 2026-08-10.
 *
 * What used to be here turned the live horizontal scroll-snap rail into a fixed
 * 3-column grid and then hid the pieces that no longer fitted:
 *
 *     .spx-railwrap .spx-rail{display:grid;grid-template-columns:repeat(3,1fr)}
 *     .spx-dots,.spx-nx,.spx-pv,.spx-ghost-n{display:none!important}
 *
 * That removed the left/right scrolling, both arrows, the dots, and the "34 more"
 * headline off the ghost card, and it pushed the ghost card (the fourth rail item)
 * onto a second row of a three-column grid. Every markup check passed the whole time,
 * because the markup was correct and the damage was in this file. A check that reads
 * the DOM cannot see a stylesheet that hides half of it.
 *
 * The rail scrolls left to right and ends with the trial ghost card. That is the live
 * pattern and it stays. */
.pf-chip{display:inline-block;margin-right:10px;padding:3px 8px;border:1px solid var(--line);
  background:var(--card);font-family:var(--pf-mono);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;vertical-align:2px}
.pf-cap{margin-top:10px;padding:10px 12px;background:var(--paper);
  border-left:2px solid var(--pf-data2);font-size:13px;line-height:1.5;color:var(--ink-soft)}
.pf-cap b{display:block;font-family:var(--pf-mono);font-size:8.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-faint);font-weight:400;margin-bottom:5px}
body[data-firm="unclaimed"] .pf-cap,body[data-firm="claimed"] .pf-cap,
body[data-firm="unclaimed"] .pf-chip,body[data-firm="claimed"] .pf-chip{display:none}

/* ═══════════ tabs (wayfinding, never orange) ═══════════ */
.pf-tabs{display:flex;margin:26px 0 0;border-bottom:1px solid var(--line);overflow-x:auto}
.pf-tabs a{padding:9px 18px 11px;font-size:14px;font-weight:600;color:var(--ink-faint);
  text-decoration:none;border-bottom:2px solid transparent;white-space:nowrap}
.pf-tabs a:hover{color:var(--ink);border-bottom-color:var(--line)}
[id^="pf-"]{scroll-margin-top:70px}

/* ═══════════ §5.4 weighted collaboration rows ═══════════ */
.pf-net{margin:34px 0 0}
.pf-net h2,.pf-creds h2{font-family:var(--pf-serif);font-size:27px;font-weight:400;margin:0}
.pf-sub{margin:6px 0 0;font-size:13px;color:var(--ink-faint);max-width:70ch}
.pf-src{margin-top:12px;font-family:var(--pf-mono);font-size:10px;line-height:1.7;
  color:var(--ink-faint)}
.pf-collabs{list-style:none;margin:18px 0 0;padding:0}
.pf-collab{display:grid;grid-template-columns:minmax(0,1fr) 160px 44px auto;gap:16px;
  align-items:center;padding:12px 0;border-bottom:1px solid var(--line-soft)}
@media(max-width:760px){.pf-collab{grid-template-columns:1fr auto}
  .pf-collab-bar{display:none}}
.pf-collab-n a{font-family:var(--pf-serif);font-size:21px;color:var(--ink);text-decoration:none}
.pf-collab-n a:hover{color:var(--pf-data-deep)}
.pf-collab-n em{display:block;font-style:normal;font-family:var(--pf-mono);font-size:9px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink-faint);margin-top:4px}
.pf-collab-bar{height:7px;background:var(--pf-data-soft);border:1px solid var(--pf-data-line)}
.pf-collab-bar i{display:block;height:100%;background:var(--pf-data)}
.pf-collab-c{font-family:var(--pf-serif);font-size:21px;color:var(--ink);text-align:right}
.pf-repeat{font-family:var(--pf-mono);font-size:9px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--pf-data2);background:var(--pf-data2-soft);border:1px solid var(--pf-data2-line);
  padding:3px 8px;white-space:nowrap}
/* §4: at <3 connections, one compact line, never a headed empty section */
.pf-netline{margin:14px 0 0;font-size:14px;color:var(--ink-soft)}
/* The connections card's own tabs, its "view all" link and its heading were hidden
   here. That is what "a lot of the live functionality is missing" looked like: the
   card was on the page and three of its controls were switched off in CSS.
   Removed 2026-08-10. */

/* ═══════════ §5.5 credentials passport + §5.7 issuance bars ═══════════ */
.pf-creds{margin:34px 0 0}
.pf-credgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line-soft);
  border:1px solid var(--line-soft);margin-top:16px}
@media(max-width:760px){.pf-credgrid{grid-template-columns:1fr 1fr}}
.pf-credgrid>div{background:var(--card);padding:15px 16px}
.pf-credgrid .l{display:block;font-family:var(--pf-mono);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint)}
.pf-credgrid .v{display:block;margin-top:7px;font-family:var(--pf-serif);font-size:23px;
  line-height:1;color:var(--ink)}
.pf-credgrid .v.ok{color:var(--good)}
.pf-credgrid .m{display:block;margin-top:7px;font-family:var(--pf-mono);font-size:8.5px;
  letter-spacing:.05em;color:var(--ink-faint)}
.pf-issue{margin-top:22px;padding-top:16px;border-top:1px solid var(--line-soft)}
.pf-issue .l{font-family:var(--pf-mono);font-size:9px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-faint)}
.pf-ibar{display:grid;grid-template-columns:110px minmax(0,1fr) auto;gap:12px;align-items:center;
  margin-top:11px;font-size:12.5px;color:var(--ink-soft)}
.pf-ibar i{display:block;height:9px;background:var(--pf-data);border:1px solid var(--pf-data-deep)}
.pf-ibar.med i{background:var(--pf-data-soft);border-color:var(--pf-data-line)}
.pf-ibar b{font-family:var(--pf-mono);font-size:10px;font-weight:400;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-faint)}

/* ═══════════ sources ═══════════ */
.pf-colophon{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;margin:34px 0 0;
  padding:20px 0 0;border-top:1px solid var(--line-soft)}
@media(max-width:860px){.pf-colophon{grid-template-columns:1fr 1fr}}
@media(max-width:600px){.pf-colophon{grid-template-columns:1fr}}
.pf-colophon .l{display:block;font-family:var(--pf-mono);font-size:9px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-faint)}
.pf-colophon p{margin:6px 0 0;font-size:12px;line-height:1.65;color:var(--ink-faint)}

/* ═══════════ §4 owner layer, ported from mockup_v2 v2.3 with 8/10 vocabulary ═══════════ */
.pf-modal{display:none;position:fixed;inset:0;z-index:900;background:rgba(10,10,10,.55);
  padding:6vh 20px;overflow:auto}
.pf-modal:target{display:block}
.pf-modal-in{max-width:520px;margin:0 auto;background:var(--card);border:1px solid var(--line);
  padding:26px 28px;position:relative}
.pf-x{position:absolute;top:12px;right:16px;font-size:22px;color:var(--ink-faint);
  text-decoration:none}
.pf-modal h3{font-family:var(--pf-serif);font-size:25px;font-weight:400;margin:0}
.pf-field{display:block;margin:18px 0 8px}
.pf-field span{display:block;font-family:var(--pf-mono);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint);margin-bottom:6px}
.pf-field input{width:100%;padding:11px 12px;border:1px solid var(--line);background:var(--paper);
  font-size:14px;font-family:inherit}
.pf-note{font-size:12px;color:var(--ink-faint);margin:0 0 16px}

.pf-dash{display:none;margin:40px 0 0;padding:26px 0 0;border-top:2px solid var(--ink)}
body[data-owner="yes"] .pf-dash{display:block}
.pf-dash-head h2{font-family:var(--pf-serif);font-size:27px;font-weight:400;margin:0}
.pf-dash-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:20px}
@media(max-width:900px){.pf-dash-grid{grid-template-columns:1fr}}
.pf-pane{border:1px solid var(--line);background:var(--card);padding:18px 19px}
.pf-pane h3{font-family:var(--pf-serif);font-size:19px;font-weight:400;margin:0 0 4px}
.pf-events{list-style:none;margin:12px 0 0;padding:0}
.pf-events li{display:flex;gap:11px;padding:9px 0;border-bottom:1px dotted var(--line);
  font-size:13.5px}
.pf-events li:last-child{border-bottom:0}
.pf-events .d{font-family:var(--pf-mono);font-size:10px;color:var(--ink-faint);width:52px;flex:none}
.pf-events em{display:block;font-style:normal;font-size:12px;color:var(--ink-faint)}
.pf-editor{list-style:none;margin:12px 0 0;padding:0}
.pf-editor li{display:flex;justify-content:space-between;gap:12px;align-items:center;
  padding:10px 0;border-bottom:1px dotted var(--line);font-size:13.5px}
.pf-prov{font-family:var(--pf-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--pf-data2);background:var(--pf-data2-soft);border:1px solid var(--pf-data2-line);
  padding:3px 8px;white-space:nowrap}
.pf-badge{border:1px solid var(--line);background:var(--paper);padding:14px 15px;margin-top:12px}
.pf-badge .t{font-family:var(--pf-mono);font-size:8.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-faint)}
.pf-badge .n{font-family:var(--pf-serif);font-size:20px;margin:5px 0 10px}
.pf-badge .r{display:flex;justify-content:space-between;gap:12px;font-size:12.5px;
  padding:6px 0;border-top:1px dotted var(--line);color:var(--ink-soft)}
.pf-badge .f{margin-top:10px;font-family:var(--pf-mono);font-size:8px;letter-spacing:.09em;
  color:var(--ink-faint)}
.pf-embed{background:var(--ink);color:#e3dfd2;font-family:var(--pf-mono);font-size:10px;
  padding:11px 13px;overflow-x:auto;margin:12px 0 0}
.pf-price{font-family:var(--pf-serif);font-size:27px;margin:6px 0 0}
.pf-incl{margin:12px 0 0;padding:0;list-style:none}
.pf-incl li{padding:7px 0 7px 18px;position:relative;font-size:13.5px;color:var(--ink-soft)}
.pf-incl li:before{content:"";position:absolute;left:0;top:15px;width:9px;height:1px;
  background:var(--pf-data2)}

/* ═══════════ prototype ribbon (§6), not product ═══════════ */
.pf-ribbon{position:fixed;left:0;right:0;bottom:0;z-index:800;background:var(--ink);
  display:flex;gap:6px;align-items:center;flex-wrap:wrap;padding:8px 14px}
.pf-ribbon-l{font-family:var(--pf-mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;
  color:#7a7975;margin-right:4px}
.pf-ribbon button{background:#1e1e1c;border:1px solid #3d3d3a;color:#b9b6ae;
  font-family:var(--pf-mono);font-size:10px;padding:5px 10px;cursor:pointer}
.pf-ribbon button[aria-pressed="true"]{background:#f4f1ea;color:#0a0a0a;border-color:#f4f1ea}
.pf-ribbon-d{margin-left:auto;font-family:var(--pf-mono);font-size:10px;color:#b9b6ae;
  text-decoration:none;border:1px solid #3d3d3a;padding:5px 10px}
body{padding-bottom:52px}

/* ═══════════ viewer axis (§2.3, §2.6): independent of the firm axis ═══════════ */
.pf-leads,.pf-acct{display:none}
body[data-viewer="acct"] .pf-acct,body[data-viewer="leads"] .pf-acct{display:block}
body[data-viewer="leads"] .pf-leads{display:block}

/* §3: the trial end-card is a PermitPipeline promotion sitting below the firm's own work.
   It keeps orange as its accent but is not a second filled-orange object competing with
   the firm's action in the same screen. */
.spx-hero-go.pf-quietcta{background:var(--card)!important;color:var(--accent-dark)!important;
  border:1px solid var(--accent)!important;box-shadow:none!important}
.spx-hero-go.pf-quietcta:hover{background:var(--accent)!important;color:#fff!important}

/* ═══════════ Capabilities: the derived data restored (Josh, 2026-08-10) ═══════════ */
.pf-caps{margin:34px 0 0}
.pf-caps h2{font-family:var(--pf-serif);font-size:27px;font-weight:400;margin:0}
.pf-capgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line-soft);
  border:1px solid var(--line-soft);margin-top:16px}
@media(max-width:900px){.pf-capgrid{grid-template-columns:1fr 1fr}}
@media(max-width:620px){.pf-capgrid{grid-template-columns:1fr}}
.pf-capgrid>div{background:var(--card);padding:15px 16px}
.pf-capgrid .l{display:block;font-family:var(--pf-mono);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint)}
.pf-capgrid .v{display:block;margin-top:8px;font-family:var(--pf-serif);font-size:21px;
  line-height:1.15;color:var(--ink)}
.pf-capgrid .m{display:block;margin-top:10px;font-family:var(--pf-mono);font-size:8.5px;
  line-height:1.6;letter-spacing:.05em;color:var(--ink-faint)}
.pf-types{list-style:none;margin:9px 0 0;padding:0}
.pf-types li{font-size:13px;color:var(--ink-soft);padding:3px 0}
.pf-mixrow{display:grid;grid-template-columns:78px minmax(0,1fr) 32px;gap:8px;align-items:center;
  margin-top:8px;font-size:12.5px;color:var(--ink-soft)}
.pf-mixbar{height:7px;background:var(--pf-data-soft);border:1px solid var(--pf-data-line)}
.pf-mixbar i{display:block;height:100%;background:var(--pf-data)}
.pf-mixrow.alt .pf-mixbar{background:var(--pf-data2-soft);border-color:var(--pf-data2-line)}
.pf-mixrow.alt .pf-mixbar i{background:var(--pf-data2)}
.pf-mixrow b{font-family:var(--pf-mono);font-size:11px;font-weight:400;text-align:right}

/* tabs sit under the stat strip, so they need breathing room above the next block */
.pf-tabs{margin:2px 0 0}

/* sparse relationships: compact, anchored, never a headed empty section */
.pf-net-thin{margin:28px 0 0;padding:14px 16px;background:var(--paper);
  border-left:2px solid var(--pf-data)}
.pf-net-thin .l{display:block;font-family:var(--pf-mono);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint);margin-bottom:5px}
.pf-net-thin .pf-netline{margin:0;font-size:14px;color:var(--ink-soft)}

/* ═══════════ ghost card: the live-site cut-off pattern (Josh 2026-08-10) ═══════════ */
.pf-ghost{display:block;margin:16px 0 0;padding:22px 24px;text-decoration:none;
  border:1px dashed var(--accent);background:var(--accent-soft)}
.pf-ghost:hover{background:#ffe0d0}
.pf-ghost .pf-ghost-n{display:block;font-family:var(--pf-serif);font-size:23px;color:var(--ink)}
.pf-ghost .pf-ghost-s{display:block;margin-top:6px;font-size:14px;color:var(--ink-soft)}
.pf-ghost .pf-ghost-go{display:inline-block;margin-top:14px;font-weight:600;font-size:14px;
  color:var(--accent-dark)}

/* active tab */
.pf-tabs a.on{color:var(--ink);border-bottom-color:var(--accent)}
.pf-h,.pf-net-thin h2{font-family:var(--pf-serif);font-size:27px;font-weight:400;margin:0 0 6px}

/* ghost card on one row (Josh 2026-08-10) */
.pf-ghost-row{display:flex;align-items:center;gap:20px;flex-wrap:wrap;padding:16px 20px}
.pf-ghost-row .pf-ghost-n{flex:none;font-size:19px}
.pf-ghost-row .pf-ghost-s{flex:1;min-width:180px;margin-top:0;font-size:13.5px}
.pf-ghost-row .pf-ghost-go{margin-top:0;white-space:nowrap}
/* The live contact row used to be hidden in the Portfolio state, on the theory that
   our own buttons replaced it. Those buttons are gone now and the row is the only
   contact detail on the page. Removed 2026-08-10. */

/* the state switcher must read as a control, not chrome */
.pf-ribbon{padding:10px 16px;border-top:2px solid var(--accent)}
.pf-ribbon-l{font-size:10px;color:#e3dfd2;letter-spacing:.16em}
.pf-ribbon button{padding:6px 12px;font-size:10.5px}
.pf-ribbon button:hover{border-color:#b9b6ae;color:#fff}

/* preview disclaimer: this mockup carries invented copy on real companies' names */
.pf-preview{position:relative;z-index:1000;background:#8a5a12;color:#fff;padding:10px 18px;
  font:600 12.5px/1.55 -apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;text-align:center}

/* value-not-declared marker on a project card (2026-08-10) */
.pf-nodv{display:inline-block;font-family:'JetBrains Mono',monospace;font-size:10px;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint);
  border:1px solid var(--line);border-radius:4px;padding:1px 5px}

/* ONE PAGE, anchor tabs (2026-08-10) -----------------------------------------
   The tabs no longer navigate, so they have to stay on screen and report where
   the reader is. Sticky bar + scroll-margin so an anchor does not land under it. */
/* Fixed, not sticky. See the note in the tab script: sticky worked on paper and kept
   not working on the page. Full-bleed bar, contents aligned to the same 1100px column
   as everything else. scroll-margin is set by script from the measured bar heights. */
/* In flow, under the firm card, where it belongs. It only leaves the flow once you
   have scrolled past it, and a spacer of the same height keeps the page from jumping.
   A sentinel element drives that, not position:sticky: sticky was correct on paper
   here twice and did not hold on the page either time. */
.pf-tabs{position:static;z-index:790;background:var(--paper,#fefdf9);
  border-bottom:1px solid var(--line);margin:2px 0 0;overflow:visible}
/* Pinned, the bar IS the content column, using the same geometry the live page already
   uses for its own pinned CTA (#fp2-cta-pin): width:min(1060px, 100vw-40px) centred with
   left:50% + translateX(-50%). 1060 = main.wrap's 1100px max minus its 2x20px padding.
   The previous attempt centred a 1100px inner box inside a full-bleed bar and then added
   20px of padding to it, which is the same arithmetic done twice and drifted. One box,
   one calculation, and the tabs sit flush left inside it in both states. */
.pf-tabs.pf-stuck{position:fixed;left:50%;transform:translateX(-50%);right:auto;
  width:min(1060px,calc(100vw - 40px));margin:0;border-radius:0 0 10px 10px;
  border-bottom:1px solid var(--line);
  box-shadow:0 8px 20px rgba(10,10,10,.10)}
/* The live page carries an inline `main.wrap > *{margin-bottom:18px}`. It applied to
   the sentinel, the nav and the spacer, three of which are structural and none of which
   should occupy space. That, not our own margin, was the gap under the stat strip. */
main.wrap > .pf-tabsentinel{height:1px;margin:0!important}
main.wrap > .pf-tabspacer{height:0;margin:0!important}
main.wrap > .pf-tabs{margin:0 0 10px!important}
/* In flow the nav already sits inside main.wrap, which is the 1100px column with its
   own 20px padding. Repeating both here centred the row and pushed it 20px in from
   everything above it. The column treatment belongs ONLY to the pinned state, where
   the bar is full-bleed and has to find that column for itself. */
.pf-tabs-in{display:flex;overflow-x:auto;scrollbar-width:none;width:100%}
.pf-tabs-in::-webkit-scrollbar{display:none}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}

/* anchor targets are block-level so scroll-margin-top applies (2026-08-10) */
#pf-portfolio,#pf-projects,#pf-network,#pf-activity,#pf-credentials{display:block}

/* Owner CTA band (2026-08-10). Split by audience: the buyer's action is the live
   "Monitor firm" button in the identity block; this strip is addressed to the firm. */
.pf-ownerband{margin:26px 0 0;padding:20px 22px;border:1px solid var(--line);
  border-radius:12px;background:var(--paper-2)}
.pf-ob-t{font-size:17px;font-weight:800;letter-spacing:-.01em;color:var(--ink)}
.pf-ob-s{font-size:13.5px;color:var(--ink-soft);line-height:1.5;margin:6px 0 14px;
  max-width:62ch}
.pf-ownerband .pf-btn-primary{display:inline-block}
/* the live trial panel keeps its position; only its button is toned down (§3 budget) */
.pf-quietcta .spx-hero-go{background:transparent;color:var(--paper);
  border:1px solid rgba(255,255,255,.55)}
.pf-quietcta .spx-hero-go:hover{background:rgba(255,255,255,.12)}

/* ═══════════ 2026-08-10 restructure ═══════════════════════════════════════════
   Tab order flips on claim. Projects is the permit record and is always there;
   Portfolio is what the firm supplies and leads only once it is filled. Flex
   `order` does this with no script and no second markup path. */
.pf-tabs a[data-tab="portfolio"]{order:9}
.pf-tabs a[data-tab="projects"]{order:1;padding-left:0}
.pf-tabs a[data-tab="relationships"]{order:2}
.pf-tabs a[data-tab="activity"]{order:3}
.pf-tabs a[data-tab="credentials"]{order:4}
body[data-firm="folio"] .pf-tabs a[data-tab="portfolio"]{order:0}

/* the Portfolio badge, in the h1 line to the right of the firm name */
.pf-badge-folio{display:inline-flex;align-items:center;gap:5px;vertical-align:middle;
  margin-left:11px;padding:4px 10px 4px 8px;border-radius:999px;
  border:1px solid var(--pf-data2,#8aa6c8);background:var(--paper-2,#f4f1ea);
  font-family:var(--pf-mono);font-size:10px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-soft);white-space:nowrap}
.pf-badge-tick{font-style:normal;font-size:10px;line-height:1;color:var(--pf-data2,#8aa6c8)}
body[data-firm="unclaimed"] .pf-badge-folio,
body[data-firm="claimed"] .pf-badge-folio{display:none}

/* Placeholder photography reads as a placeholder: desaturated, never passed off as
   this firm's work. Josh 2026-08-10. Kept at full contrast so the claimed state still
   looks worth paying for; grey is the signal, not a downgrade. */
/* Photographs render in COLOUR. Josh, 2026-08-10.
 *
 * They were desaturated so a placeholder read as a placeholder. That reasoning does not
 * survive contact with where they actually appear: the photo band only renders in the
 * paid Portfolio state, so the grey treatment was landing on precisely the one screen
 * whose job is to show a firm what $399 buys, and nowhere else. The captions still say
 * "Illustrative photograph", which is what carries the placeholder claim.
 *
 * If a greyed treatment is wanted again, it belongs on a before-claim mock-up of the
 * band, not on the band itself. */
.pf-shot{position:relative}

/* Unclaimed: the Portfolio section is an invitation, not a hole in the page. */
.pf-folio-empty{margin:26px 0 0;padding:26px 22px;border:1px dashed var(--line);
  border-radius:12px;background:var(--paper-2);text-align:left}
.pf-folio-empty .t{font-size:16px;font-weight:800;color:var(--ink)}
.pf-folio-empty .s{font-size:13.5px;color:var(--ink-soft);line-height:1.55;
  margin:6px 0 0;max-width:62ch}
body[data-firm="folio"] .pf-folio-empty{display:none}
body[data-firm="unclaimed"] .pf-folio-empty,
body[data-firm="claimed"] .pf-folio-empty{display:block}

/* the preview control now sits at the top and has to read as a control, not a banner */
/* The ribbon was declared position:fixed;bottom:0 further up this file, and the later
   rule changed position without ever clearing bottom. Both are set explicitly here. */
.pf-ribbon{position:fixed;top:0;bottom:auto;left:0;right:0;z-index:800;
  border-top:0;border-bottom:2px solid var(--accent)}
/* .pf-tabs top and the body's top padding are set by script from the measured heights */

/* ═══════════ 2026-08-10: the anonymous view of an UNCLAIMED page ══════════════════
   This is the state we are nailing down first. 5,278 firms are in it. */

/* 1. Top actions, Zillow-style: orange text links with icons, in a row. Not buttons.
      Monitor is the live save button restyled, so its gate and behaviour are untouched. */
.pf-actionrow{flex:none;display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  justify-content:flex-end;margin:2px 0 0}
/* Every property the live .fp2-save sets is unset here, or Monitor keeps its box:
   border, background, border-radius, padding, min-width, text-align, display. */
.pf-actionrow .pf-alink,
.pf-actionrow .fp2-save,
.pf-actionrow .fp2-save.is-saved{display:inline-flex;align-items:center;gap:7px;
  margin:0;padding:0;border:0;background:none;border-radius:0;box-shadow:none;
  min-width:0;text-align:left;white-space:nowrap;cursor:pointer;
  color:var(--accent-dark);font-size:14px;font-weight:700;line-height:1.2;
  text-decoration:none}
/* The live page carries an INLINE a.fi-freegate:hover{background:var(--accent);color:#fff}
   which my hover rule never mentioned background, so the button still filled to an orange
   rectangle on rollover. Every property that block sets is now named here. */
.pf-actionrow .pf-alink:hover,
.pf-actionrow a.fp2-save:hover,
.pf-actionrow a.fi-freegate:hover{text-decoration:underline;background:none;
  border:0;border-color:transparent;box-shadow:none;color:var(--accent-dark)}
.pf-actionrow a.fi-freegate{background:none;border:0;border-radius:0;padding:0}
.pf-actionrow .fp2-save.is-saved{color:var(--pf-data2)}
.pf-actionrow .fp2-save.is-saved:hover{color:var(--pf-data2)}
.pf-ico{flex:none;display:block}
@media(max-width:640px){.pf-actionrow{justify-content:flex-start;gap:16px;margin-top:10px}}

/* 2. One card per call to action, at the foot of the page. */
.pf-ctacards{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin:36px 0 0}
@media(max-width:820px){.pf-ctacards{grid-template-columns:1fr}}
.pf-ctacard{display:flex;flex-direction:column;gap:7px;padding:20px 20px 18px;
  border:1px solid var(--line);border-radius:12px;background:var(--card);
  text-decoration:none;color:inherit;transition:border-color .12s,transform .12s}
.pf-ctacard:hover{border-color:var(--ink);transform:translateY(-1px)}
.pf-cc-i{color:var(--accent-dark)}
.pf-cc-t{font-size:16px;font-weight:800;letter-spacing:-.01em;color:var(--ink)}
.pf-cc-s{font-size:13px;line-height:1.5;color:var(--ink-soft);flex:1}
.pf-cc-go{margin-top:4px;font-size:13.5px;font-weight:700;color:var(--accent-dark)}
body[data-firm="folio"] .pf-ctacard.pf-claim,
body[data-owner="yes"] .pf-ctacard.pf-claim{display:none}

/* 4. The live trial panel becomes a sticky bar pinned to the bottom of the screen.
      It keeps its place in the DOM; position:fixed takes it out of the flow, so the
      page order and the live component both stay intact. */
/* The panel stays where the live page puts it. A COPY of its message floats up from
   the bottom only once that panel has scrolled out of sight, so the page never shows
   the same offer twice at once (Josh, 2026-08-10). */
.pf-floatbar{position:fixed;left:50%;transform:translateX(-50%) translateY(120%);
  bottom:14px;z-index:70;width:calc(100% - 40px);max-width:1060px;
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:12px 18px;border-radius:12px;background:var(--ink);color:var(--paper);
  box-shadow:0 10px 34px rgba(10,10,10,.28);opacity:0;pointer-events:none;
  transition:transform .22s ease,opacity .18s ease}
.pf-floatbar.on{transform:translateX(-50%) translateY(0);opacity:1;pointer-events:auto}
.pf-floatbar-t{font-size:13.5px;line-height:1.35;margin:0}
.pf-floatbar-go{flex:none;display:inline-flex;align-items:center;padding:9px 16px;
  border-radius:8px;background:var(--accent);color:#fff;font-size:13.5px;font-weight:700;
  text-decoration:none;white-space:nowrap}
.pf-floatbar-go:hover{background:var(--accent-dark)}
.pf-floatbar-x{flex:none;background:none;border:0;color:#b9b6ae;font-size:18px;
  line-height:1;cursor:pointer;padding:2px 2px 4px}
.pf-floatbar-x:hover{color:#fff}
@media(max-width:700px){.pf-floatbar{padding:10px 14px;bottom:10px;width:calc(100% - 20px)}
  .pf-floatbar-t{font-size:12.5px}}

/* 5. The unclaimed Portfolio invitation, now the last section on the page. */
.pf-folio-empty .t{font-size:17px;font-weight:800;line-height:1.35;max-width:44ch}
.pf-folio-empty .pf-btn-primary{align-self:flex-start;margin-top:14px}
.pf-folio-empty{display:flex;flex-direction:column;align-items:flex-start}

/* CTA cards: the question first, in the reader's own words, then the ask. */
.pf-cc-q{font-family:var(--pf-mono);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-faint);line-height:1.4}
.pf-ctacard{gap:9px}
.pf-cc-go{color:var(--accent-dark);font-weight:700}

/* ── unclaimed page details, 2026-08-10 ───────────────────────────────────────── */

/* 1. A logo-shaped invitation where the logo goes. Same box as .pf-logo so nothing
      shifts when a real logo replaces it. */
.pf-logo-empty{display:none;float:left;width:56px;height:56px;margin:2px 16px 10px 0;
  border:1px dashed var(--line);border-radius:2px;background:var(--paper-2);
  flex-direction:column;align-items:center;justify-content:center;gap:1px;
  font-family:var(--pf-mono);font-size:7.5px;line-height:1.25;letter-spacing:.06em;
  text-transform:uppercase;text-align:center;color:var(--ink-faint);
  text-decoration:none;padding:0 4px}
.pf-logo-empty b{font-size:15px;font-weight:400;line-height:1;color:var(--ink-faint)}
.pf-logo-empty:hover{border-color:var(--ink-faint);color:var(--ink-soft)}
body[data-firm="unclaimed"] .pf-logo-empty{display:flex}

/* 2. The firm's own contact details are facts, not calls to action. Orange is for
      acting; these are black. */
.fp2-contact a{color:var(--ink)}
.fp2-contact a:hover{color:var(--ink);text-decoration:underline}

/* 3. Share and Claim sat further from their icons than Monitor did from its text star,
      because the star is a glyph with a normal word space and these are 16px SVGs. */
.pf-actionrow .pf-alink{gap:5px}
.pf-actionrow .pf-alink .pf-ico{margin-right:-1px}

/* Credentials: a list of stated facts, each with the basis under it (2026-08-10). */
.pf-credlist{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:10px;overflow:hidden}
@media(max-width:760px){.pf-credlist{grid-template-columns:1fr}}
.pf-credrow{display:flex;flex-direction:column;gap:3px;padding:16px 18px;
  background:var(--card)}
.pf-credrow .l{font-family:var(--pf-mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint)}
.pf-credrow .v{font-size:19px;font-weight:800;letter-spacing:-.01em;color:var(--ink)}
.pf-credrow .m{font-size:12.5px;line-height:1.5;color:var(--ink-soft)}
.pf-credsnote{margin:14px 0 0;font-size:12.5px;line-height:1.55;color:var(--ink-faint);
  max-width:70ch}

/* ═══════════ VIEWER-AXIS GATES, ACCESS_TIER_MATRIX_v2.1 §3a (2026-08-10) ═══════════
   Until now anonymous, free-account and Leads rendered identically, which is handoff
   open item #3: the access simulator did not simulate access. Each rule below cites the
   matrix row it enforces. */

/* "Phone / email / LinkedIn: — · ● · ●". Website is ungated in every tier. */
body[data-viewer="anon"] .fp2-contact a[href^="tel:"],
body[data-viewer="anon"] .fp2-contact a[href*="linkedin.com"]{display:none}

/* "Network: full non-owner list + shared-project counts: ○ · ● · ●".
   Top three are ungated; the rest need a free account. */
body[data-viewer="anon"] .pf-tier-acct{display:none}
.pf-netgate{margin:12px 0 0;padding:11px 14px;border:1px dashed var(--line);
  border-radius:8px;font-size:13px;line-height:1.5;color:var(--ink-soft);display:none}
.pf-netgate a{color:var(--accent-dark);font-weight:700}
body[data-viewer="anon"] .pf-netgate.pf-tier-anon-only{display:block}
/* "Network: owner and developer names / the projects behind each connection: — · — · ●" */
body[data-viewer="acct"] .pf-netgate.pf-tier-acct-only{display:block}

/* Dashboard joins the nav only once there is something to administer. */
.pf-navdash{display:none}
body[data-owner="yes"]:not([data-firm="unclaimed"]) .pf-navdash{display:inline-flex;
  align-items:center;margin-left:auto;color:var(--accent-dark);font-weight:700}

/* ═══════════ OWNER FLOWS: claim, and Portfolio setup (2026-08-10) ═══════════ */
.pf-flow{display:none;position:fixed;inset:0;z-index:950;background:rgba(10,10,10,.62);
  padding:28px 16px;overflow:auto}
.pf-flow.on{display:block}
body.pf-flowopen{overflow:hidden}
.pf-flow-in{position:relative;max-width:560px;margin:0 auto;background:var(--card);
  border-radius:14px;padding:30px 30px 26px;box-shadow:0 30px 80px rgba(0,0,0,.34)}
.pf-flow-wide{max-width:760px}
.pf-flow .pf-x{position:absolute;top:12px;right:16px;font-size:22px;line-height:1;
  background:none;border:0;color:var(--ink-faint);cursor:pointer}
.pf-flow h3{margin:0 0 6px;font-family:var(--pf-serif);font-size:26px;font-weight:400}
.pf-flow h4{margin:0 0 8px;font-size:14px;font-weight:800}
.pf-flow .pf-sub{margin:0 0 18px;font-size:14px;line-height:1.55;color:var(--ink-soft)}
.pf-flow .pf-src{margin:14px 0 0;font-size:12px;line-height:1.5;color:var(--ink-faint)}
.pf-flow .pf-alt{margin:12px 0 0;font-size:13px}
.pf-flow .pf-alt a{color:var(--accent-dark);font-weight:600}

/* step rail */
.pf-steps{display:flex;gap:6px;list-style:none;margin:0 0 20px;padding:0}
.pf-steps li{flex:1;font-family:var(--pf-mono);font-size:8.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-faint);padding-top:9px;
  border-top:2px solid var(--line)}
.pf-steps li.on{color:var(--ink);border-top-color:var(--accent)}
.pf-steps li.done{color:var(--ink-soft);border-top-color:var(--pf-data2)}
.pf-step{display:none}
.pf-step.on{display:block}

.pf-field{display:block;margin:0 0 4px}
.pf-field span{display:block;font-family:var(--pf-mono);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint);margin-bottom:6px}
.pf-field input,.pf-field textarea{width:100%;padding:11px 13px;border:1px solid var(--line);
  border-radius:8px;background:var(--paper);font:inherit;font-size:14px;color:var(--ink)}
.pf-field input:focus,.pf-field textarea:focus{outline:2px solid var(--pf-data);
  outline-offset:1px;border-color:var(--pf-data)}
.pf-err{display:none;margin:8px 0 0;padding:10px 12px;border-radius:8px;
  background:#fff4e8;border:1px solid #f2c99a;color:#8a4a12;font-size:13px;line-height:1.5}
.pf-err.on{display:block}
.pf-err a{color:#8a4a12;font-weight:700}
.pf-flow .pf-btn-primary,.pf-flow .pf-btn-quiet{margin-top:16px;cursor:pointer}
.pf-flow .pf-btn-primary.sm{margin-top:12px;padding:8px 14px;font-size:13px}

/* the verification email, drawn rather than described */
.pf-mailmock{margin:6px 0 0;border:1px solid var(--line);border-radius:10px;
  background:var(--paper);padding:14px 16px}
.pf-mailmock .h{display:flex;flex-direction:column;gap:2px;padding-bottom:9px;
  border-bottom:1px solid var(--line-soft)}
.pf-mailmock .h b{font-size:13px}
.pf-mailmock .h span{font-size:12.5px;color:var(--ink-soft)}
.pf-mailmock .b{padding:11px 0 0;font-size:13.5px;line-height:1.5;color:var(--ink-soft)}

.pf-twoup{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:4px}
@media(max-width:640px){.pf-twoup{grid-template-columns:1fr}}
.pf-twoup .pf-pane{border:1px solid var(--line);border-radius:11px;padding:16px 17px;
  background:var(--paper);display:flex;flex-direction:column}
.pf-pane-up{border-color:var(--accent);background:var(--card)}
.pf-flow .pf-incl{margin:0;padding-left:17px;font-size:13px;line-height:1.65;
  color:var(--ink-soft);flex:1}
.pf-plain{margin:0;padding-left:17px;font-size:13.5px;line-height:1.65;color:var(--ink-soft)}

/* project selection, photo drops, captions, rights */
.pf-picks{display:flex;flex-direction:column;gap:8px}
.pf-pick{display:flex;align-items:center;gap:11px;padding:12px 14px;border:1px solid var(--line);
  border-radius:9px;background:var(--paper);cursor:pointer}
.pf-pick:has(input:checked){border-color:var(--pf-data);background:var(--pf-data-soft)}
.pf-pick .t{flex:1;font-size:14px;font-weight:600}
.pf-pick .p{font-family:var(--pf-mono);font-size:8.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-faint)}
.pf-drops{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media(max-width:640px){.pf-drops{grid-template-columns:1fr}}
.pf-drop{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  text-align:center;min-height:132px;padding:14px 12px;border:1px dashed var(--line);
  border-radius:10px;background:var(--paper);cursor:pointer}
.pf-drop:hover{border-color:var(--ink-faint)}
.pf-drop b{font-size:20px;font-weight:400;color:var(--ink-faint);line-height:1}
.pf-drop span{font-size:12.5px;font-weight:600;line-height:1.35}
.pf-drop em{font-style:normal;font-family:var(--pf-mono);font-size:8px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-faint)}
.pf-capfield{margin-bottom:14px;position:relative}
.pf-capfield::after{content:attr(data-n);position:absolute;right:2px;top:0;
  font-family:var(--pf-mono);font-size:8.5px;letter-spacing:.1em;color:var(--ink-faint)}
.pf-check{display:flex;gap:11px;align-items:flex-start;padding:15px 16px;
  border:1px solid var(--line);border-radius:10px;background:var(--paper);
  font-size:13.5px;line-height:1.55;color:var(--ink-soft);cursor:pointer}
.pf-check input{margin-top:2px;flex:none}
.pf-shake{animation:pf-shake .34s}
@keyframes pf-shake{25%{transform:translateX(-5px)}75%{transform:translateX(5px)}}
.pf-flow-nav{display:flex;justify-content:space-between;align-items:center;gap:12px;
  margin-top:20px;padding-top:16px;border-top:1px solid var(--line-soft)}

/* onboarding: the ten largest, and the firm's own additions */
.pf-picks{max-height:340px;overflow:auto;padding-right:4px}
.pf-pick .n{font-family:var(--pf-mono);font-size:9px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-faint);white-space:nowrap}
.pf-addown{margin-top:16px;padding:16px 17px;border:1px dashed var(--line);
  border-radius:10px;background:var(--paper)}
.pf-addown .t{font-size:14px;font-weight:800}
.pf-addown .s{margin:5px 0 12px;font-size:13px;line-height:1.5;color:var(--ink-soft)}
.pf-addown .pf-btn-quiet{margin-top:10px}

/* ── Edit affordances for a claimed profile (2026-08-10) ──────────────────────
   A free claim buys three editable things. Nothing factual gets a pencil. */
.pf-pen{display:none;background:none;border:0;padding:2px 6px;margin-left:6px;
  font-size:13px;line-height:1;color:var(--ink-faint);cursor:pointer;vertical-align:middle}
.pf-pen:hover{color:var(--accent-dark)}
body[data-owner="yes"]:not([data-firm="unclaimed"]) .pf-pen{display:inline-block}
.pf-pen-logo{position:absolute;margin:0;left:44px;top:-4px;background:var(--card);
  border:1px solid var(--line);border-radius:99px;width:22px;height:22px;padding:0}
.fp2-idmain{position:relative}
.pf-editrow{display:flex;align-items:flex-start;gap:4px}
.pf-editrow .pf-pen{margin-top:2px}

/* Dashboard is a tab now, and only for the owner. */
.pf-tabs a[data-tab="dashboard"]{order:10;display:none;color:var(--accent-dark)}
body[data-owner="yes"]:not([data-firm="unclaimed"]) .pf-tabs a[data-tab="dashboard"]{
  display:inline-flex;margin-left:auto}

/* The Portfolio editor is a control panel, not a list. */
.pf-editor li{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:11px 0;border-bottom:1px solid var(--line-soft)}
.pf-editor .pf-ed-t{flex:1;min-width:160px;font-size:13.5px;font-weight:600}
.pf-ed-acts{display:flex;gap:4px}
.pf-ed-btn{width:26px;height:26px;display:inline-flex;align-items:center;
  justify-content:center;border:1px solid var(--line);border-radius:6px;
  background:var(--card);color:var(--ink-soft);font-size:13px;line-height:1;cursor:pointer}
.pf-ed-btn:hover{border-color:var(--ink);color:var(--ink)}
.pf-editor .pf-ed-cap{flex-basis:100%;font-size:12.5px;line-height:1.5;
  color:var(--ink-soft);padding:6px 10px;background:var(--paper);
  border-left:2px solid var(--pf-data2)}

/* the firm's own additions in the wizard */
.pf-ownlist{list-style:none;margin:12px 0 0;padding:0;display:flex;
  flex-direction:column;gap:6px}
.pf-ownlist li{display:flex;align-items:center;gap:10px;padding:9px 12px;
  border:1px solid var(--line);border-radius:8px;background:var(--card)}
.pf-ownlist .t{flex:1;font-size:13.5px;font-weight:600}
.pf-ownlist .p{font-family:var(--pf-mono);font-size:8.5px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-faint)}

/* ═══════════ 2026-08-12: visual convergence pass ═══════════════════════════════════
   Four changes, appended LAST on purpose. "The cascade order of three separate .pf-tabs
   rules" is named in this file as a reason the sticky bar did not hold the last two
   times; a block that comes after every other rule removes that question entirely.
   Nothing here touches data binding, card content or any handler. */

/* 1. SECTION NAV — sticky, not fixed ------------------------------------------------
   The bar was fixed, driven by a sentinel, a spacer and a scroll handler, because
   position:sticky failed twice before. It failed while #pf-ribbon was pinned to the top
   of the viewport and setting body padding underneath it. v2 removes the ribbon, so the
   bar's containing block is now plain document flow and sticky is the simple, correct
   mechanism. The tabs, their type, their active state and their anchors are untouched. */
.pf-tabs{position:sticky;top:0;z-index:790;background:var(--paper,#f4f1ea);
  border-bottom:1px solid var(--line);overflow:visible}
/* pf-stuck no longer moves the bar — sticky never leaves the flow. Its real job now is
   DEFENSIVE: the mockup's tab script is not present in the v2 page, but if it is ever
   restored it will add this class, and without these unsets it would drag the bar back
   out of the flow. Every property the old fixed rule set is cleared by name here.
   The shadow is therefore inert today; measured 2026-08-12, the class never fires. */
.pf-tabs.pf-stuck{position:sticky;top:0;left:auto;right:auto;transform:none;
  width:auto;margin:0 0 10px;border-radius:0;
  box-shadow:0 6px 14px rgba(10,10,10,.07)}
/* The spacer held the page height while the bar was out of the flow. Sticky never leaves
   it, so the script's inline height would now be a phantom gap under the stat strip. */
main.wrap > .pf-tabspacer{height:0!important}
/* Narrow screens still scroll the tab row horizontally — that lives on .pf-tabs-in and is
   restated here only so a future edit to .pf-tabs cannot take it away silently. */
.pf-tabs-in{display:flex;overflow-x:auto;scrollbar-width:none;width:100%}

/* 2. HEADER ACTIONS — REVERTED 2026-08-12, same day, after visual review -----------
   A convergence pass restyled this row: Monitor became a filled orange button, Share went
   to ink, Claim went to ink-faint. On the page Claim read as DISABLED and the row no
   longer matched the approved mockup. The mockup's treatment — three equal orange text
   links with icons — is the approved one and is defined above; the fix is to delete the
   override, not to write a third version of it. Nothing else in this block changed, and
   no markup, destination or handler was touched in either direction. */

/* 3. MONITOR MODAL — page tokens, no hard-coded brown --------------------------------
   The modal now carries .pf-flow / .pf-flow-in / .pf-x / .pf-field / .pf-alt, so its
   type scale, input, radius, links and spacing ARE the ones the claim flow already uses
   rather than a second set written inline. Its content is unchanged.
   The one new value: orange with dark text. White on #ff5722 is 3.0:1 and fails AA for
   body-size text; #0a0a0a on #ff5722 is about 6:1. */
.pf-modal-go{display:block;width:100%;margin-top:16px;padding:12px 18px;
  border:1px solid var(--accent-dark);border-radius:8px;background:var(--accent);
  color:var(--ink);font:inherit;font-size:15px;font-weight:700;cursor:pointer}
.pf-modal-go:hover{background:var(--accent-dark);color:#fff}
#fi-free-ov .pf-flow-in{max-width:420px;padding:28px 26px 22px}

/* 4. CLAIM MODAL — vertically centred ------------------------------------------------
   It opened 28px from the top of the viewport because the overlay was a scrolling block
   with padding. A flex overlay centres it; the panel takes its own scrollbar so a long
   claim step stays usable on a short screen. dvh, not vh, so a mobile URL bar does not
   push the buttons out of reach. The opener, the focus move and all four entry points
   are untouched — this is placement only. */
.pf-flow{display:none;align-items:center;justify-content:center;padding:20px;
  overflow:auto;overscroll-behavior:contain}
.pf-flow.on{display:flex}
.pf-flow-in{margin:0;width:100%;max-width:560px;
  max-height:calc(100dvh - 40px);overflow-y:auto;overscroll-behavior:contain}
.pf-flow-in.pf-flow-wide{max-width:760px}
@supports not (height:100dvh){.pf-flow-in{max-height:calc(100vh - 40px)}}

/* ═══════════ 2026-08-12: Josh review — chart colour, firm name, section order ═════════
   All three are portfolio.css overriding what firm-intel.css (the live firm page's own
   stylesheet) already had right. Appended last so the cascade is not in question. */

/* 1. FILING-ACTIVITY BARS BACK TO THE LIVE TREATMENT.
   Line 22 paints `.fp2-bar` AND its span with --pf-data, so the whole 100%-height column
   was filled and every week looked identical — the chart read as a solid block, not a
   distribution. On the live page the COLUMN is transparent and only the span carries the
   value, in --accent. Restored exactly. */
.fp2-chart .fp2-bar{background:transparent!important}
.fp2-chart .fp2-bar:hover{background:transparent!important}
.fp2-chart .fp2-bar span{background:var(--accent)!important}

/* 2. FIRM NAME IN THE LIVE FACE.
   firm-intel.css sizes .fp2-h1 at 29px/800/-.02em and leaves the family to the page
   default (Inter). portfolio.css:35 swapped it to the serif. Size, weight, tracking and
   colour were already identical — only the family differed. */
.fp2-h1{font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}

/* 3. ACTIVITY SITS ABOVE RELATIONSHIPS.
   The sections themselves are reordered in the DOM by build_template.py; these two rules
   keep the sticky tab row in the same order as the page it navigates. */
.pf-tabs a[data-tab="activity"]{order:2}
.pf-tabs a[data-tab="relationships"]{order:3}

/* ═══════════ 2026-08-12 (2): Josh review round 2 ════════════════════════════════════ */

/* 1. AT-A-GLANCE AS THREE EQUAL COLUMNS.
   It was a wrapping flex row, so three facts ran together as one sentence and the wrap
   point moved with the content. A grid gives each fact its own column and one clean
   stack on narrow screens. */
.fp2-glance{display:grid;grid-template-columns:repeat(3,1fr);gap:10px 22px;align-items:start}
.fp2-glance>span{display:block;min-width:0}
.fp2-glance b{display:block;font-family:var(--pf-mono);font-size:9.5px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-faint);margin:0 0 3px}
.fp2-glance .g-v{color:var(--ink);font-size:13.5px}
@media(max-width:760px){.fp2-glance{grid-template-columns:1fr;gap:12px}}

/* 2. THE FIRM DESCRIPTION SHOWS ON UNCLAIMED PAGES.
   portfolio.css:44 hides .pf-intro for data-firm="unclaimed" — which is every page we are
   launching. The line it hides is the one that TELLS the firm it can add a description and
   links them to the claim flow, so hiding it removed the only prompt on the page. */
body[data-firm="unclaimed"] .pf-intro{display:block}

/* 3. NO RANK IS A SENTENCE, NOT A 34px DASH.
   activity_rank is null when a firm has too little recent activity to place. Rendering that
   as an em dash in the rank slot read as a data error. */
.n.rank .rank-none{font-size:15px;font-weight:700;letter-spacing:0;color:var(--ink-soft);
  font-family:'Inter',-apple-system,sans-serif}

/* 4. TWO BALANCED CTA CARDS.
   The Firm Report card is removed until the report exists; Monitor and Claim share the row. */
.pf-ctacards{grid-template-columns:repeat(2,1fr)}
@media(max-width:820px){.pf-ctacards{grid-template-columns:1fr}}

/* 5. CONTRAST ON THE ORANGE CLAIM CARD.
   Measured on the live preview: the eyebrow was 1.38:1, the footer line 1.45:1 and the body
   3.44:1 against #ff5722. Only the title passed. Hierarchy now comes from size and weight,
   which survives on any background, instead of from lighter greys, which do not. */
.pf-ctacard.pf-claim .pf-cc-q,
.pf-ctacard.pf-claim .pf-cc-t,
.pf-ctacard.pf-claim .pf-cc-s,
.pf-ctacard.pf-claim .pf-cc-go,
.pf-ctacard.pf-claim .pf-cc-i{color:var(--ink)}
.pf-ctacard.pf-claim .pf-cc-s{opacity:.86}

/* 6. THE CLAIM FLOW'S PRIMARY BUTTON MATCHES MONITOR'S.
   White on #ff5722 is 3.16:1 and fails AA for button text; dark ink on the same orange is
   6.26:1. Monitor's button was already corrected — the claim flow was not. */
.pf-flow .pf-btn-primary{color:var(--ink)}
.pf-flow .pf-btn-primary:hover{background:var(--accent-dark);color:#fff}

/* 7. THE PINNED CTA MUST NEVER SIT OVER A DIALOG.
   It is z-index 70 and the modals are 950, so it cannot cover them — but it can still crowd
   the buttons underneath on a short phone. It is hidden outright while either flow is open. */
body.pf-flowopen #fp2-cta-pin,
body.pf-monitoropen #fp2-cta-pin{display:none!important}

/* ═══════════ 2026-08-12 (3): at-a-glance becomes the activity card's header ══════════
   Josh: "it's just floating in space." It was the only element on that stretch of page not
   in a card, sitting between the project carousel and the activity cards as bare text on
   paper. Containment was the problem, not spacing — so it moves INSIDE the card whose chart
   it summarises (the DOM move is in build_template.py) and becomes that card's header row. */
.fp2-card > .fp2-glance{
  display:grid;grid-template-columns:repeat(3,1fr);gap:0;
  margin:-20px -20px 16px;padding:11px 0;           /* span the card's own 20px padding */
  border-bottom:1px solid var(--line-soft);
  border-radius:12px 12px 0 0;background:transparent}
.fp2-card > .fp2-glance > span{
  display:block;min-width:0;padding:0 20px;border-right:1px solid var(--line-soft)}
.fp2-card > .fp2-glance > span:last-child{border-right:0}
.fp2-card > .fp2-glance b{
  display:block;font-family:var(--pf-mono);font-size:9px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint);margin:0 0 4px}
.fp2-card > .fp2-glance .g-v{
  display:block;font-size:19px;font-weight:500;line-height:1.2;color:var(--ink);
  letter-spacing:-.01em}
.fp2-card > .fp2-glance .g-u{font-size:13px;font-weight:400;color:var(--ink-soft)}
.fp2-card > .fp2-glance .g-sub{
  display:block;margin-top:3px;font-size:12px;line-height:1.4;color:var(--ink-soft)}

/* The value-range bar. Track is the 10th-90th percentile, the filled band is the middle
   half, and the tick is the median — a range is genuinely hard to read as text. Nothing is
   labelled: the numbers are stated beside it, and an axis with unstated ends is decoration. */
.fp2-card > .fp2-glance .g-bar{
  display:block;position:relative;height:6px;margin:7px 0 0;
  background:var(--line-soft);border-radius:3px}
.fp2-card > .fp2-glance .g-bar i{
  position:absolute;top:0;bottom:0;background:var(--accent);border-radius:3px}
.fp2-card > .fp2-glance .g-bar u{
  position:absolute;top:-3px;width:2px;height:12px;background:var(--ink);text-decoration:none}

@media(max-width:760px){
  .fp2-card > .fp2-glance{grid-template-columns:1fr;gap:0;padding:4px 0 0}
  .fp2-card > .fp2-glance > span{
    border-right:0;border-bottom:1px solid var(--line-soft);padding:12px 20px}
  .fp2-card > .fp2-glance > span:last-child{border-bottom:0}
}

/* ---- 2026-08-12 (h): THE MIDPOINT SITS BESIDE THE RANGE, NOT UNDER IT ------------------
   Josh: "$120K avg" moves up next to the range so the row can lose a line. It is the same
   fact at a lighter weight — smaller, ink-soft, and NOT bold — so it reads as a qualifier
   of the number to its left rather than as a second number competing with it. Baseline is
   left alone deliberately: the two sit on one line, and nudging the smaller one up reads as
   a superscript. */
.fp2-card > .fp2-glance .g-v .g-mid{
  margin-left:8px;font-size:12px;font-weight:400;letter-spacing:0;color:var(--ink-soft);
  white-space:nowrap}

/* ---- 2026-08-12 (i): R1 CHECKPOINT 1 -------------------------------------------------
   The Monitor modal's primary control is now an <a> into the real sign-in flow rather than
   a <button type=submit> posting to an endpoint that never existed. .pf-modal-go was written
   for a button, so it needs the two properties a link does not inherit. Same rule, same
   colours, same contrast decision recorded above it. */
a.pf-modal-go{text-align:center;text-decoration:none;box-sizing:border-box}
a.pf-modal-go:hover{color:#fff}
