/* ⚠ A SECOND WEBFONT LOAD. app.html has its own <link>; this @import is a separate fetch that was
   still pulling Poppins after the faces changed — a swap done only in app.html would have left the
   old face downloading, and any rule naming Poppins directly still resolving. Option C, 10 Aug. */
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Manrope:wght@400;500;600;700;800&family=Space+Mono:wght@400;700&family=Plus+Jakarta+Sans:wght@600&display=swap');
/* latin-ext */

/* latin */

/* latin-ext */

/* latin */

/* cyrillic-ext */

/* cyrillic */

/* greek-ext */

/* greek */

/* vietnamese */

/* latin-ext */

/* latin */

/* cyrillic-ext */

/* cyrillic */

/* greek-ext */

/* greek */

/* vietnamese */

/* latin-ext */

/* latin */

/* cyrillic-ext */

/* cyrillic */

/* greek-ext */

/* greek */

/* vietnamese */

/* latin-ext */

/* latin */

/* cyrillic-ext */

/* cyrillic */

/* greek-ext */

/* greek */

/* vietnamese */

/* latin-ext */

/* latin */

/* cyrillic-ext */

/* cyrillic */

/* greek */

/* vietnamese */

/* latin-ext */

/* latin */



/* ───────── next style block ───────── */


  :root{
    /* ⛔ --bone-2 and --obsidian-2 DELETED 20 Aug (batch 4): zero var() reads across os-full.css,
       the bundle, brand.css, the draft and the generated design block, and neither is in the canon.
       Their siblings are alive — --bone 40 reads, --obsidian 31, --paper 2 — so this is two orphans
       leaving, not a palette being thinned. */
    --bone:#F5F0E6; --paper:#F4ECDE; --obsidian:#0F1115;
    /* ⛔ R252 COMPLETED, 19 Aug — THE LAST PRE-PRAEBA CHROME ON THE WALKED ROAD.
       These three held the OLD scheme's cool greys (#2A2E36 / #6B6F7A / #9CA0AB) while the
       canon inside `.pbx` read #211F1A / #5A554B / #8E887B — one name, two values, and the
       note at the dialog rules says so in as many words. Everything INSIDE .pbx redeclares
       them and never saw the old pair; everything OUTSIDE it did, and the letter/PDF preview
       (.pdf-*, ~20 reads) is a whole surface that was still painting in the old scheme —
       reachable from Invoices → Review & send, which is on the walk. Pointing them at the
       canon repaints those surfaces and changes nothing inside .pbx by construction. */
    --ink:#211F1A; --mist:#5A554B; --mist-2:#8E887B;
    /* ⛔ --line-strong DELETED 20 Aug (batch 4): zero reads, not in the canon. --line and --line-2
       (74 reads) are the pair the product actually uses. */
    --line:rgba(15,17,21,0.08);
    /* ══ THE PALETTE IS PRAEBA — 10 Aug ═══════════════════════════════════════════════════════
       These four are APPEARANCE names and Fable retired them as paint sources on 8 Aug: aliases
       during the migration, never receiving new values. This IS that migration step — they now
       hold Praeba values, so every one of their remaining call sites paints Praeba without each
       site having to be rewritten first.
         --acc / --acc-bright  → petrol #1E4E4A. Two names, one value, deliberately: both were
             teals doing "brand emphasis" and petrol is the brand's teal. They stay separate names
             so a site can be moved to its true role one at a time.
         --green               → #2F7D53, the only green Praeba has (§05, the traffic light).
       ⚠ WHY THIS IS SAFE NOW AND WAS NOT ON 7 AUG. It is the same shape of change that failed
         then. What failed was not the swap — it was that NOBODY COULD SEE THE RESULT. The chart
         token went onto 204 UI sites and the first look was Jake's. Every page is now rendered
         and read here before it ships. The check that was missing is the one that changed.
       ⚠ --warm IS DELIBERATELY NOT SWAPPED. It has 176 call sites and PRAEBA HAS NO AMBER — its
         only warm is coral, and coral is reserved for ACTION, one per view. Mapping amber to
         coral would destroy the one rule the palette is built on. It needs a ruling, not a
         value. Reported, not improvised. */
    /* THE AMBER IS RETIRED. It was #B86326 on 156 sites and PRAEBA HAS NO AMBER — its only warm
       is coral. The brief already answers what replaces it; no ruling was needed:
         S05  the semantics: Good #2F7D53 · WATCH #E1613C · Overdue #B3362B
         S19  'how loud a thing is tracks how much it needs you' — one hue, two intensities
         S25  the Watch chip, drawn: ink #9A3E1E on an 11% coral wash
       Amber maps to the CORAL PAIR the app already has the shape for: --warm carries the hue for
       fills and borders (80 of its sites are ALREADY colour-mixed down, which is the tint step
       doing its job), and text takes --attention-ink, which is the chip's ink.
       CORAL DOES NOT STOP MEANING 'ACT ON THIS': --action is coral at FULL strength and stays one
       per view; these are the quiet step. One hue can hold two jobs only at different volumes —
       which is the entire point of the S19 ladder. */
    --acc:#1E4E4A; --acc-bright:#1E4E4A; --warm:#E1613C; --green:#2F7D53;
    --font-display:'Manrope',system-ui,-apple-system,'Segoe UI',sans-serif;
    /* ── THE FOUR VOICES (7 Aug) ─────────────────────────────────────────────────────────────
       Measured: 224 font-family declarations — 218 here, 6 in the bundle — spelling four typefaces
       out by name in NINE slightly different stacks. --font-display existed; the other three did
       not, so changing a typeface meant a find-and-replace across 224 rules and hoping.
       Each value below is the stack those rules already resolved to. Nothing is restyled.
       ⚠ CHECKED, NOT ASSUMED: all four fonts really load — app.html links Instrument Serif,
         Manrope, Space Mono and Plus Jakarta Sans (Option C, 10 Aug). Tails are fallbacks.
         Instrument Serif was linked ital@1 — ITALIC ONLY — so its roman was never fetched and
         every serif heading fell back to Georgia. Now ital@0;1.
       ⚠ --font-mono was ALREADY REFERENCED once (.os-audit-flag) as var(--font-mono,monospace),
         against a token that did not exist — so the audit flag has been rendering in the system
         monospace, not JetBrains Mono, for as long as that rule has existed. Now it resolves. */
    --font-mono:'Space Mono','JetBrains Mono',monospace;
    /* ── TRACKING (7 Aug) ─────────────────────────────────────────────────────────────────────
       Measured: 175 letter-spacing declarations, 30 spellings of ~19 values, spread evenly from
       -0.04em to .16em with no clusters — drift, not a system. Six steps, named for the JOB the
       way the type ramp is, and snapped nearest / ties up so there is ONE snapping rule, not three.
       ⚠ Max movement is 0.02em. On a 9px label that is about 0.2px per character — unlike a font
         size, a tracking step of this size is not perceptible. That is why this could be swept. */
    --tr-tight:-0.02em;  /* large Poppins figures and headings — the only negative the app needs */
    --tr-none:0;
    --tr-s:.04em;        /* buttons and the larger labels */
    --tr-m:.08em;        /* THE mono uppercase label — chips, section rules, table heads */
    --tr-l:.12em;
    --tr-xl:.16em;       /* the smallest labels, where tracking does the legibility work */
    /* ── LEADING (7 Aug) ──────────────────────────────────────────────────────────────────────
       88 line-heights, 16 values, 1 → 1.7. Five steps. Max movement 0.05, about 0.6px on a 12px
       line. Named for what the text IS, because leading is a property of the text and not a knob. */
    --lh-flat:1;         /* a chip, a figure — one line that must not grow */
    --lh-tight:1.2;      /* headings */
    --lh-ui:1.4;         /* dense UI: table rows, labels, cards */
    --lh-body:1.55;      /* running text in the app */
    --lh-prose:1.7;      /* the long explanatory passages */
    --font-sans:'Manrope',system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
    /* ── THE FOUR FACES · OPTION C — Jake's ruling, 10 Aug ──────────────────────────────────────
       Measured before the change: the brief ruled four faces and this file shipped four DIFFERENT
       ones — overlap ZERO. Fraunces/Manrope/Space Mono/Plus Jakarta appeared 0 times here, in the
       bundle and in app.html; Poppins (51), Instrument Serif (6), Inter and JetBrains Mono (160)
       carried 227 tokenised call sites. Option C keeps the serif this app already had and takes
       the brief's other three, so the swap is FOUR TOKEN VALUES, not 227 edits — which is the
       whole return on the 7 Aug tokenisation.
       ⚠ --font-display and --font-sans are now the SAME face, and that is correct rather than a
         slip: the brief gives Manrope 'body, UI and every figure'. --font-display survives as the
         alias its 48 UI-and-figure call sites already use; its 3 HEADING sites moved to
         --font-serif and dropped to weight 400 for the reason below.
       ⚠ INSTRUMENT SERIF HAS ONE WEIGHT, 400. Nothing may ask for 600 — the browser synthesises a
         fake bold. Display presence comes from SIZE, not weight. */
    --font-serif:'Instrument Serif',Georgia,serif;
    --font-logo:'Plus Jakarta Sans',system-ui,sans-serif;   /* the wordmark, and only the wordmark */

    /* ── THE SEMANTIC LAYER (7 Aug) ───────────────────────────────────────────────────────────
       The app has never had one. Its 26 colour tokens are named for how they LOOK — `--warm`,
       `--acc`, `--green` — and a token named for its appearance ends up meaning several things.
       MEASURED, not asserted: `--warm` currently paints FIVE distinct meanings across 152 CSS
       call sites and 44 in the bundle —
         a STATUS (under offer: .sp-chip.warm, .fee-bar i.offer)
         an ATTENTION mark (.pp-eyezone "needs your eye", .la-anom, .lz-status.expiring)
         a CONFIDENCE band (.la-conf.mid, .la-field .fl-c.low)
         a DIARY state (.lz-day.amber, .sp-date.amber)
         an ACTION (.et-mark, .pp-fuset button.on)
       NO SINGLE VALUE IS CORRECT FOR FIVE MEANINGS, which is why colour could never be "set"
       here — every fix broke one of the other four. That is the whole diagnosis of 6 Aug, and
       ⚠ the fix recorded that day went into praeba-preview/, never into this file: measured
       7 Aug, os-full.css was byte-identical to its own pre-work rollback snapshot.
       PROCESS: ONE artefact, the real app. This block is in the file the product loads.

       EVERY VALUE HERE IS EXACTLY WHAT THE CALL SITES ALREADY RESOLVE TO. Nothing is being
       recoloured — the meanings are merely being given names they can be moved by. Splitting
       any of them to a NEW value is Jake's ruling, and is listed as PROPOSED in the report.
       `--warm` / `--acc` / `--green` stay declared and working: ~600 call sites move by meaning,
       not in one sweep. */
    /* ── THE TYPE RAMP — Jake's ruling, 7 Aug ─────────────────────────────────────────────────
       8 / 9.5 / 11 / 12.5 / 14 / 18 / 24. Snap nearest, ties UP. Weights 400 · 600 · 700 · 800;
       500 is RETIRED and folds into 600.
       There was no type scale anywhere before this — not in the app (30 distinct inline values) and
       not in the design brief (12 sizes between 7.5 and 14.5, its own drift). It could not be looked
       up because nobody had decided it. Now it is decided, so a size has somewhere to snap TO. */
    --t-xxs:8px; --t-xs:9.5px; --t-s:11px; --t-m:12.5px; --t-l:14px; --t-xl:18px; --t-xxl:24px;
    --w-regular:400; --w-semi:600; --w-bold:700; --w-black:800;
    /* ── RADII — Jake's ruling, 7 Aug ──────────────────────────────────────────────────────────
       The brief's ramp (14/20/28) STANDS and is extended DOWN, because the app's small radii had no
       home in it: 3/5/6 → 4, 10 → 8, 12 → 14. */
    --r-xs:4px; --r-s:8px; --r-m:14px; --r-l:20px; --r-xl:28px; --r-round:50%;
    /* ── THE PRAEBA SWAP WAS TRIED HERE ON 7 AUG AND REVERTED THE SAME DAY. WHY, SO IT IS NOT
       REPEATED ────────────────────────────────────────────────────────────────────────────────
       The values went in cleanly and the app still looked wrong — overwhelmingly green. The cause
       was not the hexes. It was that NOBODY COUNTED WHERE THE TOKENS LAND before changing them:
           --acc-bright  204 call sites      --warm  191      --acc  101      --green  54
           --action (coral)  10
       359 green-family call sites against 10 coral. Any green put in --acc-bright floods the
       product, because --acc-bright is not a colour — at 204 sites it is a fifth of the app doing
       headings, chips, borders, rules, links AND charts at once.
       ⚠ AND THE BRIEF WAS NOT READ CLOSELY. --acc-bright was mapped to `--petrol-data #1C9384`,
         whose NAME states its scope: charts. Choosing it because it was the brightest teal in the
         canon is pattern-matching, not reading. (Opus, and it was mine.)
       ⚠ THE SEMANTIC LAYER IS NOT YET LOAD-BEARING. --st-available / --st-let / --st-under-offer
         are used 18 times in total; the app paints from the LOOK tokens 449 times. A brand pushed
         through the look tokens reaches every one of those sites indiscriminately.
       THE ORDER THAT WORKS: split --acc-bright's 204 sites by what they are FOR, give each group
       the brief colour actually scoped to it, and look at the ratio BEFORE anything ships.
       Praeba's values are in the brief's canon block; the branch `praeba-design` has the attempt. */    /* the letting states move WITH the palette, not after it — tokenlayer.test.js pins each one to
       what its appearance token holds, and that pin is the whole point: the semantic layer must
       never quietly drift from the layer it was split out of. */
    /* CANON, 10 Aug (Jake ruled): the status colours take their OWN values from the brief's canon
       block (brand.css), no longer mirroring the appearance tokens. --st-available-bright is an
       app-only brightness variant the canon does not name; it is held EQUAL to --st-available, as
       it was before, so the available chip and the available bar cannot disagree. */
    --st-available:#0F4C5C; --st-available-bright:#0F4C5C;
    /* ⚠ WAS #E1613C — the same value as --action, because tokenlayer's PAIRS pinned it to --warm
       and --warm had moved to coral. That silently re-created the exact fault the 7 Aug ruling
       below fixed from the other direction: coral means ACT ON THIS and nothing else, so it can
       not also mean UNDER OFFER. Canon value. */
    --st-under-offer:#9A3E1E;
    /* PART LET — a floor partly let and partly available. It has painted as under-offer since the
       beginning; this gives that meaning its own name at the SAME value, so nothing moves today
       and Jake can move it in one line when he rules on it. */
    --st-part-let:#9A3E1E;
    --st-let:#3a7a4a;
    /* JAKE'S RULING 7 Aug — coral means ACT ON THIS and nothing else (his 5 Aug rule, applied).
       It was #B86326, the same value as under-offer, which is why the `fell through` and `edit`
       controls read as statuses beside the UNDER OFFER chip. --coral from the brief's canon block. */
    --action:#E1613C;
    --attention:#E1613C;     /* needs your eye / expiring / anomaly */
    --confidence-mid:#E1613C;
    /* ── ROLE TOKENS · SLICE 1 (charts) — Fable's ruling, 8 Aug ─────────────────────────────────
       Only the tokens SLICE 1 lands on are declared here. --ground / --hover / --support arrive
       with their own slices: a token with no readers is the fault this file caught twice on 7 Aug.

       --mark, quoted from the brief: "Petrol-data — a measured value. The chart-safe step of
       petrol. The default mark."
       And the constraints it exists to enforce, also quoted:
         petrol   — "Nav rail, brand panels, chrome. Never a chart mark."
         petrol-2 — "Hover and pressed states only — never a chart mark, never a surface."
         coral    — "Coral and every coral-derived tint never plot, never highlight, never appear
                     in a chart in any strength."
         good/danger — "Green and red are semantic only: they never appear as a chart series, a
                     surface or a brand accent."
       ⚠ THE SET IS NOT COMPLETE, AND THE BRIEF SAYS SO. --p-sage is marked PROPOSED in the brief
         ("Not yet ticked — without it the mark set is two pastels and petrol-data"), so it is
         declared here PROPOSED and painted by nothing until Jake ticks it.
       ⚠ AND THERE IS NO ASSIGNMENT RULE. The brief drops the ordered series outright — "chart
         marks — the differentiated NON-CORAL set. No ordered series." — so which pastel a named
         category takes is not ruled anywhere. Only the DEFAULT mark is ruled, and only the default
         mark has been converted. The rest is reported, not guessed. */
    /* ── ROLE TOKENS · SLICE 3 (the petrol flood) — 10 Aug ─────────────────────────────────────
       Declared here because they now HAVE readers. Quoted scopes, from the brief:
         --ground "Nav rail, brand panels, chrome. Never a chart mark."
         --hover  "Hover and pressed states only — never a chart mark, never a surface."
       ⚠ THESE CHANGE THE HUE AT THEIR SITES, and that is the point rather than a side effect:
         the sites were painting --acc #0F4C5C / --acc-bright #2C7A8E, which are APPEARANCE names.
         Each site now takes the value the brief scopes to what the element IS. Counted before the
         change: 276 CSS + 25 bundle = 301. Only 97 had a role the brief names; the other 204 are
         listed in slice3-classification.txt and were NOT moved.
       ⚠ THE THREE STEPS MUST STAY THREE DISTINCT VALUES — the ladder is closed (brief §21).
         Collapsing any two is guarded in brandtokens.test.js. */
    --ground:#1E4E4A;
    --hover:#2A6560;
    --mark:#1C9384;
    /* ── THE CHART KIT · OPTION A — Jake's ruling, 10 Aug, verbatim from the prototype source.
       "Four categories coloured, the tail grouped into a neutral Other. Each solved to L*78 so
       they carry equal weight and separate by hue. NO CORAL."
       Declared HERE and not only in brand.css: the app does not load brand.css yet, and
       tokenlayer.test.js caught these being READ by rules that nothing declared — a token with a
       reader and no declaration resolves to nothing and the bar paints transparent.
       G1 (Jake): same colour if measuring the same consistent thing. One series → --mark.
       G2: max four coloured categories; the fifth and beyond group into "Other · N". */
    --m1:#93CCC4; --m2:#BEBFD7; --m3:#D9BBAB; --m4:#B5C4C6;
    --mark-none:#D9D3C8;
    /* the traffic light — brief §25, chips ONLY, never a surface and never a chart mark.
       Declared here because the chip now reads them and the app does not load brand.css.
       --warn is --action: coral's one chip exception, per §25. */
    --good:#2F7D53; --danger:#B3362B;
    /* the stadium, for arch-top bars and pills. --r-round 50% is the CIRCLE and they are not the
       same shape — 50% on a wide element is an ellipse. Both exist until Jake rules. */
    --r-pill:999px;
    --p-petrol:#93CCC4;
    --p-iris:#BEBFD7;
    --p-sage:#BEC3B7;   /* PROPOSED in the brief — not ticked, painted by nothing */
    /* ── FOUR MEANINGS THAT HAD NO NAME (7 Aug) ────────────────────────────────────────────────
       Measured: four values across 43 sites — 33 in this stylesheet, 10 in the bundle — and not one
       of them had a name, so not one of them could be moved. Every value below is exactly what those
       43 sites already resolved to: NOTHING IS RECOLOURED. The meanings just became movable.
       ⚠ Declared in :root ONLY, and that is the truth rather than an oversight: no theme redeclares
         them today, so Studio and Dusk have been borrowing Praeba's adverse red all along. A gap,
         not a decision — flagged to Jake rather than invented. */
    --adverse:#C84A38;        /* expired · overdue · over-run · no fit — a thing gone against you */
    --adverse-ink:#b54a2b;    /* its text weight on a light surface (the two always travel together) */
    --attention-ink:#9A3E1E;  /* the ink partner of --attention: soon, expiring, near fit, mid confidence */
    --st-let-mark:#5A9B6E;
    /* the let green as TEXT on a dark chip — the third member of the ink family, beside
       --adverse-ink and --attention-ink. Same value it has always been. */
    --st-let-ink:#7FB78E;    /* the let / won green as a rule or dot, lighter than the chip's text */
    /* ⚠ A THIRD red in the adverse family, one value off the other two, on a single site (the unread
       dot). Kept at its own value rather than merged into --adverse, because merging is a RECOLOUR
       and that is your call, not mine. It is now one line to merge if you want it merged. */
    --notify-dot:#C84A38;   /* merged into --adverse 7 Aug — was #D6452F, a third red for one meaning */
    --on-accent:#fff;         /* ink on a filled accent chip — was a bare #fff in the bundle */
  }
  *{box-sizing:border-box;margin:0;padding:0;}
  /* Display font (Manrope, was Poppins) filters across the WHOLE platform — same look as Team. It lands on every
     heading, primary button, and big numeric value in the app. Body copy stays Inter; the mono
     micro-labels (JetBrains) and the italic serif ACCENT phrases (.serif / .tg — they carry their
     own font-family and win on specificity) and the wordmark are all deliberately left alone. */
  h1, h2, h3,
  .fc-greet h1, .fc-card h3, .pp-head h3, .sp-head h2, .la-hero h2, .la-head h3,
  .sp-btn, .fc-btn, .fc-btn.primary, .btn, .nav-cta, .replay, .viewall,
  .sp-tot .v, .os-vital .big, .tm-kpi .v, .lz-donut-c b, .lz-donut-c .v,
  .pp-fee .v, .sp-badge, .fc-vital .v{font-family:var(--font-display);}
  /* numerals go upright + tabular (several were serif-italic before) */
  .sp-tot .v, .os-vital .big, .tm-kpi .v, .lz-donut-c b, .lz-donut-c .v, .fc-vital .v{font-style:normal;font-weight:600;letter-spacing:var(--tr-tight);font-variant-numeric:tabular-nums;}
  body{font-family:var(--font-sans);
    -webkit-font-smoothing:antialiased;line-height:var(--lh-body);}
  .serif{font-family:var(--font-serif);font-style:italic;font-weight:400;}
  .mono{font-family:var(--font-mono);}
  a{color:inherit;}
  button{font-family:inherit;}

  /* source attribution pills */
  .src{display:inline-flex;align-items:center;gap:5px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);color:var(--mist);text-transform:uppercase;}
  .src .dot{width:6px;height:6px;border-radius:var(--r-round);flex-shrink:0;}
  .src.lease .dot{background:var(--acc);}
  .src.cal .dot{background:var(--acc-bright);}
  .src.email .dot{background:var(--warm);}
  .src.files .dot{background:var(--obsidian);}
  .src.ask .dot{background:var(--mist-2);}

  /* motion system */
  body[data-motion="Full"] .rise{opacity:0;animation:riseIn .55s cubic-bezier(.2,.7,.25,1) forwards;animation-delay:var(--d,0ms);}
  @keyframes riseIn{from{opacity:0;transform:translateY(12px);}to{opacity:1;transform:translateY(0);}}
  @media(prefers-reduced-motion:reduce){
    body .rise{animation:none !important;opacity:1 !important;transform:none !important;}
    .sp-space,.sp-backdrop,.fc-cmdpanel,.sp-modal{animation:none !important;}
  }

  #app-toast{position:fixed;left:50%;bottom:84px;transform:translateX(-50%) translateY(8px);background:var(--obsidian);color:var(--bone);
    font-size:var(--t-m);padding:9px 18px;border-radius:100px;opacity:0;pointer-events:none;transition:opacity .2s ease,transform .2s ease;
    z-index:200;box-shadow:0 8px 24px rgba(0,0,0,.4);white-space:nowrap;border:1px solid color-mix(in srgb,var(--bone) 14%,transparent);}
  #app-toast.show{opacity:1;transform:translateX(-50%) translateY(0);}


/* ───────── next style block ───────── */


/* FLOW OS — shared styles: theme vars, home, dock, command bar, spaces. */

/* ── themes ─────────────────────────────────────── */
body.flow-dusk{background:#0C0E12;color:var(--bone);}
body.flow-dusk::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;
  background:radial-gradient(60% 50% at 85% -10%,color-mix(in srgb,var(--ground) 13%,transparent),transparent 60%),
             radial-gradient(50% 40% at -10% 110%,color-mix(in srgb,var(--warm) 9%,transparent),transparent 60%);}
.flow-dusk{--fs:#15181E;--fs2:#1B1F27;--fb:rgba(245,240,230,.13);--fb2:rgba(245,240,230,.22);
  --ft:#F5F0E6;--fd:rgba(245,240,230,.72);--fd2:rgba(245,240,230,.50);--fhl:rgba(245,240,230,.06);--fbg:#0C0E12;
  --wash:radial-gradient(55% 45% at 82% -10%,color-mix(in srgb,var(--ground) 14%,transparent),transparent 62%),
    radial-gradient(45% 38% at -8% 108%,color-mix(in srgb,var(--warm) 13%,transparent),transparent 60%),
    radial-gradient(34% 28% at 50% 112%,color-mix(in srgb,var(--warm) 10%,transparent),transparent 70%);}
body.flow-dawn{background:var(--paper);color:var(--obsidian);}
/* THE GROUND IS PRAEBA'S, not Agenovas's — this is the background Jake kept seeing unchanged.
   S05 gives four surface steps inside four points of lightness, separated by the hairline, not
   by fill: canvas #F4ECDE · cream #F1ECE1 · surface #FBF6EC · card #FFFDF7. Dawn was still
   painting #FAF6ED and #fff, and the inks were the Agenovas obsidian rather than S05's. */
/* canon --sh-1/--sh-2 (MASTER v3 §15) — the draft's cards and the dock ask for them. */
:root{--sh-1:0 1px 2px rgba(33,31,26,.05);--sh-2:0 1px 2px rgba(33,31,26,.05),0 14px 34px -16px rgba(33,31,26,.22);}
/* HERO METRICS — MEASURED off draft .ttl-lg and .phead .note, then NAMED. They are not on the
   canon ramp (which tops out at --t-xxl 24px), so writing 34px/1.12/-0.01em at the call site
   would be four loose literals — and cssLooseType/Track/Lead all sit at a ZERO baseline, which
   is worth keeping. Named here they are authored once, quotable in a conformance table, and
   changeable in one place if the hero is ever re-ruled. */
:root{--t-hero:34px;--lh-hero:1.12;--tr-hero:-0.01em;--lh-strap:1.6;--t-panel-h:22px;}
/* THE CANON SPACING SCALE (MASTER v3 §15, via brand.css). The app declared none of it — it was
   defined in the canon and never applied, so `var(--sp-8)` pointed at nothing and
   tokenlayer.test.js caught the dangling reference on the first run. Values copied from the
   canon block, not chosen. */
/* ⚠ THE SPACING RAMP STAYS, AND SIX OF ITS SEVEN RUNGS HAVE ZERO READERS. Kept deliberately, 20 Aug:
   --sp-8 IS read, so this is a live ramp with unused rungs, not dead weight — and a ramp with rungs
   missing is worse than a ramp nobody has climbed yet, because the next reader has to guess whether
   12px was omitted or forbidden. Same reason --r-xl stays. Named here so the next census does not
   re-litigate it. */
:root{--sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-6:24px;--sp-8:32px;--sp-12:48px;}
.flow-dawn{--fs:#FFFDF7;--fs2:#FBF6EC;--fb:rgba(33,31,26,.08);--fb2:rgba(33,31,26,.16);
  --ft:#211F1A;--fd:#5A554B;--fd2:#8E887B;--fhl:rgba(33,31,26,.035);--fbg:#F4ECDE;}
/* Dawn — the landing page's atmospheric wash, carried into the product:
   blush top-left, amber top-right, teal + green settling in the lower corners.
   Defined as --wash so every surface (Today, full-page spaces) shares the SAME
   viewport-anchored colour — seamless from page to page. */
.flow-dawn{--wash:none;} /* PRAEBA: flat canvas #F4ECDE — the atmospheric wash is retired (Jake, 10 Aug: "the flat praeba canvas"). */
body.flow-dawn::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;
  background:var(--wash);}

/* Studio — neutral white canvas, separation by shading (layered greys + soft
   shadows) — but the accents go BOLD: electric indigo + vivid orange, so colour
   means something (selections, warnings, graphs) against the clean white. */
body.flow-studio{background:#FFFFFF;color:#17181C;}
.flow-studio{--fs:#F7F8F9;--fs2:#FFFFFF;--fb:rgba(18,20,24,.07);--fb2:rgba(18,20,24,.14);
  --ft:#17181C;--fd:#5C5F66;--fd2:#9A9CA3;--fhl:rgba(18,20,24,.045);--fbg:#FFFFFF;
  --acc:#4F46E5;--acc-bright:#6366F1;--warm:#E1613C;--green:#16A34A;
  /* ⚠ LITERAL, NOT `var(--warm)`. A custom property whose value contains var() is substituted at
     computed-value time on the element it is DECLARED on. Aliasing these at :root would compute
     against the DAWN palette and hand Studio the wrong colours — the same trap as "a theme that
     only sets :root loses" (6 Aug). Every scope that redeclares a look token redeclares its
     meanings beside it. */
  --st-available:#4F46E5;--st-available-bright:#6366F1;--st-under-offer:#E1613C;--st-let:#16A34A;--st-part-let:#E1613C;
  /* Studio keeps its OWN vivid orange as the act-colour — the ruling is "coral means act on this"
     in the Praeba palette; Studio's accent language is indigo + orange and #E1613C plays exactly the
     same role in it. Flagged to Jake rather than assumed. */
  --action:#E1613C;--attention:#E1613C;--confidence-mid:#E1613C;
  /* Studio's own alarm. ⚠ THIS ONE IS A RECOLOUR, not a renaming — the only one in the whole
     standardisation pass. Studio was borrowing Praeba's rust red, which sits between its indigo
     and its orange and therefore read as a third brand colour instead of as a warning. */
  --adverse:#DC2626;--adverse-ink:#B91C1C;--attention-ink:#E1613C;--st-let-mark:#16A34A;--st-let-ink:#4ADE80;
  --notify-dot:#DC2626;--st-part-let:#E1613C;}
/* Studio — the same atmospheric idea, whisper-faint in its own bold accents,
   so the white canvas keeps its clean shading-led separation */
.flow-studio{--wash:
    radial-gradient(60% 55% at 6% -10%,rgba(99,102,241,.22),transparent 68%),
    radial-gradient(68% 60% at 92% -14%,rgba(234,88,12,.17),transparent 70%),
    radial-gradient(62% 55% at 108% 80%,rgba(79,70,229,.17),transparent 72%);}
body.flow-studio::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;
  background:var(--wash);}
/* Studio shading — boxes lift off the white with soft depth instead of hard lines */
body.flow-studio .fc-card,body.flow-studio .os-vital,body.flow-studio .lz-panel,
body.flow-studio .sp-q,body.flow-studio .mt-card,body.flow-studio .tm-card,
body.flow-studio .tm-totals,body.flow-studio .calc-card,body.flow-studio .sp-lane,
body.flow-studio .la-doc{box-shadow:0 1px 2px rgba(18,20,24,.05),0 10px 28px -20px rgba(18,20,24,.18);}
body.flow-studio .sp-space{box-shadow:0 2px 6px rgba(18,20,24,.06),0 40px 90px -30px rgba(18,20,24,.28);}
body.flow-studio .os-dock,body.flow-studio .fc-cmd{box-shadow:0 2px 5px rgba(18,20,24,.06),0 16px 40px -18px rgba(18,20,24,.25);}
body.flow-studio .sp-backdrop{background:rgba(18,20,24,.28);}

/* bottom scrim — content fades out before it reaches the dock, so nothing hides abruptly */
body::after{content:'';position:fixed;left:0;right:0;bottom:0;height:150px;pointer-events:none;z-index:105;
  background:linear-gradient(to top,var(--fbg) 36%,transparent);}
body.flow-dusk .src{color:var(--fd2);}
body.flow-dusk .src.files .dot{background:var(--bone);}

/* ── stage / status / dock ──────────────────────── */
:root{--topbar-h:56px;}
/* ── TODAY'S SKELETON, per draft screen 01 (Stage 2, 10 Aug) ──────────────────
   The draft builds Today from TWO grids with DIFFERENT splits: .greetrow is
   minmax(0,400px) | minmax(0,1fr) — the greeting narrow, the four vitals wide —
   and .hubtop is minmax(0,1fr) | 330px — the stack wide, the rail narrow. One
   grid cannot be two splits, and wrapping the rows would mean new markup on a
   page whose controls must not move. THREE TRACKS carry both: the greeting takes
   track 1, the vitals span 2-3, the card stack spans 1-2, the rail takes 3.
   ⚠ ONE ACCEPTED DIFFERENCE: a single grid has ONE column-gap. The draft uses 40px
   between greeting and vitals and 32px beside the rail; 32px is taken because the
   rail relationship repeats down the whole page, so row 1 runs 8px tight. */
/* PAGE BOX — measured off draft #s-today: padding 48px, max-width 1560px, which yields a 1344px
   content band at 1440. ⚠ the TOP padding stays topbar-relative: the app's bar is fixed and the
   draft's is in flow, so 48px there would put the hero under the bar. Accepted difference. */
.fc-stage{position:relative;z-index:1;max-width:1560px;margin:0 auto;padding:calc(var(--topbar-h) + 26px) 48px 190px;
  display:grid;grid-template-columns:minmax(0,400px) minmax(0,1fr) 330px;
  /* ⚠ THE ROWS MUST BE SIZED, and this cost a screenshot to find. The rail spans rows 2-3 and is
     taller than the two rows' own content, so with auto tracks the browser distributes the slack
     across BOTH — inflating row 2 and dropping a ~116px hole between the label and the card. A 1fr
     final track sends that slack to the last row, where it is invisible. */
  /* MEASURED TRACKS. The draft is not one grid — it is rows with DIFFERENT splits:
       .greetrow  400px | 904px   gap 40
       .hubtop    982px | 330px   gap 32
       .squares   656px | 656px   gap 32
     Three tracks at a uniform 32px gap reproduce the one that governs most of the page EXACTLY:
     400 + 32 + 550 + 32 + 330 = 1344, so the content column (tracks 1-2) is 400+32+550 = 982px,
     the draft's .hubtop content width to the pixel. The cost is the vitals band, which comes out at
     912px against the draft's 904 — one gap's difference, and the only geometry not matched. */
  grid-template-columns:400px minmax(0,1fr) 330px;
  grid-template-rows:auto auto auto auto auto auto auto;gap:32px;align-items:start;}
/* .os-main is a WRAPPER, not a box — dissolving it lets its three children take
   their own grid cells without a single change to the markup or the components. */
.os-main{display:contents;}
/* Every body block claims a ROW as well as a column, so the rail can span all of them and there is
   no dead zone beside the lower half of the page. */
.fc-greet{grid-column:1;grid-row:1;align-self:center;}
/* NEEDS YOU — the draft draws it as a CONTAINED PANEL with a header row (.sec + .sech), not a bare
   label over loose cards. The app's label and stack are siblings, so the panel is made from the two
   of them: the label takes the head (surface ground, top corners, the draft's 20px/24px padding) and
   the stack takes the body (card ground, bottom corners), with no gap between them. CSS only — the
   markup, the controls and the card deck are untouched. */
.fc-qlabel{grid-column:1/3;grid-row:2;margin-top:0;padding:20px 24px;background:var(--fs2);border:1px solid var(--fb);border-bottom:0;border-radius:var(--r-l) var(--r-l) 0 0;}
/* MEASURED off the draft's .sech: title Manrope 800 22px sentence-case on --ink; kicker Space Mono
   10px uppercase on --ink-2; the count hard right. The app had ALL of it as one 9.5px mono uppercase
   line on --ink-3 — a caption where the draft has a heading. Head height 57px -> the draft's 73px. */
.fc-qlabel .sect{font-family:var(--font-sans);font-size:var(--t-panel-h);font-weight:var(--w-black);letter-spacing:var(--tr-tight);text-transform:none;color:var(--ft);}
.fc-qlabel .kick{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd);}
.fc-qlabel .n{margin-left:auto;font-family:var(--font-sans);font-size:var(--t-l);font-weight:var(--w-semi);letter-spacing:var(--tr-none);text-transform:none;color:var(--ft);}
/* THE CARD IS NOT A CARD INSIDE A CARD. Measured: the draft's question body is background:none,
   border:0, box-shadow:none — the content sits DIRECTLY on the panel. The app was drawing a bordered,
   heavily-shadowed card inside an identically-coloured panel. Ground and radius stay (the deck
   stacks behind), the box that made it read as a second surface goes. */
.fc-stack .fc-card{border-color:transparent;box-shadow:none;}
.fc-stack{grid-column:1/3;grid-row:3;margin-top:calc(-1 * var(--sp-8));padding:24px;background:var(--fs);border:1px solid var(--fb);border-top:0;border-radius:0 0 var(--r-l) var(--r-l);}
.fc-feed{grid-column:3;grid-row:2/span 6;align-self:start;}
body.flow-dusk::before{background:
  radial-gradient(55% 45% at 82% -10%,color-mix(in srgb,var(--ground) 14%,transparent),transparent 62%),
  radial-gradient(45% 38% at -8% 108%,color-mix(in srgb,var(--warm) 13%,transparent),transparent 60%),
  radial-gradient(34% 28% at 50% 112%,color-mix(in srgb,var(--warm) 10%,transparent),transparent 70%);}
/* Top bar — fixed and visible at all times (over Today AND over any open space),
   so the brand, user, date and settings anchor the whole experience. No border,
   no hard edge: a scrim that dissolves into the canvas, so it reads as part of
   the page rather than a separate strip. */
.fc-status{position:fixed;top:0;left:0;right:0;z-index:115;height:var(--topbar-h);
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:0 clamp(32px,4vw,76px);
  font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd2);}
/* T1 — a TRANSLUCENT scrim (not a flat --fbg fill) so the page blush runs continuously beneath the
   blurred bar — the bar and page share one background, no "sudden stop" at the bar edge. The blur
   keeps the lockup/date legible over whatever blush/content sits behind. Holds in all three themes
   (--fbg is theme-aware). */
.fc-status::before{content:'';position:absolute;left:0;right:0;top:0;bottom:-30px;z-index:-1;pointer-events:none;
  background:linear-gradient(to bottom,color-mix(in srgb,var(--fbg) 48%,transparent) 0%,color-mix(in srgb,var(--fbg) 24%,transparent) 55%,transparent 100%);
  -webkit-backdrop-filter:blur(16px) saturate(1.05);backdrop-filter:blur(16px) saturate(1.05);
  -webkit-mask-image:linear-gradient(to bottom,#000 58%,transparent);mask-image:linear-gradient(to bottom,#000 58%,transparent);}
.fc-status .brand{display:flex;align-items:center;gap:10px;color:var(--ft);}
/* Logo → Today home affordance — no visual change beyond a subtle hover fade */
.fc-status .brand-home{display:inline-flex;align-items:center;gap:10px;background:none;border:0;padding:0;margin:0;color:inherit;font:inherit;cursor:pointer;transition:opacity .15s ease;}
.fc-status .brand-home:hover{opacity:.7;}
.fc-status .brand-home:focus-visible{outline:2px solid var(--hover);outline-offset:3px;border-radius:var(--r-xs);}
.fc-status .brand svg{width:26px;height:26px;}
.fc-status .brand svg path{stroke:currentColor;stroke-width:6;fill:none;stroke-linecap:round;}
.fc-status .brand .wm{font-family:var(--font-logo);font-size:var(--t-xl);font-weight:600;letter-spacing:var(--tr-tight);text-transform:none;display:inline-flex;align-items:baseline;gap:4px;}
/* Wordmark V3 "The Seam" — UI/nav row */
.fc-status .brand .wm .wmA{font-weight:600;letter-spacing:var(--tr-tight);}
.fc-status .brand .wm .wmB{font-weight:400;letter-spacing:var(--tr-s);margin-left:0.5px;}
.fc-status .brand .osb{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);color:var(--ground);border:1px solid color-mix(in srgb,var(--ground) 40%,transparent);border-radius:var(--r-xs);padding:1.5px 5px;transform:translateY(-1px);}
/* draft .topbar .bdiv — 1px x 16px on --line-2 (== --fb2 in Dawn, rgba(33,31,26,.16)). */
.fc-status .brand .bdiv{width:1px;height:16px;background:var(--fb2);margin:0 4px;}
/* The firm sits BELOW the wordmark in the draft (15px against 17px), not level with it — the
   app had both at --t-xl, which is why praeba and Reardon & Co read as one size. ⚠ 15px is
   NOT on the canon type ramp; --t-l (14px) is the nearest ramp step and preserves the ruled
   hierarchy. The draft's own 15px is unquotable against canon, so the RAMP wins. */
.fc-status .brand .client{font-family:var(--font-serif);font-style:italic;font-size:var(--t-l);font-weight:var(--w-regular);letter-spacing:0;text-transform:none;color:var(--fd);}
.fc-status .sync{display:flex;align-items:center;gap:9px;}
/* draft .topbar .dt — 700 on --ink. The app had 600. */
.fc-status .sync .hd{font-family:var(--font-sans);font-size:var(--t-m);font-weight:var(--w-bold);letter-spacing:var(--tr-none);text-transform:none;color:var(--ft);}
.fc-status .sync .hd + .pulse{margin-left:5px;}
.fc-status .sync .pulse{width:6px;height:6px;border-radius:var(--r-round);background:var(--mark);box-shadow:0 0 0 3px color-mix(in srgb,var(--mark) 20%,transparent);}
.canvas-toggle{display:inline-flex;align-items:center;gap:6px;margin-left:12px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd);background:var(--fhl);border:1px solid var(--fb);border-radius:100px;padding:4px 11px;cursor:pointer;transition:all .15s ease;}
.canvas-toggle:hover{color:var(--ft);border-color:var(--fb2);}
.canvas-toggle .sw{width:10px;height:10px;border-radius:var(--r-round);border:1px solid currentColor;background:linear-gradient(90deg,currentColor 50%,transparent 50%);transform:rotate(-25deg);}
/* top-bar space controls — expand & close live up here when a space is open */
.tb-btn{width:28px;height:28px;margin-left:10px;border-radius:var(--r-s);background:var(--fhl);border:1px solid var(--fb);color:var(--fd);cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;padding:0;vertical-align:middle;transition:color .15s ease,border-color .15s ease;}
.tb-btn:hover{color:var(--ft);border-color:var(--fb2);}
.tb-btn svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;}
.tb-btn.x{font-size:var(--t-xl);line-height:var(--lh-flat);font-family:var(--font-sans);}

/* ── the dock — always visible, never slides ─────
   Compact by default: Today + the three group headings. Hover (or tap) a heading
   and its options emerge in place; the bar itself stays put and never scrolls. */
.os-dock{display:flex;flex-wrap:nowrap;justify-content:flex-start;align-items:center;gap:4px;margin-bottom:8px;
  align-self:center;width:max-content;max-width:100%;
  overflow-x:auto;scrollbar-width:none;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;
  /* THE GLASS PILL — draft .dock, ruled 10 Aug. Was a rounded rect with a ground->warm gradient
     border; the draft draws one glass capsule on --line-2 with the canon's --sh-2 shadow. --glass
     is canon rgba(255,253,247,.58) = --card at 58%, expressed here against --fs so all three
     canvases keep their own surface instead of being handed Dawn's. */
  background:color-mix(in srgb,var(--fs) 58%,transparent);
  -webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);
  border:1px solid var(--fb2);border-radius:var(--r-pill);padding:8px 12px;
  box-shadow:0 1px 2px rgba(33,31,26,.05),0 14px 34px -16px rgba(33,31,26,.22);}
.os-dock::-webkit-scrollbar{display:none;}
.os-dock > *{flex-shrink:0;}
/* A section heading is one of the six, not a capsule containing one. The draft draws all six
   identically, so the group loses its own border and ground; only the REVEAL still needs a
   container. ⚠ .live keeps a whisper of ground so an open section still reads as open —
   the draft has no open state to copy, so this is the one invented value here. */
.os-dock .dgrp{display:flex;align-items:center;gap:1px;flex-wrap:nowrap;background:none;border:1px solid transparent;border-radius:var(--r-pill);padding:0;transition:background .3s ease;}
.os-dock .dgrp.live{background:color-mix(in srgb,var(--ft) 4%,transparent);}
/* WAS uppercase mono on --ground — which is why MONEY/BOOK/FIRM read as a different KIND of
   thing from Portfolio and Deals in the 10 Aug screenshot. The draft's .dock b is one rule
   for all six: 600 13px sans on --ink-2. ⚠ 13px is not on the canon ramp; --t-m (12.5px)
   is the nearest step. */
.os-dock .glabel{font-family:var(--font-sans);font-size:var(--t-m);font-weight:var(--w-semi);letter-spacing:var(--tr-none);text-transform:none;color:var(--fd);
  padding:8px 12px;border-radius:var(--r-pill);cursor:pointer;white-space:nowrap;user-select:none;transition:color .15s ease,background .15s ease;}
.os-dock .glabel{display:inline-flex;align-items:center;gap:5px;}
.os-dock .glabel::after{content:'';width:0;height:0;border-left:3.5px solid transparent;border-right:3.5px solid transparent;
  border-top:4.5px solid var(--action);opacity:.55;transition:transform .3s ease,opacity .15s ease;}
.os-dock .glabel:hover{color:var(--ft);background:color-mix(in srgb,var(--action) 14%,transparent);}
.os-dock .glabel:hover::after{opacity:.9;}
.os-dock .dgrp.openg{background:color-mix(in srgb,var(--action) 9%,transparent);}
.os-dock .dgrp.openg .glabel::after{transform:rotate(180deg);opacity:.85;}
/* options reveal — width is measured in px (not a guessed max-width), so the
   glide tracks the real content edge-to-edge with no jump or dead time */
.os-dock .dbtns{display:flex;align-items:center;flex-wrap:nowrap;width:0;opacity:0;overflow:hidden;
  transition:width .55s cubic-bezier(.22,.61,.36,1),opacity .4s ease;will-change:width;}
.os-dock .dbtns.open{opacity:1;transition:width .55s cubic-bezier(.22,.61,.36,1),opacity .45s ease .06s;}
.os-dock .dbtns-in{display:flex;align-items:center;gap:1px;flex-wrap:nowrap;padding:0 2px;}
/* draft .dock b — one rule, all six. */
.os-dock button{font-family:var(--font-sans);font-size:var(--t-m);font-weight:var(--w-semi);color:var(--fd);background:none;border:1px solid transparent;border-radius:var(--r-pill);padding:8px 12px;cursor:pointer;transition:color .15s ease,background .15s ease,border-color .15s ease;white-space:nowrap;}
/* draft: color:var(--ink); background:rgba(33,31,26,.06) — a tint of the ink, not a surface. */
.os-dock button:hover:not(.on){color:var(--ft);border-color:transparent;background:color-mix(in srgb,var(--ft) 6%,transparent);}
/* draft .dock b.on{background:var(--petrol);color:var(--card)}. --ground IS petrol. ⚠ the ink
   stays --bone (#F5F0E6), NOT --fs: --fs is the theme surface and goes DARK in Dusk, which
   would put near-black text on the petrol pill. A 2-step difference from --card, taken
   deliberately so the on-state survives all three canvases. */
.os-dock button.on{color:var(--bone);background:var(--ground);border-color:var(--ground);font-weight:var(--w-semi);}
/* THE WAVE, at the head of the dock — draft .dock .wv. Note the stroke: the top bar's wave is
   --ink, the DOCK's wave is --coral (== --action). Two marks, two colours, both in the draft. */
.os-dock .dockwave{display:inline-flex;align-items:center;padding:0 8px 0 4px;flex-shrink:0;}
.os-dock .dockwave svg{width:24px;height:24px;}
.os-dock .dockwave path{stroke:var(--action);stroke-width:6;fill:none;stroke-linecap:round;}
/* THE ARC IS RETIRED — Jake, 25 Aug: "the nav bar, can we make sure each word is exactly in
   line." The draft's wave-arc (±2.5px translateY per slot) read as misalignment on the real
   page, and the person it was drawn for has ruled it out. The wave glyph at the dock's head
   carries the wave; the words sit on one baseline. */

/* ── THE SECTION CARD (draft .sec / .sech) — Today's Stage 3 blocks all wear it ── */
.fc-sec{--d:210ms;grid-column:1/3;grid-row:5;margin-top:0;background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-l);box-shadow:var(--sh-1);overflow:hidden;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease;}
.fc-sec:hover{border-color:var(--fb2);box-shadow:var(--sh-2);}
.fc-sec:focus-visible{outline:2px solid var(--hover);outline-offset:3px;}
/* draft .sech — the head sits on --surface with a rule beneath, the figure hard right. */
/* draft .sech — 20px 24px, not 16px 24px. */
.fc-sech{display:flex;align-items:center;gap:12px;padding:20px 24px;background:var(--fs2);border-bottom:1px solid var(--fb);}
.fc-sech .sect{font-family:var(--font-serif);font-size:var(--t-xl);font-weight:var(--w-regular);color:var(--ft);}
.fc-sech .kick{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd2);}
.fc-sech .n{margin-left:auto;font-family:var(--font-display);font-size:var(--t-xl);font-weight:var(--w-black);color:var(--ft);font-variant-numeric:tabular-nums;}
.fc-sech .go{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);}
.fc-secb{padding:20px 24px 18px;}
/* draft .sbar / .sbleg — the topline bar every section opens with. */
.sbar{display:flex;width:100%;height:10px;border-radius:var(--r-pill);overflow:hidden;gap:2px;background:var(--fhl);}
.sbar i{display:block;height:100%;border-radius:var(--r-xs);min-width:3px;}
.sbleg{display:flex;flex-wrap:wrap;gap:6px 18px;margin-top:10px;font-size:var(--t-s);color:var(--fd);}
.sbleg span{display:inline-flex;align-items:center;gap:6px;}
.sbleg i{width:8px;height:8px;border-radius:var(--r-xs);display:inline-block;}
.sbleg b{color:var(--ft);font-variant-numeric:tabular-nums;}
/* The Option A mark set, by class — G2's four categories plus the NEUTRAL for the grouped tail.
   --mark-none is the canon's absence colour; the tail is not a fifth category. */
.sbar i.k0,.sbleg i.k0{background:var(--m1);}
.sbar i.k1,.sbleg i.k1{background:var(--m2);}
.sbar i.k2,.sbleg i.k2{background:var(--m3);}
.sbar i.k3,.sbleg i.k3{background:var(--m4);}
.sbar i.kx,.sbleg i.kx{background:var(--mark-none);}
.fc-secfoot{margin:14px 0 0;font-size:var(--t-s);color:var(--fd2);line-height:var(--lh-body);}
/* draft .cards / .tc — cards first, table underneath (Jake's slide-12 ruling). The headline is the
   NAME + THE MONEY; the status is the stage; the address follows. */
.fc-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:16px;margin-top:18px;}
.fc-tc{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:14px 16px;cursor:pointer;transition:border-color .15s ease,transform .15s ease;}
.fc-tc:hover{border-color:var(--fb2);transform:translateY(-1px);}
.fc-tc .tc-head{display:flex;align-items:flex-start;gap:10px;}
.fc-tc .tc-av{flex:0 0 auto;width:28px;height:28px;border-radius:var(--r-round);background:color-mix(in srgb,var(--ground) 12%,var(--fs2));color:var(--ground);display:inline-flex;align-items:center;justify-content:center;font-family:var(--font-mono);font-size:var(--t-xs);font-weight:var(--w-bold);}
.fc-tc .tc-id{display:flex;flex-direction:column;min-width:0;}
.fc-tc .tc-nm{font-size:var(--t-l);font-weight:var(--w-semi);color:var(--ft);}
.fc-tc .tc-sub{font-size:var(--t-s);color:var(--fd2);}
.fc-tc .tc-money{margin-left:auto;text-align:right;display:flex;flex-direction:column;}
.fc-tc .tc-money b{font-family:var(--font-display);font-size:var(--t-l);font-weight:var(--w-black);color:var(--ft);font-variant-numeric:tabular-nums;}
.fc-tc .tc-money i{font-family:var(--font-mono);font-size:var(--t-xxs);font-style:normal;letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);}
.fc-tc .tc-stats{display:flex;gap:18px;margin-top:12px;}
.fc-tc .tc-stats b{display:block;font-size:var(--t-m);font-weight:var(--w-semi);color:var(--ft);font-variant-numeric:tabular-nums;}
.fc-tc .tc-stats span{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);}
.fc-tc .tc-foot{display:flex;align-items:center;gap:10px;margin-top:12px;}
.fc-tc .tc-go{margin-left:auto;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);}

/* An invoice awaiting payment is an ACT-ON-THIS, so its chip takes --attention (G5: a chip anywhere
   a row carries an urgency judgement). Named for the meaning, never for the colour. */
.sp-chip.awaiting{color:var(--attention);background:color-mix(in srgb,var(--attention) 11%,transparent);}

/* draft .squares — the two director-only squares sit side by side beneath the line. */
/* draft .squares — two equal columns at a 32px gap. In the app they sit in the content column
   (982px), so each square is 475px against the draft's 656px full-width pair. Ruled by Jake:
   Fees / directors / squares align in the LEFT column. */
.fc-squares{--d:250ms;grid-column:1/3;grid-row:7;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:32px;margin-top:0;}
/* ⚠ .fc-square INHERITS .fc-sec, which carries grid-column:1/3 for the Today grid. Inside the
   two-column .fc-squares grid that same declaration means "span both columns", so the two
   squares stacked instead of sitting side by side. A placement written for one grid is not a
   placement in another. */
.fc-square{grid-column:auto;grid-row:auto;margin-top:0;}

/* draft .permline — the rule that says what is below is not for everyone.
   Claims its column, like every Today block (see the note on .fc-qnav). */
/* draft .permline — margin 32px top AND bottom. */
.fc-permline{--d:230ms;grid-column:1/3;grid-row:6;display:flex;align-items:center;gap:12px;margin:0;}
.fc-permline i{flex:1;height:1px;background:var(--fb2);}
.fc-permline span{display:inline-flex;align-items:center;gap:4px;font-family:var(--font-mono);font-size:var(--t-xs);font-weight:var(--w-bold);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd2);}
.fc-permline svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.8;}

/* draft .qnav - the strip beneath the question card: where you are in the queue, and the dots.
   It lives in the card stack's own grid cell, so it needs no new track. */
/* The stagger delay lives HERE, not on the element. Every other .rise in the app carries
   style={{'--d': ...}} inline; designdebt counts each of those, and it is right to — a look
   value threaded through markup is a value a stylesheet cannot reach. This one stays reachable. */
/* ⚠ EXPLICIT PLACEMENT IS NOT OPTIONAL HERE. .os-main is display:contents, so every child of
   OsHome is a DIRECT grid item of .fc-stage. Anything without a grid-column auto-places into
   whatever cell is free — the qnav landed in the 400px greeting column and the Fees tracker in
   the 531px middle one, both silently, both looking plausible in a narrow crop. Every new block
   added to Today must claim its column. */
.fc-qnav{--d:190ms;grid-column:1/3;grid-row:4;display:flex;align-items:center;gap:14px;margin-top:0;}
.fc-qnav .kick{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd2);}
.fc-qdots{display:inline-flex;align-items:center;gap:6px;}
.fc-qdots i{width:6px;height:6px;border-radius:var(--r-round);background:var(--fb2);display:inline-block;transition:background .2s ease,transform .2s ease;}
.fc-qdots i.on{background:var(--ground);transform:scale(1.25);}

/* ── home: greet, stack ─────────────────────────── */
/* (.os-main is dissolved above — see the Today skeleton) */
.fc-greet{margin-top:0;}
/* HERO — measured off draft .ttl-lg: Instrument Serif 400, 34px / 38.08px (1.12), -0.34px
   (-0.01em), max-width 26ch. The app was Manrope 600 at 37.44px — a different FACE, weight and size.
   Canon §: one weight, 400 — never ask the browser for 600 on the serif, it fakes it. */
.fc-greet h1{font-family:var(--font-serif);font-size:var(--t-hero);font-weight:var(--w-regular);letter-spacing:var(--tr-hero);line-height:var(--lh-hero);max-width:26ch;color:var(--ft);}
/* draft .ttl-lg span — rgb(142,136,123) == --ink-3 == --fd2. It was teal. */
.fc-greet h1 .em{color:var(--fd2);}
/* draft .phead .note — Manrope 11px / 17.6px (1.6), 10px above. The app was 14px / 21.7 at 8px. */
.fc-greet .strap{margin-top:10px;font-size:var(--t-s);line-height:var(--lh-strap);color:var(--fd);}
.fc-greet .strap .hl-warm{color:color-mix(in srgb,var(--warm) 80%,#fff);font-weight:600;}
:is(body.flow-dawn,body.flow-studio) .fc-greet .strap .hl-warm{color:var(--attention-ink);}
.fc-qlabel > span:first-child{display:inline-flex;align-items:center;gap:8px;}
.fc-qlabel > span:first-child::before{content:'';width:7px;height:7px;border-radius:var(--r-round);background:var(--attention);}
body[data-motion="Full"] .fc-qlabel > span:first-child::before{animation:osPulse 2.4s ease-in-out infinite;}
@keyframes osPulse{0%,100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--warm) 45%,transparent);}50%{box-shadow:0 0 0 6px transparent;}}
.fc-qlabel{margin:24px 0 12px;display:flex;align-items:baseline;justify-content:space-between;
  font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd2);}
.fc-stack{position:relative;height:300px;}
.fc-card{position:absolute;inset:0;background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-l);padding:28px 30px;
  display:flex;flex-direction:column;transition:transform .45s cubic-bezier(.2,.7,.25,1),opacity .45s ease;
  box-shadow:0 30px 60px -30px rgba(0,0,0,.5);}
.fc-card.leaving{transform:translateY(-44px) rotate(-1.5deg) !important;opacity:0 !important;pointer-events:none;}
.fc-tag{align-self:flex-start;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;
  border:1.5px solid currentColor;border-radius:var(--r-xs);padding:4px 10px;transform:rotate(-1.5deg);}
/* ── THE TRAFFIC-LIGHT CHIP — brief §25. A TINTED PILL carrying an icon and a word; it leads the
   row and says what the row needs from you. Was bare uppercase text in a colour — which is
   "colour alone", the one thing the rule forbids, and it does not survive greyscale.
   ⚠ THE WORDS ARE NOT THE RULED VOCABULARY. §25 fixes them at good · watch · overdue plus the
     neutral "asks you"; these cards carry their own labels ("Aged debtor · 68 days"). The
     ANATOMY is applied because it is ruled; changing the WORDS is a data change and Jake's call.
     An aged debtor at 68 days is arguably OVERDUE, not watch. REPORTED, not improvised. */
.fc-tag{display:inline-flex;align-items:center;gap:6px;border-radius:var(--r-pill);
  padding:3px 10px 3px 8px;border:1px solid;}
.fc-tag::before{font-size:var(--t-xs);line-height:var(--lh-flat);}
.fc-tag.teal{color:var(--good);background:color-mix(in srgb,var(--good) 10%,transparent);
  border-color:color-mix(in srgb,var(--good) 28%,transparent);}
.fc-tag.teal::before{content:'\2713';}
.fc-tag.warm{color:var(--action);background:color-mix(in srgb,var(--action) 11%,transparent);
  border-color:color-mix(in srgb,var(--action) 32%,transparent);}
.fc-tag.warm::before{content:'\25B2';}
.fc-tag.over{color:var(--danger);background:color-mix(in srgb,var(--danger) 10%,transparent);
  border-color:color-mix(in srgb,var(--danger) 30%,transparent);}
.fc-tag.over::before{content:'\25CF';}
.fc-tag.mist{color:var(--fd2);background:var(--fhl);border-color:var(--fb);}
.fc-tag.mist::before{content:'\25D7';}
.fc-card h3{font-size:var(--t-xxl);font-weight:600;letter-spacing:var(--tr-tight);margin-top:16px;color:var(--ft);}
.fc-card .meta{font-size:var(--t-l);color:var(--fd);line-height:var(--lh-body);margin-top:8px;flex:1;max-width:54ch;}
.fc-actions{display:flex;align-items:center;gap:10px;margin-top:18px;}
.fc-btn{font-family:inherit;font-size:var(--t-m);font-weight:600;border-radius:var(--r-s);padding:11px 18px;cursor:pointer;border:1px solid transparent;transition:all .15s ease;}
/* ⚠ 7 Aug — THE ONE CORAL ACT. `.fc-card` is the Needs-you card on Today: exactly one is live at a
   time, and its primary button is the single most important thing on the first screen. That is what
   the 5 Aug ruling describes, so this is where coral belongs.
   ⚠ I FIRST TRIED IT ON `.sp-btn.primary` — every primary button in the product — and the coral
     counter refused it: SpTenants 8 coral elements, SpClients 6, SpTeam 5. That is not a palette
     problem, it is those views having EIGHT equally-weighted buttons and therefore no primary act
     at all. Reverted. The guard was right; the finding is recorded in the handoff. */
.fc-btn.primary{background:var(--action);color:var(--on-accent);}
.fc-btn.primary:hover{background:color-mix(in srgb,var(--action) 88%,var(--ink));}
.fc-btn.ghost{background:transparent;color:var(--ft);border-color:var(--fb2);}
.fc-btn.ghost:hover{border-color:var(--fd);}
.fc-later{margin-left:auto;font-size:var(--t-m);color:var(--fd2);background:none;border:none;cursor:pointer;font-family:inherit;}
.fc-later:hover{color:var(--fd);}
.fc-srcline{margin-top:16px;padding-top:14px;border-top:1px solid var(--fb);display:flex;justify-content:space-between;align-items:center;}
.fc-done{position:absolute;inset:0;border:1.5px dashed var(--fb2);border-radius:var(--r-l);padding:30px;
  display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:10px;}
.fc-done .big{font-family:var(--font-display);font-weight:600;font-style:normal;font-size:var(--t-xxl);color:var(--ft);}
.fc-done .sub{font-size:var(--t-l);color:var(--fd);line-height:var(--lh-body);max-width:46ch;}
.fc-done .replay{margin-top:10px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;
  color:var(--fd2);background:none;border:1px solid var(--fb2);border-radius:100px;padding:7px 14px;cursor:pointer;}
.fc-done .replay:hover{color:var(--ft);}

/* ── vitals strip ──────────────────────────────── */
/* draft .chips4 — four equal columns, 16px. */
.os-vitals{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-top:26px;}
.os-vitals.top{display:block;grid-column:2/-1;grid-row:1;margin-top:0;margin-bottom:0;align-self:center;}
.os-vitals.top > .os-vitals{margin-top:0;}
/* draft .statc — the §08 ARCH: a large radius on the top corners, a small one at
   the foot, so the chip reads as a standing card rather than a rounded rectangle.
   --fs is the theme's card surface (== canon --card in Dawn), --fb its line. */
.os-vital{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-l) var(--r-l) var(--r-s) var(--r-s);box-shadow:var(--sh-1);min-height:150px;padding:20px 16px 16px;cursor:pointer;text-align:left;
  font-family:inherit;color:inherit;transition:transform .18s ease,border-color .18s ease;}
.os-vital:hover{transform:translateY(-2px);border-color:color-mix(in srgb,var(--hover) 50%,transparent);}
/* teal vitals highlight like the amber one — tinted label, coloured hover border */
:is(body.flow-dawn,body.flow-studio) .os-vital .vk{color:var(--acc);}
/* "Ready to raise" is a thing that NEEDS YOUR EYE, so its label takes --attention — the role —
   rather than --warm, an appearance name. Same value; now it can be moved.
   Its BAR rule is gone: a bar is a plotted value and takes the Option A kit, never a state colour. */
.os-vital.raise .vk{color:color-mix(in srgb,var(--attention) 80%,#fff);}
:is(body.flow-dawn,body.flow-studio) .os-vital.raise .vk{color:var(--attention);}
.os-vital.raise:hover{border-color:color-mix(in srgb,var(--warm) 50%,transparent);}
.os-vital .vk{display:flex;align-items:baseline;justify-content:space-between;gap:8px;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--acc-bright);}
.os-vital .vk .go{letter-spacing:0;color:var(--fd2);opacity:0;transition:opacity .15s ease;}
.os-vital:hover .vk .go{opacity:1;color:var(--hover);}
.os-vital .big{display:block;font-family:var(--font-display);font-weight:600;font-style:normal;font-size:var(--t-xxl);line-height:var(--lh-flat);margin-top:7px;color:var(--ft);font-variant-numeric:tabular-nums;}
.os-vital .viz{display:flex;align-items:flex-end;height:18px;margin-top:7px;}
.os-vital .vbar{display:flex;width:100%;height:6px;border-radius:100px;overflow:hidden;gap:2px;align-self:center;}
/* OPTION A as CLASSES, not inline colours — an inline colour is a design literal the ratchet
   counts and a rule nobody can find. k0-k4 = m1-m4 then the neutral tail, per G2. */
.os-vital .vbar i{display:block;height:100%;border-radius:var(--r-xs);background:var(--m1);}
.os-vital .vbar i.k0{background:var(--m1);}
.os-vital .vbar i.k1{background:var(--m2);}
.os-vital .vbar i.k2{background:var(--m3);}
.os-vital .vbar i.k3{background:var(--m4);}
.os-vital .vbar i.k4{background:var(--mark-none);}
.os-vital .vbars{display:flex;gap:4px;align-items:flex-end;height:20px;}
.os-vital .vbars i{display:block;width:9px;border-radius:var(--r-pill) var(--r-pill) 0 0;background:var(--mark);}
.os-vital .vbars i.zero{height:3px;background:var(--fb2);}
body[data-motion="Full"] .os-vital .vbar i{transform-origin:left;animation:osGrowX .85s cubic-bezier(.22,.61,.36,1) backwards;}
body[data-motion="Full"] .os-vital .vbars i{transform-origin:bottom;animation:osGrowY .55s cubic-bezier(.3,.9,.4,1.1) backwards;}
@keyframes osGrowX{from{transform:scaleX(0);opacity:.35;}to{opacity:1;}}
@keyframes osGrowY{from{transform:scaleY(0);opacity:.35;}to{opacity:1;}}
.os-vital .sub{display:block;margin-top:7px;font-size:var(--t-xs);color:var(--fd);line-height:var(--lh-ui);}

/* ── property record ─────────────────────────────── */
.pp-back{font-family:inherit;font-size:var(--t-m);font-weight:500;color:var(--acc-bright);background:none;border:0;cursor:pointer;padding:0;margin-bottom:14px;}
/* Fees scoped-to-a-person banner (from the person page) */
.sp-scopebar{display:flex;align-items:center;gap:10px;font-size:var(--t-m);color:var(--fd);background:color-mix(in srgb,var(--mark) 8%,transparent);border:1px solid color-mix(in srgb,var(--mark) 22%,transparent);border-radius:var(--r-m);padding:9px 14px;margin-bottom:14px;}
.sp-scopebar b{color:var(--ft);}
.sp-scopebar button{margin-left:auto;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--mark);background:none;border:0;cursor:pointer;}
/* ── Person profile page (SpPerson) — same detail-page pattern as the deal ── */
.pp-card{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-l);padding:18px 22px;box-shadow:0 10px 28px -22px rgba(18,20,24,.18);margin-top:4px;}
.pp-card .pp-top{display:flex;align-items:center;gap:13px;}
.pp-card .pp-top h3{display:flex;align-items:center;gap:10px;font-family:var(--font-serif);font-weight:var(--w-regular);font-size:var(--t-xl);letter-spacing:var(--tr-tight);color:var(--ft);}
.pp-card .pp-top h3 .tm-role{font-size:var(--t-xxs);padding:3px 9px;}
/* two-column top: fees pie left, activity stats right + compact */
.pp-grid{display:grid;grid-template-columns:1fr 1.5fr;gap:14px;margin-top:16px;align-items:stretch;}
@media(max-width:760px){.pp-grid{grid-template-columns:1fr;}}
.pp-grid .pp-fees{margin-top:0;height:100%;}
.pp-grid .pp-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:0;}
.pp-grid .pp-stat{min-width:0;}
.pp-donut::after{content:attr(data-pct);position:absolute;inset:7px;background:var(--fs);border-radius:var(--r-round);display:flex;align-items:center;justify-content:center;font-family:var(--font-display);font-weight:600;font-size:var(--t-s);color:var(--ft);}
.pp-deal{padding:11px 6px;}
/* narrower page + two-column lower section (deals left, desks right) */
.pp-wrap{max-width:1140px;margin:0 auto;}
.pp-cols{display:grid;grid-template-columns:1.25fr 1fr;gap:30px;margin-top:20px;align-items:start;}
@media(max-width:840px){.pp-cols{grid-template-columns:1fr;gap:6px;}}
.pp-col .sp-sec{margin-top:0;}
.pp-card .pp-sub{font-size:var(--t-m);color:var(--fd);}
.pp-card .tm-role{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;border-radius:100px;padding:5px 11px;color:var(--acc-bright);background:color-mix(in srgb,var(--acc-bright) 10%,transparent);white-space:nowrap;}
.pp-stats{display:flex;gap:12px;flex-wrap:wrap;}
.pp-stat{flex:1;min-width:110px;background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-m);padding:13px 15px;display:flex;flex-direction:column;gap:2px;}
.pp-stat b{font-family:var(--font-display);font-weight:600;font-size:var(--t-xxl);color:var(--ft);font-variant-numeric:tabular-nums;}
.pp-stat span{font-size:var(--t-s);color:var(--fd);}
.pp-actions{margin-top:18px;display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
.pp-deal{display:flex;align-items:center;gap:12px;padding:14px 6px;border-bottom:1px solid var(--fb);cursor:pointer;transition:background .15s ease;border-radius:var(--r-s);}
.pp-deal:hover{background:var(--fhl);}
.pp-deal .tmain{flex:1;min-width:0;}
.pp-deal .tmain b{display:block;font-size:var(--t-l);color:var(--ft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pp-deal .tmain small{display:block;font-size:var(--t-s);color:var(--fd);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pp-deal .pp-fee{font-family:var(--font-display);font-weight:600;font-size:var(--t-l);color:var(--ft);}
.pp-go{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--acc);}
.pp-deal .pp-go{min-width:54px;text-align:right;}
/* personal fees card */
.pp-fees{margin-top:4px;border:1px solid var(--fb);border-radius:var(--r-m);padding:14px 16px;background:var(--fhl);transition:background .15s ease;}
.pp-fees:hover{background:color-mix(in srgb,var(--hover) 5%,transparent);}
.pp-fees .pp-fh{display:flex;align-items:baseline;gap:10px;}
.pp-fees .pp-fh b{font-family:var(--font-display);font-weight:600;font-size:var(--t-xl);color:var(--ft);font-variant-numeric:tabular-nums;}
.pp-fsub{font-size:var(--t-s);color:var(--fd);}
.pp-fees .pp-pipe{font-family:var(--font-sans);font-size:var(--t-s);font-weight:500;color:var(--acc);}
/* In-negs monitor — person page: fees with live interest on, next to the pipeline figure. */
.pp-fees .pp-innegs{font-family:var(--font-mono);font-size:var(--t-xs);font-weight:600;color:var(--attention-ink);padding:2px 7px;border-radius:var(--r-s);background:color-mix(in srgb,var(--warm) 12%,transparent);}
.pp-fees .pp-fh .pp-go{margin-left:auto;}
.pp-feebody{display:flex;gap:16px;align-items:center;margin-top:12px;}
.pp-donut{width:60px;height:60px;border-radius:var(--r-round);flex-shrink:0;position:relative;}
.pp-legend{font-size:var(--t-s);color:var(--fd);line-height:var(--lh-prose);}
.pp-legend span{display:block;}
.pp-legend i{display:inline-block;width:8px;height:8px;border-radius:var(--r-xs);margin-right:6px;}
/* activity sparklines */
.pp-stat .pp-spark{display:flex;align-items:flex-end;gap:2px;height:18px;margin-top:9px;}
.pp-stat .pp-spark i{flex:1;background:color-mix(in srgb,var(--mark) 42%,transparent);border-radius:var(--r-xs) 2px 0 0;}
.pp-stat .pp-spark.seed i{background:repeating-linear-gradient(45deg,color-mix(in srgb,var(--mark) 42%,transparent) 0 2px,color-mix(in srgb,var(--mark) 12%,transparent) 2px 4px);}
/* desk pair-up on the person page */
.pp-addbtn{margin-left:12px;font-family:var(--font-display);font-size:var(--t-s);font-weight:600;color:var(--acc);background:color-mix(in srgb,var(--acc-bright) 10%,transparent);border:1px solid color-mix(in srgb,var(--acc-bright) 26%,transparent);border-radius:100px;padding:4px 12px;cursor:pointer;vertical-align:middle;}
.pp-pair{background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-m);padding:14px 16px;margin:10px 0 14px;}
.pp-chips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px;}
.pp-chips .pchip{display:flex;align-items:center;gap:7px;font-family:var(--font-display);font-size:var(--t-m);font-weight:500;color:var(--ft);background:var(--fs);border:1px solid var(--fb);border-radius:100px;padding:5px 13px 5px 5px;cursor:pointer;transition:border-color .15s ease,background .15s ease;}
.pp-chips .pchip.on{border-color:var(--acc-bright);background:color-mix(in srgb,var(--acc-bright) 12%,transparent);}
.pp-chips .pchip .sp-av{width:24px;height:24px;font-size:var(--t-xs);}
.pp-pairsave{display:flex;gap:8px;align-items:center;flex-wrap:wrap;}
.pp-pairsave input{flex:1;min-width:160px;font-family:var(--font-sans);font-size:var(--t-m);color:var(--ft);background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-s);padding:9px 12px;}
.pp-back:hover{text-decoration:underline;}
.pp-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;}
.pp-head h3{font-size:var(--t-xxl);font-weight:600;letter-spacing:var(--tr-tight);color:var(--ft);}
.pp-addr{font-size:var(--t-m);color:var(--fd);margin-top:3px;}
/* Agent · <name> — the instruction owner on the property record (SPINE invariant 3). */
.pp-agent{font-family:var(--font-mono);font-size:var(--t-s);font-weight:600;color:var(--acc);margin-top:5px;letter-spacing:var(--tr-none);}
.pp-facts{display:flex;flex-wrap:wrap;margin-top:16px;border-top:1px solid var(--fb2);border-bottom:1px solid var(--fb2);}
.pp-f{padding:12px 22px 13px;border-left:1px solid var(--fb);display:flex;flex-direction:column;gap:3px;}
.pp-f:first-child{padding-left:2px;border-left:0;}
.pp-f .fl{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);}
.pp-f .fv{font-size:var(--t-l);font-weight:600;color:var(--ft);letter-spacing:var(--tr-none);}
.pp-eye{display:flex;gap:11px;padding:10px 2px;border-bottom:1px solid var(--fb);}
.pp-eye .n{width:20px;height:20px;border-radius:var(--r-xs);background:color-mix(in srgb,var(--acc-bright) 16%,transparent);color:var(--acc-bright);display:flex;align-items:center;justify-content:center;font-family:var(--font-mono);font-size:var(--t-xs);font-weight:600;flex-shrink:0;margin-top:1px;}
:is(body.flow-dawn,body.flow-studio) .pp-eye .n{color:var(--acc);background:color-mix(in srgb,var(--acc) 11%,transparent);}
.pp-eye .t{font-size:var(--t-m);color:var(--fd);line-height:var(--lh-body);}
.pp-eye .t b{color:var(--ft);font-weight:600;}
.pp-flow{display:flex;align-items:flex-start;padding:14px 2px 4px;}
.pp-nw{display:flex;flex-direction:column;align-items:center;gap:6px;flex-shrink:0;}
.pp-node{width:28px;height:28px;border-radius:var(--r-round);display:flex;align-items:center;justify-content:center;font-size:var(--t-s);}
.pp-node.done{background:var(--ft);color:var(--fbg);}
.pp-node.now{background:var(--acc-bright);color:var(--fbg);box-shadow:0 0 0 4px color-mix(in srgb,var(--acc-bright) 20%,transparent);}
.pp-node.next{background:transparent;border:1.5px dashed var(--fb2);}
.pp-nl{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--fd2);}
.pp-nw.now .pp-nl{color:var(--ft);font-weight:600;}
.pp-fline{flex:1;border-top:2px dotted var(--fb2);margin-top:13px;min-width:8px;}
.pp-dealnote{font-size:var(--t-m);color:var(--fd);line-height:var(--lh-body);margin-top:12px;max-width:64ch;}
.pp-cols{display:grid;grid-template-columns:1.35fr 1fr;gap:0 40px;align-items:start;}
.pp-ctype{display:inline-flex;background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-s);padding:2px;margin:2px 0 10px;}
.pp-ctype button{font-family:inherit;font-size:var(--t-s);font-weight:500;color:var(--fd);background:none;border:0;border-radius:var(--r-s);padding:5px 13px;cursor:pointer;transition:all .15s ease;}
.pp-ctype button.on{background:var(--fs2);color:var(--ft);font-weight:600;box-shadow:0 1px 3px rgba(0,0,0,.25);}
.pp-composer{display:flex;gap:8px;margin:4px 0 14px;}
.pp-composer input{flex:1;font-family:inherit;font-size:var(--t-m);color:var(--ft);background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-s);padding:9px 13px;outline:none;}
.pp-composer input::placeholder{color:var(--fd2);}
.pp-composer input:focus{border-color:var(--hover);}
.pp-cmt{display:grid;grid-template-columns:32px 1fr;gap:10px;padding:10px 0;border-bottom:1px solid var(--fb);}
.pp-cmeta{display:block;font-size:var(--t-m);color:var(--fd);}
.pp-cmeta b{color:var(--ft);font-weight:600;}
.pp-typetag{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--acc-bright);background:color-mix(in srgb,var(--acc-bright) 13%,transparent);border-radius:100px;padding:2px 7px;margin-left:7px;}
.pp-cx{display:block;font-size:var(--t-m);color:var(--fd);line-height:var(--lh-body);margin-top:3px;}
.pp-person{display:flex;align-items:center;gap:10px;padding:7px 0;cursor:pointer;border-bottom:1px solid var(--fb);}
.pp-person:hover b{color:var(--hover);}
.pp-person b{display:block;font-size:var(--t-m);font-weight:600;color:var(--ft);}
.pp-person small{display:block;font-size:var(--t-s);color:var(--fd);}
.pp-doc{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:var(--t-m);color:var(--ft);padding:8px 0;border-bottom:1px solid var(--fb);cursor:pointer;}
.pp-doc:hover span:first-child{color:var(--hover);}
.pp-act{font-size:var(--t-m);color:var(--fd);padding:5px 0;line-height:var(--lh-body);}
.pp-act b{color:var(--ft);font-weight:600;}
@media(max-width:980px){.pp-cols{grid-template-columns:1fr;}}

/* Deal page merged top card: stage ticks + chips (left) beside the fee panel (right); stacks narrow. */
.deal-topgrid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,0.85fr);gap:20px;align-items:stretch;margin-top:14px;}
@media(max-width:760px){.deal-topgrid{grid-template-columns:1fr;}}

/* ── ambient feed ───────────────────────────────── */
/* draft .ledger — the rail becomes a PANEL: the app's feed sat bare on the canvas.
   --fs2 is the theme's raised surface (== canon --surface in Dawn), --fb its line. */
/* draft .rail — a flex COLUMN holding two panels, 24px apart. The panel paint moved off .fc-feed
   and onto .fc-led when the dome joined it, so the rail itself is now just the column. */
.fc-feed{position:sticky;top:calc(var(--topbar-h) + 24px);display:flex;flex-direction:column;gap:24px;}
.fc-led{background:var(--fs2);border:1px solid var(--fb);border-radius:var(--r-l);padding:20px;}
/* draft .dome — --petrol-tint is canon #DCE9E5, i.e. the ground at a whisper over the card. Expressed
   as a mix against --fs so Studio and Dusk tint their OWN surface instead of being handed Dawn's. */
.os-dome{background:color-mix(in srgb,var(--ground) 12%,var(--fs));border-radius:var(--r-l);padding:24px;text-align:center;}
.os-dome .cap{display:block;font-family:var(--font-sans);font-size:var(--t-m);font-weight:var(--w-bold);line-height:var(--lh-tight);color:var(--ground);margin-bottom:8px;}
.os-dome .arc{display:block;width:120px;max-width:100%;margin:0 auto 4px;}
.os-dome .arc path{fill:none;stroke-width:9;stroke-linecap:round;}
.os-dome .arc .tr{stroke:color-mix(in srgb,var(--ground) 18%,transparent);}
.os-dome .arc .vl{stroke:var(--mark);transition:stroke-dashoffset .6s cubic-bezier(.22,.61,.36,1);}
.os-dome .val{font-family:var(--font-display);font-size:var(--t-xxl);font-weight:var(--w-black);letter-spacing:var(--tr-tight);line-height:var(--lh-flat);color:var(--ground);font-variant-numeric:tabular-nums;}
.os-dome .un{display:block;margin-top:8px;font-family:var(--font-mono);font-size:var(--t-xs);font-weight:var(--w-bold);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--hover);}
.os-dome .note{margin:12px 0 0;font-size:var(--t-s);line-height:var(--lh-body);color:var(--hover);}
/* draft .ledger .lh — 700 15px sans on --ink, NOT the old mono kicker.
   ⚠ The draft's own comment says the head is "Instrument Serif 400"; its CSS draws sans 700. The
   PIXELS are the approved artefact, so the CSS wins and the discrepancy is logged, not guessed at. */
.fc-feed .fh{font-family:var(--font-sans);font-size:var(--t-l);font-weight:var(--w-bold);letter-spacing:var(--tr-none);text-transform:none;color:var(--ft);
  padding-bottom:10px;border-bottom:1px solid var(--fb);display:flex;justify-content:space-between;align-items:baseline;}
/* draft .ledger .lk — the mono kicker moves BELOW the head, with the pulsing --mark dot. */
.fc-feed .fh .live{color:var(--mark);}
.fc-feed .lk{display:flex;align-items:center;gap:6px;margin-top:2px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd2);}
.fc-feed .lk i{width:6px;height:6px;border-radius:var(--r-round);background:var(--mark);display:inline-block;box-shadow:0 0 0 3px color-mix(in srgb,var(--mark) 20%,transparent);}
/* ── THE LEDGER — brief §24, ON THE MARKUP THAT EXISTS. ═══════════════════════════════════════
   The spec: a half-dome arc glyph, then a two-line entry — the event, and beneath it the
   timestamp in mono. The markup is <div class="fc-entry"><span class="t">07:42</span>
   <span class="x">…</span></div> and it is NOT CHANGING: the bundle is frozen for the design, on
   the standing finding that every incident this week traces to a code edit and no stylesheet
   change has ever blanked the app. So the layout is done with grid placement and `order`, and the
   glyph with ::before, on exactly the two spans already there.
   ⚠ WHAT THIS CANNOT DO, AND IT IS A ROW NOT A SILENCE: the kind colour-coding. §24 wants the
     glyph coloured by which of the five kinds an entry is, and the entry carries no `kind` — the
     class that would select it does not exist in the DOM. The glyph is therefore ONE colour, the
     neutral. Row R-T4 stays open for it, and it needs a field on the entry, not a rule here. */
.fc-entry{display:grid;grid-template-columns:20px minmax(0,1fr);grid-template-rows:auto auto;
  column-gap:10px;row-gap:2px;padding:10px 0;border-bottom:1px solid var(--fb);align-items:start;
  width:100%;text-align:left;cursor:pointer;}
.fc-entry::before{content:'';grid-column:1;grid-row:1 / span 2;width:14px;height:7px;margin-top:5px;
  border-radius:var(--r-pill) var(--r-pill) 0 0;background:var(--mark-none);}
.fc-entry:hover{background:var(--fhl);}
/* the event first, the timestamp under it — `order` does what the markup order will not */
.fc-entry .x{grid-column:2;grid-row:1;order:1;display:block;font-size:var(--t-m);color:var(--fd);
  line-height:var(--lh-ui);}
.fc-entry .t{grid-column:2;grid-row:2;order:2;display:block;font-family:var(--font-mono);
  font-size:var(--t-xs);color:var(--fd2);letter-spacing:var(--tr-s);}
.fc-entry.fresh{animation:fcEntry .5s cubic-bezier(.2,.7,.25,1);}
@keyframes fcEntry{from{opacity:0;transform:translateX(10px);}}
.fc-feednote{margin-top:12px;font-size:var(--t-s);color:var(--fd2);line-height:var(--lh-body);}
/* §6 — Today feed scrolls inside a fixed height; subtle fade at the bottom edge */
/* draft .ledger .les is a flat max-height:430px. The app's viewport-relative calc is kept AS THE
   FLOOR so a short window cannot be given a 430px scroller it has no room for — min() takes the
   draft's height whenever there is room for it. */
.fc-feedscroll{margin-top:14px;max-height:min(430px,calc(100vh - var(--topbar-h) - 190px));min-height:120px;overflow-y:auto;overflow-x:hidden;-webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 22px),transparent);mask-image:linear-gradient(to bottom,#000 calc(100% - 22px),transparent);}
.fc-feedscroll::-webkit-scrollbar{width:6px;}
.fc-feedscroll::-webkit-scrollbar-thumb{background:var(--fb2);border-radius:var(--r-xs);}
/* Dusk — the live feed has to read clearly against the dark wash; entry text runs
   near-full strength, timestamps and the header sit a clear step above the canvas. */
body.flow-dusk .fc-entry .x{color:color-mix(in srgb,var(--bone) 92%,transparent);}
body.flow-dusk .fc-entry .t{color:color-mix(in srgb,var(--bone) 58%,transparent);}
body.flow-dusk .fc-feed .fh{color:color-mix(in srgb,var(--bone) 66%,transparent);}
body.flow-dusk .fc-feednote{color:color-mix(in srgb,var(--bone) 52%,transparent);}
body.flow-dusk .fc-greet .strap{color:color-mix(in srgb,var(--bone) 78%,transparent);}
body.flow-dusk .os-vital .s{color:color-mix(in srgb,var(--bone) 62%,transparent);}

/* ── command bar ────────────────────────────────── */
.fc-cmdwrap{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);width:min(1180px,calc(100% - 32px));z-index:110;display:flex;flex-direction:column;align-items:stretch;}
.fc-cmdwrap .fc-cmd{width:min(620px,100%);margin:0 auto;}
.fc-cmd:focus-within{border-color:color-mix(in srgb,var(--hover) 55%,transparent);box-shadow:0 18px 44px -16px rgba(0,0,0,.55),0 0 24px -8px color-mix(in srgb,var(--hover) 30%,transparent);}
.fc-cmdpanel{position:absolute;bottom:54px;left:50%;transform:translateX(-50%);width:min(620px,100%);background:var(--fs2);border:1px solid var(--fb2);border-radius:var(--r-m);
  overflow:hidden;box-shadow:0 30px 60px -20px rgba(0,0,0,.55);animation:fcEntry .2s ease;z-index:5;}
.fc-sugg{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding:11px 16px;cursor:pointer;font-size:var(--t-l);color:var(--ft);}
.fc-sugg .hint{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);}
.fc-sugg.hi{background:color-mix(in srgb,var(--attention) 18%,transparent);}
.fc-answer{padding:16px 18px;}
.fc-answer .at{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--mark);display:flex;justify-content:space-between;align-items:baseline;}
.fc-answer .ax{cursor:pointer;color:var(--fd2);font-size:var(--t-l);line-height:var(--lh-flat);}
.fc-answer .ar{display:flex;justify-content:space-between;gap:14px;padding:9px 0;border-bottom:1px solid var(--fb);font-size:var(--t-m);}
.fc-answer .ar b{font-weight:600;color:var(--ft);}
.fc-answer .ar span{color:var(--fd);text-align:right;}
.fc-answer .an{margin-top:10px;font-size:var(--t-s);color:var(--fd2);}
.fc-cmd{display:flex;align-items:center;gap:11px;background:var(--fs2);border:1px solid var(--fb2);border-radius:100px;padding:6px 8px 6px 18px;
  box-shadow:0 18px 44px -16px rgba(0,0,0,.55);}
.fc-cmd svg{width:15px;height:15px;stroke:var(--fd2);fill:none;stroke-width:1.8;flex-shrink:0;}
.fc-cmd input{flex:1;background:transparent;border:0;outline:0;font-family:inherit;font-size:var(--t-l);color:var(--ft);padding:7px 0;}
.fc-cmd input::placeholder{color:var(--fd2);}
.fc-cmd kbd{font-family:var(--font-mono);font-size:var(--t-xs);color:var(--fd2);border:1px solid var(--fb2);border-radius:var(--r-xs);padding:4px 8px;}

/* ── space overlay ──────────────────────────────── */
.sp-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.5);backdrop-filter:blur(3px);z-index:95;animation:spFade .25s ease;transition:background .4s ease;}
/* Light themes — a misty paper veil instead of a dark dim, so the wash (and the
   seamless top bar) stay part of the picture behind a floating space */
:is(body.flow-dawn,body.flow-studio) .sp-backdrop{background:color-mix(in srgb,var(--fbg) 42%,transparent);backdrop-filter:blur(9px);-webkit-backdrop-filter:blur(9px);}
/* Full-screen space paints its own washed canvas — no veil needed behind it,
   which also keeps the strip above the space clean under the top bar */
body:has(.sp-space.full:not(.peeking)) .sp-backdrop{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;}
@keyframes spFade{from{opacity:0;}}
.sp-space{position:fixed;top:calc(var(--topbar-h) + 2vh);left:50%;transform:translateX(-50%);width:min(1140px,calc(100% - 64px));max-height:calc(98vh - var(--topbar-h) - 172px);
  background:var(--fs2);border:1px solid var(--fb2);border-radius:var(--r-l);z-index:100;display:flex;flex-direction:column;
  box-shadow:0 50px 100px -30px rgba(0,0,0,.6);animation:spIn .35s cubic-bezier(.2,.7,.25,1);overflow:hidden;
  transition:top .45s cubic-bezier(.22,.61,.36,1),left .45s cubic-bezier(.22,.61,.36,1),width .45s cubic-bezier(.22,.61,.36,1),
    max-height .45s cubic-bezier(.22,.61,.36,1),transform .45s cubic-bezier(.22,.61,.36,1),border-radius .45s ease,
    padding-top .45s ease,box-shadow .45s ease,background-color .45s ease;}
@keyframes spIn{from{opacity:0;transform:translateX(-50%) translateY(22px) scale(.985);}}
.sp-space:has(.sp-modalbg){z-index:130;}
body[data-motion="Off"] .sp-space,body[data-motion="Off"] .sp-backdrop{animation:none;transition:none;}
.sp-space.peeking{box-shadow:0 50px 100px -30px rgba(0,0,0,.6),0 0 0 1px var(--fb2);}
.sp-space.peeking .sp-kicker{color:var(--acc-bright);}
.sp-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:14px 30px 12px;border-bottom:1px solid var(--fb);flex-shrink:0;}
/* the description scrolls with the body now — only the name bar stays pinned */
.sp-lede-scroll{margin:2px 0 6px;}
.sp-kicker{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd2);}
.sp-kicker kbd{border:1px solid var(--fb2);border-radius:var(--r-xs);padding:1px 6px;font-size:var(--t-xxs);}
.sp-head h2{font-size:var(--t-xxl);font-weight:600;letter-spacing:var(--tr-tight);color:var(--ft);margin-top:4px;}
.sp-head h2 .tg{font-family:var(--font-serif);font-style:italic;font-weight:400;color:var(--acc-bright);}
.sp-lede{font-size:var(--t-m);color:var(--fd);line-height:var(--lh-body);margin-top:7px;max-width:64ch;}
.sp-x{font-size:var(--t-xxl);line-height:var(--lh-flat);color:var(--fd);background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-s);width:36px;height:36px;cursor:pointer;flex-shrink:0;}
.sp-x:hover{color:var(--ft);}
.sp-body{padding:20px 30px 30px;overflow-y:auto;}

/* ── space building blocks ──────────────────────── */
.sp-totals{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;padding-bottom:18px;border-bottom:1px solid var(--fb);margin-bottom:6px;}
.sp-totals.four{grid-template-columns:repeat(4,1fr);}
.sp-tot .v{font-family:var(--font-display);font-weight:600;font-style:normal;font-size:var(--t-xxl);color:var(--ft);font-variant-numeric:tabular-nums;}
.sp-tot .l{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);margin-top:4px;}
.sp-tot .s{font-size:var(--t-s);color:var(--fd);margin-top:3px;}
.sp-sec{display:flex;align-items:center;gap:10px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--ft);margin:30px 0 6px;padding:6px 0;}
.sp-sec::before{content:'';width:18px;height:2px;background:var(--ground);border-radius:var(--r-xs);flex-shrink:0;}
/* Both names on one rule: the state name the code now emits, and the colour word the ~100 sites
   still on look-names emit. Neither is unstyled while the families move across one at a time. */
.sp-sec.warm::before,.sp-sec.under-offer::before{background:var(--st-under-offer);}
.sp-sec.part-let::before{background:var(--st-part-let);}
.sp-sec.green::before,.sp-sec.let::before{background:var(--st-let-mark);}
.sp-sec.mist::before,.sp-sec.coming-soon::before{background:var(--fd2);}
.sp-sec::after{content:'';flex:1;border-top:1px solid var(--fb2);}
.sp-body > .sp-sec:first-child,.sp-totals + .sp-sec,.sp-viz + .sp-sec{margin-top:16px;}
.sp-row{display:flex;align-items:center;gap:16px;padding:13px 2px;border-bottom:1px solid var(--fb);cursor:pointer;transition:background .12s ease;}
.sp-row:hover,.sp-row.active{background:var(--fhl);}
.sp-row-main{flex:1;min-width:0;}
.sp-row-main b{display:block;font-size:var(--t-l);font-weight:600;color:var(--ft);letter-spacing:var(--tr-none);}
.sp-row-main small{display:block;font-size:var(--t-m);color:var(--fd);margin-top:2px;}
.sp-row-main .x{display:block;font-size:var(--t-m);color:var(--fd);margin-top:3px;}
.sp-row-side{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex-shrink:0;}
/* ── THE FLOOR-ROW CONTROLS — an ACT, not a STATE (Jake, 7 Aug) ─────────────────────────────────
   Jake hit this twice: on the property record the `fell through` and `✎ edit` controls sit in the
   same inline-flex row as the UNDER OFFER chip, at the same baseline, the same size, the same pill
   shape — and, until today, painted from the SAME TOKEN (`--warm` was both). Nothing distinguished
   "what this floor IS" from "what you can do to it" except already knowing.
   His 5 Aug ruling settles it: CORAL MEANS ACT ON THIS AND NOTHING ELSE. `--action` is coral now, so
   these read as controls and the status word keeps the status colour.
   Written as classes because an inline style is unreachable from a stylesheet — five identical
   declarations lived in five places and could not be restyled without editing React. */
.fb-act{font:inherit;font-size:var(--t-xxs);font-weight:var(--w-semi);cursor:pointer;padding:2px 7px;
  border-radius:var(--r-s);white-space:nowrap;border:1px solid var(--fb2);background:transparent;color:var(--fd);}
.fb-act:hover{border-color:color-mix(in srgb,var(--action) 45%,var(--fb2));color:var(--action);}
/* the primary act on the row — an offer to log, or a confirm */
/* ⚠ NOT `.fb-act.go` — `go` is ALREADY a class in this codebase (SpPerson, SpTenants, OsVitals all
   carry it). An invented class name that collides with a real one is R213 in a new coat: it binds to
   the wrong thing, or reads as the wrong thing to the next person, and nothing errors. `is-` prefixed
   modifiers cannot collide with a content class. */
.fb-act.is-primary{border-color:color-mix(in srgb,var(--action) 55%,transparent);
  background:color-mix(in srgb,var(--action) 10%,var(--fs));color:var(--action);}
/* a two-step confirm, mid-flight: the same act, asked once more */
.fb-act.is-confirm{font-weight:var(--w-semi);border-color:var(--action);
  background:color-mix(in srgb,var(--action) 12%,var(--fs));color:var(--action);}
/* the quiet, reversible one — dashed, so an affordance still reads as an affordance */
.fb-act.is-quiet{border-style:dashed;color:var(--fd2);font-weight:var(--w-regular);}
.sp-badge,.sp-chip{display:inline-block;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-m);text-transform:uppercase;padding:3px 9px;border-radius:100px;white-space:nowrap;}
.sp-badge.warm,.sp-chip.warm,.sp-badge.under-offer,.sp-chip.under-offer{color:color-mix(in srgb,var(--st-under-offer) 85%,#fff);background:color-mix(in srgb,var(--st-under-offer) 18%,transparent);}
.sp-badge.part-let,.sp-chip.part-let{color:color-mix(in srgb,var(--st-part-let) 85%,#fff);background:color-mix(in srgb,var(--st-part-let) 18%,transparent);}
:is(body.flow-dawn,body.flow-studio) .sp-badge.warm,:is(body.flow-dawn,body.flow-studio) .sp-chip.warm,:is(body.flow-dawn,body.flow-studio) .sp-badge.under-offer,:is(body.flow-dawn,body.flow-studio) .sp-chip.under-offer{color:var(--st-under-offer);background:color-mix(in srgb,var(--st-under-offer) 11%,transparent);}
:is(body.flow-dawn,body.flow-studio) .sp-badge.part-let,:is(body.flow-dawn,body.flow-studio) .sp-chip.part-let{color:var(--st-part-let);background:color-mix(in srgb,var(--st-part-let) 11%,transparent);}
.sp-badge.teal,.sp-chip.teal,.sp-badge.available,.sp-chip.available{color:var(--st-available-bright);background:color-mix(in srgb,var(--st-available-bright) 14%,transparent);}
.sp-badge.green,.sp-chip.green,.sp-badge.let,.sp-chip.let{color:var(--st-let-ink);background:color-mix(in srgb,var(--green) 18%,transparent);}
:is(body.flow-dawn,body.flow-studio) .sp-badge.green,:is(body.flow-dawn,body.flow-studio) .sp-chip.green,:is(body.flow-dawn,body.flow-studio) .sp-badge.let,:is(body.flow-dawn,body.flow-studio) .sp-chip.let{color:var(--st-let);background:color-mix(in srgb,var(--green) 11%,transparent);}
.sp-badge.mist,.sp-chip.mist,.sp-badge.coming-soon,.sp-chip.coming-soon{color:var(--fd);background:var(--fhl);border:1px solid var(--fb);}
.sp-note{margin-top:18px;font-size:var(--t-m);color:var(--fd2);line-height:var(--lh-body);max-width:70ch;}
.sp-note b{color:var(--fd);}
.muted{color:var(--fd);font-size:var(--t-m);}
.mono-sm{font-family:var(--font-mono);font-size:var(--t-s);color:var(--fd);}
.dim{color:var(--fd2);}
.amt{font-family:var(--font-mono);font-size:var(--t-m);font-weight:600;color:var(--ft);text-align:right;}
.amt.hi{color:var(--acc-bright);}

/* tables */
.sp-thead{display:grid;gap:12px;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);padding:16px 2px 7px;border-bottom:1px solid var(--fb2);}
.sp-trow{display:grid;gap:12px;align-items:center;padding:12px 2px;border-bottom:1px solid var(--fb);cursor:pointer;transition:background .12s ease;}
.sp-trow:hover{background:var(--fhl);}
/* Fees — on the All tab, acquisition instructions carry a quiet accent tint so the
   two sides of the book read at a glance (disposals stay on the plain canvas). */
.sp-trow.acq-side{background:color-mix(in srgb,var(--acc) 7%,transparent);border-radius:var(--r-s);}
.sp-trow.acq-side:hover{background:color-mix(in srgb,var(--hover) 11%,transparent);}
.sp-trow b{font-size:var(--t-l);font-weight:600;color:var(--ft);}
.sp-trow.total{cursor:default;border-top:1px solid var(--fb2);border-bottom:0;}
.sp-thead.c5,.sp-trow.c5{grid-template-columns:1.2fr 1.3fr .9fr 1.05fr .8fr;}  /* col 4 widened 29 Jul: renaming the header "Pipeline" → "Fee pipeline" (R68) overflowed a .9fr
     column at 8.5px/.13em and pushed the label into "WHERE IT SITS". A longer word needs a wider
     column — the values were always aligned; it was the HEADER that lied about where they sat. */
.sp-trow.c5.team{grid-template-columns:44px 1.4fr .7fr .7fr 1.4fr;cursor:default;}
.sp-thead.c5.team{grid-template-columns:44px 1.4fr .7fr .7fr 1.4fr;}
.sp-thead.c4,.sp-trow.c4{grid-template-columns:1.6fr .8fr .8fr .9fr;}
.sp-thead.c6,.sp-trow.c6{grid-template-columns:1.5fr 1fr .8fr 1fr 1fr 1.1fr;}
.sp-trow.c6{cursor:default;}
.sp-trow .amt{text-align:left;}
.sp-thead.c4 + .sp-trow .amt,.sp-trow.c4 .amt{text-align:right;}
.sp-trow.c5 .amt{text-align:left;}

/* space visualisations */
.sp-viz{padding:18px 0 14px;border-bottom:1px solid var(--fb);}
.sp-viz .vt{display:flex;justify-content:space-between;align-items:baseline;gap:12px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd);margin-bottom:12px;}
.sp-viz .vt .dim{letter-spacing:var(--tr-s);color:var(--fd2);text-transform:none;}
.sp-hrow{display:grid;grid-template-columns:92px 1fr 56px;gap:12px;align-items:center;padding:4px 0;}
.sp-hrow .hl{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--fd);text-align:right;}
.sp-hrow .hv{font-family:var(--font-mono);font-size:var(--t-s);font-weight:600;color:var(--ft);}
.sp-hbar{height:10px;border-radius:100px;background:var(--fhl);overflow:hidden;}
.sp-hbar i{display:block;height:100%;background:var(--mark);border-radius:var(--r-pill) var(--r-pill) 0 0;transition:width .7s cubic-bezier(.22,.61,.36,1);}
.sp-hbar i.won{background:var(--st-let-ink);}
:is(body.flow-dawn,body.flow-studio) .sp-hbar i.won{background:var(--green);}
/* Diary colour pass — horizon bars graded by urgency window (warm→amber→teal) */
.sp-hbar i.warm{background:var(--adverse);}
.sp-hbar i.amber{background:var(--warm);}
body[data-motion="Full"] .sp-hbar i{transform-origin:left;animation:osGrowX .85s cubic-bezier(.22,.61,.36,1) backwards;}
.sp-stack{display:flex;height:14px;border-radius:var(--r-s);overflow:hidden;gap:2px;}
.sp-stack.tall{height:30px;border-radius:var(--r-s);}
/* THE ARC AS FORM — arch-top bars, per the brief's arc family: "arch bars on every chart".
   A bar is a half-round standing up, which is the same shape as the dome gauge and the Ledger's
   entry glyph. One motif, three sizes.
   ── OPTION A ON THE GRAPHICS — Jake, 10 Aug. Categorical, so m1-m4 and the neutral tail.
   Was: under-offer on --warm, available and coming BOTH on --mark with one faded by an inline
   opacity of .45. Two vocabularies in one graphic, and a faded token is a colour that exists in
   no palette and can be looked up nowhere. Every segment is a token now, and the LEGEND is what
   identifies them — colour MEANS, labels IDENTIFY. */
.sp-stack i{display:block;height:100%;background:var(--m1);min-width:3px;transition:width .7s cubic-bezier(.22,.61,.36,1);
  font-style:normal;display:flex;align-items:center;justify-content:center;font-family:var(--font-mono);font-size:var(--t-xs);font-weight:600;color:var(--bone);white-space:nowrap;overflow:hidden;}
:is(body.flow-dawn,body.flow-studio) .sp-stack i{color:#fff;}
.sp-stack i.c1{background:var(--m1);}
.sp-stack i.c2{background:var(--m2);}
.sp-stack i.c3{background:var(--m3);}
.sp-stack i.warm{background:var(--m1);}
.sp-stack i.won{background:var(--st-let-mark);}
body[data-motion="Full"] .sp-stack i{transform-origin:left;animation:osGrowX .85s cubic-bezier(.22,.61,.36,1) backwards;}
.sp-legend{display:flex;flex-wrap:wrap;gap:8px 18px;margin-top:11px;font-size:var(--t-s);color:var(--fd);}
.sp-legend span{display:inline-flex;align-items:center;gap:6px;}
.sp-legend i{width:9px;height:9px;border-radius:var(--r-xs);background:var(--m1);font-style:normal;}
.sp-legend i.c1{background:var(--m1);}
.sp-legend i.c2{background:var(--m2);}
.sp-legend i.c3{background:var(--m3);}
.sp-legend i.warm{background:var(--m1);}
.sp-legend i.won{background:var(--st-let-mark);}
.sp-legend b{color:var(--ft);font-weight:600;}

/* deals lanes */
.sp-lanes{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:8px;}
/* BOOT TRUTH D3 — grouped board: four stable columns, Under-offer expandable (spotlight grammar). */
.sp-board{display:flex;gap:12px;margin-top:8px;align-items:flex-start;}
.sp-group{flex:1 1 0;min-width:0;background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-m);padding:10px;display:flex;flex-direction:column;}
.sp-group.under{border-color:color-mix(in srgb,var(--warm) 40%,var(--fb));background:color-mix(in srgb,var(--warm) 5%,var(--fhl));}
.sp-group-h{display:flex;justify-content:space-between;align-items:baseline;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd);padding:2px 4px 10px;gap:8px;}
.sp-group-h .tot{color:var(--acc-bright);white-space:nowrap;}
.sp-group.under .sp-group-h .tot{color:var(--attention-ink);}
.sp-group-collapse{margin-left:8px;border:none;background:transparent;color:var(--attention-ink);font:inherit;cursor:pointer;text-transform:none;letter-spacing:0;}
.sp-cards{display:flex;flex-direction:column;gap:8px;max-height:520px;overflow-y:auto;}
.sp-substages{display:flex;flex-direction:column;gap:6px;}
.sp-substage{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:9px 10px;border:1px solid var(--fb);border-radius:var(--r-s);background:var(--fs);cursor:pointer;font-size:var(--t-s);color:var(--ft);}
.sp-substage:hover{border-color:var(--attention-ink);}
.sp-substage .c{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sp-substage .n{font-family:var(--font-mono);font-size:var(--t-xs);color:var(--fd2);}
.sp-substage .f{font-family:var(--font-mono);font-size:var(--t-xs);color:var(--attention-ink);background:color-mix(in srgb,var(--warm) 13%,transparent);border-radius:100px;padding:2px 8px;white-space:nowrap;}
.sp-board.spot .sp-group.open{flex:1 1 100%;}
.sp-group.rail{flex:0 0 56px;align-items:center;cursor:pointer;min-height:160px;}
.sp-group.rail .sp-rail-l{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd);margin-top:8px;}
.sp-group.rail .sp-rail-n{margin-top:auto;font-family:var(--font-mono);font-size:var(--t-m);color:var(--ground);}
.sp-sublanes{display:flex;gap:10px;overflow-x:auto;padding-bottom:4px;}
.sp-sublane{flex:0 0 240px;background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-s);padding:8px;}
.sp-sublane.hl-on{outline:2px solid var(--warm);outline-offset:3px;}
.sp-sublane-h{display:flex;justify-content:space-between;align-items:baseline;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd);padding:2px 4px 8px;}
.sp-sublane-h .tot{color:var(--attention-ink);}
@media (max-width:900px){.sp-board{overflow-x:auto;}.sp-group{flex:0 0 240px;}}
.sp-lane{background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-m);padding:10px;min-height:160px;}
.sp-lane-h{display:flex;justify-content:space-between;align-items:baseline;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd);padding:2px 4px 10px;}
.sp-lane-h .tot{color:var(--acc-bright);}
.sp-deal{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-s);padding:12px;margin-bottom:8px;cursor:pointer;}
.sp-deal:hover{border-color:var(--fb2);}
.sp-deal b{display:block;font-size:var(--t-m);font-weight:600;color:var(--ft);letter-spacing:var(--tr-none);}
.sp-deal small{display:block;font-size:var(--t-s);color:var(--fd);margin-top:2px;}
.sp-deal .fee{display:inline-block;font-family:var(--font-mono);font-size:var(--t-xs);color:var(--acc-bright);background:color-mix(in srgb,var(--acc-bright) 13%,transparent);border-radius:100px;padding:2px 8px;margin-top:8px;}
.sp-deal.won .fee{color:var(--st-let-ink);background:color-mix(in srgb,var(--green) 16%,transparent);}
.sp-deal .x{display:block;font-size:var(--t-s);color:var(--fd);margin-top:7px;}
.sp-deal .mv{display:flex;justify-content:space-between;align-items:center;margin-top:9px;padding-top:8px;border-top:1px solid var(--fb);}
.sp-deal .ago{font-size:var(--t-xs);color:var(--fd2);}

/* check-ins */
.sp-prog .bar{height:6px;border-radius:100px;background:var(--fhl);overflow:hidden;}
.sp-prog .bar i{display:block;height:100%;background:var(--mark);border-radius:100px;transition:width .35s ease;}
.sp-prog .lbl{margin-top:8px;display:flex;justify-content:space-between;font-size:var(--t-s);color:var(--fd);}
.sp-q{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:18px 20px;margin-top:12px;}
.sp-q .qh{display:flex;align-items:center;gap:10px;}
.sp-q .qh b{font-size:var(--t-l);color:var(--ft);}
.sp-q .ctx{font-size:var(--t-m);color:var(--fd);margin-top:7px;}
.sp-q .opts{display:flex;flex-wrap:wrap;gap:8px;margin-top:13px;align-items:center;}
.sp-q .opt{font-family:inherit;font-size:var(--t-m);font-weight:500;color:var(--ft);background:transparent;border:1px solid var(--fb2);border-radius:100px;padding:8px 15px;cursor:pointer;transition:all .12s ease;}
.sp-q .opt:hover{border-color:var(--hover);background:color-mix(in srgb,var(--hover) 10%,transparent);}
.sp-q .opt.save{background:var(--acc);color:var(--bone);border-color:var(--acc);}
.sp-q .opt.snz{color:var(--fd2);border-color:transparent;}
.sp-q .figfield{display:inline-flex;align-items:center;gap:4px;border:1px solid var(--fb2);border-radius:100px;padding:4px 6px 4px 14px;color:var(--fd);font-weight:600;}
.sp-q .figfield input{border:0;outline:0;background:transparent;font-family:inherit;font-size:var(--t-l);font-weight:600;color:var(--ft);width:110px;padding:5px;}
/* R316 — the coming-soon date step reuses the figure pill, and a date input is not a figure input:
   it renders its own picker glyph and a full dd/mm/yyyy, which 110px clips. Widened and stepped down
   one size so the three segments and the glyph all fit on the card without the pill growing taller
   than the buttons beside it. ⚠ THIS RULE IS OUTSIDE BUILD_STAMP (R265) — the stamp is sha256 of
   engine.js + the bundle only, so a CSS-only change leaves it untouched. The receipt that
   discriminates a CSS deploy is a served-bytes grep on /flow-os/os-full.css for this selector. */
.sp-q .figfield input[type="date"]{width:auto;min-width:154px;font-size:var(--t-m);padding:5px 2px 5px 0;}
/* R316 — THE QUESTION PROMPT, AS A CLASS. designdebt.test.js refused the coming-soon card's prompt
   as new inline styling and it was right to: the same three declarations are threaded inline through
   four other renderers on this page (near-name, under-offer, more-to-capture, and the old
   still-available), which is a look travelling through the code instead of living in a stylesheet.
   ⚠ ONLY THE NEW CARD ADOPTS IT HERE. Two of the four are the under-offer / deal-capture renderers,
   fenced out of R316, and a cosmetic edit inside a fenced road is still an edit inside a fenced
   road. THE DEBT IS THEREFORE WRITTEN DOWN RATHER THAN PAID: four inline copies remain, this class
   is what they should collapse into, and whoever next opens the deal road can do it in one pass. */
.sp-q .q-ask{margin-top:0;color:var(--ft);font-weight:var(--w-semi);}
.sp-q.done{display:flex;align-items:center;gap:13px;background:var(--fhl);}
.sp-q.done .tick{width:24px;height:24px;border-radius:var(--r-round);background:var(--acc-bright);color:var(--bone);display:flex;align-items:center;justify-content:center;font-size:var(--t-m);flex-shrink:0;}
.sp-q.done b{display:block;font-size:var(--t-l);color:var(--ft);}
.sp-q.done small{display:block;font-size:var(--t-s);color:var(--fd);}
.sp-q.done div{flex:1;}
.sp-q.done .undo{font-family:inherit;font-size:var(--t-m);font-weight:500;color:var(--acc-bright);background:none;border:0;cursor:pointer;}
.sp-clear{border:1.5px dashed var(--fb2);border-radius:var(--r-m);padding:24px;margin-top:14px;}
.sp-clear .big{font-family:var(--font-display);font-weight:600;font-style:normal;font-size:var(--t-xxl);color:var(--ft);font-variant-numeric:tabular-nums;}
.sp-clear .sub{font-size:var(--t-m);color:var(--fd);margin-top:6px;line-height:var(--lh-body);}

/* ── Check-ins · hover-to-reveal (ported from leasing-agent prototype) ── */
.sp-q .qh .hint{margin-left:auto;font-size:var(--t-s);color:var(--fd2);font-family:var(--font-mono);letter-spacing:var(--tr-s);}
@media(hover:hover){.sp-q .qh .hint::after{content:'hover';}}
@media(hover:none){.sp-q .qh .hint::after{content:'tap';}}
/* Smooth reveal — the body expands to its true height (grid-rows trick, no max-height
   jump), with a soft fade + drift, so the card breathes open instead of jolting. */
.sp-q.reveal:not(.done){cursor:pointer;transition:border-color .4s ease,box-shadow .4s ease,transform .4s cubic-bezier(.22,.61,.36,1);}
.sp-q.reveal .sp-q-body{display:grid;grid-template-rows:0fr;opacity:0;
  transition:grid-template-rows .5s cubic-bezier(.22,.61,.36,1),opacity .32s ease;}
.sp-q.reveal .sp-q-body > .sp-q-inner{min-height:0;overflow:hidden;transform:translateY(-4px);transition:transform .5s cubic-bezier(.22,.61,.36,1);}
.sp-q.reveal.open .sp-q-body{grid-template-rows:1fr;opacity:1;transition:grid-template-rows .5s cubic-bezier(.22,.61,.36,1),opacity .4s ease .1s;}
.sp-q.reveal.open .sp-q-body > .sp-q-inner{transform:translateY(0);}
@media(hover:hover){
  .sp-q.reveal:not(.done):hover{border-color:var(--fb2);box-shadow:0 12px 30px -20px color-mix(in srgb,var(--obsidian) 40%,transparent);transform:translateY(-1px);}
  .sp-q.reveal:not(.done):hover .sp-q-body{grid-template-rows:1fr;opacity:1;transition:grid-template-rows .5s cubic-bezier(.22,.61,.36,1),opacity .4s ease .1s;}
  .sp-q.reveal:not(.done):hover .sp-q-body > .sp-q-inner{transform:translateY(0);}
}
.sp-q .sp-q-div{height:1px;background:var(--fb);margin-top:14px;}

/* ── Diary · quick questions (human-knowledge gaps) ── */
.dq{margin-bottom:18px;background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);overflow:hidden;}
.dq-head{padding:14px 18px;background:var(--fhl);border-bottom:1px solid var(--fb);}
.dq-head .t{font-size:var(--t-l);font-weight:600;color:var(--ft);}
.dq-head .s{font-size:var(--t-m);color:var(--fd);margin-top:2px;}
.dq-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 18px;border-top:1px solid var(--fb);flex-wrap:wrap;}
.dq-row:first-of-type{border-top:0;}
.dq-row .q{font-size:var(--t-l);color:var(--fd);}
.dq-row .q b{font-weight:600;color:var(--ft);}
.dq-opts{display:flex;gap:8px;}
.dq-opt{font-family:inherit;font-size:var(--t-m);font-weight:500;color:var(--ft);background:transparent;border:1px solid var(--fb2);border-radius:100px;padding:7px 15px;cursor:pointer;transition:all .12s ease;}
.dq-opt:hover{border-color:var(--hover);background:color-mix(in srgb,var(--hover) 10%,transparent);}
.dq-opt.done{background:var(--acc);color:var(--bone);border-color:var(--acc);}

/* ── Fees · scope tabs + pipeline bar + inline pct ── */
.fee-scope{display:inline-grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:4px;background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-m);padding:4px;margin:2px 0 16px;}
.fee-scope button{min-width:150px;}
.fee-scope button{font-family:inherit;font-size:var(--t-m);font-weight:600;color:var(--fd);background:none;border:none;border-radius:var(--r-s);padding:7px 16px;cursor:pointer;display:flex;flex-direction:column;align-items:flex-start;line-height:var(--lh-tight);}
.fee-scope button .ssub{font-family:var(--font-mono);font-size:var(--t-xs);font-weight:500;color:var(--fd2);letter-spacing:var(--tr-s);}
.fee-scope button.on{background:var(--fs);color:var(--ft);box-shadow:0 1px 2px color-mix(in srgb,var(--obsidian) 6%,transparent);}
.fee-scope button.on .ssub{color:var(--acc-bright);}
.fee-bar{display:flex;height:14px;border-radius:var(--r-s);overflow:hidden;gap:2px;}
.fee-bar i{display:block;height:100%;min-width:3px;transition:width .7s cubic-bezier(.22,.61,.36,1);}
.fee-bar i.billed{background:var(--st-let,var(--green));}
.fee-bar i.offer{background:var(--st-under-offer);}
.fee-bar i.avail{background:var(--st-available);}
body[data-motion="Full"] .fee-bar i{transform-origin:left;animation:osGrowX .85s cubic-bezier(.22,.61,.36,1) backwards;}
.fee-rowpct{width:34px;border:0;border-bottom:1px solid var(--fb2);background:transparent;font-family:var(--font-mono);font-size:var(--t-s);text-align:right;color:var(--ft);outline:0;}

/* ── Account & settings cog (prototype; live injects its own from app.html) ── */
.os-cogwrap{position:relative;display:inline-flex;align-items:center;margin-left:12px;vertical-align:middle;}
.os-cog{width:26px;height:26px;border-radius:999px;background:var(--acc);color:#fff;border:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;font-size:var(--t-l);line-height:var(--lh-flat);padding:0;}
.os-cog:hover{filter:brightness(1.08);}
.os-cogveil{position:fixed;inset:0;z-index:100000;}
.os-setpanel{position:fixed;right:16px;top:calc(var(--topbar-h) + 6px);z-index:100001;width:280px;background:var(--fs2);border:1px solid var(--fb2);border-radius:var(--r-m);box-shadow:0 18px 50px rgba(0,0,0,.45);padding:6px;text-align:left;}
.os-setpanel .sp-acc{padding:12px 12px 8px;}
.os-setpanel .sp-acc .k{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--fd2);}
.os-setpanel .sp-acc .em{font-weight:600;color:var(--ft);margin-top:4px;word-break:break-all;font-size:var(--t-m);}
.os-setpanel .sp-acc .sub{color:var(--fd);margin-top:2px;font-size:var(--t-m);}
.os-setpanel .div{height:1px;background:var(--fb);margin:4px 8px;}
.os-setpanel .row{display:block;width:100%;text-align:left;background:none;border:0;padding:9px 12px;border-radius:var(--r-s);cursor:pointer;font:inherit;}
.os-setpanel .row:hover{background:color-mix(in srgb,var(--hover) 8%,transparent);}
.os-setpanel .row b{display:block;font-size:var(--t-m);font-weight:600;color:var(--ft);}
.os-setpanel .row small{display:block;font-size:var(--t-s);color:var(--fd2);margin-top:1px;}
.os-setpanel .row.so b{color:var(--acc-bright);}

/* ── Leases · dashboard (key dates + status donut, ported & restyled to Flow) ── */
.lz-mid{display:grid;grid-template-columns:1.7fr 1fr;gap:14px;margin-top:18px;}
@media(max-width:820px){.lz-mid{grid-template-columns:1fr;}}
.lz-panel{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:18px 20px;}
.lz-ph{font-size:var(--t-l);font-weight:600;color:var(--ft);margin-bottom:4px;}
.lz-ph .dim{color:var(--fd2);font-weight:400;}
.lz-tl{display:flex;align-items:center;gap:14px;padding:12px 0;border-top:1px solid var(--fb);cursor:pointer;}
.lz-tl:first-of-type{border-top:0;}
.lz-tl:hover .lz-info b{color:var(--hover);}
.lz-day{display:flex;flex-direction:column;align-items:center;justify-content:center;width:46px;height:46px;border-radius:var(--r-s);flex-shrink:0;background:var(--fhl);}
.lz-day b{font-size:var(--t-l);font-weight:700;line-height:var(--lh-flat);color:var(--ft);}
.lz-day small{font-size:var(--t-xs);text-transform:uppercase;letter-spacing:var(--tr-s);color:var(--fd2);margin-top:2px;}
.lz-day.warm{background:color-mix(in srgb,var(--adverse) 14%,transparent);}.lz-day.warm b{color:var(--adverse-ink);}
.lz-day.amber{background:color-mix(in srgb,var(--warm) 16%,transparent);}.lz-day.amber b{color:var(--attention-ink);}
.lz-day.teal{background:color-mix(in srgb,var(--acc-bright) 12%,transparent);}.lz-day.teal b{color:var(--acc);}
.lz-info{flex:1;min-width:0;}
.lz-info b{display:block;font-size:var(--t-l);color:var(--ft);}
.lz-info small{display:block;font-size:var(--t-s);color:var(--fd);}
.lz-donutwrap{display:flex;align-items:center;gap:24px;margin-top:16px;padding:4px 0;}
.lz-donut{position:relative;width:158px;height:158px;border-radius:var(--r-round);flex-shrink:0;}
.lz-donut::after{content:'';position:absolute;inset:26px;border-radius:var(--r-round);background:var(--fs);}
body[data-motion="Full"] .lz-donut{animation:lzPop .8s cubic-bezier(.22,.61,.36,1) backwards;}
body[data-motion="Full"] .lz-donut-c{animation:riseIn .5s ease .25s backwards;}
@keyframes lzPop{from{opacity:0;transform:scale(.86) rotate(-12deg);}to{opacity:1;transform:none;}}
.lz-donut-c{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:1;}
.lz-donut-c b{font-size:var(--t-xxl);font-weight:700;color:var(--ft);line-height:var(--lh-flat);}
.lz-donut-c small{font-size:var(--t-xs);text-transform:uppercase;letter-spacing:var(--tr-s);color:var(--fd2);margin-top:4px;}
.lz-legend{flex:1;}
.lz-legend > div{display:flex;align-items:center;gap:9px;font-size:var(--t-m);color:var(--fd);padding:7px 0;}
.lz-legend b{margin-left:auto;color:var(--ft);font-size:var(--t-l);}
.lz-dot{width:9px;height:9px;border-radius:var(--r-round);flex-shrink:0;}
.lz-allh{display:flex;align-items:center;gap:14px;margin:22px 0 4px;font-size:var(--t-l);font-weight:600;color:var(--ft);}
.lz-allh .dim{color:var(--fd2);font-weight:400;}
.lz-allh .sp-search{margin-left:auto;max-width:280px;flex:0 1 280px;min-width:180px;}

/* ── Leases · clean table (copied from leasing-agent dashboard) ── */
.lz-table{width:100%;border-collapse:collapse;}
.lz-table thead th{font-size:var(--t-s);font-weight:600;letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);text-align:left;padding:12px 16px;border-bottom:1px solid var(--fb);white-space:nowrap;}
.lz-table thead th:first-child{padding-left:4px;}
.lz-table thead th.r{text-align:right;}
.lz-table tbody tr{border-bottom:1px solid var(--fb);transition:background .1s;cursor:pointer;}
.lz-table tbody tr:last-child{border-bottom:none;}
.lz-table tbody tr:hover{background:var(--fhl);}
.lz-table td{padding:14px 16px;font-size:var(--t-m);color:var(--fd);vertical-align:middle;}
.lz-table td:first-child{padding-left:4px;color:var(--ft);font-weight:600;}
.lz-table td.r{text-align:right;}
.lz-table .date-cell{white-space:nowrap;font-family:var(--font-mono);font-size:var(--t-m);color:var(--fd);}
.lz-table .date-cell.soon{color:var(--attention-ink);font-weight:500;}
.lz-table .date-cell.urgent{color:var(--adverse-ink);font-weight:600;}
.lz-table .rent-cell{font-family:var(--font-mono);font-size:var(--t-m);color:var(--ft);font-weight:500;text-align:right;}
.lz-status{display:inline-flex;align-items:center;gap:5px;font-size:var(--t-s);font-weight:600;letter-spacing:var(--tr-s);padding:3px 9px;border-radius:100px;white-space:nowrap;}
.lz-status::before{content:'';width:5px;height:5px;border-radius:var(--r-round);background:currentColor;}
.lz-status.active{background:color-mix(in srgb,var(--acc-bright) 13%,transparent);color:var(--acc-bright);}
:is(body.flow-dawn,body.flow-studio) .lz-status.active{color:var(--acc);}
.lz-status.expiring{background:color-mix(in srgb,var(--warm) 14%,transparent);color:var(--attention-ink);}
:is(body.flow-dawn,body.flow-studio) .lz-status.expiring{color:var(--attention-ink);}
.lz-status.expired{background:color-mix(in srgb,var(--adverse) 14%,transparent);color:var(--adverse-ink);}
.lz-view{display:inline-flex;align-items:center;gap:5px;font-family:inherit;font-size:var(--t-m);font-weight:500;color:var(--acc-bright);background:color-mix(in srgb,var(--acc-bright) 10%,transparent);border:1px solid color-mix(in srgb,var(--acc-bright) 20%,transparent);border-radius:100px;padding:5px 11px;cursor:pointer;white-space:nowrap;}
.lz-view:hover{background:color-mix(in srgb,var(--hover) 18%,transparent);}

.sp-lane-empty{font-size:var(--t-m);color:var(--fd2);text-align:center;padding:14px 0;}

/* ── Space back button (cross-space navigation) ── */
.sp-back{display:inline-flex;align-items:center;gap:5px;font-family:inherit;font-size:var(--t-s);font-weight:600;color:var(--acc-bright);background:var(--fhl);border:1px solid var(--fb);border-radius:100px;padding:5px 12px;cursor:pointer;margin-bottom:10px;}
.sp-back:hover{border-color:var(--hover);}

/* ── Clients (client management hub) ── */
/* ⛔ THE APP'S OWN .pbx-sort IS DELETED (20 Aug, batch 4) — one source per control. It was fully
   superseded on 16 Aug when the draft gained its own `.sort` rule: the generated design block is
   spliced at the END of this sheet, so at equal specificity the draft's rule wins every property
   this one set — family and size through its `font:` shorthand, plus colour, background, border,
   radius, padding, outline and cursor. Measured, declaration by declaration, before deleting: there
   is no property here the later rule leaves unset, so nothing on screen moves. Two rules for one
   control is the `.fe` shape, and this is the second of the pair the 16 Aug note named. */
.cl-props{display:flex;flex-wrap:wrap;gap:6px;margin-top:7px;}
.cl-prop{font-size:var(--t-s);color:var(--fd);background:var(--fhl);border:1px solid var(--fb);border-radius:100px;padding:3px 10px;cursor:pointer;}
.cl-prop:hover{border-color:var(--hover);color:var(--ft);}
.cl-flag{display:inline-flex;align-items:center;gap:5px;font-size:var(--t-s);font-weight:600;line-height:var(--lh-ui);color:var(--adverse-ink);background:color-mix(in srgb,var(--adverse) 12%,transparent);border:0;border-radius:100px;padding:5px 11px;white-space:nowrap;}
.cl-flagbox{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px;align-items:center;}
.cl-actions{display:flex;flex-wrap:wrap;gap:8px;margin:16px 0 4px;}
.cl-mini{width:100%;border-collapse:collapse;margin-top:4px;}
.cl-mini td{padding:10px 0;border-top:1px solid var(--fb);font-size:var(--t-m);color:var(--fd);vertical-align:middle;}
.cl-mini tr:first-child td{border-top:0;}
.cl-mini td.r{text-align:right;font-variant-numeric:tabular-nums;color:var(--ft);font-weight:600;}
.cl-cmp{margin-bottom:13px;}
.cl-cmp-h{display:flex;justify-content:space-between;gap:10px;font-size:var(--t-m);color:var(--ft);font-weight:600;margin-bottom:5px;}
.cl-cmp-h .dim{color:var(--fd2);font-weight:400;font-family:var(--font-mono);font-size:var(--t-s);white-space:nowrap;}
.cl-cmp .sp-hbar{margin-bottom:3px;}
.cl-link{color:var(--acc-bright);cursor:pointer;border-bottom:1px solid color-mix(in srgb,var(--acc-bright) 35%,transparent);}
.cl-link:hover{border-bottom-color:var(--hover);}
.cl-prolabel{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--fd2);margin-bottom:6px;}
.cl-msel{display:flex;flex-wrap:wrap;gap:6px;flex:1;}
.cl-mchip{font-family:inherit;font-size:var(--t-s);color:var(--ft);background:var(--fhl);border:1px solid var(--fb2);border-radius:100px;padding:5px 11px;cursor:pointer;}
.cl-mchip.on{background:var(--acc);color:var(--bone);border-color:var(--acc);}
.cl-flag.clickable{cursor:pointer;font-family:inherit;}
.cl-flag.clickable:hover{filter:brightness(1.06);}
.cl-corr{display:flex;gap:12px;padding:9px 0;border-top:1px solid var(--fb);font-size:var(--t-m);line-height:var(--lh-body);}
.cl-corr:first-of-type{border-top:0;}
.cl-corr .cd{font-family:var(--font-mono);font-size:var(--t-s);color:var(--fd2);white-space:nowrap;min-width:54px;padding-top:1px;}
.cl-corr .cx{color:var(--ft);}
/* ── Calculators ── */
.calc-card{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:18px 20px;margin-top:14px;}
.calc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px 18px;}
@media(max-width:720px){.calc-grid{grid-template-columns:1fr 1fr;}}
.calc-fld{display:flex;flex-direction:column;gap:5px;}
.calc-fld label{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);}
.calc-inp{display:flex;align-items:center;gap:6px;background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-s);padding:8px 11px;}
.calc-inp:focus-within{border-color:var(--hover);}
.calc-inp .pre{color:var(--fd2);font-size:var(--t-m);}
.calc-inp input{flex:1;min-width:0;border:0;background:transparent;outline:0;font-family:inherit;font-size:var(--t-m);color:var(--ft);font-variant-numeric:tabular-nums;}
.calc-inp .unit{color:var(--fd2);font-size:var(--t-s);font-family:var(--font-mono);white-space:nowrap;}
.calc-res{margin-top:2px;}
.calc-row{display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-top:1px solid var(--fb);font-size:var(--t-m);color:var(--fd);}
.calc-row:first-child{border-top:0;}
.calc-row b{color:var(--ft);font-variant-numeric:tabular-nums;font-weight:600;}
.calc-tbl{width:100%;border-collapse:collapse;}
.calc-tbl th{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--fd2);text-align:right;padding:6px 10px;border-bottom:1px solid var(--fb);}
.calc-tbl th:first-child{text-align:left;}
.calc-tbl td{padding:9px 10px;font-size:var(--t-m);color:var(--fd);text-align:right;border-bottom:1px solid var(--fb);font-variant-numeric:tabular-nums;}
.calc-tbl tr:last-child td{border-bottom:0;color:var(--ft);font-weight:600;}
.calc-tbl td:first-child{text-align:left;color:var(--ft);}
.calc-top{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px;margin-bottom:4px;}
.calc-work{display:flex;gap:8px;}
.calc-lines{margin-top:14px;}
.cvl-head{font-size:var(--t-m);color:var(--fd);margin-bottom:8px;}
.cvl-head .dim{color:var(--fd2);}
.cvl-empty{font-size:var(--t-m);color:var(--fd2);padding:2px 0 8px;}
.cvl-line{display:flex;align-items:center;gap:12px;padding:8px 0;border-top:1px solid var(--fb);font-size:var(--t-m);}
.cvl-line .cvl-nm{font-weight:600;color:var(--ft);min-width:120px;}
.cvl-line .cvl-md{color:var(--fd2);font-size:var(--t-s);}
.cvl-line .cvl-de{margin-left:auto;color:var(--ft);font-variant-numeric:tabular-nums;}
.cvl-x{border:0;background:none;color:var(--fd2);cursor:pointer;font-size:var(--t-xl);line-height:var(--lh-flat);padding:0 2px;}
.cvl-x:hover{color:var(--adverse-ink);}
.cvl-add{display:flex;align-items:center;gap:8px;margin-top:12px;flex-wrap:wrap;}
.cvl-add .cvl-in{flex:1;min-width:140px;}
.cvl-add .cvl-in,.cvl-add .cvl-sel{padding:8px 10px;border:1px solid var(--fb2);border-radius:var(--r-s);background:var(--fs2);color:var(--ft);font:inherit;font-size:var(--t-m);}
.cvl-add .cvl-amt{width:108px;}
.calc-res .calc-row.total{border-top:1px solid var(--fb2);margin-top:4px;padding-top:9px;font-weight:700;}
.calc-res .calc-row.total b{color:var(--ft);}
/* Save-to-property bar on the calculators */
.calc-savebar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:16px;padding:13px 15px;border:1px solid var(--fb);border-radius:var(--r-m);background:var(--fhl);}
.calc-savebar .csb-lab{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd);}
.calc-savebar .cvl-in,.calc-savebar .cvl-sel{padding:8px 10px;border:1px solid var(--fb2);border-radius:var(--r-s);background:var(--fs2);color:var(--ft);font:inherit;font-size:var(--t-m);}
.calc-savebar .csb-sel{min-width:190px;}
.calc-savebar .csb-note{flex:1;min-width:150px;}
.calc-savebar .sp-btn[disabled]{opacity:.45;cursor:not-allowed;}
/* Saved calculations on the property screen */
.pp-save{border:1px solid var(--fb);border-radius:var(--r-s);margin-bottom:8px;overflow:hidden;}
.pp-save-h{display:flex;align-items:center;gap:10px;padding:10px 12px;cursor:pointer;}
.pp-save-h:hover{background:var(--fhl);}
.pp-save-t{flex:1;min-width:0;font-size:var(--t-m);color:var(--ft);}
.pp-save-t small{color:var(--fd);}
.pp-save-v{font-family:var(--font-mono);font-size:var(--t-m);font-weight:600;color:var(--acc-bright);white-space:nowrap;}
.pp-save-d{font-family:var(--font-mono);font-size:var(--t-xs);color:var(--fd2);white-space:nowrap;}
.pp-save-body{padding:4px 12px 10px;border-top:1px solid var(--fb);background:var(--fhl);}
.pp-save-body .calc-row{padding:7px 0;font-size:var(--t-m);}
/* Two-way matching */
/* — visual layer: match matrix + demand-vs-supply by area — */
.mt-vizrow{display:grid;grid-template-columns:1.6fr 1fr;gap:14px;margin:14px 0 8px;align-items:stretch;}
@media(max-width:880px){.mt-vizrow{grid-template-columns:1fr;}}
.mt-panel{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:16px 18px;}
.mt-panel .vt{display:flex;justify-content:space-between;align-items:baseline;gap:12px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd);margin-bottom:6px;}
.mt-panel .vt .dim{letter-spacing:var(--tr-s);color:var(--fd2);text-transform:none;}
.mt-mx{display:grid;gap:5px 6px;align-items:center;margin-top:10px;}
.mt-mx .mx-col{font-family:var(--font-mono);font-size:var(--t-xs);color:var(--fd2);text-align:center;letter-spacing:var(--tr-s);cursor:default;}
.mt-mx .mx-row{font-size:var(--t-s);color:var(--ft);font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;padding-right:6px;}
.mt-mx .mx-row:hover{color:var(--hover);}
.mt-mx .mx-cell{height:26px;border-radius:var(--r-s);display:flex;align-items:center;justify-content:center;font-size:var(--t-s);font-weight:700;background:var(--fhl);color:var(--fd2);}
.mt-mx .mx-cell.strong{background:color-mix(in srgb,var(--green) 18%,transparent);color:var(--st-let-mark);cursor:pointer;}
:is(body.flow-dawn,body.flow-studio) .mt-mx .mx-cell.strong{color:var(--green);background:color-mix(in srgb,var(--green) 13%,transparent);}
.mt-mx .mx-cell.near{background:color-mix(in srgb,var(--warm) 15%,transparent);color:var(--attention-ink);cursor:pointer;}
:is(body.flow-dawn,body.flow-studio) .mt-mx .mx-cell.near{color:var(--attention-ink);}
.mt-mx .mx-cell.none::after{content:'·';opacity:.5;}
body[data-motion="Full"] .mt-mx .mx-cell{animation:riseIn .45s ease backwards;}
.mx-l{width:12px;height:12px;border-radius:var(--r-xs);display:inline-block;background:var(--fhl);border:1px solid var(--fb);font-style:normal;}
.mx-l.strong{background:color-mix(in srgb,var(--green) 35%,transparent);border-color:transparent;}
.mx-l.near{background:color-mix(in srgb,var(--warm) 30%,transparent);border-color:transparent;}
.mt-area{display:grid;grid-template-columns:82px 1fr;gap:4px 10px;padding:9px 0;border-top:1px solid var(--fb);align-items:center;}
.mt-area:first-of-type{border-top:0;}
.mt-area .an{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--fd);}
.mt-dots{display:flex;gap:3px;align-items:center;flex-wrap:wrap;}
.mt-dots i{width:8px;height:8px;border-radius:var(--r-pill) var(--r-pill) 0 0;background:var(--mark);font-style:normal;}
.mt-dots small{margin-left:6px;font-size:var(--t-s);color:var(--fd);}
.mt-supply{grid-column:2;display:flex;align-items:center;gap:8px;}
.mt-supply .sp-hbar{flex:1;height:8px;}
.mt-supply .sv{font-family:var(--font-mono);font-size:var(--t-xs);color:var(--fd);white-space:nowrap;}
.mt-supply .sv.none{color:var(--adverse-ink);}
.mt-card{border:1px solid var(--fb);border-radius:var(--r-m);padding:14px 16px;margin-bottom:12px;}
.mt-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;}
.mt-h-main b{font-size:var(--t-l);font-weight:600;color:var(--ft);}
.mt-h-main small{display:block;font-size:var(--t-m);color:var(--fd);margin-top:2px;}
.mt-count{font-size:var(--t-m);color:var(--fd);margin:11px 0 6px;padding-top:10px;border-top:1px solid var(--fb);}
.mt-count b{color:var(--ft);font-weight:700;}
.mt-count .dim{color:var(--fd2);}
.mt-strong{color:var(--st-let-mark);font-weight:600;}
:is(body.flow-dawn,body.flow-studio) .mt-strong{color:var(--green);}
.mt-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 10px;border-radius:var(--r-s);cursor:pointer;transition:background .12s;}
.mt-row:hover{background:var(--fhl);}
.mt-row.strong{background:color-mix(in srgb,var(--green) 8%,transparent);}
.mt-r-main{min-width:0;}
.mt-r-nm{font-size:var(--t-m);font-weight:600;color:var(--ft);display:flex;align-items:center;gap:7px;}
.mt-r-main small{display:block;font-size:var(--t-s);color:var(--fd);margin-top:1px;}
.mt-dual{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--acc-bright);background:color-mix(in srgb,var(--acc-bright) 14%,transparent);padding:2px 6px;border-radius:var(--r-xs);}
.mt-fits{display:flex;gap:5px;flex-shrink:0;}
.mt-fit{font-family:var(--font-mono);font-size:var(--t-xs);padding:3px 7px;border-radius:var(--r-xs);white-space:nowrap;}
.mt-fit.ok{color:var(--st-let-ink);background:color-mix(in srgb,var(--green) 14%,transparent);}
:is(body.flow-dawn,body.flow-studio) .mt-fit.ok{color:var(--green);}
.mt-fit.near{color:var(--attention-ink);background:color-mix(in srgb,var(--warm) 16%,transparent);}
.mt-fit.no{color:var(--fd2);background:var(--fhl);}
/* "X internal matches" badge on a tenant requirement */
.tn-match{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:14px;padding:11px 14px;border:1px solid var(--fb);border-radius:var(--r-s);background:var(--fhl);cursor:pointer;font-size:var(--t-m);color:var(--fd);transition:border-color .12s;}
.tn-match:hover{border-color:var(--fb2);}
.tn-match b{color:var(--ft);font-weight:700;}
.tn-match .dim{color:var(--fd2);}
.tn-match-strong{color:var(--st-let-mark);font-weight:600;}
:is(body.flow-dawn,body.flow-studio) .tn-match-strong{color:var(--green);}
.tn-match-go{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--acc-bright);white-space:nowrap;flex-shrink:0;}
.ss-bar{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--fd2);margin-bottom:9px;}
.ss-head{display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap;}
.ss-head .ss-bar{margin-bottom:0;}
.ss-exp{display:flex;gap:7px;margin-bottom:9px;}
.ss-exp .sp-btn{padding:5px 11px;font-size:var(--t-s);}
.ss{font-family:var(--font-mono);font-size:var(--t-s);border:1px solid var(--fb2);border-radius:var(--r-s);overflow:hidden;min-width:460px;}
.ss-row{display:grid;border-top:1px solid var(--fb);}
.ss-row:first-child{border-top:0;}
.ss-ab{grid-template-columns:30px 1fr 170px;}
.ss-cf{grid-template-columns:30px 86px 1fr 1fr 1fr;}
.ss-cn{text-align:center;padding:6px 0;color:var(--fd2);font-size:var(--t-xs);background:var(--fhl);border-right:1px solid var(--fb);}
.ss-c{padding:6px 10px;color:var(--ft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-right:1px solid var(--fb);}
.ss-c:last-child{border-right:0;}
.ss-col{text-align:center;color:var(--fd2);font-size:var(--t-xs);}
.ss-lab{color:var(--fd);}
.ss-vc{text-align:right;}
.ss-strip .ss-cn,.ss-h{background:var(--fhl);}
.ss-h{color:var(--ft);font-weight:600;}
.ss-res{background:color-mix(in srgb,var(--acc-bright) 11%,transparent);color:var(--ft);font-weight:700;}
.ss-fx{color:var(--acc-bright);}

/* ── Lease abstract — full document view ── */
.la-doc{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:26px 30px 22px;margin-top:6px;}
.la-dochead{display:flex;justify-content:space-between;align-items:flex-start;padding-bottom:16px;border-bottom:1px solid var(--fb);}
.la-brand{display:inline-flex;align-items:center;gap:8px;font-size:var(--t-xl);font-weight:600;letter-spacing:var(--tr-tight);color:var(--ft);}
/* Wordmark V3 "The Seam" — UI/nav row */
.la-brand .wmA{font-weight:700;letter-spacing:var(--tr-tight);}
.la-brand .wmB{font-weight:400;letter-spacing:var(--tr-s);margin-left:0.5px;}
.la-brand svg{width:20px;height:20px;}
.la-brand svg path{stroke:var(--ft);stroke-width:6;fill:none;stroke-linecap:round;}
.la-docref{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd2);text-align:right;line-height:var(--lh-prose);}
.la-docref b{font-size:var(--t-xs);letter-spacing:var(--tr-s);text-transform:none;color:var(--fd);font-weight:600;}
.la-headright{display:flex;align-items:center;gap:16px;}
.la-hero{margin:20px 0 18px;}
.la-hero .eyebrow{display:inline-flex;align-items:center;gap:7px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--acc-bright);font-weight:600;}
.la-hero .eyebrow::before{content:'';width:5px;height:5px;border-radius:var(--r-round);background:var(--ground);}
.la-hero h2{font-size:var(--t-xxl);font-weight:600;letter-spacing:var(--tr-tight);line-height:var(--lh-flat);color:var(--ft);margin-top:7px;}
.la-hero h2 .accent{font-family:var(--font-serif);font-style:italic;font-weight:400;}
.la-hero .meta{font-size:var(--t-m);color:var(--fd);margin-top:5px;}
.la-glance{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-bottom:20px;padding:16px 18px;background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-m);}
.la-glance .g-item{padding:2px 8px;border-left:1px solid var(--fb);}
.la-glance .g-item:first-child{border-left:0;}
.la-glance .k{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);margin-bottom:6px;}
.la-glance .v{font-family:var(--font-mono);font-size:var(--t-xl);font-weight:600;letter-spacing:var(--tr-tight);color:var(--ft);line-height:var(--lh-flat);}
.la-glance .v.sm{font-size:var(--t-m);}
.la-glance .sub{font-size:var(--t-xs);color:var(--fd);margin-top:5px;line-height:var(--lh-ui);}
.la-glance .sub.warn{color:var(--attention-ink);}
body.flow-dusk .la-glance .sub.warn{color:var(--attention-ink);}
.la-parties{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:20px;}
.la-party{padding:14px 16px;background:var(--fs2);border:1px solid var(--fb);border-radius:var(--r-s);}
.la-party .role{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--acc-bright);font-weight:600;margin-bottom:6px;}
.la-party .name{font-size:var(--t-l);font-weight:600;color:var(--ft);letter-spacing:var(--tr-none);}
.la-party .reg{font-size:var(--t-s);color:var(--fd);margin-top:3px;}
.la-party .addr{font-size:var(--t-s);color:var(--fd);margin-top:7px;padding-top:7px;border-top:1px solid var(--fb);line-height:var(--lh-ui);}
.la-sec{margin-bottom:18px;}
.la-seclabel{display:flex;justify-content:space-between;align-items:flex-end;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--fd2);font-weight:600;padding-bottom:9px;margin-bottom:12px;border-bottom:1px solid var(--fb);}
.la-seclabel .meta{letter-spacing:var(--tr-s);text-transform:none;color:var(--fd);font-weight:500;}
.la-sumcard{background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-s);padding:16px 18px;}
.la-sumcard p{font-size:var(--t-m);line-height:var(--lh-body);color:var(--ft);}
.la-legend{display:flex;flex-wrap:wrap;align-items:center;gap:14px;font-size:var(--t-xs);color:var(--fd);background:var(--fhl);border-radius:var(--r-s);padding:8px 12px;margin-bottom:16px;}
.la-legend .lab{font-weight:600;color:var(--fd);}
.la-legend > span{display:inline-flex;align-items:center;gap:5px;}
.la-legend .vf{margin-left:auto;font-style:italic;}
.la-legend .chip{font-family:var(--font-mono);font-size:var(--t-xxs);font-weight:600;padding:1px 7px;border-radius:100px;}
.la-conf.hi,.la-legend .chip.hi{color:var(--mark);background:color-mix(in srgb,var(--mark) 14%,transparent);}
.la-conf.mid,.la-legend .chip.mid{color:var(--attention-ink);background:color-mix(in srgb,var(--warm) 16%,transparent);}
body.flow-dusk .la-conf.mid,body.flow-dusk .la-legend .chip.mid{color:var(--attention-ink);}
.la-conf.low,.la-legend .chip.low{color:var(--adverse-ink);background:color-mix(in srgb,var(--adverse) 14%,transparent);}
.la-fields{display:grid;grid-template-columns:1fr 1fr;gap:0 28px;}
.la-f{padding:11px 0;border-bottom:1px solid var(--fb);}
.la-fk{display:flex;justify-content:space-between;align-items:center;gap:8px;font-size:var(--t-xs);font-weight:600;color:var(--fd2);letter-spacing:var(--tr-s);}
.la-conf{font-family:var(--font-mono);font-size:var(--t-xxs);font-weight:600;padding:1px 6px;border-radius:100px;}
.la-fv{font-size:var(--t-m);font-weight:500;color:var(--ft);margin-top:4px;line-height:var(--lh-ui);}
.la-fn{font-size:var(--t-xs);color:var(--fd);font-style:italic;margin-top:2px;line-height:var(--lh-ui);}
.la-anom{display:grid;grid-template-columns:auto 1fr auto;gap:13px;align-items:start;padding:13px 15px;background:var(--fs2);border:1px solid color-mix(in srgb,var(--warm) 22%,transparent);border-left:3px solid var(--warm);border-radius:var(--r-s);margin-bottom:9px;}
.la-anom .ico{width:20px;height:20px;border-radius:var(--r-xs);background:color-mix(in srgb,var(--warm) 16%,transparent);color:var(--attention-ink);display:flex;align-items:center;justify-content:center;font-family:var(--font-mono);font-weight:700;font-size:var(--t-s);flex-shrink:0;}
.la-anom .lab{font-size:var(--t-s);font-weight:600;color:var(--ft);margin-bottom:3px;}
.la-anom .det{font-size:var(--t-s);color:var(--fd);line-height:var(--lh-body);}
.la-anom .ref{font-family:var(--font-mono);font-size:var(--t-xs);color:var(--fd2);white-space:nowrap;text-align:right;}
.la-disc{background:var(--fhl);border-radius:var(--r-s);padding:14px 16px;font-size:var(--t-s);line-height:var(--lh-body);color:var(--fd);}
.la-disc b{color:var(--ft);font-weight:600;}
.la-docfoot{display:flex;align-items:center;gap:14px;margin-top:18px;padding-top:14px;border-top:1px solid var(--fb);font-size:var(--t-s);color:var(--fd2);}
.la-docfoot .sp-btn{margin-left:auto;}
@media(max-width:680px){.la-glance{grid-template-columns:1fr 1fr;}.la-parties,.la-fields{grid-template-columns:1fr;}}

/* ── Tenants (acquisition) ── */
.tn-fb{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;}
.tn-fitrow{display:flex;flex-wrap:wrap;gap:6px;margin-top:7px;}
.tn-fitpill{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);padding:2px 8px;border-radius:100px;}
.tn-fitpill.ok{color:var(--acc-bright);background:color-mix(in srgb,var(--acc-bright) 12%,transparent);}
:is(body.flow-dawn,body.flow-studio) .tn-fitpill.ok{color:var(--acc);}
.tn-fitpill.no{color:var(--adverse-ink);background:color-mix(in srgb,var(--adverse) 12%,transparent);}
.tn-planrow{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px;}
.tn-pf{display:flex;flex-direction:column;gap:3px;}
.tn-pf label{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);}
.tn-pf input{font-family:inherit;font-size:var(--t-m);color:var(--ft);background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-s);padding:6px 10px;outline:none;}
.tn-pf input:focus{border-color:var(--hover);}
.tn-itin{margin-top:14px;}
.tn-stop{display:flex;gap:13px;align-items:flex-start;}
.tn-stop .tt{font-family:var(--font-mono);font-size:var(--t-m);font-weight:600;color:var(--acc-bright);min-width:46px;padding-top:1px;}
.tn-stop .tb b{display:block;font-size:var(--t-m);color:var(--ft);}
.tn-stop .tb small{display:block;font-size:var(--t-s);color:var(--fd);}
.tn-leg{display:flex;align-items:center;gap:8px;margin:4px 0;padding-left:59px;font-size:var(--t-s);color:var(--fd2);font-family:var(--font-mono);}
.tn-leg .ln{width:14px;height:1px;background:var(--fb2);}
.tn-end{margin-top:12px;font-size:var(--t-m);font-weight:600;color:var(--acc);background:color-mix(in srgb,var(--acc-bright) 10%,transparent);border-radius:var(--r-s);padding:9px 13px;}
:is(body.flow-dawn,body.flow-studio) .tn-end{color:var(--acc);}
.tn-end.over{color:var(--adverse-ink);background:color-mix(in srgb,var(--adverse) 12%,transparent);}
.cl-twocol{display:grid;grid-template-columns:1.7fr 1fr;gap:18px;margin-top:8px;align-items:start;}
@media(max-width:860px){.cl-twocol{grid-template-columns:1fr;}}
.cl-twocol .sp-viz{margin-top:0;}
.cl-twocol .sp-toolbar{padding-top:0;}
.cl-opp{display:flex;align-items:center;gap:10px;padding:9px 0;border-top:1px solid var(--fb);cursor:pointer;}
.cl-opp:first-of-type{border-top:0;}
.cl-opp:hover b{color:var(--hover);}
.cl-opp .oi{width:6px;height:6px;border-radius:var(--r-round);background:var(--acc-bright);flex-shrink:0;}
.cl-opp .om{flex:1;min-width:0;}
.cl-opp .om b{display:block;font-size:var(--t-m);font-weight:500;color:var(--ft);line-height:var(--lh-ui);}
.cl-opp .om small{display:block;font-size:var(--t-s);color:var(--fd2);}

/* ── Fees · ±0.5% steppers ── */
.fee-stepper{display:inline-flex;align-items:center;gap:4px;}
.fee-step{width:18px;height:18px;border-radius:var(--r-xs);border:1px solid var(--fb2);background:transparent;color:var(--fd);font-size:var(--t-m);line-height:var(--lh-flat);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;font-family:inherit;}
.fee-step:hover{border-color:var(--hover);color:var(--ft);}
.fee-feewrap{display:inline-flex;align-items:baseline;justify-content:flex-end;}
.fee-feeinput{width:64px;border:0;border-bottom:1px dashed var(--fb2);background:transparent;font-family:inherit;font-size:var(--t-l);font-weight:600;color:var(--ft);text-align:right;outline:0;padding:1px 2px;}
.fee-feeinput:hover{border-bottom-color:var(--hover);}
.fee-feeinput:focus{border-bottom-style:solid;border-bottom-color:var(--hover);}
.fee-revert{display:block;margin-top:3px;font-size:var(--t-xs);color:var(--acc-bright);background:none;border:0;padding:0;cursor:pointer;font-family:inherit;}
.fee-revert:hover{text-decoration:underline;}

/* ── Team · totals card (copied from leasing-agent prototype) ── */
.tm-totals{margin-top:16px;background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:20px 24px;}
.tm-totals .tsum{font-size:var(--t-l);line-height:var(--lh-body);color:var(--ft);padding-bottom:16px;margin-bottom:18px;border-bottom:1px solid var(--fb);}
.tm-tgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;}
.tm-ttot{border-left:1px solid var(--fb);padding-left:22px;}
.tm-ttot:first-child{border-left:0;padding-left:0;}
.tm-ttot .tv{font-size:1.7rem;font-weight:600;letter-spacing:var(--tr-tight);line-height:var(--lh-flat);color:var(--ft);}
.tm-ttot .tl{font-size:var(--t-m);color:var(--fd);margin-top:7px;}
.tm-ttot .td{font-size:var(--t-m);color:var(--acc-bright);font-weight:500;margin-top:5px;}
@media(max-width:640px){.tm-tgrid{grid-template-columns:1fr;}.tm-ttot{border-left:0;padding-left:0;}}

/* ── Team · restricted-visibility note ── */
.tm-locked{display:flex;align-items:center;gap:13px;background:var(--fs);border:1px solid var(--fb);border-left:3px solid var(--acc);border-radius:var(--r-m);padding:13px 18px;margin-top:14px;}
.tm-locked .ic{width:30px;height:30px;border-radius:var(--r-s);background:color-mix(in srgb,var(--acc-bright) 12%,transparent);display:flex;align-items:center;justify-content:center;flex-shrink:0;}
.tm-locked .ic svg{width:15px;height:15px;stroke:var(--acc-bright);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
.tm-locked .tx{font-size:var(--t-m);color:var(--fd);line-height:var(--lh-ui);}
.tm-locked .tx b{color:var(--ft);}
.tm-locked .tx .soon{color:var(--fd2);}
.tm-locked .dv{margin-left:auto;flex-shrink:0;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--acc-bright);border:1px solid color-mix(in srgb,var(--acc-bright) 40%,transparent);border-radius:100px;padding:4px 11px;white-space:nowrap;}
/* discreet padlocked badge in the space header, in line with the kicker */
.sp-dirbadge{display:inline-flex;align-items:center;gap:7px;flex-shrink:0;cursor:default;white-space:nowrap;
  font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--acc-bright);
  border:1px solid color-mix(in srgb,var(--acc-bright) 40%,transparent);border-radius:100px;padding:5px 12px;}
.sp-dirbadge svg{width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;}

/* ── Team · control centre (mission-control dashboard) ── */
.tm-kpis{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-top:16px;}
@media(max-width:1080px){.tm-kpis{grid-template-columns:repeat(3,1fr);}}
@media(max-width:640px){.tm-kpis{grid-template-columns:1fr 1fr;}}
.tm-kpi{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:12px 14px;cursor:pointer;transition:transform .18s ease,border-color .18s ease;text-align:left;font-family:inherit;color:inherit;}
.tm-kpi:hover{transform:translateY(-2px);border-color:var(--fb2);}
.tm-kpi .k{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);}
.tm-kpi .v{font-family:var(--font-display);font-weight:600;font-style:normal;font-size:var(--t-xxl);color:var(--ft);margin-top:5px;line-height:var(--lh-flat);font-variant-numeric:tabular-nums;}
.tm-kpi .s{font-size:var(--t-s);color:var(--fd);margin-top:4px;line-height:var(--lh-ui);}
.tm-kpi .s.up{color:var(--acc-bright);}
:is(body.flow-dawn,body.flow-studio) .tm-kpi .s.up{color:var(--acc);}
.tm-kpi .s.warn{color:var(--adverse-ink);}
.tm-ctrl{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:14px;align-items:start;}
@media(max-width:900px){.tm-ctrl{grid-template-columns:1fr;}}
.tm-panel{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:16px 18px;}
.tm-panel .ph{display:flex;justify-content:space-between;align-items:baseline;gap:10px;font-size:var(--t-l);font-weight:600;color:var(--ft);}
.tm-panel .ph .dim{font-weight:400;color:var(--fd2);font-size:var(--t-s);}
.tm-panel .ph .go{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--acc-bright);cursor:pointer;white-space:nowrap;background:none;border:0;padding:0;}
.tm-panel .ph .go:hover{text-decoration:underline;}
.tm-target{margin:12px 0 2px;}
.tm-target .bar{height:9px;border-radius:100px;background:var(--fhl);overflow:hidden;display:flex;gap:2px;}
.tm-target .bar i{display:block;height:100%;font-style:normal;}
.tm-target .bar .b1{background:var(--green,var(--green));border-radius:100px 0 0 100px;}
.tm-target .bar .b2{background:var(--warm);opacity:.75;}
body[data-motion="Full"] .tm-target .bar i{transform-origin:left;animation:osGrowX .85s cubic-bezier(.22,.61,.36,1) backwards;}
.tm-target .lbl{display:flex;justify-content:space-between;font-size:var(--t-s);color:var(--fd);margin-top:7px;}
.tm-mbars{display:flex;align-items:flex-end;gap:8px;height:70px;margin-top:14px;}
.tm-mb{flex:1;display:flex;flex-direction:column;align-items:center;gap:5px;height:100%;justify-content:flex-end;}
.tm-mb i{display:block;width:100%;max-width:34px;border-radius:var(--r-pill) var(--r-pill) 0 0;background:var(--mark);font-style:normal;}
.tm-mb.pend i{background:color-mix(in srgb,var(--warm) 55%,transparent);}
.tm-mb.zero i{height:3px !important;background:var(--fb2);}
.tm-mb small{font-family:var(--font-mono);font-size:var(--t-xxs);color:var(--fd2);letter-spacing:var(--tr-s);}
body[data-motion="Full"] .tm-mb i{transform-origin:bottom;animation:osGrowY .55s cubic-bezier(.3,.9,.4,1.1) backwards;}
/* §5 — "The work" list: capped height + internal scroll so it can never stretch the page grid */
.tm-worklist{max-height:340px;overflow-y:auto;overflow-x:hidden;}
.tm-worklist::-webkit-scrollbar{width:6px;}
.tm-worklist::-webkit-scrollbar-thumb{background:var(--fb2);border-radius:var(--r-xs);}
.tm-viewall{width:100%;margin-top:8px;padding:7px 0;font:inherit;font-size:var(--t-s);font-weight:600;color:var(--acc-bright);background:transparent;border:0;border-top:1px solid var(--fb);cursor:pointer;}
.tm-viewall:hover{color:var(--ft);}
.tm-line{display:flex;align-items:center;gap:11px;padding:10px 0;border-top:1px solid var(--fb);font-size:var(--t-m);}
.tm-line:first-of-type{border-top:0;}
.tm-line.click{cursor:pointer;}
.tm-line.click:hover .tmain b{color:var(--hover);}
.tm-line .tmain{flex:1;min-width:0;}
.tm-line .tmain b{display:block;font-size:var(--t-m);color:var(--ft);font-weight:600;}
.tm-line .tmain small{display:block;font-size:var(--t-s);color:var(--fd);margin-top:1px;line-height:var(--lh-ui);}
.tm-who{width:26px;height:26px;border-radius:var(--r-round);flex-shrink:0;background:color-mix(in srgb,var(--acc) 11%,transparent);color:var(--acc);display:flex;align-items:center;justify-content:center;font-size:var(--t-xs);font-weight:600;}
body.flow-dusk .tm-who{background:color-mix(in srgb,var(--acc) 30%,transparent);color:var(--acc-bright);}
.tm-avail{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-s);color:var(--fd);margin-top:8px;}
.tm-avail::before{content:'';width:6px;height:6px;border-radius:var(--r-round);background:var(--green,var(--green));flex-shrink:0;}
.tm-avail.out::before{background:var(--warm);}

/* ── Team · mission control: ops queue rail + focus board ── */
.tm-mc{display:grid;grid-template-columns:minmax(255px,300px) 1fr;gap:16px;margin-top:14px;align-items:start;}
@media(max-width:980px){.tm-mc{grid-template-columns:1fr;}}
.tm-rail{position:sticky;top:6px;background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:15px 17px;}
.tm-rail.pulse{animation:tmRailPulse 1.6s ease 2;}
@keyframes tmRailPulse{0%,100%{box-shadow:none;}50%{box-shadow:0 0 0 3px color-mix(in srgb,var(--warm) 35%,transparent);}}
.tm-rail .rh{display:flex;align-items:center;justify-content:space-between;gap:8px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--ft);padding-bottom:10px;border-bottom:1px solid var(--fb);}
.tm-rail .rh::before{content:'';width:7px;height:7px;border-radius:var(--r-round);background:var(--warm);flex-shrink:0;}
body[data-motion="Full"] .tm-rail .rh::before{animation:osPulse 2.4s ease-in-out infinite;}
.tm-rail .rh .n{margin-left:auto;color:var(--fd2);letter-spacing:var(--tr-s);}
.tm-qi{padding:11px 0;border-top:1px solid var(--fb);}
.tm-qi:first-of-type{border-top:0;}
.tm-qi b{display:block;font-size:var(--t-m);color:var(--ft);line-height:var(--lh-ui);}
.tm-qi small{display:block;font-size:var(--t-s);color:var(--fd);margin-top:2px;line-height:var(--lh-ui);}
.tm-qi .qa{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;}
.tm-qi .qa .sp-btn{padding:5px 11px;font-size:var(--t-s);}
.tm-qi .qa .skip{border-color:transparent;color:var(--fd2);}
.tm-qi.done{display:flex;align-items:center;gap:10px;}
.tm-qi.done .tick{width:20px;height:20px;border-radius:var(--r-round);background:var(--acc);color:#fff;display:flex;align-items:center;justify-content:center;font-size:var(--t-xs);flex-shrink:0;}
.tm-qi.done b{font-size:var(--t-m);}
.tm-qi.done small{margin-top:0;}
.tm-qi.done .undo{margin-left:auto;font-family:inherit;font-size:var(--t-s);color:var(--acc-bright);background:none;border:0;cursor:pointer;flex-shrink:0;}
.tm-qclear{border:1.5px dashed var(--fb2);border-radius:var(--r-m);padding:14px;margin-top:10px;}
.tm-qclear .big{font-family:var(--font-display);font-weight:600;font-style:normal;font-size:var(--t-xl);color:var(--ft);font-variant-numeric:tabular-nums;}
.tm-qclear .sub{font-size:var(--t-s);color:var(--fd);margin-top:3px;line-height:var(--lh-body);}
.tm-qprog{margin-top:13px;padding-top:12px;border-top:1px solid var(--fb2);}
.tm-qprog .bar{height:6px;border-radius:100px;background:var(--fhl);overflow:hidden;}
.tm-qprog .bar i{display:block;height:100%;background:var(--mark);border-radius:100px;transition:width .5s cubic-bezier(.22,.61,.36,1);}
.tm-qprog .lbl{display:flex;justify-content:space-between;font-size:var(--t-s);color:var(--fd);margin-top:6px;}
.tm-qprog .lbl b{color:var(--ft);}
/* KPIs as controls */
.tm-kpi{position:relative;}
.tm-kpi.on{border-color:var(--acc);background:color-mix(in srgb,var(--acc) 5%,var(--fs));}
.tm-kpi.on::after{content:'';position:absolute;left:14px;right:14px;bottom:8px;height:2px;border-radius:var(--r-xs);background:var(--acc-bright);}
/* focus chips + focused panel */
.tm-chips{display:flex;flex-wrap:wrap;gap:7px;margin:2px 0 12px;align-items:center;}
.tm-chips .lab{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);margin-right:3px;}
.tm-chip{font-family:inherit;font-size:var(--t-s);font-weight:500;color:var(--fd);background:var(--fhl);border:1px solid var(--fb);border-radius:100px;padding:5px 13px;cursor:pointer;transition:all .15s ease;}
.tm-chip:hover{color:var(--ft);border-color:var(--fb2);}
.tm-chip.on{color:#fff;background:var(--acc);border-color:var(--acc);font-weight:600;}
.tm-focus-enter{animation:riseIn .4s cubic-bezier(.2,.7,.25,1) backwards;}
body[data-motion="Off"] .tm-focus-enter{animation:none;}
.tm-ctrl.single{grid-template-columns:1fr;}
/* person focus header */
.tm-ph{display:flex;align-items:center;gap:14px;background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:16px 18px;margin-bottom:14px;}
.tm-ph .who{width:44px;height:44px;border-radius:var(--r-round);background:color-mix(in srgb,var(--acc) 12%,transparent);color:var(--acc);display:flex;align-items:center;justify-content:center;font-size:var(--t-l);font-weight:600;flex-shrink:0;}
body.flow-dusk .tm-ph .who{background:color-mix(in srgb,var(--acc) 30%,transparent);color:var(--acc-bright);}
.tm-ph .pm b{display:block;font-size:var(--t-xl);color:var(--ft);letter-spacing:var(--tr-none);}
.tm-ph .pm small{display:block;font-size:var(--t-m);color:var(--fd);margin-top:1px;}
.tm-ph .pstats{margin-left:auto;display:flex;gap:22px;text-align:right;}
.tm-ph .pstats span b{display:block;font-size:var(--t-xl);color:var(--ft);font-variant-numeric:tabular-nums;}
.tm-ph .pstats span small{font-size:var(--t-xs);font-family:var(--font-mono);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--fd2);}
@media(max-width:760px){.tm-ph{flex-wrap:wrap;}.tm-ph .pstats{margin-left:0;width:100%;justify-content:space-between;}}

/* documents read panel */
.sp-read{background:var(--fhl);border:1px solid var(--fb);border-radius:0 0 12px 12px;padding:16px 18px;margin:-1px 0 8px;}
.sp-read .rl{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--acc-bright);margin-bottom:8px;}
.sp-read .kv{display:flex;justify-content:space-between;gap:14px;padding:6px 0;border-bottom:1px solid var(--fb);font-size:var(--t-m);}
.sp-read .kv .k{color:var(--fd);}
.sp-read .kv .v{color:var(--ft);font-weight:500;text-align:right;}
.sp-read .rn{margin-top:10px;font-size:var(--t-s);color:var(--fd);line-height:var(--lh-body);}
.sp-read .rn.dim{color:var(--fd2);}

/* portfolio toolbar */
.sp-toolbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:16px 0 12px;border-bottom:1px solid var(--fb);}
/* F-1 — "+ New property" sits at the right of the toolbar, quiet until wanted */
.sp-toolbar .np-add{margin-left:auto;white-space:nowrap;}
/* F-1 — capture chips on a hand-added property record (quick-question pattern) */
.pp-capchips{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin:-4px 0 16px;}
.pp-capchips .cc-lbl{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--fd2);}
.pp-capchips .cc-chip{font:inherit;font-size:var(--t-s);font-weight:600;cursor:pointer;padding:3px 9px;border-radius:var(--r-s);border:1px solid var(--acc);background:color-mix(in srgb, var(--acc) 10%, var(--fs));color:var(--acc-bright);white-space:nowrap;transition:background .15s ease;}
.pp-capchips .cc-chip:hover{background:color-mix(in srgb, var(--hover) 18%, var(--fs));}
/* F-2 — Tenancy schedule (summonable panel + the CRE table) */
/* ⚠ THE PLATE'S WIDTH, MEASURED (12 Aug — third pass on the same two screens, so
   measured this time rather than adjusted). Tabs A and F draw their table inside
   .screen (max-width 1560, padding 48) → .rec at 1fr → .panel.pad (padding 24):
   the table is drawn at 1416px. This capped it at 1080, and the schedule's
   fourteen columns wrapped their headers and grew a horizontal scrollbar INSIDE
   the panel — which is what Jake photographed. .ten-sched and .mt-wrap add 44px
   of padding of their own, so 1460 hands the table exactly the 1416 the plate
   drew it at, and width:96% keeps a narrow screen honest. */
/* ⚠ THE PLATE'S OWN FRAME, NOT A NUMBER I CHOSE (12 Aug, after the panels went through the porter).
   The gated root inside is `pbx pbx-screen`, and the ported sheet gives .pbx-screen the draft's own
   page frame: max-width 1560, padding 48 down each side. .pbx-panel.pbx-pad then takes 24 more, so
   the table is drawn at 1416px — which is what the plate draws it at, because it is the same rule.
   Nothing here decides a width; it hands the screen the room its own stylesheet asks for. */
.sp-modal.ten-wide{max-width:1560px;width:96%;position:relative;}
.ten-sched{padding:0;max-height:86vh;overflow:auto;}
/* the draft's .screen carried the page's own bottom air because it WAS the page. Inside a summoned
   panel the modal's own edge does that job, so the BOTTOM is trimmed and nothing else — the sides
   are the plate's, and they are what hand the table its width. */
/* ⚠ THE PAGE GUTTERS ARE THE MODAL'S JOB HERE, AND THE CAPTURE MEASURED IT. .pbx-screen carries the
   draft's own page frame — 48px down each side, 120px of air at the foot — because in the draft it
   WAS the page. Inside a summoned panel the modal is already inset from the viewport, so those
   gutters are charged twice and the table pays: side by side at 1500px the draft drew "No review
   (5-year term)" on two lines and the panel on five, on an identical tree. Trimming the panel's own
   gutters hands the table 1392px against the draft's 1404 — nearer the plate, not further. CSS only:
   the gate compares markup and neither side moves. */
.ten-sched .pbx-screen{padding:0 24px 24px;}
/* the close × is chrome and lives outside the gated root, so it is placed from here. */
.sp-modal.ten-wide > .x{position:absolute;top:12px;right:14px;z-index:2;}
/* ⚠ PRINT — THE CONTROLS LEAVE BY SELECTOR, NEVER BY A CLASS ON THE NODE. `no-print` written into
   the markup is a decision the plate does not make, and the gate said so: nine th/td carrying it
   were nine differences against draft screen 13. Which cells are controls is already known from the
   classes the design itself gives them. */
@media print{
  .ten-sched .pbx-t th:last-child,
  .ten-sched .pbx-t td.pbx-st{display:none;}
  .ten-sched .pbx-docact{display:none;}
}
.ts-print-head{display:none;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid var(--fb);}
.ts-print-head .brand{display:inline-flex;align-items:center;gap:8px;color:var(--ft);}
.ts-print-head .brand svg{width:22px;height:22px;}
.ts-print-head .brand svg path{stroke:currentColor;stroke-width:6;fill:none;stroke-linecap:round;}
.ts-print-head .wm{font-family:var(--font-logo);font-size:var(--t-l);font-weight:600;letter-spacing:var(--tr-tight);display:inline-flex;align-items:baseline;}
.ts-print-head .wm .wmA{font-weight:700;letter-spacing:var(--tr-tight);}
.ts-print-head .wm .wmB{font-weight:400;letter-spacing:var(--tr-s);margin-left:0.5px;}
.ts-print-head .ts-ph-title{font-weight:600;font-size:var(--t-m);color:var(--ft);}
.ts-print-head .ts-ph-date{font-family:var(--font-mono);font-size:var(--t-xs);color:var(--fd2);}
.ts-table{width:100%;border-collapse:collapse;font-size:var(--t-s);}
.ts-table th{text-align:left;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--fd2);font-weight:600;padding:6px 8px;border-bottom:1px solid var(--fb2);white-space:nowrap;}
.ts-table td{padding:8px;border-bottom:1px solid var(--fb);color:var(--ft);vertical-align:middle;white-space:nowrap;}
.ts-table tr:last-child td{border-bottom:0;}
.ts-table .ts-unit{font-weight:600;}
.ts-table .ts-na{color:var(--fd2);}
/* R66 (29 Jul) — A PROPOSAL IS NOT A TENANCY. A row whose terms come from a live unsigned deal is
   marked here as well as in words: the applicant's name carries its role, and the row sits back a
   half-tone from the executed tenancies around it. Both survive PRINT, which is the point — this
   document gets posted to a landlord who has no chips to hover over. */
.ts-table .ts-role{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--attention-ink);font-weight:600;}
.ts-table .ts-position{display:block;margin-top:3px;font-size:var(--t-xs);line-height:var(--lh-ui);color:var(--attention-ink);white-space:nowrap;}
.ts-table tr.ts-proposed td{background:color-mix(in srgb, var(--warm) 5%, transparent);}
.ts-footnote{margin:10px 0 0;font-size:var(--t-s);line-height:var(--lh-body);color:var(--fd);}
/* ── THE MONEY TIMELINE (P-E item 6, 29 Jul) ──────────────────────────────────────────────────
   Its five phase words are NOT the tenancy schedule's three, and the styling keeps them apart on
   purpose: this panel is about where the MONEY is, the schedule is about what the FLOOR is. The
   "available" phase is deliberately quiet — a floor with viewings shows its fee without that fee
   counting as anything, which is Jake's "this doesnt move the fee in the pipeline" made visible. */
/* ⛔ .mt-wrap IS GONE. The money timeline's private wrapper was the last of the mt- kit; the panel
   now renders the ported screen inside the same .ten-sched frame the schedule uses, so both
   summoned documents have ONE frame and printSchedule() clones whichever is open. */
.mt-head{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;padding:6px 2px 14px;border-bottom:1px solid var(--fb);}
.mt-head > div{display:flex;flex-direction:column;gap:2px;}
.mt-k{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);font-weight:600;}
.mt-v{font-size:var(--t-xxl);font-weight:600;letter-spacing:var(--tr-tight);line-height:var(--lh-tight);color:var(--ft);}
.mt-v.acc{color:var(--acc-bright);}
.mt-s{font-size:var(--t-s);color:var(--fd);}
.mt-phases{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin:14px 0 6px;}
.mt-phase{display:flex;flex-direction:column;gap:1px;padding:9px 11px;border-radius:var(--r-m);border:1px solid var(--fb);background:var(--fs);}
.mt-phase .amt{font-size:var(--t-l);font-weight:600;letter-spacing:var(--tr-none);color:var(--ft);}
.mt-phase .lab{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd);font-weight:600;}
.mt-phase .sub{font-size:var(--t-xs);color:var(--fd2);}
/* the money is not in the available phase — it reads as potential, not as a total */
.mt-phase.ph-available{border-style:dashed;}
.mt-phase.ph-available .amt{color:var(--fd2);font-weight:500;}
.mt-phase.ph-pipeline{border-color:color-mix(in srgb, var(--warm) 40%, var(--fb));}
.mt-phase.ph-pipeline .amt{color:var(--attention-ink);}
.mt-phase.ph-achieved .amt{color:var(--acc-bright);}
.mt-phase.ph-invoiced .amt,.mt-phase.ph-paid .amt{color:var(--green);}
.mt-phase.ph-paid{border-color:color-mix(in srgb, var(--green) 40%, var(--fb));}
.mt-table{width:100%;border-collapse:collapse;font-size:var(--t-s);margin-top:8px;}
.mt-table th{text-align:left;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);font-weight:600;padding:6px 8px;border-bottom:1px solid var(--fb2);white-space:nowrap;}
.mt-table td{padding:9px 8px;border-bottom:1px solid var(--fb);color:var(--ft);vertical-align:middle;}
.mt-table tr:last-child td{border-bottom:0;}
.mt-table .mt-floor{font-weight:600;white-space:nowrap;}
.mt-table .mt-fee{font-family:var(--font-mono);white-space:nowrap;}
.mt-table tr.ph-available td{color:var(--fd);}
.mt-table .mt-na{color:var(--fd2);}
.mt-inv{margin-left:7px;font-family:var(--font-mono);font-size:var(--t-xs);color:var(--fd);cursor:pointer;}
.mt-inv:hover{color:var(--hover);}
.mt-rail{display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
.mt-ev{font-size:var(--t-xs);color:var(--fd);white-space:nowrap;padding:2px 7px;border-radius:var(--r-s);background:color-mix(in srgb, var(--fd2) 8%, transparent);}
.mt-ev b{font-weight:600;color:var(--ft);}
.mt-ev.ev-paid{background:color-mix(in srgb, var(--green) 12%, transparent);}
.mt-ev.ev-paid b{color:var(--green);}
.mt-open{font-size:var(--t-xs);color:var(--acc-bright);cursor:pointer;white-space:nowrap;}
.mt-nodate{font-size:var(--t-xs);color:var(--attention-ink);white-space:nowrap;}
.mt-done{margin:14px 0 0;font-size:var(--t-s);line-height:var(--lh-body);color:var(--green);font-weight:600;}
.mt-note{margin:14px 0 0;font-size:var(--t-s);line-height:var(--lh-body);color:var(--fd);}
@media (max-width:820px){
  .mt-head,.mt-phases{grid-template-columns:1fr 1fr;}
}
/* THE RETAINER CREDIT LINE on a draft invoice (29 Jul). Reads as part of the document, not as an
   error: it is a normal thing for an invoice to say, and colouring it like a warning would make a
   firm hesitate over its own agreement. */
.mdoc .inv-creditline .desc{color:var(--fd);font-style:italic;}
.mdoc .inv-creditline .amt{color:var(--fd);text-align:right;}
.ts-footnote b{color:var(--attention-ink);font-weight:600;}
.ts-cap{font:inherit;font-size:var(--t-s);font-weight:700;line-height:var(--lh-flat);cursor:pointer;width:20px;height:20px;border-radius:var(--r-xs);border:1px solid var(--acc);background:color-mix(in srgb, var(--acc) 10%, var(--fs));color:var(--acc-bright);transition:background .15s ease;}
.ts-cap:hover{background:color-mix(in srgb, var(--hover) 20%, var(--fs));}
.ts-table .ts-edit{font:inherit;font-size:var(--t-s);font-weight:600;cursor:pointer;padding:3px 9px;border-radius:var(--r-s);border:1px solid var(--fb2);background:transparent;color:var(--fd);white-space:nowrap;transition:border-color .15s ease,color .15s ease;}
.ts-table .ts-edit:hover{border-color:var(--hover);color:var(--hover);}
/* EPC column — sits under its header, nudged right */
.ts-table th.ts-epc,.ts-table td.ts-epc{text-align:right;padding-right:16px;}
/* Totals footer row — total area + total rent + area-weighted average £/sq ft */
.ts-table tfoot .ts-total td{border-top:2px solid var(--fb2);padding-top:10px;font-weight:600;color:var(--ft);}
.ts-table tfoot .ts-total .ts-avg{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--fd2);font-weight:600;}
/* Print / export → one clean page per building, wordmark V3 in the header */
/* THE SCHEDULE PRINTS FROM ITS OWN ROOT (29 Jul). printSchedule() clones .ten-sched into
   #os-print-root at the end of <body> and sets .os-printing. Everything else is DISPLAY:NONE, not
   visibility:hidden — hidden content still occupies space, which is what put two blank sheets in
   front of Jake's schedule. Nothing above the clone clips, positions or sizes it. */
@media print{
  body.os-printing > *{display:none !important;}
  body.os-printing > #os-print-root{display:block !important;}
  #os-print-root{position:static !important;width:100% !important;padding:0 !important;background:#fff !important;}
  #os-print-root .ten-sched{position:static !important;width:100% !important;max-height:none !important;overflow:visible !important;padding:0 !important;background:#fff !important;box-shadow:none !important;border:0 !important;}
  /* NO BLANKING FALLBACK. 29 Jul, second sighting: Jake printed again and got ONE blank sheet.
     The old `body *{visibility:hidden}` rule was GLOBAL — it hid the whole application on every
     print, and only un-hid `.ten-sched`. So any print that did not go through printSchedule()
     produced white paper: ⌘P from anywhere in the app, a print fired before the clone landed, a
     schedule closed a moment earlier. A stylesheet that blanks the page unless one specific element
     happens to be on screen is a trap, and it caught the same person twice in one afternoon.
     Now: the clone path (below) prints the clean one-page schedule, and every other print prints
     the page as it stands — imperfect, and never blank. */
  .sp-modalbg{position:static !important;background:none !important;display:block !important;}
  .sp-modal.ten-wide{position:static !important;box-shadow:none !important;border:0 !important;max-width:100% !important;width:100% !important;background:#fff !important;}
  .ts-print-head{display:flex !important;}
  .no-print{display:none !important;}
  .ts-cap{border:0 !important;background:none !important;color:#999 !important;}
  .ts-table{font-size:var(--t-xs);}
  .ts-table tr.ts-proposed td{background:#f6f2ec !important;}
  .ts-table .ts-role{color:#8a5a2b !important;}
  .ts-table .ts-position{color:#8a5a2b !important;font-size:var(--t-xxs);}
  .ts-footnote{color:#444 !important;font-size:var(--t-xs);}
  @page{size:landscape;margin:14mm;}
}
.sp-search{position:relative;flex:1;min-width:220px;display:block;}
.sp-search svg{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:14px;height:14px;stroke:var(--fd2);fill:none;stroke-width:1.8;}
.sp-search input{width:100%;font-family:inherit;font-size:var(--t-m);color:var(--ft);background:var(--fhl);border:1px solid var(--fb);border-radius:100px;padding:8px 14px 8px 34px;outline:none;transition:border-color .15s ease;}
.sp-search input::placeholder{color:var(--fd2);}
.sp-search input:focus{border-color:var(--hover);}

/* contacts */
.sp-chips{display:flex;flex-wrap:wrap;gap:7px;padding-bottom:14px;border-bottom:1px solid var(--fb);}
.sp-filter{font-family:inherit;font-size:var(--t-m);font-weight:500;color:var(--fd);background:none;border:1px solid var(--fb);border-radius:100px;padding:6px 13px;cursor:pointer;}
.sp-filter:hover{color:var(--ft);border-color:var(--fb2);}
.sp-filter.on{color:var(--ft);background:var(--fhl);border-color:var(--fb2);}
.sp-av{width:32px;height:32px;border-radius:var(--r-round);background:color-mix(in srgb,var(--acc) 30%,transparent);color:var(--acc-bright);display:flex;align-items:center;justify-content:center;font-size:var(--t-s);font-weight:600;flex-shrink:0;}
:is(body.flow-dawn,body.flow-studio) .sp-av{background:color-mix(in srgb,var(--acc) 11%,transparent);color:var(--acc);}

/* diary date block */
.sp-date{width:52px;text-align:center;flex-shrink:0;}
.sp-date b{display:block;font-size:var(--t-xl);font-weight:600;color:var(--ft);line-height:var(--lh-flat);}
.sp-date span{display:block;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);margin-top:3px;}
.sp-date small{display:block;font-size:var(--t-xs);color:var(--fd);margin-top:2px;}
/* Diary colour pass — date cells tinted by urgency window, matching the Leases lz-day treatment */
.sp-date.warm,.sp-date.amber,.sp-date.teal{border-radius:var(--r-s);padding:7px 0;}
.sp-date.warm{background:color-mix(in srgb,var(--adverse) 13%,transparent);}
.sp-date.warm b{color:var(--adverse-ink);}
.sp-date.amber{background:color-mix(in srgb,var(--warm) 15%,transparent);}
.sp-date.amber b{color:var(--attention-ink);}
.sp-date.teal{background:color-mix(in srgb,var(--acc-bright) 11%,transparent);}
.sp-date.teal b{color:var(--acc);}
/* Diary — an event addressed by answering its quick question reads as handled */
.sp-date.done{border-radius:var(--r-s);padding:7px 0;background:color-mix(in srgb,var(--green) 12%,transparent);}
.sp-date.done b{color:var(--st-let-ink);}
:is(body.flow-dawn,body.flow-studio) .sp-date.done b{color:var(--green);}
.sp-row.handled{opacity:.62;}
.sp-row.handled .sp-row-main b{text-decoration:line-through;text-decoration-color:var(--fd2);text-decoration-thickness:1px;}

/* team bars */
.sp-bar{display:block;height:5px;border-radius:100px;background:var(--fhl);overflow:hidden;margin:6px 0 4px;max-width:150px;}
.sp-bar i{display:block;height:100%;background:var(--mark);border-radius:100px;}

/* compliance pills */
.sp-pill{display:inline-flex;align-items:center;gap:5px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);padding:3px 9px;border-radius:100px;white-space:nowrap;}
.sp-pill::before{content:'';width:5px;height:5px;border-radius:var(--r-round);background:currentColor;}
.sp-pill.ok{color:var(--st-let-ink);background:color-mix(in srgb,var(--green) 16%,transparent);}
:is(body.flow-dawn,body.flow-studio) .sp-pill.ok{color:var(--green);background:color-mix(in srgb,var(--green) 10%,transparent);}
.sp-pill.miss{color:color-mix(in srgb,var(--warm) 85%,#fff);background:color-mix(in srgb,var(--warm) 18%,transparent);}
:is(body.flow-dawn,body.flow-studio) .sp-pill.miss{color:var(--attention-ink);background:color-mix(in srgb,var(--warm) 11%,transparent);}
.sp-pill.unk{color:var(--fd);background:var(--fhl);border:1px solid var(--fb);}
.sp-flag{margin-top:16px;font-size:var(--t-m);color:var(--fd);line-height:var(--lh-body);border:1px solid color-mix(in srgb,var(--warm) 30%,transparent);border-left:3px solid var(--warm);border-radius:var(--r-s);padding:13px 16px;}
.sp-flag b{color:var(--ft);}

/* reports coming-soon */
.sp-coming{text-align:center;padding:44px 30px;max-width:480px;margin:10px auto;}
.sp-coming .big{font-size:var(--t-xl);font-weight:600;color:var(--ft);letter-spacing:var(--tr-tight);margin-top:14px;}
.sp-coming p{font-size:var(--t-m);color:var(--fd);line-height:var(--lh-prose);margin-top:10px;}
.sp-coming p b{color:var(--ft);}
.sp-coming .mono-sm{display:block;margin-top:18px;letter-spacing:var(--tr-m);text-transform:uppercase;font-size:var(--t-xs);}

/* buttons in spaces */
.sp-btn{font-family:inherit;font-size:var(--t-m);font-weight:600;color:var(--ft);background:transparent;border:1px solid var(--fb2);border-radius:var(--r-s);padding:8px 14px;cursor:pointer;white-space:nowrap;}
.sp-btn:hover{border-color:var(--fd);}
/* ⚠ 7 Aug — WHY CORAL WAS NOWHERE ON THE SCREEN, and it was never the palette's fault.
   --action (coral) was created on 5 Aug to stop the `fell through` control reading as a status, so it
   was wired to FIVE floor-row controls on one panel of one page — and nowhere else. Every actual CTA
   in the product — Answer the check-in, Raise →, every primary button — painted from --acc. So the
   app's action colour and the BRAND's action colour were two different things, and the brand's one
   was invisible by construction. The Praeba swap did not cause that; it just stopped hiding it.
   A PRIMARY BUTTON IS AN ACT. This is Jake's 5 Aug ruling applied properly, not relaxed. */
.sp-btn.primary{background:var(--acc);color:var(--bone);border-color:var(--acc);}
.sp-btn.primary:hover{background:var(--hover);}

/* ── THE FEE CALCULATOR'S TWO BITS OF LAYOUT (19 Aug) ────────────────────────────────────────────
   Named as classes rather than written inline, because designdebt.test.js refused them — correctly.
   ⚠ Its siblings (the NER/valuation/cashflow panels) still carry the same two as inline styles; they
   are the existing 520 and are not touched here. A new panel does not get to add to a debt it can
   avoid, and the ratchet is the only reason anyone would ever notice. */
.calc-basis{padding:0;border:0;margin-bottom:12px;}
.calc-totals{margin-top:14px;}

/* invoice modal */
.sp-modalbg{position:fixed;inset:0;background:rgba(0,0,0,.45);backdrop-filter:blur(2px);z-index:120;display:flex;align-items:center;justify-content:center;padding:24px;}
.sp-modal{background:var(--fs2);border:1px solid var(--fb2);border-radius:var(--r-m);width:min(540px,100%);box-shadow:0 30px 80px rgba(0,0,0,.5);overflow:hidden;animation:spIn2 .25s cubic-bezier(.2,.7,.25,1);display:flex;flex-direction:column;max-height:min(86vh,calc(100vh - 180px));}
.sp-modal .mh{flex-shrink:0;}
.sp-modal .mact{flex-shrink:0;border-top:1px solid var(--fb);padding-top:13px;}
.sp-modal .nd-wrap,.sp-modal .mdoc{overflow-y:auto;flex:1 1 auto;min-height:0;}
@keyframes spIn2{from{opacity:0;transform:translateY(14px) scale(.98);}}
.sp-modal .mh{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--fb);font-size:var(--t-l);font-weight:600;color:var(--ft);}
.sp-modal .mh .auto{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--acc-bright);background:color-mix(in srgb,var(--acc-bright) 13%,transparent);border-radius:100px;padding:3px 9px;margin-left:9px;}
.sp-modal .x{font-size:var(--t-xl);line-height:var(--lh-flat);color:var(--fd);background:none;border:0;cursor:pointer;}
.sp-modal .mdoc{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);margin:16px 20px;padding:20px 22px;}
.sp-modal .mtop{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;border-bottom:1px solid var(--fb);padding-bottom:13px;}
.sp-modal .mtop b{display:block;font-size:var(--t-l);color:var(--ft);}
.sp-modal .mtop small{display:block;font-size:var(--t-xs);color:var(--fd2);margin-top:3px;}
.sp-modal .no{font-family:var(--font-mono);font-size:var(--t-s);color:var(--ft);font-weight:600;}
.sp-modal .mfld{margin-top:13px;}
.sp-modal label{display:block;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);margin-bottom:3px;}
.sp-modal input{font-family:inherit;font-size:var(--t-m);color:var(--ft);background:transparent;border:0;border-bottom:1px solid var(--fb2);padding:4px 2px;width:100%;outline:none;}
.sp-modal input:focus{border-bottom-color:var(--hover);}
.sp-modal .mline{display:flex;gap:12px;margin-top:14px;padding-top:12px;border-top:1px solid var(--fb);align-items:flex-start;}
.sp-modal .mline .desc{flex:1;}
.sp-modal textarea.desc{flex:1;font-family:inherit;font-size:var(--t-m);color:var(--ft);background:transparent;border:1px solid var(--fb2);border-radius:var(--r-s);padding:8px 10px;min-height:66px;resize:vertical;outline:none;line-height:var(--lh-body);}
.sp-modal textarea.desc:focus{border-color:var(--hover);}
.sp-modal .mline .amt{width:96px;text-align:right;font-family:var(--font-mono);font-weight:600;}
.sp-modal .msub{display:flex;justify-content:space-between;font-size:var(--t-m);color:var(--fd);padding:8px 0 0;}
.sp-modal .mtot{display:flex;justify-content:space-between;font-size:var(--t-l);font-weight:700;color:var(--ft);border-top:1px solid var(--fb2);margin-top:9px;padding-top:10px;}
.sp-modal .mtot span:last-child{color:var(--acc-bright);}
.sp-modal .mact{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:2px 20px 18px;}
.sp-modal .hint{font-size:var(--t-s);color:var(--fd2);max-width:50%;}

@media(max-width:980px){
  .fc-stage{grid-template-columns:1fr;padding:calc(var(--topbar-h) + 20px) 22px 210px;gap:30px;}
  .fc-status{padding:0 22px;}
  .fc-stack{height:340px;}
  .fc-greet h1{font-size:var(--t-xxl);}
  .os-vitals{grid-template-columns:1fr 1fr;}
  .sp-lanes{grid-template-columns:repeat(5,minmax(170px,1fr));overflow-x:auto;}
  .sp-totals,.sp-totals.four{grid-template-columns:1fr 1fr;}
  .sp-thead{display:none;}
  .sp-trow.c5,.sp-trow.c4,.sp-trow.c6,.sp-trow.c5.team{grid-template-columns:1fr;gap:6px;}
  .sp-trow .amt{text-align:left !important;}
}

/* ── lease abstract (Leases space) ──────────────── */
.la-head{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;}
.la-head h3{font-size:var(--t-xxl);font-weight:600;letter-spacing:var(--tr-tight);color:var(--ft);}
.la-head .la-prop{font-weight:400;color:var(--fd);font-size:var(--t-l);}
.la-ref{margin-top:5px;color:var(--fd2);}
.la-verify{display:flex;flex-wrap:wrap;gap:14px;align-items:center;margin-top:14px;padding:10px 14px;background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-s);font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);text-transform:uppercase;}
.la-verify .ok{color:var(--acc-bright);}
.la-verify .fl{color:var(--attention-ink);}
.la-verify .legend{margin-left:auto;color:var(--fd2);}
.la-summary{margin-top:16px;font-size:var(--t-l);line-height:var(--lh-prose);color:var(--fd);max-width:74ch;}
.la-groups{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px;margin-top:18px;}
.la-group{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:16px 18px;}
.la-gh{display:flex;justify-content:space-between;align-items:baseline;gap:10px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--fd2);padding-bottom:9px;border-bottom:1px solid var(--fb);}
.la-field{display:grid;grid-template-columns:1fr auto;gap:1px 12px;padding:10px 0;border-bottom:1px solid var(--fb);}
.la-field:last-child{border-bottom:0;padding-bottom:2px;}
.la-field .fl-l{font-size:var(--t-s);letter-spacing:var(--tr-s);color:var(--fd2);text-transform:uppercase;}
.la-field .fl-v{font-size:var(--t-m);color:var(--ft);line-height:var(--lh-ui);}
.la-field .fl-v b{font-weight:600;}
.la-field .fl-s{display:block;font-size:var(--t-s);color:var(--fd);margin-top:1px;}
.la-field .fl-c{font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-s);justify-self:end;}
.la-field .fl-c.hi{color:var(--acc-bright);}
.la-field .fl-c.mid{color:var(--attention-ink);}
.la-field .fl-c.low{color:var(--attention-ink);font-weight:700;}
.la-field .fl-ref{grid-column:2;justify-self:end;align-self:end;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-s);color:var(--fd2);}
.la-flags{margin-top:18px;background:var(--fs);border:1px solid color-mix(in srgb,var(--warm) 38%,transparent);border-radius:var(--r-m);padding:16px 18px;}
.la-flag{padding:12px 0;border-bottom:1px solid var(--fb);}
.la-flag:last-child{border-bottom:0;padding-bottom:2px;}
.la-flag b{display:block;font-size:var(--t-m);color:var(--ft);}
.la-flag p{font-size:var(--t-m);color:var(--fd);line-height:var(--lh-body);margin-top:3px;max-width:80ch;}
.la-flag .mono-sm{display:block;margin-top:5px;color:var(--fd2);}
.la-foot{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:16px;padding-top:13px;border-top:1px solid var(--fb);font-size:var(--t-s);color:var(--fd2);flex-wrap:wrap;}

/* ── property record — colour rhythm from the original property page ── */
.pp-eyezone{background:color-mix(in srgb,var(--warm) 7%,transparent);border:1px solid color-mix(in srgb,var(--warm) 20%,transparent);border-left:3px solid var(--warm);border-radius:var(--r-m);padding:0 16px 6px;margin-top:22px;}
.pp-eyezone .sp-sec{margin:10px 0 2px;color:var(--attention-ink);}
.pp-eyezone .sp-sec::before{background:var(--warm);}
.pp-eyezone .sp-sec::after{border-top-color:color-mix(in srgb,var(--warm) 25%,transparent);}
.pp-eyezone .pp-eye{border-bottom-color:color-mix(in srgb,var(--warm) 14%,transparent);padding-left:0;padding-right:0;}
.pp-eyezone .pp-eye:last-child{border-bottom:0;}
.pp-eyezone .pp-eye .n{background:color-mix(in srgb,var(--warm) 15%,transparent);color:var(--attention-ink);}
.pp-rail{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:2px 20px 16px;align-self:start;}
.pp-rail .sp-sec{margin-top:18px;}
.pp-rail .sp-sec:first-child{margin-top:12px;}

/* property space follows the standard canvas again (bone surface, white panels) */

/* ── space presentation variants (Tweaks → Spaces) ──
   Floating = current modal-style panel. Sheet = rises from the dock, anchored
   to the bottom edge. Takeover = becomes the page, dock stays. Hover-peek
   remains a floating preview in every mode — only a pinned space changes. */
body[data-spaces="Sheet"] .sp-space:not(.peeking){top:auto;bottom:0;left:0;width:100%;transform:none;max-height:86vh;
  border-radius:var(--r-l) 22px 0 0;border-left:0;border-right:0;border-bottom:0;animation:spSheet .42s cubic-bezier(.2,.7,.25,1);}
@keyframes spSheet{from{transform:translateY(70px);opacity:0;}}
body[data-spaces="Sheet"] .sp-backdrop{background:rgba(0,0,0,.25);backdrop-filter:none;}
body[data-spaces="Sheet"] .sp-space:not(.peeking) .sp-body{padding-bottom:175px;}
body[data-spaces="Takeover"] .sp-space:not(.peeking){top:0;bottom:0;left:0;width:100%;transform:none;max-height:100vh;padding-top:var(--topbar-h);
  background-color:var(--fbg);background-image:var(--wash);background-attachment:fixed;
  background:var(--fbg);border:0;border-radius:0;box-shadow:none;animation:spTake .3s ease;}
@keyframes spTake{from{opacity:0;transform:translateY(14px);}}
body[data-spaces="Takeover"] .sp-backdrop{display:none;}
body[data-spaces="Takeover"] .sp-space:not(.peeking) .sp-head{max-width:1680px;margin:0 auto;width:100%;padding-left:clamp(32px,4vw,76px);padding-right:clamp(32px,4vw,76px);}
body[data-spaces="Takeover"] .sp-space:not(.peeking) .sp-body{max-width:1680px;margin:0 auto;width:100%;padding-left:clamp(32px,4vw,76px);padding-right:clamp(32px,4vw,76px);padding-bottom:185px;}
body[data-motion="Off"] .sp-space:not(.peeking){animation:none !important;}

/* ── per-space full screen (button next to ×) ──── */
.sp-hbtns{display:flex;align-items:center;gap:4px;flex-shrink:0;}
.sp-fs{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:none;border:0;border-radius:var(--r-s);cursor:pointer;color:var(--fd);}
.sp-fs:hover{color:var(--ft);background:var(--fhl);}
.sp-fs svg{width:13px;height:13px;}
.sp-fs svg path{stroke:currentColor;stroke-width:1.6;fill:none;stroke-linecap:round;stroke-linejoin:round;}
.sp-space.full:not(.peeking){top:0;bottom:0;left:0;width:100%;transform:none;max-height:100vh;padding-top:var(--topbar-h);border:0;border-radius:0;box-shadow:none;
  background-color:var(--fbg);background-image:var(--wash);background-attachment:fixed;}
.sp-space.full:not(.peeking) .sp-head{max-width:1680px;margin:0 auto;width:100%;padding-left:clamp(32px,4vw,76px);padding-right:clamp(32px,4vw,76px);}
.sp-space.full:not(.peeking) .sp-body{max-width:1680px;margin:0 auto;width:100%;padding-left:clamp(32px,4vw,76px);padding-right:clamp(32px,4vw,76px);padding-bottom:185px;}

/* ── review-pass additions (12 Jun): drafts, PDF abstract, fees edit, docs grouping, team cards, whitespace ── */
.fc-entry.link{cursor:pointer;}
.fc-entry.link:hover .x{color:var(--hover);}
.nd-wrap{padding:14px 20px 6px;}
.nd-fld{display:grid;grid-template-columns:98px 1fr;gap:12px;align-items:start;padding:9px 0;border-bottom:1px solid var(--fb);font-size:var(--t-m);}
.nd-fld label{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--fd2);padding-top:3px;line-height:var(--lh-ui);}
.nd-fld input{font-family:inherit;font-size:var(--t-m);color:var(--ft);background:none;border:0;outline:0;width:100%;}
.nd-fld .ro{color:var(--fd);}
.nd-fld .ro b{color:var(--ft);font-weight:600;font-size:var(--t-l);}
.nd-fld.total{border-bottom:0;}
/* New-requirement modal — wider, two-column form so the whole box (fields, footer
   and Create button) sits fully on screen with nothing cut off or overlapped. */
.sp-modal.req-new{width:min(720px,100%);max-height:calc(100vh - 96px);}
.sp-modal.req-new .nd-wrap{display:grid;grid-template-columns:1fr 1fr;gap:0 28px;align-content:start;}
.sp-modal.req-new .nd-fld{grid-template-columns:88px 1fr;}
.sp-modal.req-new .nd-fld.full{grid-column:1/-1;}
@media(max-width:640px){.sp-modal.req-new .nd-wrap{grid-template-columns:1fr;}}
.nd-body{width:100%;margin:12px 0 8px;background:var(--fhl);border:1px solid var(--fb);border-radius:var(--r-s);padding:12px 14px;font-family:inherit;font-size:var(--t-m);line-height:var(--lh-body);color:var(--ft);resize:vertical;min-height:172px;outline:none;}
.nd-body:focus{border-color:var(--hover);}
.mbtns{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end;}
.la-headr{display:flex;flex-direction:column;align-items:flex-end;gap:8px;flex-shrink:0;}
.la-summary{margin-top:20px;padding:14px 18px;background:var(--fhl);border-left:3px solid var(--acc-bright);border-radius:0 12px 12px 0;max-width:none;}
.la-verify{margin-top:18px;}
.la-groups{gap:18px;margin-top:26px;}
.la-group{padding:18px 20px;}
.la-flags{margin-top:26px;}
.doc-filter{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:2px;}
.sp-av.lg{width:38px;height:38px;font-size:var(--t-m);}
.tm-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px;margin-top:22px;}
.tm-card{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:16px 18px;}
/* A4 — roster management on each person card + the "add person" tile */
.tm-manage{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:10px;padding-top:10px;border-top:1px solid var(--fb);}
.tm-role{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-s);text-transform:uppercase;font-weight:600;padding:2px 7px;border-radius:var(--r-xs);background:var(--fhl);color:var(--fd);margin-right:auto;}
.tm-role.director{color:var(--acc-bright);background:color-mix(in srgb,var(--acc) 12%,transparent);}
.tm-mini{font:inherit;font-size:var(--t-s);font-weight:600;cursor:pointer;padding:3px 8px;border-radius:var(--r-s);border:1px solid var(--fb2);background:transparent;color:var(--fd);}
.tm-mini:hover{border-color:var(--hover);color:var(--hover);}
.tm-mini.danger:hover{border-color:var(--attention-ink);color:var(--attention-ink);}
.tm-card.tm-add{display:flex;align-items:center;justify-content:center;font-size:var(--t-m);font-weight:600;color:var(--acc-bright);cursor:pointer;border-style:dashed;min-height:120px;}
.tm-card.tm-add:hover{border-color:var(--hover);background:color-mix(in srgb,var(--hover) 5%,var(--fs));}
/* T7/T8 — derived "works with" line + on-card building-state */
.tm-works{display:block;margin-top:10px;font-size:var(--t-s);color:var(--fd2);line-height:var(--lh-body);}
.tm-works.dim{font-style:italic;opacity:.85;}
.tm-build{margin:10px 0 0;font-size:var(--t-s);color:var(--fd2);line-height:var(--lh-body);}
@keyframes qin{from{opacity:0;transform:translateY(5px);}to{opacity:1;transform:none;}}
.tm-head{display:flex;align-items:center;gap:11px;}
.tm-head b{display:block;font-size:var(--t-l);color:var(--ft);}
.tm-head small{display:block;font-size:var(--t-s);color:var(--fd);}
/* S7 — the per-person under-offer figure reads ORANGE (--warm), distinct from billed indigo. */
.tm-pipe{margin-left:auto;display:flex;flex-direction:column;align-items:flex-end;font-family:var(--font-display);font-weight:600;font-style:normal;font-size:var(--t-xl);color:var(--attention-ink);font-variant-numeric:tabular-nums;line-height:var(--lh-flat);}
.tm-pipelbl{font-family:var(--font-mono);font-style:normal;font-weight:500;font-size:var(--t-xxs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--fd2);margin-top:2px;}
.tm-stats{display:flex;margin-top:14px;border-top:1px solid var(--fb);}
.tm-stats > span{flex:1;padding:10px 12px 0;border-left:1px solid var(--fb);}
.tm-stats > span:first-child{border-left:0;padding-left:0;}
.tm-stats b{display:block;font-size:var(--t-l);color:var(--ft);}
.tm-stats small{font-size:var(--t-xs);color:var(--fd2);}
.tm-bar{height:5px;border-radius:100px;background:var(--fhl);margin-top:13px;overflow:hidden;}
.tm-bar i{display:block;height:100%;background:var(--warm);border-radius:100px;}
.tm-spark{display:flex;align-items:flex-end;gap:3px;margin-top:13px;}
.tm-spark i{width:14px;background:color-mix(in srgb,var(--mark) 35%,transparent);border-radius:var(--r-xs) 3px 0 0;}
.tm-spark small{margin-left:9px;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--fd2);}
.sp-space.prop .sp-body{padding:24px 36px 40px;}
.sp-space.prop .sp-sec{margin-top:38px;}
.sp-space.prop .pp-facts{margin-top:20px;}
.sp-space.prop .pp-eyezone{margin-top:26px;padding:2px 18px 10px;}
.sp-space.prop .pp-cols{margin-top:6px;gap:0 48px;}
.sp-space.prop .pp-dealnote{margin-top:14px;}
.la-pdfwrap{width:min(840px,94vw);max-height:92vh;display:flex;flex-direction:column;border-radius:var(--r-m);overflow:hidden;background:var(--obsidian);box-shadow:0 40px 90px rgba(0,0,0,.6);}
.la-pdfbar{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:10px 16px;color:var(--bone);font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-l);text-transform:uppercase;}
.la-pdfbar .btns{display:flex;gap:8px;}
.la-pdfbar .sp-btn{color:var(--bone);border-color:color-mix(in srgb,var(--bone) 30%,transparent);background:none;}
.la-pdfbar .sp-btn:hover{border-color:var(--bone);}
.la-pdfframe{width:100%;height:82vh;border:0;display:block;background:#d8d3c8;flex:1 1 auto;}
.la-pdfpaper{overflow-y:auto;background:#fff;color:var(--obsidian);padding:44px 52px 38px;font-size:var(--t-m);line-height:var(--lh-body);}
.pdf-top{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px;border-bottom:2px solid var(--obsidian);}
.pdf-brand{display:inline-flex;align-items:center;gap:8px;font-weight:600;font-size:var(--t-xl);letter-spacing:var(--tr-tight);color:var(--obsidian);}
.pdf-brand svg{width:20px;height:20px;}
.pdf-brand svg path{stroke:var(--obsidian);stroke-width:6;fill:none;stroke-linecap:round;}
.pdf-ref{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--mist);}
.la-pdfpaper h1{font-size:var(--t-xxl);font-weight:600;letter-spacing:var(--tr-tight);margin-top:20px;color:var(--obsidian);}
.la-pdfpaper h1 span{color:var(--mist);font-weight:400;}
.pdf-eyebrow{display:inline-flex;align-items:center;gap:6px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--acc);font-weight:600;margin-top:18px;}
.pdf-addr{font-size:var(--t-m);color:var(--mist);margin-top:4px;}
.pdf-parties{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:18px;}
.pdf-party{padding:14px 16px;background:var(--paper);border:1px solid color-mix(in srgb,var(--obsidian) 10%,transparent);border-radius:var(--r-s);}
.pdf-party .role{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--acc);font-weight:600;margin-bottom:6px;}
.pdf-party .name{font-size:var(--t-l);font-weight:600;color:var(--obsidian);letter-spacing:var(--tr-none);}
.pdf-party .reg{font-size:var(--t-s);color:var(--mist);margin-top:3px;}
.pdf-party .addr{font-size:var(--t-s);color:var(--mist);margin-top:7px;padding-top:7px;border-top:1px solid color-mix(in srgb,var(--obsidian) 8%,transparent);line-height:var(--lh-ui);}
.pdf-band{display:flex;margin-top:18px;border-top:1px solid color-mix(in srgb,var(--obsidian) 12%,transparent);border-bottom:1px solid color-mix(in srgb,var(--obsidian) 12%,transparent);}
.pdf-band > div{flex:1;padding:12px 16px;border-left:1px solid color-mix(in srgb,var(--obsidian) 8%,transparent);}
.pdf-band > div:first-child{border-left:0;padding-left:0;}
.pdf-band small{display:block;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--mist);}
.pdf-band b{display:block;font-size:var(--t-xl);font-weight:600;margin-top:4px;color:var(--obsidian);}
.pdf-sec{margin:26px 0 8px;display:flex;justify-content:space-between;gap:10px;font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:var(--tr-xl);text-transform:uppercase;color:var(--obsidian);font-weight:600;border-bottom:1px solid color-mix(in srgb,var(--obsidian) 35%,transparent);padding-bottom:6px;}
.pdf-sec em{font-style:normal;font-weight:500;letter-spacing:var(--tr-m);color:var(--attention-ink);}
.pdf-sum{color:var(--ink);}
.pdf-legend{font-family:var(--font-mono);font-size:var(--t-xxs);color:var(--mist);margin:6px 0 10px;}
.pdf-legend i{display:inline-block;width:7px;height:7px;border-radius:var(--r-round);margin:0 4px 0 10px;}
.pdf-legend i.hi{background:var(--mark);}
.pdf-legend i.mid{background:var(--warm);}
.pdf-legend i.low{background:var(--warm);outline:2px solid color-mix(in srgb,var(--warm) 30%,transparent);}
.pdf-grp{margin-bottom:14px;}
.pdf-gh{display:flex;justify-content:space-between;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--mist);padding:7px 0 5px;border-bottom:1px solid color-mix(in srgb,var(--obsidian) 12%,transparent);}
.pdf-row{display:grid;grid-template-columns:170px 1fr 64px 92px;gap:12px;padding:8px 0;border-bottom:1px solid color-mix(in srgb,var(--obsidian) 7%,transparent);align-items:start;font-size:var(--t-m);}
.pdf-row .l{color:var(--mist);}
.pdf-row .pbx-v b{font-weight:600;color:var(--obsidian);}
.pdf-row .pbx-v small{display:block;color:var(--mist);font-size:var(--t-s);}
.pdf-row .c{font-family:var(--font-mono);font-size:var(--t-xs);text-align:right;}
.pdf-row .c.hi{color:var(--acc);}
.pdf-row .c.mid,.pdf-row .c.low{color:var(--attention-ink);}
.pdf-row .c.low{font-weight:700;}
.pdf-row .r{font-family:var(--font-mono);font-size:var(--t-xxs);color:var(--mist-2);text-align:right;}
.pdf-flag{border-left:3px solid var(--warm);background:color-mix(in srgb,var(--warm) 5%,transparent);padding:10px 14px;margin:8px 0;}
.pdf-flag b{font-size:var(--t-m);color:var(--obsidian);}
.pdf-flag p{font-size:var(--t-m);color:var(--ink);margin-top:2px;}
.pdf-flag span{font-family:var(--font-mono);font-size:var(--t-xxs);color:var(--mist-2);display:block;margin-top:4px;}
.pdf-note{margin-top:22px;font-size:var(--t-s);color:var(--mist);border-top:1px solid color-mix(in srgb,var(--obsidian) 12%,transparent);padding-top:12px;}
.pdf-foot{display:flex;justify-content:space-between;margin-top:26px;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-xl);color:var(--mist-2);text-transform:uppercase;}
@media print{
  body.la-printing > *{visibility:hidden;}
  body.la-printing .la-pdfpaper,body.la-printing .la-pdfpaper *{visibility:visible;}
  body.la-printing .la-pdfpaper{position:fixed;inset:0;overflow:visible;max-height:none;padding:0;}
  body.la-printing::after{display:none;}
}

/* ── property record rebuilt on the original page's layout (12 Jun) ── */
.pp-back b{font-weight:600;color:var(--ft);}
.pp-u{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:var(--t-m);padding:10px 2px;border-bottom:1px solid var(--fb);}
.pp-u .un{font-weight:600;color:var(--ft);}
.pp-u .um{color:var(--fd);font-family:var(--font-mono);font-size:var(--t-s);margin-left:auto;}
.pp-pipe{display:flex;gap:6px;padding-top:4px;}
.pp-stg{flex:1;text-align:center;padding:8px 6px;border-radius:var(--r-s);background:var(--fhl);border:1px solid var(--fb);font-size:var(--t-s);color:var(--fd2);white-space:nowrap;}
.pp-stg.done{color:var(--fd);}
.pp-stg.pbx-now{background:var(--acc);color:var(--bone);border-color:var(--acc);font-weight:600;}
.pp-kv{display:flex;justify-content:space-between;gap:12px;font-size:var(--t-m);padding:8px 2px;border-bottom:1px solid var(--fb);}
.pp-kv:last-of-type{border-bottom:0;}
.pp-kv .pbx-k{color:var(--fd);}
.pp-kv .pbx-v{font-weight:600;color:var(--ft);text-align:right;}
.pp-next{display:flex;flex-wrap:wrap;gap:7px;}
.pp-next .chip{font-size:var(--t-s);font-weight:500;color:var(--acc-bright);background:color-mix(in srgb,var(--acc-bright) 12%,transparent);border-radius:100px;padding:5px 12px;display:inline-flex;align-items:center;gap:6px;cursor:pointer;transition:all .15s ease;}
.pp-next .chip:hover{background:color-mix(in srgb,var(--hover) 20%,transparent);}
:is(body.flow-dawn,body.flow-studio) .pp-next .chip{color:var(--acc);background:color-mix(in srgb,var(--acc) 9%,transparent);}
.pp-next .chip::before{content:'→';font-family:var(--font-mono);font-size:var(--t-xs);}
.pp-live{display:flex;align-items:center;gap:8px;font-size:var(--t-m);color:var(--fd);}
.pp-live .pulse{width:8px;height:8px;border-radius:var(--r-round);background:var(--acc-bright);box-shadow:0 0 0 3px color-mix(in srgb,var(--acc-bright) 18%,transparent);flex-shrink:0;}
.pp-cad{font-size:var(--t-m);color:var(--fd);line-height:var(--lh-prose);}
.pp-cad select{font-family:inherit;font-size:var(--t-m);font-weight:600;color:var(--ft);border:1px solid var(--fb2);border-radius:var(--r-s);padding:4px 8px;background:var(--fs2);margin:0 3px;}
.pp-cad b{color:var(--ft);}
.pp-fup{display:flex;align-items:center;gap:9px;font-size:var(--t-m);color:var(--ft);background:color-mix(in srgb,var(--warm) 8%,transparent);border:1px solid color-mix(in srgb,var(--warm) 22%,transparent);border-radius:var(--r-s);padding:9px 13px;margin-bottom:12px;}
.pp-fup .dot{width:7px;height:7px;border-radius:var(--r-round);background:var(--warm);flex-shrink:0;}
.pp-fup b{font-weight:600;}
.pp-fup .when{margin-left:auto;font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--attention-ink);white-space:nowrap;}
.pp-comp{background:var(--fs);border:1px solid var(--fb);border-radius:var(--r-m);padding:12px 14px;}
.pp-comp textarea{width:100%;border:0;outline:0;resize:none;background:transparent;font-family:inherit;font-size:var(--t-m);color:var(--ft);line-height:var(--lh-body);margin-top:10px;display:block;}
.pp-comp textarea::placeholder{color:var(--fd2);}
.pp-comprow{display:flex;align-items:center;gap:8px;margin-top:6px;flex-wrap:wrap;}
.pp-fuset{display:flex;align-items:center;gap:4px;flex-wrap:wrap;}
.pp-fuset .ful{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--fd2);margin-right:3px;}
.pp-fuset button{font-family:inherit;font-size:var(--t-s);color:var(--fd);background:none;border:1px solid var(--fb);border-radius:100px;padding:3px 9px;cursor:pointer;}
.pp-fuset button.pbx-on{color:var(--attention-ink);border-color:color-mix(in srgb,var(--warm) 45%,transparent);background:color-mix(in srgb,var(--warm) 9%,transparent);font-weight:600;}
.pp-comprow .post{margin-left:auto;}
.pp-hint{font-size:var(--t-s);color:var(--fd2);margin:9px 2px 2px;line-height:var(--lh-body);}
.pp-hint b{color:var(--fd);font-weight:600;}
.pp-tf{display:flex;gap:5px;margin:12px 0 4px;}
.pp-tf button{font-family:inherit;font-size:var(--t-s);color:var(--fd);background:none;border:1px solid var(--fb);border-radius:100px;padding:3px 10px;cursor:pointer;}
.pp-tf button.pbx-on{background:var(--ft);color:var(--fbg);border-color:var(--ft);font-weight:600;}
.pp-tags{display:flex;gap:8px;flex-wrap:wrap;margin-top:6px;align-items:center;}
.fu-flag{font-family:var(--font-mono);font-size:var(--t-xxs);letter-spacing:var(--tr-s);text-transform:uppercase;color:var(--attention-ink);}
.ai-sugg{font-size:var(--t-s);color:var(--acc-bright);background:color-mix(in srgb,var(--acc-bright) 10%,transparent);border-radius:100px;padding:3px 11px;cursor:pointer;}
.ai-sugg b{font-weight:600;}
:is(body.flow-dawn,body.flow-studio) .ai-sugg{color:var(--acc);background:color-mix(in srgb,var(--acc) 9%,transparent);}
.sp-space.prop .sp-sec{margin-top:30px;}
.sp-space.prop .pp-eyezone .sp-sec{margin-top:10px;}

/* ── needs-your-eye → obsidian drama panel (works on both canvases) ── */
.pp-eyezone{background:var(--obsidian);border:1px solid color-mix(in srgb,var(--bone) 14%,transparent);border-left:0;border-radius:var(--r-m);padding:2px 20px 12px;
  box-shadow:0 14px 34px -18px color-mix(in srgb,var(--obsidian) 50%,transparent);}
body.flow-dusk .pp-eyezone{background:#080A0D;border-color:color-mix(in srgb,var(--bone) 10%,transparent);}
.pp-eyezone .sp-sec{color:var(--bone);margin:12px 0 2px;}
.pp-eyezone .sp-sec::before{background:color-mix(in srgb,var(--warm) 80%,#fff);}
.pp-eyezone .sp-sec::after{border-top-color:color-mix(in srgb,var(--bone) 16%,transparent);}
.pp-eyezone .pp-eye{border-bottom:1px solid color-mix(in srgb,var(--bone) 10%,transparent);}
.pp-eyezone .pp-eye:last-child{border-bottom:0;}
.pp-eyezone .pp-eye .pbx-n{background:color-mix(in srgb,var(--warm) 30%,transparent);color:color-mix(in srgb,var(--warm) 70%,#fff);}
.pp-eyezone .pp-eye .pbx-t{color:color-mix(in srgb,var(--bone) 72%,transparent);}
.pp-eyezone .pp-eye .pbx-t b{color:var(--bone);}
.sp-viz .sp-hrow{border-radius:var(--r-s);padding:2px 4px;transition:background .12s ease;}
.sp-viz .sp-hrow:hover{background:color-mix(in srgb,var(--warm) 8%,transparent);}
.sp-viz .sp-hrow.hl-on .hl{color:var(--attention-ink);font-weight:600;}
.sp-lane.hl-on{outline:2px solid var(--warm);outline-offset:3px;border-radius:var(--r-m);}

/* ── Figure Ledger — Fig channel + ?audit=1 leak detector (§4.2 / §4.5) ── */
/* The Fig span is a transparent typed wrapper: it never changes layout — it exists so figures are a
   channel (data-fig) the audit sweep and downstream tooling can recognise. */
.fig{display:inline;}
/* The runtime leak detector only paints when ?audit=1 flags a text node with no data-fig / data-copy
   ancestor inside a governed [data-fig-scope] surface. On a coherent build it paints nothing. */
.os-audit-flag{outline:2px solid #ff2d2d !important;outline-offset:1px;background:color-mix(in srgb,#ff2d2d 12%,transparent) !important;position:relative;}
.os-audit-flag::after{content:"UNREGISTERED FIGURE";position:absolute;top:-16px;left:0;font:700 9px/1 var(--font-mono);letter-spacing:var(--tr-s);color:#fff;background:#ff2d2d;padding:2px 5px;border-radius:var(--r-xs);white-space:nowrap;z-index:99999;pointer-events:none;}

/* R86 — the signed lock, said before anything is typed. Warm rather than red: a let floor is a good
   outcome, not an error state. The person is being told what this form can and cannot do, not told off. */
.nd-lock{margin:0 0 12px;padding:9px 12px;border-radius:var(--r-s);font-size:var(--t-m);line-height:var(--lh-ui);
  background:color-mix(in srgb,var(--acc) 8%,var(--fs));border:1px solid color-mix(in srgb,var(--acc) 26%,var(--fs));color:var(--ft)}
.nd-lock b{color:var(--acc)}
.nd-wrap input:disabled,.nd-wrap textarea:disabled{color:var(--fd2);cursor:default}
.nd-wrap .cl-mchip:disabled{opacity:.6;cursor:default}

/* R86 — ending a tenancy. Warm, not alarming: a letting reaching its end is ordinary. */
.et-lead{margin:0 0 14px;font-size:var(--t-m);line-height:var(--lh-body);color:var(--fd)}
.et-lead b{color:var(--ft)}
/* R92 — a primary button that cannot act must not look like one that can. `.waiting` is the
   end-tenancy button before a reason is picked: still pressable (it explains itself), visibly not
   ready. And any genuinely disabled button in the app now reads as disabled. */
.sp-btn.primary.waiting{opacity:.5}
.sp-btn:disabled,.sp-btn.primary:disabled{opacity:.45;cursor:not-allowed}
.mact .hint.need{color:var(--attention-ink);font-weight:600}
/* R94 — the fee question in the end-tenancy panel. The book's own answer is shown first, coloured by
   what it says, so the person answering is not answering from memory. */
.et-money{margin:0 0 12px;padding:8px 11px;border-radius:var(--r-s);font-size:var(--t-m);line-height:var(--lh-ui);
  background:color-mix(in srgb,var(--fd2) 8%,var(--fs));border:1px solid var(--fb2);color:var(--fd)}
.et-money.st-raised{background:color-mix(in srgb,var(--warm) 9%,var(--fs));border-color:color-mix(in srgb,var(--warm) 28%,var(--fs));color:var(--attention-ink);font-weight:600}
.et-money.st-paid{background:color-mix(in srgb,var(--green) 9%,var(--fs));border-color:color-mix(in srgb,var(--green) 26%,var(--fs))}
.et-hint{display:block;margin-top:7px;font-size:var(--t-s);line-height:var(--lh-ui);color:var(--fd2)}
.et-hint.warn{color:var(--attention-ink)}
/* R95 — the refusal's door. A settled fee is one press away from the panel that demands it, and the
   press goes through the one payment writer, not around it. */
.et-money{display:flex;align-items:center;justify-content:space-between;gap:10px}
.et-mark{flex:0 0 auto;font:inherit;font-size:var(--t-s);font-weight:700;cursor:pointer;padding:4px 10px;border-radius:var(--r-m);
  border:1px solid var(--warm);background:color-mix(in srgb,var(--warm) 14%,var(--fs));color:var(--attention-ink);white-space:nowrap}
.et-mark:hover{background:color-mix(in srgb,var(--warm) 22%,var(--fs))}

/* ── THE ENTRANCE, RESTORED ON THE PORTED NAMES (10 Aug, Jake's ruling) ────
   THE DEFECT, NAMED: Today's blocks used to rise in on load. The port dropped the `rise` class
   because the draft has no such class and verify-today compares class lists exactly — and I filed
   that as a trade. Jake ruled it was not a trade: **restyle-in-place loses nothing, so a port that
   loses behaviour has a defect in it, not a cost.** A picture cannot authorise the removal of
   something it simply has no way of depicting; motion is invisible in a still.
   So the entrance is re-attached BY SELECTOR rather than by adding a class — the markup stays the
   draft's, node for node, and the gate is untouched. The delays are the ones the hand-built page
   used (greeting 60 · vitals 40 then staggered · stack 170 · rail 230), so the rhythm is the one
   Jake already signed off, not a new one.
   ⚠ The reduced-motion guard below is the SAME one `.rise` sits under. A new animation that does not
   honour it is a new accessibility fault, and adding one while fixing a defect is not a fix. */
.fc-stage.ported .pbx-greetrow > .pbx-phead,
.fc-stage.ported .pbx-chips4 > .pbx-statc,
.fc-stage.ported .pbx-hubtop > .pbx-stack,
.fc-stage.ported .pbx-hubtop > .pbx-rail,
.fc-stage.ported > .pbx-permline,
.fc-stage.ported > .pbx-squares{
  opacity:0;animation:riseIn .55s cubic-bezier(.2,.7,.25,1) forwards;}
.fc-stage.ported .pbx-greetrow > .pbx-phead{animation-delay:60ms;}
.fc-stage.ported .pbx-chips4 > .pbx-statc:nth-child(1){animation-delay:120ms;}
.fc-stage.ported .pbx-chips4 > .pbx-statc:nth-child(2){animation-delay:160ms;}
.fc-stage.ported .pbx-chips4 > .pbx-statc:nth-child(3){animation-delay:200ms;}
.fc-stage.ported .pbx-chips4 > .pbx-statc:nth-child(4){animation-delay:240ms;}
.fc-stage.ported .pbx-hubtop > .pbx-stack{animation-delay:170ms;}
.fc-stage.ported .pbx-hubtop > .pbx-rail{animation-delay:230ms;}
.fc-stage.ported > .pbx-permline{animation-delay:290ms;}
.fc-stage.ported > .pbx-squares{animation-delay:320ms;}
@media(prefers-reduced-motion:reduce){
  body .fc-stage.ported .pbx-greetrow > .pbx-phead,
  body .fc-stage.ported .pbx-chips4 > .pbx-statc,
  body .fc-stage.ported .pbx-hubtop > .pbx-stack,
  body .fc-stage.ported .pbx-hubtop > .pbx-rail,
  body .fc-stage.ported > .pbx-permline,
  body .fc-stage.ported > .pbx-squares{animation:none !important;opacity:1 !important;transform:none !important;}
}

/* ── THE HOST STEPS ASIDE FOR A PORTED SCREEN ──────────────────────────────
   .fc-stage is a three-column grid that placed the hand-built Today. A ported page brings its own
   frame and its own grids from the draft, so the host must stop laying out — otherwise the ported
   children auto-place into the old columns and the page looks plausible and is wrong. That is
   exactly what the first screenshot of this port showed while verify-today read 0 differences:
   the TREE was right and only the LAYOUT was not, which is the half a node-for-node gate cannot see.
   The one thing the host still owes is clearance for the fixed top bar. */
.fc-stage.ported{display:block;grid-template-columns:none;max-width:none;padding:var(--topbar-h) 0 0;}

/* ==== 12 AUG · THE PORTED SCREEN OWNS ITS OWN INSET (start) ==== */
/* ── THE DRAFT WINS ON LAYOUT (Jake + Fable, the Fees close-out) ──────────────────────────────
   A ported screen already carries the DRAFT'S OWN page frame — padding 48/48/120, max-width 1560,
   centred — because design-port copies it verbatim from the draft's own `.screen`. The space shell
   was insetting it a SECOND time, clamp(32px,4vw,76px) each side, so at a 1500px viewport the app
   had 1284px of content where the draft has 1404. Nothing in the node-for-node gate could see it:
   the TREE was right and only the WIDTH was wrong — the same class of fault as the collapsed
   .fc-stage grid on 10 Aug, and again it took a screenshot to find.
   What it actually cost: `.cards` is repeat(auto-fill,minmax(316px,1fr)), so 1284 fits THREE columns
   and 1404 fits FOUR. The picture Jake approved has four. One inset, one owner: the screen's.
   ⚠ SCOPED BY :has(), NOT BY A LIST OF SPACES, deliberately — a list is a thing the NEXT ported page
   can forget to join, and that failure would be silent (R213's family). Every context that insets
   .sp-body is answered here by name, because the takeover and full-screen rules out-specify a bare
   .sp-body and would otherwise win.
   ⚠ AND NOTHING IS MIRRORED. The obvious fix — a negative margin equal to the padding — would copy
   the 30px / 36px / clamp() figure into four places and go stale in silence the first time one of
   them moved. Zeroing the padding needs no copy of it.
   Guarded by portwidth.test.js. os-full.css is NOT in the build stamp, so this change alone does not
   move it — it is verified by effect (the rendered width), never by the stamp. */
.sp-body:has(> .pbx-screen){padding-left:0;padding-right:0;}
body[data-spaces="Takeover"] .sp-space:not(.peeking) .sp-body:has(> .pbx-screen),
.sp-space.full:not(.peeking) .sp-body:has(> .pbx-screen),
.sp-space.prop .sp-body:has(> .pbx-screen){padding-left:0;padding-right:0;}
/* 25 AUG (Jake): "remove [the lede] and move the page up — it creates a void." The lede's removal
   lives in the bundle; this closes the vertical gap it leaves behind. .pbx-screen carries its own
   48px top gutter sized for the ported/full page under the app top bar — inside a space, under the
   Back header, that gutter plus the sp-body padding read as dead space above the masthead. Scoped
   the same way the inset rules above are (direct child of sp-body), so the ported page's own
   gutter is untouched. */
.sp-body > .pbx-screen{padding-top:16px;}
/* ==== 12 AUG · the ported inset (end) ==== */

/* ==== PRAEBA PORTED DESIGN — GENERATED by apply-design-css.js, DO NOT HAND-EDIT (start) ==== */
/* source: praeba-preview/stage6/gen/design.rules.css — itself generated from
   Praeba_Design_Draft_2026-08-05.html. Scoped on .pbx, so the draft's tokens
   land on the scope and cannot reach the rest of the app. */
/* ══ OPTION C, EMBEDDED ═════════════════════════════════════════════════
   Jake ruled Option C on 10 Aug: Plus Jakarta Sans 600 (wordmark only) ·
   INSTRUMENT SERIF 400 (display) · Manrope (body and every figure) ·
   Space Mono (micro). Canon: "ONE WEIGHT, 400: never ask for 600, the
   browser fakes it" — all 11 serif call sites are at 400.
   The faces are INSIDE this file as base64 woff2. It used to fetch them from
   fonts.googleapis.com at open time, and whenever that did not complete the
   sans fell back to system-ui — the "default sans" fault, three times over.
   No network call remains. ══════════════════════════════════════════════ */
/* ══ THE CANON BLOCK — Design Brief v2.1 §15, verbatim ═══════════════════ */
.pbx{
  --canvas:#F4ECDE; --cream:#F1ECE1; --surface:#FBF6EC; --card:#FFFDF7;
  --glass:rgba(255,253,247,.58); --line:rgba(33,31,26,.08); --line-2:rgba(33,31,26,.16);
  --ink:#211F1A; --ink-2:#5A554B; --ink-3:#8E887B;
  --coral:#E1613C; --coral-hover:#EC7A54; --coral-deep:#C24E2E;
  --petrol:#1E4E4A; --petrol-2:#2A6560; --petrol-data:#1C9384;
  --iris:#6568A1;
  --sage:#949C89;   /* un-retired 25 Aug — the brief's own green, back as a chart mark */
  --p-petrol:var(--m2); --p-iris:var(--m3);   /* the old pastel names, repointed */
  --mark-strong:#1C9384; --mark-none:#D9D3C8;
  --good:#2F7D53; --warn:#E1613C; --danger:#B3362B;
  --coral-tint:#F8E3DA; --petrol-tint:#DCE9E5; --iris-tint:#E5E6EF;
  --r-s:8px; --r-m:14px; --r-l:20px; --r-pill:999px;
  /* ROLE TOKENS + OPTION A CHART MARKS — copied verbatim from the canon block of
     Praeba_Design_Brief_MASTER_v3_2026-08-10.html (§15, marker "Praeba Minimal", 10 Aug).
     ADDITIVE: no existing token changed, so screens 02-12 are untouched. */
  --action:#E1613C; --ground:#1E4E4A; --mark:#1C9384; --hover:#2A6560; --support:#6568A1;
  --m1:#93CCC4; --m2:#BEBFD7; --m3:#D9BBAB; --m4:#B5C4C6;
  --sh-1:0 1px 2px rgba(33,31,26,.05);
  --sh-2:0 1px 2px rgba(33,31,26,.05),0 14px 34px -16px rgba(33,31,26,.22);
  --focus:0 0 0 3px rgba(225,97,60,.22);
  /* ══ THE COLOUR CONTRACT — one meaning, one colour, everywhere ════════
     Jake, v2 slides 2 and 3: "can we make sure colours match up in the boxes"
     and "please ensure consistency using colours — this comment is something
     throughout". So each status, stage and invoice state is bound to ONE mark
     here, and every bar, chip, card and chart reads it from this block. A
     colour never means two things on the same page.
     Non-status breakdowns (area, client) do NOT borrow these — they use one
     mark and let the label identify, so they cannot collide. */
  /* LETTING STATES → Option A. Four coloured, the tail in the neutral (G2). */
  --st-under-offer:var(--m1); --st-available:var(--m2); --st-coming:var(--m3);
  /* FLOOR MARKS → the colour a FLOOR BAR is drawn in. Ruled by Jake on 11 Aug, with his eyes, against
     this screen: "teal under-offer, clay negotiating, grey-blue let — the approved look". Extracted
     VERBATIM from screen 07's own three floors, which have drawn exactly this since 5 Aug:
       under offer        --m1  #93CCC4  teal        (the screen wrote var(--m1))
       negotiating terms  --m3  #D9BBAB  clay        (the screen wrote var(--p-iris), which IS --m3)
       let                --m4  #B5C4C6  grey-blue   (the screen wrote var(--m4))
       available          --m2  #BEBFD7  lilac       (the space bar already wrote --st-available = --m2)
     A floor bar is a CHART MARK — it is in the geometry register — so it takes the Option A pastels,
     never the saturated status INKS, which paint the chips and the status word and are a different
     job. ADDITIVE: not one existing token changes value, so nothing outside a floor bar moves.
     ⚠ NAMED --fl-* AND NOT --st-*-mark: `--st-let-mark` ALREADY EXISTS at #5A9B6E with five live
     consumers, and one name may not carry two values. ⚠ --fl-terms is the ONE distinction the
     approved picture draws that the letting vocabulary has no word for — a floor under offer whose
     deal has moved past the offer. It is not --st-coming (that is a different meaning) and it is not
     --sg-terms (which the canon sets to --m2 and which has ZERO consumers anywhere — see the report). */
  --fl-under-offer:var(--m1); --fl-terms:var(--m3); --fl-let:var(--m4); --fl-available:var(--m2);
  /* AND THE INK THAT LABELS THE MARK. Renaming --st-underoffer to --st-under-offer (Jake, 11 Aug)
     made the two vocabularies agree — and it also handed the STATUS WORD the mark's value, because
     the word was reading the same token as the bar. Measured on the plate: `UNDER OFFER` went from
     rust to pale teal on cream, which is a legibility regression, not a restyle. The word is an INK
     and the bar is a MARK, and that is the whole lesson of this page: one token cannot be both.
     Value taken VERBATIM from screen 07's own under-offer floor, which has labelled it --coral-deep
     since 5 Aug. ⚠ The AVAILABLE word still reads --st-available (a pale mark) for the same reason,
     and the LET word still reads the app's quiet --fd where screen 07 draws it --good: both predate
     this change, both are logged, neither is fixed on a guess. */
  --fl-ink-under-offer:var(--coral-deep);
  --st-let:var(--m4);        --st-forsale:var(--mark-none); --st-none:var(--mark-none);
  /* DEAL STAGES → Option A. Offer received · negotiating terms · in solicitors ·
     awaiting signature carry the four; viewing and negotiating lease are the tail. */
  /* ── THE STAGE TABLE · RULED BY JAKE, 11 AUG (D-B12) ────────────────────────────────────────
     There were THREE answers to "what colour is a deal stage": screen 07's floors, screen 08's
     strip, and this block, and none of them agreed. Worse, the app was not reading any of them —
     the strip and the arch chart indexed a POSITIONAL array by the stage's rank in a list sorted by
     count, so a stage changed colour when the board moved. Colour identified a rank, not a meaning.
     Jake's ruling: ONE table, each stage assigned its mark once, and SCREEN 07'S TEAL WINS —
     under offer stays --m1 everywhere, because that is the look he approved twice. Screen 08's
     strip conforms to the table, not the other way round.
     ⚠ EXACTLY TWO CELLS MOVE ON SCREEN 08, and no more: Offer received --m2 -> --m1 (the ruling)
     and Viewing --m1 -> --mark-none (forced: --m1 now belongs to Offer received, and Viewing is a
     pre-pipeline lane, which is what the G2 tail is for and what this block already said).
     ⚠ --m2 IS NOW UNUSED BY THE STAGE LADDER. Stated rather than filled: three coloured stages and
     a three-stage tail is inside G2's max-of-four, and giving Awaiting signature a mark it has
     never had would be a fourth answer invented to tidy a table. It still carries Available in the
     letting ladder above.

     ── COMPLETED BY JAKE, 20 AUG (rider 0a) — THE TABLE IS THE WHOLE VOCABULARY ─────────────
     Every stage in the engine vocabulary is named here, keyed on the stage and never on its rank,
     and the neutral is an honest category rather than a gap.
     ⚠ SIX WAS ASKED FOR AND SIX IS NOT REACHABLE — MEASURED. Against the v3 chart-colour decision's
     own metric (ΔE76, its own ΔE-15 line) and its own non-coral L*78 mark roster, the best possible
     weakest link is: 3 marks 24.5 · 4 marks 16.3 · 5 marks 14.4 · 6 marks 8.2. FOUR IS THE CEILING.
     Jake: "the measurement outranks my 'no two sharing' wording — indistinguishable hues are
     sharing by another name."
     ⛔ AND THE MEASUREMENT FOUND SOMETHING UNDER THE SHIPPED KIT: the v3 doc says Option A's four
     clear at ΔE 15.3, but 15.3 is m1↔m4 and the WEAKEST pair is m2↔m4 at ΔE 13.0 — a pair quoted,
     not a minimum. On that reading a green from the v3 doc (#A0CCA6, L* 78.1) briefly replaced --m4
     in this table.
     ⛔⛔ REVERSED BY JAKE ON 20 AUG, FROM THE PLATES, AND THE REVERSAL IS THE RULING THAT STANDS.
     The green was admitted conditionally — "his final word comes at the batch-7 plates, where he
     sees it on real pages in context" — and seen there it was refused. The stage table is the
     brief's own four, --m1 · --m2 · --m3 · --m4, plus the neutral tail. **THE ΔE 13.0 FIGURE IS NOT
     WITHDRAWN AND IS NOT A FAULT**: it is a recorded advisory. An eye on real pages outranks a
     pairwise number on a swatch sheet, and this sheet's own share bento has run the four pastels
     side by side since the draft was drawn — the precedent was already in the picture.
     ⚠ WHICH STAGE TAKES WHICH IS THE LEAST-INVENTED MAPPING AVAILABLE: three cells are exactly the
     11 Aug ruling (offer --m1 · terms --m3 · solicitors --m4) and the fourth pastel goes to Awaiting
     signature, the stage this block's opening sentence always said should carry it. Nothing new is
     decided by the reversal.
     ⚠ AND NOTHING STRUCTURAL FROM 20 AUG IS UNDONE — one table, one consumer, keyed on the stage
     and never on rank, every stage in the vocabulary named, the rest states wearing the neutral by
     MEANING rather than by falling through a lookup, and the whole table declared HERE so a
     regeneration cannot revert it. Only the four values moved.
     ⚠ WHICH FOUR STAGES ARE COLOURED IS NOT NEW — it is the sentence this block opened with:
     offer received · negotiating terms · in solicitors · awaiting signature carry the four.
     ⚠ AVAILABLE AND SIGNED/COMPLETE WEAR THE NEUTRAL BY MEANING (Jake: "rest states aren't
     activity") — named rather than left to fall through, so the neutral fallback fires only for a
     stage genuinely outside the vocabulary.
     ⛔ AND IT IS DECLARED HERE, IN THE DRAFT, FOR A REASON LEARNED THE HARD WAY ON 20 AUG: this
     table was first written straight into os-full.css, INSIDE the block marked GENERATED BY
     apply-design-css.js — DO NOT HAND-EDIT. It survived four days only because nobody regenerated;
     the first run of that generator wiped the whole ruling. The draft is the source, so the ruling
     lives in the source. */

  /* ⚠ 25 AUG RIDER (Jake, from a printout of the deals + fees arch charts): "too many the
     same colour — use the colours from Where the deals are." Viewing and Negotiating lease
     wore the neutral, so three bars in one chart matched. Structure untouched — keyed on the
     stage, never rank, whole vocabulary named, REST STATES still neutral by meaning. Only the
     two neutral ACTIVITY stages gain marks, and they take the canon's own data teals
     (petrol-data · petrol-2) rather than repeating a pastel, so no two activity stages share
     a colour anywhere the ladder renders together. Declared HERE because the draft is the
     source; reaches os-full.css by design-port → apply-design-css, never by hand. */
  /* ⚠ 25 AUG — THE SEVEN-COLOUR RULING (Jake, from the brief's own accents; supersedes the
     riders above where they conflict): "we've got all our colours here. now use them."
     Seven stages, seven marks, every one already in this canon — the four pastels, the
     un-retired sage, the deep iris, and petrol-data (the brief's own "default mark") for
     the done state. Keyed on the stage, never rank (D-B12 stands); no two stages share a
     colour anywhere the ladder renders together. AVAILABLE alone keeps the neutral — the
     one true rest state. SIGNED/COMPLETE now wears the mark itself: done is not absence. */
  --sg-offer:var(--m1);        --sg-viewing:var(--m2);      --sg-terms:var(--m3);
  --sg-solicitors:var(--m4);   --sg-lease:var(--sage);      --sg-signature:var(--iris);
  --sg-complete:var(--petrol-data);
  --sg-available:var(--mark-none);
  /* INVOICE STATES → Option A. Credit notes are the tail. */
  --iv-draft:var(--m1);      --iv-issued:var(--m2);  --iv-overdue:var(--m3);
  --iv-paid:var(--m4);       --iv-credit:var(--mark-none);
  --logo:'Plus Jakarta Sans',sans-serif;
  --serif:'Instrument Serif',Georgia,serif;
  --sans:'Manrope',system-ui,sans-serif;
  --mono:'Space Mono',monospace;
}*{box-sizing:border-box;}/* ── the contact sheet ─────────────────────────────────────────────────── */
.pbx-screen{display:block;padding:48px 48px 120px;max-width:1560px;margin:0 auto;}.pbx-screen.pbx-on{display:block;}.pbx-caption{display:flex;align-items:baseline;gap:12px;margin-bottom:32px;
  padding-bottom:12px;border-bottom:1px solid var(--line-2);}.pbx-caption h2{margin:0;font:400 15px/1.2 var(--serif);}.pbx-caption span{font:400 10px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);}.pbx-caption em{margin-left:auto;font:400 11px/1.5 var(--sans);font-style:normal;color:var(--ink-3);max-width:56ch;text-align:right;}/* ══ §06 · TYPE ═════════════════════════════════════════════════════════ */
.pbx-wm{font:600 17px/1 var(--logo);letter-spacing:-.02em;text-transform:lowercase;}.pbx-kick{font:400 10px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);}.pbx-ttl{font:800 22px/1.15 var(--sans);letter-spacing:-.02em;margin:0;}.pbx-ttl-lg{font:400 34px/1.12 var(--serif);letter-spacing:-.01em;margin:0;}.pbx-sect{font:700 15px/1.2 var(--sans);}.pbx-fig{font:800 20px/1 var(--sans);font-variant-numeric:tabular-nums;}.pbx-fig-lg{font:800 28px/1 var(--sans);letter-spacing:-.03em;font-variant-numeric:tabular-nums;}.pbx-hero{font:800 44px/1 var(--sans);letter-spacing:-.03em;font-variant-numeric:tabular-nums;}.pbx-hero small{display:block;font:400 11px/1.4 var(--mono);letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-3);margin-top:8px;}.pbx-lbl{font:600 11px/1.3 var(--sans);color:var(--ink-2);}.pbx-mut{color:var(--ink-3);}.pbx-dash{color:var(--ink-3);}.pbx-note{font:400 11px/1.6 var(--sans);color:var(--ink-3);}.pbx-s{font:400 9px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);}/* ══ SURFACES ═══════════════════════════════════════════════════════════ */
.pbx-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-m);box-shadow:var(--sh-1);}.pbx-panel{background:var(--card);border:1px solid var(--line);border-radius:var(--r-l);box-shadow:var(--sh-1);}.pbx-pad{padding:24px;}.pbx-stack{display:flex;flex-direction:column;gap:32px;}.pbx-stack-s{display:flex;flex-direction:column;gap:16px;}.pbx-row{display:flex;align-items:center;gap:16px;}.pbx-grow{flex:1;min-width:0;}.pbx-cols2{display:grid;grid-template-columns:1fr 1fr;gap:32px;}.pbx-cols3{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;}.pbx-vizc{background:var(--card);border:1px solid var(--line);border-radius:var(--r-l);box-shadow:var(--sh-1);padding:24px;}.pbx-vizc h4{margin:0 0 4px;font:400 15px/1.2 var(--serif);}/* ══ BUTTONS — one coral action per view ═══════════════════════════════ */
.pbx-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:36px;padding:0 16px;
  border-radius:var(--r-s);cursor:pointer;font:600 12px/1 var(--sans);
  border:1px solid var(--line-2);background:var(--card);color:var(--ink);}.pbx-btn:hover{border-color:var(--ink-3);}.pbx-btn.pbx-primary{background:var(--action);border-color:var(--action);color:#FFF6F0;font-weight:700;height:44px;padding:0 24px;}.pbx-btn.pbx-primary:hover{background:var(--coral-hover);border-color:var(--coral-hover);}.pbx-btn.pbx-ghost{background:transparent;border-color:transparent;color:var(--ink-2);}.pbx-btn.pbx-ghost:hover{background:var(--surface);color:var(--ink);}.pbx-btn.pbx-danger{color:var(--danger);border-color:var(--danger);background:transparent;}.pbx-btn.pbx-sm{height:32px;padding:0 12px;font-size:11px;}.pbx-btn:focus-visible{outline:none;box-shadow:var(--focus);border-color:var(--coral);}/* ══ CHIPS ══════════════════════════════════════════════════════════════ */
.pbx-chip{display:inline-flex;align-items:center;gap:4px;height:22px;padding:0 8px;border-radius:var(--r-pill);
  border:1px solid var(--line-2);background:var(--surface);
  font:700 9px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-2);white-space:nowrap;}.pbx-chip svg{width:11px;height:11px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}.pbx-chip.pbx-on{background:var(--petrol);border-color:var(--petrol);color:var(--card);}.pbx-chip.pbx-warnct{background:rgba(225,97,60,.12);border-color:transparent;color:var(--coral-deep);}.pbx-chip.pbx-good{background:var(--petrol-tint);border-color:transparent;color:var(--good);}.pbx-chip.pbx-watch{background:var(--coral-tint);border-color:transparent;color:var(--coral-deep);}.pbx-chip.pbx-bad{background:var(--coral-tint);border-color:transparent;color:var(--danger);}.pbx-chip.pbx-iris{background:var(--iris-tint);border-color:transparent;color:var(--iris);}.pbx-chip.pbx-none{background:var(--surface);border-color:var(--line-2);color:var(--ink-3);}/* ══ SEARCH ═════════════════════════════════════════════════════════════
   ADDED 11 Aug, and INHERITED RATHER THAN INVENTED (Jake ruled it): the product already has a
   designed search field — the global "Find a property or person" bar — so this is that treatment as
   a smaller variant, and the app has ONE search look instead of two that drifted apart. Same pill
   radius, same hairline border, the same transparent input inside a bordered shell.
   WHAT CHANGES FOR THIS SIZE, and why: the placeholder is MONO, because this field sits in a lens
   row of mono chips and an inherited sans placeholder reads there as a foreign object. The focus
   ring is PETROL — the canon's own accent — where the global bar uses --hover, a chrome token that
   does not exist inside this scope.
   ⚠ THE TYPED VALUE IS NOT UPPERCASED. Only the placeholder is. Shouting a landlord's name back at
   the person typing it is what happens when a chip's type rule is applied to a field without asking
   what the field is for.
   ⚠ AND THE CONTROL IS HERE AT ALL BECAUSE A STILL CANNOT DEPICT A FIELD BEING TYPED INTO — screen
   06 never drew one, the page needs one, so the control was added to the picture and its LOOK is
   authored HERE, in the design, rather than decided in passing by whichever session ported the page.
   No new token: every value below is already canon, which is why brandgen is unchanged. */
.pbx-search{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 10px;
  border-radius:var(--r-pill);border:1px solid var(--line-2);background:var(--card);
  transition:border-color .18s ease,box-shadow .18s ease;}.pbx-search svg{width:11px;height:11px;fill:none;stroke:var(--ink-3);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;}.pbx-search input{width:150px;background:transparent;border:0;outline:0;padding:0;
  font:400 9px/1 var(--mono);letter-spacing:.08em;color:var(--ink);}.pbx-search input::placeholder{color:var(--ink-3);text-transform:uppercase;letter-spacing:.08em;}.pbx-search:focus-within{border-color:var(--petrol);box-shadow:0 0 0 3px rgba(30,78,74,.12);}.pbx-lens{display:flex;gap:8px;flex-wrap:wrap;align-items:center;}/* AMEND 6 Aug (client, slide 10): "The select options here should be the only two
   that affect the graphics. Then put the rest below the graphics that affect the
   list."  One lens row is now TWO, and the client's second sentence is the hard
   part — "the two rows should not look like one row that wrapped". So each row is
   LABELLED with what it governs (a `.s` caption, ruled off from the chips), and
   the list's row is joined to the list by a hairline rather than floating between
   the two. No background is added to either: the page has one ground. */
.pbx-lens.pbx-lensx{gap:8px;align-items:center;}.pbx-lens.pbx-lensx > .pbx-s{align-self:center;padding-right:10px;border-right:1px solid var(--line-2);}.pbx-lens.pbx-lensx > .pbx-note{margin-left:4px;}.pbx-lens.pbx-lensx.pbx-forlist{padding-top:16px;border-top:1px solid var(--line);}/* ══ TABLES — cards first, TABLE UNDERNEATH (slide 12, ruled) ══════════ */
table.pbx-t{width:100%;border-collapse:collapse;}table.pbx-t th{font:700 8.5px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);
  /* 19 Aug — the product corrected the flush table head (Jake's walk ruling); the draft follows. */
  text-align:left;padding:16px 16px 8px;border-bottom:1px solid var(--line-2);background:var(--card);}table.pbx-t th.pbx-n{text-align:right;}table.pbx-t td{height:44px;padding:0 16px;border-bottom:1px solid var(--line);font:600 13px/1.4 var(--sans);vertical-align:middle;}table.pbx-t tr:last-child td{border-bottom:0;}table.pbx-t tbody tr:hover td{background:rgba(33,31,26,.03);}table.pbx-t tr.pbx-sel td:first-child{box-shadow:inset 3px 0 0 var(--coral);}table.pbx-t td.pbx-name{font-weight:600;}table.pbx-t td.pbx-n{text-align:right;font-weight:800;font-variant-numeric:tabular-nums;}/* ══ 12 AUG · JAKE'S RULING ON THE TENANCY SCHEDULE ═══════════════════════════
   "Unbold every figure except the Totals row." The rule above — table.t td.n{font-weight:800} —
   is shared by Portfolio, Book and every other table, so it is NOT edited: the quiet reading is
   opted into per table, exactly where ruled, and everything else keeps the weight it had. */
table.pbx-t.pbx-quiet td{font-weight:400;}/* ══ 12 AUG · THE MONEY TIMELINE'S FIVE PHASE MARKS ═══════════════════════════
   The legend's swatch was about to be an inline style carrying a COLOUR, which is the one thing the
   design-debt ratchet exists to stop: appearance belongs in the sheet, and a colour in a style
   attribute is invisible to every check that reads this file. Declared per phase, in the chart kit's
   own inks, in the order the money moves. `available` takes the neutral because it is not money yet. */
.pbx-ph-available i{background:var(--mark-none);}.pbx-ph-pipeline i{background:var(--m1);}.pbx-ph-achieved i{background:var(--m2);}.pbx-ph-invoiced i{background:var(--m3);}.pbx-ph-paid i{background:var(--m4);}/* the schedule's sub-line sits tight under its header — spacing, declared not inlined */
.pbx-schedsub{margin-top:4px;}/* ══ 12 AUG · THE SUMMONED DOCUMENTS' OWN RHYTHM ══════════════════════════════
   Tabs A and F are drawn here as full screens and rendered in the app as panels
   summoned over the property record. I first drew their spacing INLINE on the
   plate — and inline spacing cannot travel: it has no name for the porter to
   carry and the app's ratchet refuses inline style outright, so the app got the
   markup with none of the gaps and the legend sat on the table's head. Jake
   photographed exactly that. Each gap is declared here, named for the part of
   the document it separates, and the plate wears the same classes the app does,
   so the two cannot drift again. */
.pbx-dochead{display:flex;align-items:baseline;gap:12px;margin-bottom:4px;}.pbx-docact{display:flex;align-items:center;gap:8px;margin-left:auto;}.pbx-docfigs{margin-top:20px;}.pbx-doctable{margin-top:16px;}.pbx-docnote{margin-top:12px;}/* a record laid out as ONE column — no right rail. The plate carried this inline, and an inline
   declaration cannot travel: the app's ratchet refuses `style={{`, so the panel could never answer
   the plate at that node and every child below it misaligned in the gate. Declared, named for what
   it is. */
.pbx-rec.pbx-wide{grid-template-columns:1fr;}/* ══ 12 AUG · THE SCHEDULE'S COLUMN PROPORTIONS (Fable's diff) ════════════════
   The plate draws every row at one line: a unit name, a tenant with its applicant
   chip beside it, and the Total's figures. The plate's OWN data is short, so it
   never showed what a building with longer names does — "Fourth floor" broke over
   two lines and the row lost the 44px it is drawn at. The three columns that must
   hold their line are named here. Everything else may wrap: a review clause that
   honestly reads "5-yearly, upward only" should take the space it needs rather
   than push a fourteen-column document off its own page. */
table.pbx-t.pbx-sched th{white-space:nowrap;}table.pbx-t.pbx-sched td.pbx-name{white-space:nowrap;}table.pbx-t.pbx-sched td.pbx-tenant{white-space:nowrap;}table.pbx-t.pbx-sched td.pbx-when{white-space:nowrap;}table.pbx-t.pbx-sched tr.pbx-total td{white-space:nowrap;}table.pbx-t.pbx-quiet td.pbx-n{font-weight:400;}table.pbx-t.pbx-quiet td.pbx-name{font-weight:600;}table.pbx-t tr.pbx-total td{font-weight:800;border-top:1px solid var(--line);border-bottom:0;}table.pbx-t tr.pbx-total td.pbx-name{font-weight:800;}table.pbx-t td.pbx-st{text-align:right;}/* AMEND 6 Aug (client, slide 5): "Table needs to be clear with a clear heading.
   Each property needs to be clickable, the information should be there because we
   are using the same data as before."
   The heading is a `.sech` inside the panel — the same section header every other
   panel in this draft uses — and is markup, below. These rules are the second half
   of the comment: the row now SAYS it opens. Cursor, a chevron beside the name,
   and a petrol wash on hover. Petrol, not coral: coral is the one action on this
   view ("Add a property"), and a hover is not an action.
   The hover WASH is deliberately left as the sheet already had it: every other
   row in this product highlights to the same quiet tint, and a table that lit up
   differently from every other table would be the inconsistency the client keeps
   flagging. Only the chevron takes petrol, and only on hover. */
table.pbx-t tbody tr{cursor:pointer;}table.pbx-t td.pbx-name i{font-style:normal;font-weight:700;color:var(--ink-3);margin-left:6px;
  display:inline-block;opacity:.5;transition:opacity .15s ease,transform .15s ease;}table.pbx-t tbody tr:hover td.pbx-name i{opacity:1;color:var(--petrol);transform:translateX(2px);}/* slide 10 — "on the page they show a max of 8 before some clicks to view
   table". The grid is capped at 8 and the fold below carries the rest. */
.pbx-tablefold{margin-top:24px;}.pbx-tablefold summary{cursor:pointer;list-style:none;display:inline-flex;align-items:center;gap:8px;
  font:700 9px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);
  border:1px solid var(--line-2);border-radius:var(--r-pill);padding:10px 16px;background:var(--card);}.pbx-tablefold summary::-webkit-details-marker{display:none;}.pbx-tablefold summary:hover{border-color:var(--ink-3);}.pbx-tablefold[open] summary{margin-bottom:16px;}/* ══ THE CARD — slide 12. "a small display of data which gives the core
      facts, and if you need more you click through to its own page."
      Headline = the name + the money · Status = the stage · Address. ════ */
.pbx-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(316px,1fr));gap:16px;}.pbx-tc{background:var(--card);border:1px solid var(--line);border-radius:var(--r-m);box-shadow:var(--sh-1);
  padding:20px;display:flex;flex-direction:column;gap:14px;cursor:pointer;
  transition:border-color .16s ease, box-shadow .16s ease;}.pbx-tc:hover{border-color:var(--line-2);box-shadow:var(--sh-2);}.pbx-tc-head{display:flex;align-items:flex-start;gap:12px;}.pbx-tc-av{width:38px;height:38px;border-radius:var(--r-pill);background:var(--petrol-tint);color:var(--petrol);
  font:700 12px/38px var(--sans);text-align:center;flex-shrink:0;letter-spacing:.02em;}.pbx-tc-id{min-width:0;flex:1;display:block;}.pbx-tc-nm{display:block;font:600 14px/1.25 var(--sans);}.pbx-tc-sub{display:block;font:400 10px/1.5 var(--mono);color:var(--ink-2);margin-top:3px;}.pbx-tc-money{text-align:right;flex-shrink:0;max-width:62%;}/* ⚠ THE CAP IS THE GUARD (S2, 12 Aug).
  flex-shrink:0 is right for a figure — "£180,500" must never be broken across lines — but with no
  ceiling it also meant the box sized to its content for ever. Live, this slot took a SENTENCE
  (engine.js:3006 composes "£54,500 pa · 1,650 sq ft on the market"), which could neither shrink nor
  wrap, so it crushed .tc-id to nothing, wrapped a building's name down three lines and ran off the
  card. Four cards on the live Portfolio, every one of them a long-form headline; every short one
  fine, which is why no plate and no test ever saw it. The cap leaves the name at least 38% and lets
  a long value wrap at its spaces. Short figures have no spaces and are untouched — the plates are
  byte-identical. */
.pbx-tc-money b{display:block;font:800 var(--t-xl)/1 var(--sans);letter-spacing:-.02em;font-variant-numeric:tabular-nums;}/* Fraunces frames the number; Manrope is the number. */
.pbx-tc-money i{display:block;font:400 italic 12px/1.35 var(--serif);color:var(--ink-2);margin-top:4px;}.pbx-tc-stats{display:grid;grid-template-columns:repeat(3,1fr);
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);}.pbx-tc-stats div{padding:12px 0;}.pbx-tc-stats div+div{border-left:1px solid var(--line);padding-left:12px;}.pbx-tc-stats b{display:block;font:800 17px/1 var(--sans);font-variant-numeric:tabular-nums;}.pbx-tc-stats span{display:block;font:400 9px/1.4 var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink-2);margin-top:4px;}/* ── 6 Aug 2026 · SLIDE 13 (Deals) · "sort formatting" ─────────────────────
   The board's third stat carries a SENTENCE ("12 days since it moved"), not a
   unit. It fitted on one line on one card and wrapped to two on the next, so
   the address and the status chip sat on different lines across a row of six —
   and with no padding on the right it ran into the card's own edge. Two lines
   are reserved for every label on the board and the cells are kept off the
   rules between them, so the six cards read as one row. Scoped: the Book's
   cards are three units wide and Jake calls them good. */
.pbx-dealcards .pbx-tc-stats span{min-height:26px;}.pbx-dealcards .pbx-tc-stats div{padding-right:12px;}/* the same fault one row higher: a building name or an applicant line that
   runs to two lines ("22 Rivington Street · Attwater & Sons · Sarah Penrose")
   pushed that card's whole body down while its neighbour's stayed put. The
   cards already stretch to a common height in the grid, so reserving the
   second line costs nothing that was not already paid for — and it buys the
   row one set of baselines. */
.pbx-dealcards .pbx-tc-nm{display:block;min-height:35px;}.pbx-dealcards .pbx-tc-sub{min-height:30px;}/* 25 Aug (Jake, "S2 — make sure the lines are in line with each other"): the slide-13
   alignment treatment is PROMOTED from the deal grid to every card grid — on Portfolio and
   Contacts a wrapped name pushed the stats row and the status pill out of line across a row
   of cards. Same recipe, same figures, now on the shared card family. */
.pbx-cards .pbx-tc-nm{display:block;min-height:35px;}.pbx-cards .pbx-tc-sub{min-height:30px;}.pbx-tc-bar{height:6px;border-radius:var(--r-pill);background:var(--surface);overflow:hidden;display:flex;}.pbx-tc-bar i{display:block;height:100%;}.pbx-tc-addr{display:block;font:400 10px/1.5 var(--mono);color:var(--ink-2);}.pbx-tc-foot{display:flex;align-items:center;gap:8px;margin-top:auto;}.pbx-tc-go{margin-left:auto;font:700 9px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);}.pbx-tc:hover .pbx-tc-go{color:var(--petrol);}.pbx-tc-spark{display:flex;gap:3px;align-items:flex-end;height:14px;}.pbx-tc-spark i{width:7px;background:var(--p-petrol);border-radius:2px 2px 0 0;display:block;}.pbx-pills{display:flex;flex-wrap:wrap;gap:6px;}.pbx-pills b{font:600 10px/1 var(--sans);color:var(--ink-2);background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-pill);padding:6px 10px;white-space:nowrap;}.pbx-pills b.pbx-more{color:var(--ink-3);border-style:dashed;}.pbx-horizon li{list-style:none;position:relative;padding:0 0 16px 20px;}.pbx-horizon li::before{content:'';position:absolute;left:0;top:6px;width:7px;height:7px;
  border-radius:var(--r-pill);background:var(--petrol-data);}.pbx-horizon .pbx-w{display:block;font:600 12px/1.45 var(--sans);color:var(--ink);}.pbx-horizon .pbx-d{display:block;font:400 10px/1.5 var(--mono);color:var(--ink-2);margin-top:3px;}.pbx-tc.pbx-add{border-style:dashed;align-items:center;justify-content:center;color:var(--ink-3);
  font:600 12px/1 var(--sans);min-height:220px;box-shadow:none;background:transparent;}/* ══ ARC FAMILY ═════════════════════════════════════════════════════════ */
.pbx-dome{background:var(--petrol-tint);border-radius:var(--r-l);padding:24px;text-align:center;}.pbx-dome .pbx-cap{font:700 13px/1.2 var(--sans);color:var(--petrol);display:block;margin-bottom:8px;}.pbx-dome .pbx-val{font:800 34px/1 var(--sans);letter-spacing:-.03em;color:var(--petrol);font-variant-numeric:tabular-nums;}.pbx-dome .pbx-un{font:700 9px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--petrol-2);display:block;margin-top:8px;}.pbx-dome .pbx-note{color:var(--petrol-2);margin:12px 0 0;}/* ── the stacked status bar Jake asked back for (slides 3 and 6) ─────── */
.pbx-statusbar{padding:20px 24px;background:var(--card);border:1px solid var(--line);border-radius:var(--r-m);box-shadow:var(--sh-1);}.pbx-statusbar .pbx-sbh{display:flex;align-items:baseline;gap:12px;margin-bottom:12px;}.pbx-statusbar .pbx-sbh .pbx-t{font:400 10px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);}.pbx-statusbar .pbx-sbh .pbx-r{margin-left:auto;font:400 10px/1 var(--mono);color:var(--ink-2);}.pbx-sbar{display:flex;height:16px;border-radius:var(--r-pill);overflow:hidden;background:var(--surface);}.pbx-sbar i{display:block;height:100%;}.pbx-sbleg{display:flex;flex-wrap:wrap;gap:20px;margin-top:12px;}.pbx-sbleg span{font:600 11px/1 var(--sans);color:var(--ink-2);display:inline-flex;align-items:center;gap:8px;}.pbx-sbleg i{width:9px;height:9px;border-radius:var(--r-pill);display:inline-block;}.pbx-sbleg b{font:800 11px/1 var(--sans);color:var(--ink);font-variant-numeric:tabular-nums;}.pbx-legend{display:flex;flex-wrap:wrap;gap:12px;margin-top:12px;}.pbx-legend i{display:inline-block;width:10px;height:10px;border-radius:var(--r-pill) var(--r-pill) 0 0;margin-right:8px;vertical-align:-1px;}.pbx-legend span{font:600 11px/1 var(--sans);color:var(--ink-2);}.pbx-legend b{font:800 11px/1 var(--sans);color:var(--ink);margin-left:8px;font-variant-numeric:tabular-nums;}.pbx-segpill{display:flex;height:14px;border-radius:var(--r-pill);overflow:hidden;background:var(--surface);}.pbx-segpill i{display:block;height:100%;}.pbx-delta{font:600 11px/1 var(--sans);color:var(--good);}.pbx-bento{display:grid;gap:8px;grid-auto-rows:76px;}.pbx-bento div{border-radius:var(--r-s);padding:12px;display:flex;flex-direction:column;justify-content:flex-end;}.pbx-bento b{font:800 17px/1 var(--sans);font-variant-numeric:tabular-nums;}.pbx-bento span{font:600 10px/1.25 var(--sans);opacity:.85;margin-top:4px;}.pbx-kpirow{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;}.pbx-kpi .pbx-v{font:800 24px/1 var(--sans);letter-spacing:-.02em;font-variant-numeric:tabular-nums;}.pbx-kpi .pbx-l{font:400 9px/1.4 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);display:block;margin-top:4px;}/* the big KPI row Jake preferred on Book */
.pbx-kpibig{display:grid;grid-template-columns:repeat(4,1fr);gap:32px;padding-bottom:32px;border-bottom:1px solid var(--line);margin-bottom:32px;}.pbx-kpibig .pbx-v{font:800 34px/1 var(--sans);letter-spacing:-.03em;font-variant-numeric:tabular-nums;}.pbx-kpibig .pbx-l{display:block;font:400 9px/1.4 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);margin-top:8px;}.pbx-kpibig .pbx-d{display:block;font:600 12px/1.4 var(--sans);color:var(--ink-2);margin-top:4px;}/* ══ THE DOCK ═══════════════════════════════════════════════════════════ */
.pbx-dock{position:sticky;bottom:24px;margin:48px auto 0;width:max-content;z-index:150;
  display:flex;align-items:center;gap:4px;padding:8px 12px;border-radius:var(--r-pill);
  background:var(--glass);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  border:1px solid var(--line-2);box-shadow:var(--sh-2);}.pbx-dock .pbx-wv{display:inline-flex;padding:0 8px 0 4px;}.pbx-dock .pbx-wv svg{width:24px;height:24px;}.pbx-dock .pbx-wv path{stroke:var(--coral);stroke-width:6;fill:none;stroke-linecap:round;}.pbx-dock b{font:600 13px/1 var(--sans);color:var(--ink-2);padding:8px 12px;border-radius:var(--r-pill);white-space:nowrap;cursor:pointer;}.pbx-dock b.pbx-on{background:var(--petrol);color:var(--card);}.pbx-dock b:hover:not(.pbx-on){color:var(--ink);background:rgba(33,31,26,.06);}.pbx-dock b:nth-of-type(1){transform:translateY(2px);}.pbx-dock b:nth-of-type(2){transform:translateY(-1px);}.pbx-dock b:nth-of-type(3){transform:translateY(-2.5px);}.pbx-dock b:nth-of-type(4){transform:translateY(-2.5px);}.pbx-dock b:nth-of-type(5){transform:translateY(-1px);}.pbx-dock b:nth-of-type(6){transform:translateY(2px);}/* ══ PAGE HEADER — page header only, no status bar ═════════════════════ */
.pbx-phead{display:flex;align-items:flex-start;gap:24px;padding-bottom:16px;
  border-bottom:1px solid var(--line);margin-bottom:32px;flex-wrap:wrap;}.pbx-phead .pbx-l{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px;}.pbx-phead .pbx-acts{display:flex;align-items:center;gap:8px;padding-top:24px;}/* JAKE, 10 Aug: "the four white cards in line with the title, move billing year
   down, I don't like having so much empty space." The greeting and the four
   vitals share ONE FULL-WIDTH ROW — nothing sits beside them, so the cards keep
   their width and the half-empty line next to the title is gone. The rail below
   leads with the Ledger; the billing year sits under it. */
.pbx-greetrow{display:grid;grid-template-columns:minmax(0,400px) minmax(0,1fr);gap:40px;
  align-items:center;margin-bottom:32px;}.pbx-greetrow .pbx-phead{padding-bottom:0;border-bottom:0;}.pbx-topbar{display:flex;align-items:center;gap:12px;padding:0 0 16px;
  border-bottom:1px solid var(--line);margin-bottom:28px;}.pbx-topbar .pbx-wv{width:26px;height:26px;display:inline-flex;align-items:center;flex-shrink:0;}.pbx-topbar .pbx-wv path{stroke:var(--ink);stroke-width:6;fill:none;stroke-linecap:round;}.pbx-topbar .pbx-wm{font:600 17px/1 var(--logo);letter-spacing:-.02em;text-transform:lowercase;color:var(--ink);}.pbx-topbar .pbx-bdiv{width:1px;height:16px;background:var(--line-2);margin:0 4px;}.pbx-topbar .pbx-firm{font:400 italic 15px/1 var(--serif);color:var(--ink-2);}.pbx-topbar .pbx-rt{margin-left:auto;display:flex;align-items:center;gap:14px;}.pbx-topbar .pbx-dt{font:700 12px/1 var(--sans);color:var(--ink);}.pbx-topbar .pbx-sy{display:inline-flex;align-items:center;gap:6px;font:400 9px/1 var(--mono);
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);}.pbx-topbar .pbx-sy i{width:6px;height:6px;border-radius:var(--r-pill);background:var(--mark);display:inline-block;}.pbx-topbar .pbx-tg{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line-2);
  border-radius:var(--r-pill);padding:6px 12px;font:400 9px/1 var(--mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-2);background:var(--card);}.pbx-topbar .pbx-cg{width:28px;height:28px;border-radius:50%;background:var(--ground);color:var(--card);
  display:inline-flex;align-items:center;justify-content:center;font-size:12px;flex-shrink:0;}.pbx-hubmark{display:flex;align-items:baseline;gap:12px;}.pbx-hubmark .pbx-wv{width:22px;height:22px;align-self:center;}.pbx-hubmark .pbx-wv path{stroke:var(--coral);stroke-width:6;fill:none;stroke-linecap:round;}.pbx-hubmark .pbx-firm{font:400 italic 15px/1 var(--serif);color:var(--ink-2);}.pbx-hubmark .pbx-sep{width:1px;height:14px;background:var(--line-2);}/* ══ TODAY ══════════════════════════════════════════════════════════════ *//* slide 1: the live feed STOPS at the permission line, and below it Invoices
   and People are two separate larger squares next to each other. */
.pbx-hubtop{display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:32px;align-items:start;}.pbx-chips4{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;}.pbx-statc{background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-l) var(--r-l) var(--r-s) var(--r-s);   /* §08 arch top */
  box-shadow:var(--sh-1);padding:20px 16px 16px;display:flex;flex-direction:column;gap:8px;min-height:150px;}.pbx-statc .pbx-cap{font:400 9px/1.2 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);}.pbx-statc .pbx-sub{font:600 11px/1.4 var(--sans);color:var(--ink-2);margin-top:auto;}.pbx-sec{background:var(--card);border:1px solid var(--line);border-radius:var(--r-l);box-shadow:var(--sh-1);overflow:hidden;}.pbx-sech{display:flex;align-items:center;gap:12px;padding:16px 24px;background:var(--surface);border-bottom:1px solid var(--line);}.pbx-sech .pbx-n{margin-left:auto;font:800 20px/1 var(--sans);font-variant-numeric:tabular-nums;}.pbx-v{display:inline-flex;align-items:center;gap:4px;height:32px;padding:0 12px;border-radius:var(--r-pill);
  border:1px solid var(--line-2);background:transparent;color:var(--ink-2);cursor:pointer;
  font:700 9px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;}.pbx-v:hover{border-color:var(--coral);color:var(--coral);}.pbx-v svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}/* ── 6 Aug 2026 · SLIDE 14 (Book) · "just formatting needs to be fixed" ────
   `.v` names TWO things in this sheet: the pill BUTTON declared immediately
   above (a 32px-tall outlined "Open →"), and the VALUE inside a .kpi / .kpibig
   tile. `.kpibig .v` only restates the FONT, so the button's pill — its height,
   its 12px of padding, its rule and its uppercasing — was landing on every KPI
   number and pushing it 12px to the right of its own label. That is the
   misalignment on the Book's big four.
   Scoped to the Book by an opt-in class so this correction cannot move another
   agent's page mid-flight. ⚠ THE SAME COLLISION IS LIVE ON s-people (four .kpi
   tiles) AND s-firm (four more) — reported, one rule closes all three. */
.pbx-kpibig.pbx-kpi-plain .pbx-v{display:inline;height:auto;padding:0;border:0;border-radius:0;
  background:transparent;color:var(--ink);cursor:auto;text-transform:none;letter-spacing:-.03em;}/* ⚠ CLOSED AT THE SOURCE, 6 Aug, same day. The scoped fix above repaired the
   Book and left the same collision live on eight more tiles across s-people and
   s-firm — a correction that only works where somebody remembered to opt in is
   half a fault. `.v` is a BUTTON. Every place it is one, it is one; so the pill
   rule is restated for `button.v` and the bare `.v` above stops claiming a
   value. Nothing on any page changes except that a KPI number now starts where
   its own label starts. */
.pbx-kpi .pbx-v,.pbx-kpibig .pbx-v{display:inline;height:auto;padding:0;border:0;border-radius:0;
  background:transparent;color:var(--ink);cursor:auto;text-transform:none;}.pbx-kpi .pbx-v:hover,.pbx-kpibig .pbx-v:hover{border-color:transparent;color:var(--ink);}/* ══ 6 Aug 2026 · SLIDE 14 · THE BOOK'S TRAFFIC LIGHTS — A DECLARED EXCEPTION
   Jake, slide 14: *"On this page I feel this is where the traffic light system
   is appropriate."*  RULED: traffic lights on the BOOK, and only on the Book.
   Every other surface keeps the colour contract above — --st-* for a schedule
   status, --sg-* for a deal stage, --iv-* for an invoice state — where colour
   MEANS a named thing and never a temperature.

   Three marks, no fourth. They answer ONE question: how much lease is left.
     green  a lease running for years
     amber  one expiring, or breaking, inside twelve months
     red    one expired or overdue
   Green is the canon --good and red is the canon --danger; red is NEVER the
   coral action colour (--warn IS coral, which is why it cannot serve as the
   amber either). Amber has no canon token, so ONE is declared here and used
   nowhere else in this sheet. It is darkened to #9E690F so the status WORD is
   legible on cream — the same order of contrast --good already carries.
   ⚠ PROPOSED until Jake ticks the amber hex itself. ═══════════════════════ */
.pbx{
  /* JAKE, 10 Aug: "instead of the green for active can we have the brand teal."
     Active is not a status judgement, it is the normal state of a lease — so it takes
     the brand mark. --good stays for things that are actually good news. */
  --tl-green:var(--mark);      --tl-green-tint:var(--petrol-tint);
  --tl-amber:var(--warn);      --tl-amber-tint:var(--coral-tint);
  /* AMBER RETIRED — Jake, 10 Aug: "praeba has no amber". Attention and warm
     states take coral at chip intensity. The token names survive so the Book's
     18 call sites keep working; only the value moves. */
  --tl-red:var(--danger);      --tl-red-tint:var(--coral-tint);
}.pbx-permline{display:flex;align-items:center;gap:12px;margin:32px 0;}.pbx-permline i{flex:1;height:1px;background:var(--line-2);}.pbx-permline span{font:700 9px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);display:inline-flex;align-items:center;gap:4px;}.pbx-permline svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.8;}/* the two larger squares */
.pbx-squares{display:grid;grid-template-columns:1fr 1fr;gap:32px;}.pbx-square{background:var(--card);border:1px solid var(--line);border-radius:var(--r-l);box-shadow:var(--sh-1);
  display:flex;flex-direction:column;min-height:520px;overflow:hidden;}.pbx-square .pbx-sqh{display:flex;align-items:center;gap:12px;padding:20px 24px;background:var(--surface);border-bottom:1px solid var(--line);}.pbx-square .pbx-sqb{padding:24px;display:flex;flex-direction:column;gap:16px;flex:1;}/* ── the question, one at a time on Today (slide 2) ─────────────────── */
.pbx-q{padding:24px;}.pbx-q+.pbx-q{border-top:1px solid var(--line);}.pbx-qt{font:700 17px/1.4 var(--sans);letter-spacing:-.01em;color:var(--ink);margin:0 0 4px;}.pbx-qt b{font-weight:400;}/* Option C: Instrument Serif is ONE WEIGHT, 400 */
.pbx-qsrc{font:400 10px/1 var(--mono);letter-spacing:.04em;color:var(--ink-2);}.pbx-qa{display:flex;gap:8px;margin-top:16px;flex-wrap:wrap;}/* AMEND 6 Aug (Jake, slide 2): "Quick questions section needs stand out more like
   it did in agenovas prototype. Bolder title, one colour button."
   Two changes, both here so they cannot drift: the section's own name is set at
   display weight rather than the quiet 15px every other section header uses, and
   the answer row leads with ONE solid button instead of three outlines of equal
   voice. It is petrol, not coral: coral is still the single action on the view
   (the header's "Raise 2 invoices"), and two corals on one screen is the fault
   that rule exists to prevent. */
.pbx-sech.pbx-lead{padding:20px 24px;}.pbx-sech.pbx-lead .pbx-sect{font:800 22px/1.2 var(--sans);letter-spacing:-.02em;}.pbx-btn.pbx-solid{background:var(--petrol);border-color:var(--petrol);color:var(--cream);font-weight:700;}.pbx-btn.pbx-solid:hover{background:var(--petrol-2);border-color:var(--petrol-2);}.pbx-qnav{display:flex;align-items:center;gap:12px;padding:12px 24px;border-top:1px solid var(--line);background:var(--surface);}.pbx-qdots{display:flex;gap:6px;margin-left:auto;}.pbx-qdots i{width:7px;height:7px;border-radius:var(--r-pill);background:var(--line-2);display:block;}.pbx-qdots i.pbx-on{background:var(--petrol);}/* ── the feed ────────────────────────────────────────────────────────── */
.pbx-rail{display:flex;flex-direction:column;gap:24px;}.pbx-feed{background:var(--card);border:1px solid var(--line);border-radius:var(--r-l);box-shadow:var(--sh-1);overflow:hidden;}.pbx-feedrow{display:flex;align-items:baseline;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line);}.pbx-feedrow:last-child{border-bottom:0;}.pbx-feedh{display:flex;align-items:center;gap:8px;padding:16px 24px;border-bottom:1px solid var(--line);background:var(--surface);}.pbx-feedh .pbx-live{margin-left:auto;font:700 9px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--mark-strong);display:inline-flex;align-items:center;gap:4px;}/* ── THE LEDGER · brief §24, verbatim anatomy ─────────────────────────────
   Rail: sticky, --surface on a hairline, --r-l, 20px padding, scrolls inside its
   own height. Head: "The Ledger" in Instrument Serif 400, under it a mono kicker —
   a pulsing --mark dot and the words live · today. Glyph: the half-dome arc, 14×7,
   flat side down, colour-coded by KIND from the Option A set. Entry: two lines —
   the event with the subject in bold INSIDE the sentence, then mono --ink-3.
   Every entry is a BUTTON, not a div; hover lifts to --cream. Foot: the five kinds
   named in mono, then the promise. NO CORAL — a kind is a category. */
.pbx-ledger{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-l);padding:20px;}/* JAKE, 10 Aug: "needs to be title" — the Ledger head takes the same title
   treatment as Needs you, Fees, Invoices and People. §24 named the face when the
   serif was still doing UI; the title rule now governs. */
.pbx-ledger .pbx-lh{font:700 15px/1.2 var(--sans);color:var(--ink);}.pbx-ledger .pbx-lk{display:flex;align-items:center;gap:6px;font:400 9px/1 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-2);margin-top:5px;}.pbx-ledger .pbx-lk i{width:6px;height:6px;border-radius:var(--r-pill);background:var(--mark);display:inline-block;}.pbx-ledger .pbx-les{margin-top:14px;max-height:430px;overflow:auto;}.pbx-le{display:flex;gap:10px;width:100%;text-align:left;background:none;border:0;cursor:pointer;
  padding:11px 8px;border-bottom:1px solid var(--line);border-radius:var(--r-xs);}.pbx-le:last-of-type{border-bottom:0;}.pbx-le:hover{background:var(--cream);}.pbx-le .pbx-g{flex-shrink:0;width:14px;padding-top:6px;}.pbx-le .pbx-g svg{width:14px;height:7px;display:block;fill:none;stroke-width:2;stroke-linecap:round;}.pbx-le .pbx-x{display:block;font:400 12px/1.5 var(--sans);color:var(--ink);}.pbx-le .pbx-x b{font-weight:700;}.pbx-le .pbx-m{display:block;font:400 9.5px/1.6 var(--mono);letter-spacing:.04em;color:var(--ink-3);margin-top:3px;}.pbx-lkinds{display:flex;flex-wrap:wrap;gap:4px 12px;margin-top:14px;padding-top:12px;border-top:1px solid var(--line);}.pbx-lkinds span{display:inline-flex;align-items:center;gap:5px;font:400 9px/1.5 var(--mono);
  letter-spacing:.04em;color:var(--ink-2);}.pbx-lkinds i{width:9px;height:5px;border-top-left-radius:9px;border-top-right-radius:9px;display:inline-block;}.pbx-feedh .pbx-live i{width:6px;height:6px;border-radius:var(--r-pill);background:var(--mark-strong);display:inline-block;}/* ⛔ THE FEED-ENTRY `.fe` RULES ARE DELETED (20 Aug, batch 4) — and with them the collision that
     made `.fe` mean two things in one sheet. This block styled a live-activity FEED ENTRY; the block
     at the Fees screen styles an inline fee EDITOR, and both were emitted into the product, where
     the second won for `display` and `gap` and this one kept LEAKING `padding:12px 24px` and a
     `border-bottom` onto every Fees editor.
     ⚠ NOTHING USED IT. Measured: 42 elements carry `class="fe"` in this sheet and every one of them
     is a Fees editor on screen 03; `class="feed"` has zero users. This sheet's own note on screen 12
     already recorded the consequence — "class=\"fe\" now has no user on this screen, so the
     feed-entry rules at the head of this sheet are dead… The dead rules are the cleanup batch's to
     remove" — and this is that batch.
     ⚠ IT IS A VISIBLE CHANGE AND THE GATES CANNOT SEE IT: they compare markup and inline style, not
     computed style, so the Fees editors losing 12px/24px of inherited padding and a bottom border
     shows up on the PLATE and nowhere else. Named for Jake's look. */
.pbx-feedn{padding:16px 24px;font:400 11px/1.5 var(--sans);color:var(--ink-3);border-top:1px solid var(--line);}/* ── record pages ────────────────────────────────────────────────────── */
.pbx-rec{display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:32px;align-items:start;}/* 6 Aug · slide 12 — "Put the open tenancy, calc, money timeline etc in their own
   section under documents." The openers moved out of the main column into the rail,
   which is 330px wide: five pills do not sit side by side there, and wrapped pills
   read as debris. In this card each opener takes the full width of the rail, so the
   set reads as a list of panels. Scoped to the rail — every other .row of pills on
   the page is untouched. */
.pbx-rail .pbx-recmore{display:flex;flex-direction:column;gap:8px;margin-top:16px;}.pbx-rail .pbx-recmore .pbx-btn{width:100%;justify-content:flex-start;}.pbx-facts{border:1px solid var(--line);border-radius:var(--r-m);background:var(--card);overflow:hidden;}/* JAKE, 10 Aug: "make sure the instruction box is all in line." The two columns are
   separate lists, so a wrapping value on one side pushed its neighbours out of step.
   A fixed row height puts every row on the same baseline across both columns. */
.pbx-fct{display:flex;gap:16px;align-items:center;padding:0 16px;min-height:46px;border-bottom:1px solid var(--line);}.pbx-fct:last-child{border-bottom:0;}.pbx-fct dt{flex:0 0 150px;font:400 10px/1.3 var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2);margin:0;}.pbx-fct dd{margin:0;flex:1;min-width:0;font:600 13px/1.4 var(--sans);}/* JAKE, 10 Aug: "this table's text still isn't aligned." The rows lined up, but the
   VALUES did not — the three money rows were right-aligned while the word rows were
   left-aligned, so £30,850 and £8.40/sq ft flew out to the far edge. Canon right-aligns
   A COLUMN OF MONEY, read down the last digit; this is a label-and-value list with one
   money row among five word rows, so every value shares one left edge. Tabular figures
   and the 800 weight stay. */
.pbx-fct dd.pbx-n{text-align:left;font-weight:800;font-variant-numeric:tabular-nums;}/* ── 6 Aug 2026 · SLIDE 6 (Deal record) · "bottom half needs all the text to
      line up." ─────────────────────────────────────────────────────────────
   It didn't, in three separate ways, and all three were structural:
     1 · the terms were TWO independent <dl>s side by side, so the moment one
         value wrapped (Floors: "Third floor, Fourth floor, Fifth floor") every
         row beneath it in that column fell out of step with its neighbour.
         They are ONE grid now — two columns, shared rows — so a row is a row
         across the whole block whatever is in it.
     2 · `dt` was 150px wide, which is a PAGE-width label inside a QUARTER-width
         column: it squeezed "Cadence Advisory" onto two lines. Sized for the
         column it is actually in.
     3 · a money value was right-aligned (`dd.n`) while a text value was left-
         aligned, so the values themselves were ragged. Inside the terms block
         every value starts on the same line. The right-aligned convention is
         untouched everywhere else — it belongs to the wide record pages. */
.pbx-termgrid{display:grid;grid-template-columns:1fr 1fr;column-gap:32px;}.pbx-termgrid .pbx-fct{padding:12px 0;}.pbx-termgrid .pbx-fct dt{flex:0 0 96px;}.pbx-termgrid .pbx-fct dd.pbx-n{text-align:left;}/* the rule under a row belongs to the row, not to the last child of a list —
   in a two-column grid the last ROW is the last TWO items. (With an odd count
   the final pair spans two rows and the upper one loses a rule it could have
   kept: a missing hairline, never a stray one.) */
.pbx-termgrid .pbx-fct:nth-last-child(-n+2){border-bottom:0;}/* ── SLIDE 6 · the two panels' right-hand columns did not share an edge ────
   The top panel is `.cols2{gap:32px}` (its right column starts at 50%+16px);
   the bottom panel added `padding-left:48px` inside the same grid (its right
   column starts at 50%+16+48). So "THE FEE" and "COMMENTS" — one above the
   other — began 48px apart, and every line under them inherited the stagger.
   One construction for both: the gutter is paid for by the columns, so the
   dividing rule sits at exactly 50% on both panels and the text starts at
   exactly 50%+48px on both. */
.pbx-dealcols{gap:0;}.pbx-dealcols > *:first-child{padding-right:48px;}.pbx-dealcols > *:last-child{padding-left:48px;}.pbx-tl{list-style:none;margin:0;padding:0;}.pbx-tl li{position:relative;padding:0 0 16px 24px;}.pbx-tl li:last-child{padding-bottom:0;}.pbx-tl li::before{content:'';position:absolute;left:0;top:4px;width:8px;height:8px;border-radius:var(--r-pill);background:var(--mark-none);}.pbx-tl li.pbx-done::before{background:var(--mark-strong);}.pbx-tl li::after{content:'';position:absolute;left:4px;top:12px;bottom:0;width:1px;background:var(--line-2);}.pbx-tl li:last-child::after{display:none;}.pbx-tl .pbx-w{display:block;font:600 12px/1.35 var(--sans);}.pbx-tl .pbx-d{display:block;font:400 10px/1.4 var(--mono);color:var(--ink-2);margin-top:4px;}.pbx-tl li.pbx-pending .pbx-w{color:var(--ink-3);font-weight:600;}/* ── FLOORS, the old representation Jake preferred (slide 7) ─────────── */
.pbx-space{background:var(--card);border:1px solid var(--line);border-radius:var(--r-l);box-shadow:var(--sh-1);padding:24px;}.pbx-floor{padding:16px 0;border-bottom:1px solid var(--line);}.pbx-floor:last-child{border-bottom:0;}.pbx-floor .pbx-fh{display:flex;align-items:baseline;gap:8px;}.pbx-floor .pbx-fn{font:600 15px/1.2 var(--sans);}.pbx-floor .pbx-fn i{color:var(--ink-3);font-style:normal;margin-left:4px;}.pbx-floor .pbx-fs{margin-left:auto;font:700 9px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;}.pbx-floor .pbx-fbar{height:8px;border-radius:var(--r-pill);background:var(--surface);overflow:hidden;margin:10px 0 8px;}.pbx-floor .pbx-fbar i{display:block;height:100%;}.pbx-floor .pbx-fm{font:400 10px/1.6 var(--mono);color:var(--ink-2);}.pbx-floor .pbx-fm b{font:600 12px/1.6 var(--sans);color:var(--ink);}/* ── DEAL PAGE, the old set-up (slide 9) ────────────────────────────── */
.pbx-tickgrid{display:flex;flex-wrap:wrap;gap:8px;}.pbx-tick{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--line-2);border-radius:var(--r-pill);
  padding:0 16px;height:36px;background:var(--card);font:600 12px/1 var(--sans);color:var(--ink);cursor:pointer;}.pbx-tick i{width:13px;height:13px;border-radius:var(--r-pill);border:1.8px solid var(--line-2);display:block;}.pbx-tick.pbx-done i{background:var(--mark-strong);border-color:var(--mark-strong);}/* JAKE, 10 Aug: the selected stage on the Deal page reads exactly as the selected
   stage tile on Deals — solid --ground, light text. One selected state, one
   appearance, wherever a stage is picked. */
.pbx-tick.pbx-now{border-color:var(--ground);background:var(--ground);color:var(--card);}.pbx-tick.pbx-now i{border-color:var(--card);background:var(--card);}.pbx-tick.pbx-off{color:var(--ink-3);}.pbx-ta{width:100%;min-height:96px;border:1px solid var(--line-2);border-radius:var(--r-s);padding:12px;
  font:600 12px/1.6 var(--sans);color:var(--ink-3);background:var(--card);resize:none;}/* ── DEALS, the stage timeline as the feature (slide 8) ─────────────── */
.pbx-stages{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;}.pbx-stage{border:1px solid var(--line);background:var(--card);border-radius:var(--r-l) var(--r-l) var(--r-s) var(--r-s);
  padding:20px 16px 16px;cursor:pointer;display:flex;flex-direction:column;gap:8px;position:relative;}.pbx-stage:hover{border-color:var(--line-2);}.pbx-stage.pbx-on{background:var(--petrol);border-color:var(--petrol);}.pbx-stage.pbx-on .pbx-sn,.pbx-stage.pbx-on .pbx-sv{color:var(--card);}.pbx-stage.pbx-on .pbx-sl{color:var(--p-petrol);}.pbx-stage .pbx-sn{font:600 12px/1.3 var(--sans);}.pbx-stage .pbx-sv{font:800 26px/1 var(--sans);letter-spacing:-.02em;font-variant-numeric:tabular-nums;}.pbx-stage .pbx-sl{font:400 9px/1.3 var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2);}/* ── 6 Aug 2026 · SLIDE 13 (Deals) · "take the line off the cards at the top."
   `.stagearc` drew a hand-tuned six-hump wave immediately above the stage
   tiles. On a real board it is nine lanes wide, so the wave — whose humps are
   hard-coded at 200px intervals inside a 1200 viewBox stretched with
   preserveAspectRatio="none" — ran out before the tiles did and read as a
   crooked rule laid across their heads. The rule and its <svg> are both gone;
   nothing else in the sheet used it.  ⚠ THE READING: "the line ON the cards at
   the top", i.e. the wave over the tiles at the top of the page. The other
   reading — the hairline inside a deal card, under its name (.tc-stats
   border-top) — was rejected because the BOOK's cards carry exactly that same
   hairline and slide 14 calls them good. One tick reverses this if wrong. *//* ── SLIDE 13 · "sort formatting" ──────────────────────────────────────────
   A stage whose name runs to two lines ("Negotiating terms", "Negotiating
   lease", "Awaiting signature") pushed its count, its Σ fee and its bar a line
   lower than its neighbours', so the row of tiles read as steps. Two lines are
   reserved for every stage name, so the nine tiles share four baselines. */
.pbx-stage .pbx-sn{min-height:32px;}/* ── the no-photo tile ──────────────────────────────────────────────── */
.pbx-nophoto{background:var(--petrol-tint);border-radius:var(--r-m);height:150px;display:flex;align-items:center;justify-content:center;}.pbx-nophoto path{stroke:var(--petrol-2);stroke-width:5;fill:none;stroke-linecap:round;opacity:.55;}.pbx-tabs2{display:flex;gap:4px;padding:4px;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-pill);align-self:flex-start;width:max-content;}.pbx-tabs2 b{font:600 12px/1 var(--sans);color:var(--ink-2);border-radius:var(--r-pill);padding:8px 16px;}.pbx-tabs2 b.pbx-on{background:var(--petrol);color:var(--card);}.pbx-empty{text-align:center;padding:48px 24px;}.pbx-empty h3{font:800 22px/1.3 var(--sans);letter-spacing:-.02em;margin:16px 0 8px;}.pbx-empty p{font:600 13px/1.65 var(--sans);color:var(--ink-2);max-width:46ch;margin:0 auto 24px;}/* ── structure diagram ──────────────────────────────────────────────── */
.pbx-node{fill:var(--card);stroke:rgba(33,31,26,.16);}.pbx-node-h{fill:var(--petrol);stroke:none;}.pbx-dlbl{font:600 12px var(--sans);fill:var(--ink);}.pbx-dlbl-w{font:600 12px var(--sans);fill:#FFFDF7;}.pbx-dsub{font:400 9px var(--mono);letter-spacing:.06em;fill:var(--ink-3);}.pbx-dline{stroke:rgba(33,31,26,.16);fill:none;stroke-width:1.2;}[data-go]{cursor:pointer;}/* ==== 12 AUG · screen 03 gained the instruction spine (F3) — its controls, styled here (start) ==== */
.pbx-fe{display:inline-flex;align-items:center;gap:3px;justify-content:flex-end;color:var(--ink-3);font:600 13px/1 var(--sans);}.pbx-fe input{width:84px;border:1px solid var(--line);border-radius:var(--r-m);background:var(--surface);
  padding:5px 7px;font:600 13px/1 var(--sans);text-align:right;color:var(--ink);font-variant-numeric:tabular-nums;}.pbx-fe input::placeholder{color:var(--ink-3);font-weight:400;}.pbx-fe input:focus{outline:none;border-color:var(--mark);}.pbx-tablefold .pbx-kpirow{margin-top:16px;}.pbx-tablefold .pbx-panel{margin-top:16px;}.pbx-tablefold .pbx-legend{margin-top:12px;}.pbx-tablefold table.pbx-t td{height:auto;padding:10px 16px;}/* the year-on-year can point DOWN, and the draft only ever had an up value to draw */
.pbx-delta.pbx-down{color:var(--danger);}/* ==== 12 AUG · screen 03 additions (end) ==== *//* ==== 13 AUG · screen 04, the two shapes the product needed and the picture had no way to draw (start) ==== *//* OVERDUE IS A SUBDIVISION OF SENT, NOT A SIBLING (Q2b). The draft's bar only ever had flat
   siblings to draw, because a picture of a bar cannot show one segment inside another. */
.pbx-sbar i b{display:block;height:100%;}/* the ledger's section header row — the product groups by a DERIVED section (R96) and the draft's
   flat table had no heading to style. */
.pbx-tablefold .pbx-secrow td{padding:14px 16px 6px;border:0;height:auto;
  font:700 11px/1 var(--mono);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--ink-3);}/* ⛔ DUPLICATE REMOVED 20 Aug (batch 4): this rule was declared byte-identically in the 12 Aug
     screen-03 block above; the 13 Aug screen-04 block re-added it. One rule, one place. *//* ==== 13 AUG · screen 04 additions (end) ==== *//* ==== 16 AUG · screens 05 and 11 — the one control this sheet had no idiom for (start) ==== *//* THE SORT CONTROL. Screen 11's toolbar carries a <select>, and this sheet has none — checked, zero
   across all twelve screens. So it gains a rule, written in THIS SHEET'S OWN TOKENS beside the .chip
   and .search it sits between: the Fees .fe precedent, an app-invented control the draft gains rules
   for, nothing new declared.
   ⚠ NOT COPIED from os-full.css's own .pbx-sort. Those declarations name the APP's token layer
   (--ft, --fhl, --fb, --t-m) and not one of those four is declared in this sheet — the same gap the
   retired screen-05 fold ran into, 32 variables wide. */
.pbx-sort{display:inline-flex;align-items:center;height:22px;padding:0 8px;border-radius:var(--r-pill);
  border:1px solid var(--line-2);background:var(--card);font:700 9px/1 var(--mono);
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-2);outline:0;cursor:pointer;}.pbx-sort:focus-visible{border-color:var(--petrol);box-shadow:0 0 0 3px rgba(30,78,74,.12);}
/* ⛔ AND WHAT IS NOT HERE AT ALL ANY MORE: the 70 tokens of "Running the firm", screen 05's fold.
   They were never declared in this sheet (os-full.css painted that fold in 103 rules naming 37
   variables, 32 of them the app's own); on 19 Aug Jake ruled the console itself deleted and the
   markup went with it, so there is nothing left for them to paint. Nothing is missing here — the
   fold is. The retirement is recorded where the markup was, in screen 05. */
/* ==== 16 AUG · screens 05 and 11 additions (end) ==== */

/* ── added by design-port.js: the frame the draft got from <body> ─────────
   The draft's .screen carried the page padding because it WAS the page. In the
   product the router's shell already supplies it, so the scope only has to
   restate the typography the draft took from <body>. */
.pbx{background:var(--canvas);color:var(--ink);font:500 13px/1.6 var(--sans);
  font-variant-numeric:tabular-nums;-webkit-font-smoothing:antialiased;}
.pbx *{box-sizing:border-box;}
.pbx button{font-family:inherit;}
.pbx-screen{display:block;}
/* ⚠ THE DRAFT'S OWN PAGE FRAME IS KEPT (padding 48/48/120, max-width 1560, centred).
   It used to be zeroed here on the assumption that "the router's shell already supplies it" —
   which was true of the stage6 preview pages and FALSE of the product: the app's .fc-stage is a
   three-column grid, so zeroing the frame here left the ported children auto-placing into the old
   columns. The screenshot found it; verify-today could not, because the tree was right and only
   the layout was wrong. The host neutralises its own grid instead (.fc-stage.ported). */
/* the draft printed a numbered caption above each page for review. It is not
   part of the product and is dropped at the porter, not hidden here — this
   rule only guards against a hand-bound page reintroducing one. */
.pbx-caption{display:none;}

/* ==== PRAEBA PORTED DESIGN (end) ==== */

/* ══ SLICE 3a · RETIRED, 19 AUG ══════════════════════════════════════════════════════════════
   "Running the firm" (screen 05's fold) was deleted from the product by Jake's ruling, 19 Aug.
   The pbx re-dress this slice recorded went with it: every selector the fold had added to this
   sheet was pruned the same day, each class measured for consumers first — 68 classes, none
   worn by anything that survives. The original rules (.amt · .fig · .mono · .serif · .sp-chip ·
   .tm-line · .tm-who · .tm-worklist …) keep their own selectors and their place in the cascade,
   untouched. ══════════════════════════════════════════════════════════════════════════════ */

/* ── THE DOCK'S PADLOCK · rider 0c, 20 Aug ─────────────────────────────────────────────────────
   The People tab is directors-only and says so. Sized off the dock label's own type rather than a
   new number, and it takes the button's own ink so it can never disagree with the word beside it. */
.os-dock .os-docklock{width:11px;height:11px;margin-right:5px;vertical-align:-1px;
  fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;opacity:.72;}

/* ── THE REFUSAL CARD · rider 0c, 20 Aug ───────────────────────────────────────────────────────
   What a staff persona sees if any route lands them on People. Every value is a ruled token, and it
   is HERE rather than inline because the batch this belongs to is paying that debt down, not adding
   to it — OsEmpty's card writes the same recipe inline and is counted for it. */
.sp-refusal{padding:52px 8px;text-align:center;}
.sp-refusal .sp-refusal-h{font-size:var(--t-l);font-weight:var(--w-bold);color:var(--ink);margin-bottom:8px;}
.sp-refusal p{max-width:380px;margin:0 auto;line-height:var(--lh-body);font-size:var(--t-m);color:var(--ink-3);}

/* ── THE CLIENT RECORD'S PROPERTY CHIPS ARE DOORS · draft screen B, 12 Aug ─────────────────────
   The cursor lives HERE and not inline, and the reason is the ratchet: the plate carries no inline
   style on these chips, the gate compares attributes exactly, and an inline style the design does
   not draw is a difference the app can never answer. A chip that resolves to exactly one record is
   a door; one that cannot resolve carries no data-fig and therefore no pointer, which is the
   refusal made visible. */
.pbx-chip[data-fig-clientprop]:not([data-fig-clientprop=""]){cursor:pointer;}

/* C4 · the send-authority chip's own hint, inside the roster modal. A class rather than an
   inline style ON PURPOSE: designdebt's `inlineStyles` is the ratchet the whole design transfer
   turns on, and a style written in JSX is one CSS can never reach. */
.sp-modal .nd-fld .nd-fldhint{margin-top:7px}
/* ── A HINT IS A HINT (Jake, 20 Aug: "make sure the font size fits better") ──────────────────────
   `.nd-fldhint` had no size of its own, so it inherited the modal's body size and a two-line
   explanation shouted louder than the fields it explains. This is the register the rest of the
   dialog already speaks — `.sp-modal .hint` under the buttons, `.et-hint` under an end-tenancy
   question — so the sentence under a field now reads like the sentence under a control.
   ⚠ IT APPLIES TO EVERY MODAL USING THE CLASS, and there is one other today: the firm's fee policy
   ("Leave a field blank to use ours — 10% of the first year's rent…"). That is the point of a shared
   class; a size that only fixed the new dialog would be the same drift in a nicer coat. */
/* An action row sitting UNDER a panel's facts, rather than beside its heading — the instruction's
   fee-terms control. Named for where it sits, so the next one does not arrive as another inline
   margin (designdebt.test.js counts those, and it counted this one). */
.pbx-panel .pbx-acts-under{margin-top:18px;}
.sp-modal .nd-fldhint{font-size:var(--t-s);line-height:var(--lh-ui);color:var(--fd2);}
.sp-modal .nd-fldhint b{color:var(--fd);font-weight:600;}
/* A read-only row in a confirm dialog: the figure, and under it what the figure IS. Without the
   block the note ran on from the number — "~£18,500modelled at your firm's 10%". */
.sp-modal .nd-fld .ro .pbx-note{display:block;margin-top:3px;font-size:var(--t-s);line-height:var(--lh-ui);color:var(--fd2);font-weight:400;}

/* C4 · the send-authority chip on a person's card. Named for what it MEANS, not what it looks
   like — the whole reason appearanceInCode exists as an instrument. */
.pbx-chip.pbx-sendauth{background:var(--coral-tint);color:var(--coral-deep);border-color:transparent}


/* ── R265 · A CONTROL LOOKS LIKE A CONTROL (Jake's walk, 20 Aug) ────────────────────────
   "Fee not agreed — confirm to raise →" is a <span> carrying role="button": it opens the R247
   ceremony, and Jake's walk found it did not look clickable. The rule hangs on the ACCESSIBILITY
   CONTRACT rather than on a class list, because that is the fact rather than a proxy for it — an
   element that declares role="button" IS a control, and 57 of them in the bundle said so while
   showing a text caret. Hanging it there also PRESERVES the 12 Aug refusal above: a client-prop
   chip that resolves to no record carries no role and no data-fig, so it still gets no pointer,
   which is the refusal made visible. Deliberate cursor:default rulings (.sp-trow.total,
   .mt-mx .mx-col) are class selectors and outrank this attribute selector, as they should.
   ⚠ A clickable element with NO role — .pbx-floor, whose click opens its deal — is NOT reached by
   this rule and is filed as its own row: the honest fix there is markup (role + tabIndex), which is
   keyboard behaviour, not a CSS pass. */
[role="button"]{cursor:pointer;}

/* ══ THE DOCUMENTS DROPZONE — H3 Session 3, 24 Aug 2026 (D19's ruled shape) ═══════════════════════
   ⚠ THESE RULES EXIST BECAUSE THE RATCHET REFUSED THE INLINE VERSION, AND IT WAS RIGHT TO.
   The first draft of this surface carried twelve inline styles and two colour literals in the JSX,
   and `designdebt.test.js` went red: "inlineStyles: 475 → 487". Raising that baseline would have
   been a decision to make the brand harder to change, taken by accident, on a surface that did not
   exist yet. So the styling lives here, on tokens (--line-2, --action) rather than on hexes, which
   is the whole point of the ratchet.
   ⚠ AND os-full.css IS OUTSIDE BUILD_STAMP (R265, 21 Aug): the stamp hashes engine.js and the
   bundle only, so a CSS change ships without the stamp moving. The receipt that discriminates this
   file is a SERVED-BYTES grep — `curl .../flow-os/os-full.css | grep -c pbx-dropzone` — 0 before,
   1 after. */
.pbx-dropzone{border:1.5px dashed var(--line-2, rgba(33,31,26,.16));border-radius:var(--r-m, 14px);
  padding:20px 18px;text-align:center;transition:background .15s ease, border-color .15s ease;}
.pbx-dropzone.pbx-over{border-color:var(--action, #E1613C);background:rgba(225,97,60,.05);}
.pbx-dropwrap{margin-bottom:16px;}
.pbx-dropacts{gap:8px;margin-top:10px;justify-content:center;}
.pbx-dropgest{margin-top:10px;}
.pbx-droplist{margin-top:12px;}
.pbx-droprow{gap:10px;align-items:baseline;padding:4px 0;}
.pbx-dropmark{min-width:18px;text-align:center;}
.pbx-dropname{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pbx-dropwhy{flex:1 1 auto;}
.pbx-dropttl{margin:0;}

/* 25 Aug (Jake): "can they all fit on one line — looks stupid having one on its own."
   The generated sheet sets repeat(6,1fr), so seven stages wrapped one card onto its own row.
   Auto-flow columns = always exactly one row, however many stages carry deals. Declared HERE,
   after the generated block, so the cascade wins and a regeneration cannot wipe it. */
.pbx-stages{grid-auto-flow:column;grid-auto-columns:1fr;grid-template-columns:none;}

/* ── 26 Aug · UPCOMING KEY DATES, BANDED (mock approved by Jake 25 Aug — "Yes to your keydates
   solution"). Four windows with count + share bar, two rows then "+N more →", nearest non-empty
   band open, empty band prints its quiet line. Declared HERE, in the hand region after the
   generated block, so a regeneration cannot wipe it. ⚠ os-full.css is outside BUILD_STAMP (R265),
   but this ships WITH a bundle change so the stamp discriminates the deploy; this file's own
   served-bytes receipt is `grep -c pbx-kdband` — 0 before, 3 after (this comment is one of them). Bars read the traffic lights
   (--tl-amber) per the Leases page's 6 Aug ruling; coral stays the act, never a mark. */
.pbx-kdband{margin-top:14px;padding-top:12px;border-top:1px solid var(--line);}
.pbx-kdband:first-child{margin-top:0;padding-top:0;border-top:0;}
.pbx-kdhead{display:flex;align-items:center;gap:10px;}
.pbx-kdlbl{font:400 10px var(--mono);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--ink-2);}
.pbx-kdn{font-weight:800;font-size:var(--t-m);color:var(--ink);}
.pbx-kdbar{flex:1;height:5px;margin-left:6px;min-width:40px;display:block;}
.pbx-kdbar .tk{fill:var(--line);opacity:.5;}
.pbx-kdbar .fl{fill:var(--tl-amber);}
.pbx-kdquiet{font:400 9px var(--mono);letter-spacing:var(--tr-m);text-transform:uppercase;color:var(--ink-3);padding:9px 0 0;}
.pbx-kdmore{margin-top:8px;font:400 9px var(--mono);letter-spacing:var(--tr-l);text-transform:uppercase;color:var(--petrol-2);background:none;border:1px solid var(--line-2);border-radius:var(--r-pill);padding:4px 12px;cursor:pointer;}
.pbx-kdmore:hover{background:color-mix(in srgb, var(--petrol-2) 8%, transparent);}
