/* ============================================================================
   pv3 core — the shell and containers every page in the estate uses.

   Split out of portal-v3.css (2026-08-16) when the system stopped being one
   page's stylesheet and became the estate's. The line is "chrome and
   containers" vs "energy-advice content": canvas, brand bar, masthead, cards,
   buttons, pills, figures, tabs, forms, skeletons, focus and print live here;
   charts, dossier rows, household cards and the advisor spotlight cards live in
   pv3-portal.css, which only /portal_v2 loads. A wallboard should not ship the
   RdSAP form's siblings.

   Requires: tokens.css (brand tokens + the elevation layer).
   Requires: class="pv3" on <body> — that is what turns the canvas on.
   ========================================================================== */

/* ---- page canvas ---------------------------------------------------------- */
body.pv3{
  margin:0; color:var(--c-ink); font:400 16px/1.6 var(--f-body);
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  background:
    radial-gradient(120% 80% at 88% -10%, rgba(196,153,58,.10), transparent 55%),
    linear-gradient(180deg,var(--page-1),var(--page-2));
  background-attachment:fixed; min-height:100vh;
  padding:clamp(20px,4vw,56px) clamp(16px,4vw,40px) 80px;
}
.pv3 *{box-sizing:border-box}
.pv3-wrap{max-width:1080px; margin:0 auto}
.pv3 .tnum{font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1,"lnum" 1}
.pv3 .hidden{display:none !important}

/* ---- preview / environment ribbon ----------------------------------------- */
.pv3-ribbon{
  display:inline-flex; align-items:center; gap:8px; margin-bottom:22px;
  font:600 11px/1 var(--f-body); letter-spacing:.14em; text-transform:uppercase;
  color:var(--c-forest); background:rgba(255,255,255,.6); border:1px solid var(--hair);
  padding:8px 12px; border-radius:9999px; backdrop-filter:blur(4px);
}
/* NOT gold. Gold on this pill is 2.51:1 — the brand data says plainly that gold
   carries no text on cream, and this is text. The deep brass below is the same
   family at 6.44:1. Gold stays for the keel, borders and fills, where it is
   decoration rather than something to read. */
.pv3-ribbon b{color:var(--status-watch-ink)}

/* ---- co-brand bar (LDS parent + product) ---------------------------------- */
.pv3-brandbar{display:flex; align-items:center; gap:16px; margin-bottom:26px;
  background:linear-gradient(180deg,var(--c-forest),var(--c-forest-d)); border-radius:14px;
  padding:13px 20px; box-shadow:var(--shadow-card)}
.pv3-bb-lds{height:22px; width:auto; display:block}
.pv3-bb-sep{width:1px; height:22px; background:rgba(255,255,255,.22); flex:0 0 auto}
.pv3-bb-lantern{display:inline-flex; align-items:center; gap:9px; color:#F4E9C7;
  font:700 15px/1 var(--f-body); letter-spacing:.02em}
.pv3-bb-lantern img{height:24px; width:24px; display:block}
/* Product shield mark used in the portfolio / household mastheads */
.pv3-shield-img{height:34px; width:34px; display:block; flex:0 0 auto}

/* The other tools, in the brand bar. margin-left:auto lives here rather than on
   .pv3-bb-signout so the whole right-hand cluster is pushed to the far edge as
   one group — leaving it on the button would have split them, with the tools
   crowding the brand marks and Sign out alone at the edge.

   Deliberately quieter than Sign out: plain text against the forest, no
   outline. These are places you might go; Sign out is an action with a
   consequence, and it should stay the one bordered control up here. */
.pv3-bb-tools{margin-left:auto; display:flex; align-items:center; gap:4px; flex-wrap:wrap}
.pv3-bb-tool{color:rgba(244,233,199,.82); text-decoration:none;
  border-radius:999px; padding:6px 12px; font:600 13px/1 var(--f-body);
  letter-spacing:.01em; white-space:nowrap;
  transition:background .15s ease, color .15s ease}
.pv3-bb-tool:hover{background:rgba(244,233,199,.12); color:#F4E9C7}
.pv3-bb-tool:focus-visible{outline:2px solid #F4E9C7; outline-offset:2px}

/* Sign out, in the brand bar. Sits on the forest gradient so it needs a light
   outline rather than a fill. It is the last item in the right-hand cluster;
   .pv3-bb-tools owns the margin-left:auto that pushes that cluster over, with
   the rule below as the fallback for a user who has no tool links at all. */
.pv3-bb-signout{margin-left:auto; flex:0 0 auto; cursor:pointer;
  background:transparent; color:#F4E9C7; border:1px solid rgba(244,233,199,.42);
  border-radius:999px; padding:6px 15px; font:600 13px/1 var(--f-body);
  letter-spacing:.01em; transition:background .15s ease, border-color .15s ease}
.pv3-bb-signout:hover{background:rgba(244,233,199,.12); border-color:rgba(244,233,199,.7)}
.pv3-bb-signout:focus-visible{outline:2px solid #F4E9C7; outline-offset:2px}
/* Two auto margins in one flex row do not stack — they SPLIT the free space,
   which would leave the tools mid-bar and Sign out alone at the edge with a gap
   between them. When the tools are present they own the push and Sign out just
   follows. */
.pv3-bb-tools + .pv3-bb-signout{margin-left:0}

/* ---- partners strip --------------------------------------------------------
   "In partnership with" — LDS plus the customer's own mark. Quiet by design: it
   is a statement of whose service this is, not a banner. Used by the adviser
   portal today and by the wallboards, which carry the same two logos.
   ------------------------------------------------------------------------- */
.pv3-partners{display:flex; align-items:center; gap:16px; margin-top:22px; flex-wrap:wrap}
.pv3-partners-label{font:600 10px/1 var(--f-body); letter-spacing:.16em; text-transform:uppercase;
  color:var(--c-ink-soft); flex:0 0 auto}
.pv3-partners-rule{flex:1 1 40px; height:1px; background:var(--hair)}
.pv3-partners-logos{display:flex; align-items:center; gap:18px; flex-wrap:wrap}
.pv3-partner-logo{height:26px; width:auto; display:block; opacity:.9}

/* ---- masthead ------------------------------------------------------------- */
.pv3-masthead{display:flex; align-items:flex-end; justify-content:space-between; gap:28px; flex-wrap:wrap}
.pv3-brandline{display:flex; align-items:center; gap:12px; margin-bottom:18px}
.pv3-shield{width:34px;height:34px;display:grid;place-items:center;border-radius:9px;
  background:var(--c-forest); color:#F4E9C7; box-shadow:inset 0 0 0 1px rgba(255,255,255,.08); flex:0 0 auto}
.pv3-shield svg{width:19px;height:19px}
/* Same treatment when the mark is an <img> rather than inline <svg>: the artwork
   sits INSIDE the forest tile with breathing room, not flush to its edges. */
/* The small mark is the lantern alone (140x334 viewBox), so it is sized on HEIGHT
   with width:auto — forcing it square would squash it. The full shields are square
   and unaffected. */
.pv3-shield img{height:20px;width:auto;display:block}
.pv3-wordmark{font:700 15px/1 var(--f-body); letter-spacing:.02em; color:var(--c-forest)}
.pv3-wordmark span{color:var(--c-ink-soft); font-weight:500}
.pv3-eyebrow{font:600 11px/1 var(--f-body); letter-spacing:.2em; text-transform:uppercase; color:var(--c-moss);
  filter:saturate(.7) brightness(.78); margin:0 0 10px}
.pv3-title{font:600 clamp(34px,5vw,52px)/1.02 var(--f-head); letter-spacing:-.015em; margin:0;
  color:var(--c-forest-d); font-optical-sizing:auto}
.pv3-subtitle{margin:10px 0 0; color:var(--c-ink-soft); font-size:15px}
.pv3-subtitle b{color:var(--c-ink); font-weight:600}
.pv3-mast-meta{text-align:right; flex-shrink:0}
.pv3-mast-meta .as-at{font:500 12px/1.4 var(--f-body); letter-spacing:.04em; text-transform:uppercase; color:var(--c-ink-soft)}
.pv3-mast-meta .ref{font:600 18px/1.2 var(--f-head); color:var(--c-forest); margin-top:3px}
/* U12: site code demoted to a muted inline reference in the subtitle */
.pv3-mast-ref{color:var(--c-ink-soft); font-weight:500; font-size:13px; letter-spacing:.02em}
/* T18: copy-link sits with the case reference, because the reference is what the
   URL contains. Quiet by design — it must never compete with Contact. */
.pv3-copylink{display:inline-flex; align-items:center; gap:4px; margin-left:6px; padding:2px 7px;
  font:500 11px/1.4 var(--f-body); letter-spacing:.02em; color:var(--c-ink-soft);
  background:transparent; border:1px solid var(--c-sage); border-radius:999px; cursor:pointer}
.pv3-copylink:hover{color:var(--c-ink); border-color:var(--c-ink-soft)}
.pv3-copylink svg{width:12px; height:12px}
/* U14: Contact / Check-in pinned to the household header, one click from any tab */
.pv3-mast-actions{display:flex; gap:8px; margin-top:12px; justify-content:flex-end; flex-wrap:wrap}
.pv3-btn-sm{padding:9px 14px; font-size:13px}
.pv3-btn-sm svg{width:15px; height:15px}
@media (max-width:560px){ .pv3-mast-meta{text-align:left} .pv3-mast-actions{justify-content:flex-start} }
.pv3-support-btn{margin-top:12px; display:inline-flex; align-items:center; gap:7px; cursor:pointer;
  font:600 13px/1 var(--f-body); color:var(--c-forest); background:var(--c-moss-soft);
  border:1px solid var(--c-keel, rgba(62,107,87,.22)); border-radius:999px; padding:8px 14px;
  transition:background .15s var(--ease), gap .15s var(--ease)}
.pv3-support-btn:hover{gap:10px; background:var(--c-moss, #dcece2)}
.pv3-support-btn svg{width:15px;height:15px}
.pv3-support-card{max-width:640px}
.pv3-support-card + .pv3-support-card{margin-top:16px}

.pv3-keel{height:3px; border-radius:3px; background:var(--keel); margin:26px 0 0}

/* breadcrumb / back */
.pv3-back{display:inline-flex; align-items:center; gap:7px; margin-bottom:18px; cursor:pointer;
  font:600 13px/1 var(--f-body); color:var(--c-forest); background:none; border:0; padding:6px 2px;
  transition:gap .15s var(--ease)}
.pv3-back:hover{gap:11px}
.pv3-back svg{width:15px;height:15px}

/* ---- status pills / lines ------------------------------------------------- */
.pv3-status{display:inline-flex; align-items:center; gap:7px; padding:5px 11px 5px 8px; border-radius:9999px;
  font:600 12px/1 var(--f-body); border:1px solid}
.pv3-status svg{width:14px;height:14px}
.pv3-s-ok{color:var(--status-ok-ink); background:var(--c-moss-soft); border-color:var(--status-ok-border)}
.pv3-s-watch{color:var(--status-watch-ink); background:var(--status-watch-bg); border-color:var(--status-watch-border)}
.pv3-s-alert{color:var(--status-alert-ink); background:var(--c-warn-soft); border-color:var(--c-warn)}
.pv3-s-neutral{color:var(--c-ink-soft); background:var(--status-neutral-bg); border-color:var(--c-sage)}
.pv3-pill{display:inline-flex; align-items:center; gap:5px; padding:3px 9px; border-radius:9999px; font:600 12px/1 var(--f-body)}
.pv3-pill svg{width:12px;height:12px}
.pv3-pill-gold{background:var(--c-gold-soft); color:#7A5C16}
.pv3-pill-moss{background:var(--c-moss-soft); color:var(--status-ok-ink)}
.pv3-pill-warn{background:var(--c-warn-soft); color:var(--status-alert-ink)}
.pv3-pill-soft{background:#EEF2EC; color:var(--c-ink-soft)}

/* ---- at-a-glance figure band ---------------------------------------------- */
.pv3-figures{display:grid; grid-template-columns:repeat(4,1fr); margin:34px 0 6px}
.pv3-figures--5{grid-template-columns:repeat(5,1fr)}
.pv3-fig{padding:4px 26px; position:relative}
.pv3-fig + .pv3-fig::before{content:""; position:absolute; left:0; top:6px; bottom:6px; width:1px; background:var(--hair)}
.pv3-fig:first-child{padding-left:2px}
.pv3-fig-label{font:600 11px/1.3 var(--f-body); letter-spacing:.12em; text-transform:uppercase; color:var(--c-ink-soft); margin:0 0 8px}
.pv3-fig-value{font:500 clamp(28px,3.4vw,42px)/1 var(--f-head); letter-spacing:-.01em; color:var(--c-forest-d)}
.pv3-fig-value .u{font-size:.46em; color:var(--c-ink-soft); font-weight:600; letter-spacing:0; margin-left:3px; font-family:var(--f-body)}
.pv3-fig-delta{margin-top:9px; font:600 12.5px/1 var(--f-body); display:inline-flex; align-items:center; gap:5px}
.pv3-fig-delta svg{width:13px;height:13px}
/* U11: hint affordance — dotted underline + ⓘ, full explanation in the tooltip */
/* The hint affordance is a <button> so it works on touch and by keyboard, not just
   on hover. Reset the UA button chrome so it still reads as the delta line it
   replaced, and give it a real focus ring — it is now in the tab order. */
button.pv3-fig-delta{appearance:none; border:0; background:none; padding:0; margin-top:9px;
  color:inherit; font:600 12.5px/1 var(--f-body); text-align:left}
.pv3-fig-delta.has-hint{cursor:help; text-decoration:underline dotted var(--c-ink-soft); text-underline-offset:3px}
.pv3-fig-delta.has-hint:focus-visible{outline:2px solid var(--c-gold); outline-offset:3px; border-radius:5px}
.pv3-fig-hint{margin:8px 0 0; font:400 12.5px/1.5 var(--f-body); color:var(--c-ink-soft); max-width:38ch}
.pv3-fig-i{font-size:11px; opacity:.7; text-decoration:none}
.pv3 .down{color:var(--status-ok-ink)} .pv3 .up{color:var(--status-watch-ink)} .pv3 .flat{color:var(--c-ink-soft)}

/* ---- tabs ------------------------------------------------------------------ */
.pv3-tabs{display:flex; gap:4px; margin-top:30px; padding:5px; border-radius:16px;
  background:var(--page-2); border:1px solid var(--hair-soft); position:sticky; top:10px; z-index:5;
  box-shadow:var(--shadow-card); overflow-x:auto}
.pv3-tab{appearance:none; border:0; background:transparent; cursor:pointer; white-space:nowrap;
  flex:1 1 auto; display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:11px 16px; border-radius:12px; font:600 14px/1 var(--f-body); color:var(--c-ink-soft);
  transition:background .18s var(--ease), color .18s var(--ease)}
.pv3-tab svg{width:16px; height:16px}
.pv3-tab:hover{color:var(--c-ink)}
.pv3-tab.is-active{background:var(--c-forest); color:#fff; box-shadow:var(--shadow-lift)}
.pv3-tab .pv3-tab-badge{display:inline-flex; align-items:center; justify-content:center; min-width:20px;
  height:20px; padding:0 6px; border-radius:9999px; font:700 11px/1 var(--f-body);
  background:var(--c-gold-soft); color:var(--c-forest-d)}
.pv3-tab.is-active .pv3-tab-badge{background:rgba(255,255,255,.22); color:#fff}
.pv3-tabpanel{margin-top:6px}
.pv3-tabs{ -webkit-overflow-scrolling:touch; scrollbar-width:thin }

/* ---- cards / editorial shell ---------------------------------------------- */
.pv3-deck{display:grid; gap:24px; margin-top:30px}
.pv3-card{background:var(--paper); border:1px solid var(--hair); border-radius:20px;
  box-shadow:var(--shadow-card); padding:clamp(20px,2.6vw,32px); position:relative; overflow:hidden}
.pv3-card-head{display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin-bottom:20px}
.pv3-card-head h2{font:600 21px/1.2 var(--f-head); letter-spacing:-.01em; color:var(--c-forest-d); margin:0}
.pv3-card-head .meta{font:500 12px/1 var(--f-body); letter-spacing:.04em; text-transform:uppercase; color:var(--c-ink-soft)}
/* A heading with an explanatory line under it. Common on the back-office pages,
   where a section title alone does not tell an operator what they are looking
   at. Full-width so it drops below the title rather than competing with it. */
.pv3-card-head{flex-wrap:wrap}
.pv3-card-head p{flex:1 0 100%; margin:7px 0 0; color:var(--c-ink-soft);
  font:400 14.5px/1.55 var(--f-body); max-width:74ch}
.pv3-card-head p code{font:400 13px/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  background:var(--page-2); border-radius:5px; padding:2px 5px}
.pv3-two{display:grid; grid-template-columns:1.05fr 1fr; gap:24px}
.pv3-section-head{margin:0 0 4px}
.pv3-section-head h2{font:600 clamp(22px,2.6vw,28px)/1.15 var(--f-head); letter-spacing:-.01em; color:var(--c-forest-d); margin:0}
.pv3-section-head p{margin:6px 0 0; color:var(--c-ink-soft); font-size:15px; max-width:66ch}

/* narrative lead with editorial drop cap */
.pv3-lead{font-size:17px; line-height:1.72; color:#2A322D; max-width:64ch}
.pv3-lead::first-letter{font:600 58px/.82 var(--f-head); color:var(--c-forest); float:left; margin:6px 12px 0 0}
.pv3-lead b{color:var(--c-forest-d); font-weight:600}
/* Same reason: this is a highlight INSIDE a sentence, so it is body text, and
   gold on a white card is 2.64:1. */
.pv3-lead .pull{color:var(--status-watch-ink); font-weight:600}

/* inline annotations inside cards */
.pv3-note{margin:12px 0 0; font-size:14px; line-height:1.55; color:var(--c-ink)}
.pv3-note b{color:var(--c-forest-d); font-weight:600}
.pv3-note-soft{color:var(--c-ink-soft); font-size:13px}
/* "No heating at the moment", on a website enquiry. Uses the estate's existing
   warn token rather than a new red: this is the one answer on that form that
   changes what an adviser does next, and it has to be readable at a glance in a
   queue, not decorative. */
.pv3-urgent{color:var(--c-warn); font-weight:600}

/* responsive card grid */
.pv3-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); gap:18px; margin-top:24px}

/* ---- tables ----------------------------------------------------------------
   Editorial and hairline-only: no zebra striping, no vertical rules, no fill on
   the header. The wrap is not optional — a table is the one thing on these
   pages that will not reflow, so it scrolls inside its own box rather than
   pushing the whole page sideways on a phone.
   ------------------------------------------------------------------------- */
.pv3-table-wrap{width:100%; overflow-x:auto; -webkit-overflow-scrolling:touch}
.pv3-table{width:100%; border-collapse:collapse; font:400 14px/1.5 var(--f-body)}
.pv3-table thead th{
  text-align:left; font:700 11px/1.3 var(--f-body); letter-spacing:.08em; text-transform:uppercase;
  color:var(--c-ink-soft); padding:10px 12px; border-bottom:1px solid var(--border-strong);
  background:transparent; white-space:nowrap}
.pv3-table tbody td{padding:11px 12px; border-bottom:1px solid var(--hair-soft); vertical-align:middle}
.pv3-table tbody tr:last-child td{border-bottom:0}
.pv3-table tbody tr:hover{background:var(--page-1)}
/* Numeric columns line up only if they are told to. */
.pv3-table .num{text-align:right; font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1,"lnum" 1}

/* ---- spec rows — a label/value list where a table would be overkill -------
   One fact per row, label left and value right, hairline between. What a table
   gives you and this does not is columns you can compare DOWN; a case's phone
   number and its preferred contact method have nothing to compare, so they get
   this instead.

   THIS LIVES IN CORE, not in pv3-portal.css, and that is the fix rather than
   the tidy-up. It was defined only in pv3-portal.css, which /portal_v2 loads
   and /partner-cases does not — so the case detail pane on the one surface a
   delivery partner sees rendered as an indented bulleted list: no two columns,
   no label weight, no rules. Core has no generic `ul` reset to fall back on, so
   the browser default showed through. A primitive two pages need is a core
   primitive.
   ------------------------------------------------------------------------- */
.pv3-ev-list{list-style:none; margin:6px 0 0; padding:0; display:grid; gap:0}
.pv3-ev-row{display:grid; grid-template-columns:150px 1fr; gap:16px; padding:12px 0;
  border-bottom:1px solid var(--hair-soft)}
.pv3-ev-row:last-child{border-bottom:0}
.pv3-ev-row .k{font:600 13px/1.4 var(--f-body); color:var(--c-forest-d)}
.pv3-ev-row .v{font:400 14px/1.5 var(--f-body); color:var(--c-ink)}

/* ---- stat tiles ------------------------------------------------------------
   .pv3-figures is the hero band at the top of a page — big, divided, no borders.
   This is the other kind: a grid of bordered tiles for a dashboard, where no
   single number is the headline and there may be a dozen of them.
   ------------------------------------------------------------------------- */
.pv3-stats{display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:14px; margin-top:16px}
.pv3-stat{background:var(--paper); border:1px solid var(--hair); border-radius:14px; padding:16px 18px}
.pv3-stat-label{display:block; font:700 11px/1.3 var(--f-body); letter-spacing:.1em;
  text-transform:uppercase; color:var(--c-ink-soft)}
.pv3-stat-value{display:block; margin-top:5px; font:600 28px/1 var(--f-head);
  letter-spacing:-.01em; color:var(--c-forest-d); font-variant-numeric:tabular-nums}
.pv3-stat-value small{display:block; margin-top:5px; font:400 12.5px/1.4 var(--f-body);
  letter-spacing:0; color:var(--c-ink-soft)}
/* The unit that trails a figure — smaller, quieter, and in the body face so it
   never competes with the numeral. */
.pv3-fig-value-u{font:600 .46em/1 var(--f-body); color:var(--c-ink-soft); margin-left:3px; letter-spacing:0}
/* One tile carrying the number that matters, and the compact row form for a
   figure that is supporting evidence rather than a headline. */
.pv3-stat-hero{grid-column:span 2}
.pv3-stat-hero .pv3-stat-value{font-size:40px}
.pv3-stat-inline{display:flex; align-items:baseline; justify-content:space-between; gap:12px}
.pv3-stat-inline .pv3-stat-value{margin-top:0; font-size:20px}
@media (max-width:560px){ .pv3-stat-hero{grid-column:span 1} }

/* The content region of a card, when the card has a head and the body needs to
   be addressed separately (collapsing, lazy-filling). */
.pv3-card-body{margin-top:4px}

/* ---- nested surface --------------------------------------------------------
   A quiet block INSIDE a card — an evidence field, a grouped read-only record.
   Tinted rather than bordered, so nesting does not read as a second card. */
.pv3-subpanel{background:var(--page-1); border-radius:12px; padding:14px 16px; margin-top:12px}
.pv3-subpanel + .pv3-subpanel{margin-top:10px}

/* ---- spine — where you are in a multi-step piece of work --------------------
   Renders a state machine the server already owns, so it can never claim a step
   the case has not actually reached. Steps behind you are settled fact, the
   current one is the only live thing on screen, and steps ahead are visible but
   plainly not done — an adviser mid-onboarding should be able to see how much
   is left without clicking.
   ------------------------------------------------------------------------- */
.pv3-spine{display:flex; flex-wrap:wrap; gap:0; list-style:none; margin:22px 0 0; padding:0}
.pv3-spine li{position:relative; flex:1 1 96px; min-width:96px; padding:0 6px;
  display:flex; flex-direction:column; align-items:center; gap:7px; text-align:center}
/* The connecting rule sits BEHIND the dots and stops at the row's edges. */
.pv3-spine li::before{content:""; position:absolute; top:8px; left:-50%; width:100%;
  height:2px; background:var(--hair)}
.pv3-spine li:first-child::before{display:none}
.pv3-spine .dot{width:17px; height:17px; border-radius:9999px; background:var(--paper);
  border:2px solid var(--c-sage); position:relative; z-index:1; flex:0 0 auto}
.pv3-spine .lbl{font:600 11px/1.3 var(--f-body); letter-spacing:.02em; color:var(--c-ink-soft)}
/* done */
.pv3-spine li.is-done::before{background:var(--c-forest)}
.pv3-spine li.is-done .dot{background:var(--c-forest); border-color:var(--c-forest)}
.pv3-spine li.is-done .lbl{color:var(--c-forest-d)}
/* current — a gold ring, the one thing asking for attention */
.pv3-spine li.is-current::before{background:var(--c-forest)}
.pv3-spine li.is-current .dot{background:var(--c-gold); border-color:var(--c-gold);
  box-shadow:0 0 0 4px var(--c-gold-soft)}
.pv3-spine li.is-current .lbl{color:var(--c-forest-d); font-weight:700}
/* halted — cancelled, withdrawn, manual review. Not a failure state to hide. */
.pv3-spine li.is-halted .dot{background:var(--c-warn); border-color:var(--c-warn)}
.pv3-spine li.is-halted .lbl{color:var(--status-alert-ink)}
@media (max-width:640px){
  .pv3-spine li{flex-basis:64px; min-width:64px}
  .pv3-spine .lbl{font-size:10px}
}

/* The case reference, once the work has an identity worth bookmarking. */
.pv3-threadref{display:inline-flex; align-items:center; gap:8px; margin-top:14px;
  font:600 12px/1 var(--f-body); letter-spacing:.06em; text-transform:uppercase;
  color:var(--c-ink-soft)}
.pv3-threadref code{font:700 13px/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  letter-spacing:0; text-transform:none; color:var(--c-forest-d);
  background:var(--c-gold-soft); border-radius:6px; padding:4px 8px}

/* ---- escalation — the "that didn't work" rung ------------------------------
   A recovery route is NOT a peer of the happy path. It stays out of the way
   until the thing above it fails, and then it is a button, not a paragraph of
   advice telling somebody to retype an address in a different shape. */
.pv3-escalate{margin-top:20px; padding-top:18px; border-top:1px dashed var(--hair);
  display:flex; flex-wrap:wrap; align-items:center; gap:12px}
.pv3-escalate p{margin:0; font:400 14px/1.5 var(--f-body); color:var(--c-ink-soft); flex:1 1 240px}

/* ---- toolbar — the controls that sit above a table or list ---------------- */
.pv3-toolbar{display:flex; flex-wrap:wrap; align-items:center; gap:10px; margin:16px 0}
/* A bare input or select in a toolbar is styled without needing a class — the
   back-office pages are full of them and each one carrying .pv3-input is a
   thing to forget.
   ">" AND NOT A DESCENDANT, and the difference was every control on
   /partner-cases rendering 240px TALL. This rule is written for a bare input
   sitting directly in the toolbar, which is a horizontal flex row, so
   flex-basis:240px means "240px wide". But the descendant selector also matched
   every input nested inside `<label>` inside `<form class="pv3-pd-grid">`, and
   .pv3-pd-grid > label is `flex-direction:column` — so the same basis applied to
   the COLUMN axis and each field grew to 240px high. Five tabs of search boxes,
   date pickers and dropdowns, each the height of a paragraph. */
.pv3-toolbar > input,.pv3-toolbar > select{flex:0 1 240px; padding:9px 12px;
  border:1px solid var(--hair); border-radius:11px; background:var(--paper);
  color:var(--c-ink); font:400 14px/1.2 var(--f-body)}
.pv3-toolbar > input:focus,.pv3-toolbar > select:focus{outline:none; border-color:var(--c-forest)}
/* Belt and braces for the same class of mistake: a field inside a pd-grid label
   sizes to its content on the column axis, whatever a future toolbar rule says. */
.pv3-pd-grid > label input,.pv3-pd-grid > label select,.pv3-pd-grid > label textarea{flex:0 0 auto}

/* THE FORM IS THE TOOLBAR'S CONTENT, so it takes the width. Without this it is a
   flex item with no flex value, shrinks to its content, and .pv3-pd-grid's
   `auto-fit, minmax(210px, 1fr)` then resolves against 210px and returns ONE
   column — so every form on the page stacked vertically down the left edge of a
   pane with 1,000px going spare. min-width:0 because a grid item's default
   min-width:auto refuses to shrink below its content and reintroduces it. */
.pv3-toolbar > .pv3-pd-grid{flex:1 1 auto; width:100%; min-width:0}
.pv3-pd-grid > label{min-width:0}

/* A button in a field grid is not a field: it should not stretch to the row
   height or the column width. Bottom-aligned so it sits on the baseline of the
   inputs beside it rather than floating against their labels. */
.pv3-pd-grid > .pv3-btn{align-self:end; justify-self:start}

.pv3-toolbar-end{margin-left:auto; display:flex; gap:10px; flex-wrap:wrap}

/* ---- empty state ----------------------------------------------------------
   Dashed, quiet, and it must SAY something. "No results" is a dead end; the
   copy should name what would put something here. */
.pv3-empty{margin:8px 0; padding:26px 22px; text-align:center; color:var(--c-ink-soft);
  font:500 15px/1.55 var(--f-body); border:1px dashed var(--hair); border-radius:16px}
.pv3-empty b{display:block; color:var(--c-forest-d); font-weight:600; margin-bottom:4px}

/* ---- slot ------------------------------------------------------------------
   A region the page refills — a table, a list, a result. NOT the same thing as
   an empty state: the dashed centred box is right for "there is nothing here"
   and wrong the moment a table lands inside it. Slots carry no decoration of
   their own; whatever the renderer puts in brings its own. */
.pv3-slot{margin-top:12px}

/* ---- callout — a line of consequence, inline in a card -------------------- */
.pv3-callout{display:flex; gap:10px; align-items:flex-start; padding:12px 14px; border-radius:11px;
  font:500 14px/1.5 var(--f-body); border:1px solid; margin:12px 0}
.pv3-callout svg{flex:0 0 auto; width:18px; height:18px; margin-top:1px}
.pv3-callout-warn{background:var(--status-watch-bg); border-color:var(--status-watch-border); color:var(--status-watch-ink)}
.pv3-callout-alert{background:var(--status-alert-bg); border-color:var(--status-alert-border); color:var(--status-alert-ink)}
.pv3-callout-ok{background:var(--status-ok-bg); border-color:var(--status-ok-border); color:var(--status-ok-ink)}
.pv3-callout-info{background:var(--status-info-bg); border-color:var(--status-info-border); color:var(--status-info-ink)}

/* ---- code / payload block --------------------------------------------------
   Forest-dark rather than the near-black it replaces: this is the one place raw
   machine output appears on an otherwise editorial page, and it should read as
   part of the same object rather than a terminal pasted into it. */
.pv3-code{margin:12px 0 0; padding:14px 16px; border-radius:12px; overflow-x:auto;
  background:var(--c-forest-d); color:var(--c-cream); border:0;
  font:400 12px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; white-space:pre}

/* ---- modal ----------------------------------------------------------------
   One overlay for the estate. The card inside is a .pv3-card, so a dialog is
   never a second card system. */
.pv3-modal-overlay{position:fixed; inset:0; z-index:1000; background:rgba(20,35,26,.45);
  display:flex; align-items:flex-start; justify-content:center; overflow:auto; padding:32px 16px}
.pv3-modal-overlay.hidden{display:none}
.pv3-modal{width:min(100%,880px)}
.pv3-modal-head{display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin-bottom:16px}
.pv3-modal-close{cursor:pointer; background:none; border:0; padding:6px; line-height:1;
  color:var(--c-ink-soft); font:600 20px/1 var(--f-body)}
.pv3-modal-close:hover{color:var(--c-forest-d)}

/* ---- forms ----------------------------------------------------------------
   Two layers. The inline row (.pv3-form-row/.pv3-input/.pv3-check) is for one
   or two controls sitting inside a card. The fieldset system (.pv3-pd-*) is the
   full multi-field form — built first for the Property Characteristics (RdSAP)
   capture, hence the name, but it is the general form vocabulary and the
   onboarding, eligibility and admin pages use it too. The prefix is kept
   because /portal_v2 already ships it; renaming a live form for tidiness is not
   a trade worth making.
   ------------------------------------------------------------------------- */
.pv3-form-row{display:flex; gap:10px; flex-wrap:wrap; margin-top:6px}
.pv3-input{flex:1 1 180px; padding:10px 12px; border:1px solid var(--hair); border-radius:11px;
  font:400 14px/1.2 var(--f-body); color:var(--c-ink); background:var(--paper)}
.pv3-input:focus{outline:none; border-color:var(--c-forest)}
.pv3-check{display:inline-flex; align-items:center; gap:8px; margin-top:12px; font:400 13px/1.3 var(--f-body); color:var(--c-ink-soft)}
.pv3-linkbox{margin-top:14px; padding:12px 14px; border:1px dashed var(--hair); border-radius:11px;
  background:var(--page-2); font:500 13px/1.4 var(--f-body); color:var(--c-forest-d); word-break:break-all}
.pv3-linkbox::before{content:"Private link — copied to clipboard"; display:block; font:600 11px/1 var(--f-body);
  color:var(--c-ink-soft); text-transform:uppercase; letter-spacing:.06em; margin-bottom:6px}

.pv3-pd-form{margin-top:18px}
.pv3-pd-section{border:1px solid var(--hair); border-radius:16px; padding:16px 18px; margin:0 0 16px}
.pv3-pd-section legend{padding:0 8px; font:600 13px/1.2 var(--f-body); color:var(--c-forest-d); letter-spacing:.02em}
.pv3-pd-sensitive{border-color:var(--c-gold); background:rgba(228,201,127,.06)}
.pv3-pd-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:12px 16px; margin-top:8px}
/* A bare <label> inside the grid IS a field. The back-office pages write
   `<label><span>Name</span><input/></label>` and asking every one of them to
   also carry a class is how markup and stylesheet drift apart. */
.pv3-pd-field,.pv3-pd-grid > label{display:flex; flex-direction:column; gap:5px;
  font:400 13px/1.3 var(--f-body); color:var(--c-ink-soft)}
.pv3-pd-field.pv3-pd-wide,.pv3-pd-grid > label.pv3-pd-wide{grid-column:1/-1}
.pv3-pd-field select,.pv3-pd-field input,.pv3-pd-field textarea,
.pv3-pd-grid > label select,.pv3-pd-grid > label input,.pv3-pd-grid > label textarea{
  font:400 14px/1.3 var(--f-body); color:var(--c-ink); background:var(--paper);
  border:1px solid var(--hair); border-radius:10px; padding:9px 11px; width:100%}
.pv3-pd-field select:focus,.pv3-pd-field input:focus,.pv3-pd-field textarea:focus,
.pv3-pd-grid > label select:focus,.pv3-pd-grid > label input:focus,.pv3-pd-grid > label textarea:focus{
  outline:none; border-color:var(--c-forest-d); box-shadow:0 0 0 3px rgba(20,35,26,.08)}
.pv3-pd-field textarea,.pv3-pd-grid > label textarea{resize:vertical; min-height:60px}
/* A checkbox is not a stacked field — the box belongs beside its words.
   Done with an explicit class rather than `:has()`: the wallboards render on
   Raspberry Pi signage, where Chromium is often older than :has() support and
   rarely updated. One selector is not worth auditing every box for. */
.pv3-pd-grid > label.pv3-pd-checkbox{flex-direction:row; align-items:center; gap:9px}
.pv3-pd-grid > label > input[type="checkbox"]{width:auto; flex:0 0 auto}
/* A value that is stated rather than chosen — same row rhythm as a field so the
   grid does not break, but no box, because a greyed-out input reads as a control
   that is broken or that somebody forgot to enable. Used where the value is a
   fact about what will happen ("Type: Assessment") and not a choice. */
.pv3-pd-static{padding:9px 0; font:400 14px/1.2 var(--f-body); color:var(--c-ink)}

.pv3-pd-actions{display:flex; align-items:center; gap:14px; margin-top:4px}
/* Inside a field grid it takes the whole row, so the buttons sit together under
   the fields rather than becoming two more grid cells stretched to a field's
   height and column width. .pv3-pd-wide is the equivalent for a label and does
   not match a div, which is why this is its own rule rather than a second class
   on the element. */
.pv3-pd-grid > .pv3-pd-actions{grid-column:1/-1; flex-wrap:wrap}
.pv3-pd-status{font:400 13px/1.3 var(--f-body); color:var(--c-ink-soft)}
@media (max-width:640px){ .pv3-pd-grid{grid-template-columns:1fr} }

/* ---- actions footer / buttons --------------------------------------------- */
.pv3-actions{display:flex; align-items:center; justify-content:space-between; gap:20px; flex-wrap:wrap;
  margin-top:34px; padding-top:26px; border-top:1px solid var(--hair)}
.pv3-actions p{margin:0; color:var(--c-ink-soft); font-size:14px; max-width:52ch}
.pv3-actions p b{color:var(--c-forest-d); font-weight:600}
.pv3-btn-row{display:flex; gap:12px; flex-wrap:wrap}
.pv3-btn{display:inline-flex; align-items:center; gap:9px; font:600 14px/1 var(--f-body); padding:13px 20px;
  border-radius:12px; cursor:pointer; border:1px solid transparent;
  transition:transform .12s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease)}
.pv3-btn svg{width:16px;height:16px}
.pv3-btn-primary{background:var(--c-forest); color:var(--c-cream); box-shadow:0 6px 16px rgba(18,51,40,.22)}
.pv3-btn-primary:hover{transform:translateY(-2px); box-shadow:0 12px 26px rgba(18,51,40,.28); background:var(--c-forest-d)}
.pv3-btn-ghost{background:#fff; color:var(--c-forest); border-color:var(--hair)}
.pv3-btn-ghost:hover{transform:translateY(-2px); border-color:var(--c-gold); box-shadow:var(--shadow-card)}
/* Destructive. Deliberately the ONLY red control in the system: withdrawing a
   consent or deleting a case should not look like every other button, and it
   should not appear more than once on a screen. */
.pv3-btn-danger{background:var(--status-alert-ink); color:var(--c-cream); border-color:var(--status-alert-ink)}
/* The one irreversible area on the partner surface. Marked out rather than
   styled like the rest of the card, because "remove this household's data" and
   "book a visit" should not look like the same kind of control. */
.pv3-danger-zone{margin-top:20px; padding:16px 18px; border:1px solid var(--c-warn);
  border-radius:14px; background:var(--c-warn-soft)}
.pv3-danger-zone p{margin:0 0 12px; font-size:14px; line-height:1.55; color:var(--c-ink)}
.pv3-danger-zone ul{margin:8px 0 12px 18px; font-size:14px; line-height:1.5}
.pv3-danger-zone label{display:block; margin:10px 0}
.pv3-danger-zone label span{display:block; font-size:13px; margin-bottom:4px; color:var(--c-ink-soft)}
.pv3-danger-zone input{width:100%; max-width:420px; padding:8px 10px;
  border:1px solid var(--hair); border-radius:8px; font:inherit}
.pv3-danger-zone code{font:400 13px/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.pv3-btn-danger:hover{transform:translateY(-2px); box-shadow:0 12px 26px rgba(162,51,32,.28)}
.pv3-btn[disabled]{opacity:.5; cursor:not-allowed; transform:none !important; box-shadow:none !important}

/* ---- the values strip ------------------------------------------------------
   Ported from stirling-brand.css, which the wallboards no longer load. It is
   the one piece of that file that was doing real work rather than re-skinning:
   three claims the room can read, and the copyright line. Restated on tokens,
   so it follows the canvas wherever the canvas goes. */
.stirling-values{
  max-width:1280px; margin:36px auto 0; padding:20px 24px 26px;
  border-top:1px solid var(--hair); display:flex; flex-wrap:wrap;
  align-items:baseline; gap:10px 26px; color:var(--c-ink-soft)}
.stirling-values .stirling-values-mark{
  font:700 15px/1 var(--f-head); letter-spacing:.18em; text-transform:uppercase;
  color:var(--c-forest)}
.stirling-values .stirling-values-mark span{color:var(--c-gold)}
.stirling-values em{font-style:normal; font-size:12px; letter-spacing:.12em; text-transform:uppercase}
.stirling-values em + em::before{content:"·"; color:var(--c-gold); margin-right:26px}
.stirling-values .stirling-values-co{margin-left:auto; font-size:12px; letter-spacing:.04em}
@media (max-width:760px){ .stirling-values .stirling-values-co{margin-left:0} }

/* ---- loading skeletons ---------------------------------------------------- */
.pv3-sk{position:relative; overflow:hidden; background:#E9EDE7; border-radius:10px; display:block}
.pv3-sk::after{content:""; position:absolute; inset:0; transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(196,153,58,.16),transparent); animation:pv3-sweep 1.15s infinite}
.pv3-sk-line{height:1em; margin:8px 0} .pv3-sk-big{height:42px; width:55%; margin:6px 0 12px} .pv3-sk-chart{height:300px}
@keyframes pv3-sweep{100%{transform:translateX(100%)}}

/* ---- entrance choreography ------------------------------------------------ */
.pv3-rise{animation:pv3-rise .6s var(--ease) both}
.pv3-rise:nth-child(1){animation-delay:.02s} .pv3-rise:nth-child(2){animation-delay:.10s}
.pv3-rise:nth-child(3){animation-delay:.18s} .pv3-rise:nth-child(4){animation-delay:.26s}
.pv3-rise:nth-child(5){animation-delay:.34s}
@keyframes pv3-rise{from{opacity:0; transform:translateY(16px)} to{opacity:1; transform:none}}

/* ---- error frame + screen-reader announce (U3/U4) ------------------------- */
.pv3-err-msg{margin:12px 0 0; font:500 15px/1.6 var(--f-body); color:var(--c-ink-soft); max-width:60ch}
.pv3-sr-live{position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
  clip:rect(0 0 0 0); white-space:nowrap; border:0}

/* ---- accessibility (U16) --------------------------------------------------- */
/* One consistent keyboard focus ring on every interactive element. Uses
   :focus-visible, so it shows for keyboard users only — no change for mouse/touch. */
.pv3 a:focus-visible,
.pv3 button:focus-visible,
.pv3 select:focus-visible,
.pv3 input:focus-visible,
.pv3 textarea:focus-visible,
.pv3 [tabindex]:focus-visible{ outline:3px solid var(--c-gold); outline-offset:2px; border-radius:8px }

/* The moss eyebrow fails contrast on the cream canvas (~1.9:1). Deepen to a
   green that clears AA (~5:1) while staying on-brand.
   NOTE: the saturate/brightness filter declared on .pv3-eyebrow above still
   applies — a later rule setting only `color` does not cancel it — so the
   rendered ink is darker again than this hex. Left exactly as it was: the split
   is a refactor, and a refactor that quietly changes a contrast-critical colour
   is not a refactor. */
.pv3-eyebrow{ color:#4E7A34 }

/* ---- responsive ------------------------------------------------------------ */
@media (max-width:820px){
  .pv3-figures{grid-template-columns:repeat(2,1fr); row-gap:22px}
  .pv3-fig{padding:4px 18px}
  .pv3-fig:nth-child(3){padding-left:2px} .pv3-fig:nth-child(3)::before{display:none}
  .pv3-two{grid-template-columns:1fr}
}
/* A 150px label column leaves nothing for the value on a phone, so the pair
   stacks and the label reads as a heading over it. */
@media (max-width:640px){
  .pv3-ev-row{grid-template-columns:1fr; gap:2px}
}
/* The calendar grids need width and cannot have it below ~900px, where seven
   columns become seven slivers. The renderer disables Week and Month there and
   falls back to the list, so this only catches the case where somebody narrows
   the window with a grid already on screen: it keeps a readable width and
   scrolls, rather than crushing the columns to nothing. A phone never gets
   here by choosing it. */
@media (max-width:899px){
  .pv3-cal-month,.pv3-cal-week{min-width:780px}
  .pv3-cal-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch}
}
/* U17: comfortable touch targets on coarse pointers (advisers on home visits). */
@media (pointer:coarse){
  .pv3-tab{ min-height:44px }
  .pv3-btn,.pv3-btn-sm,.pv3-support-btn,.pv3-back,.pv3-pf-chip{ min-height:44px }
}
/* U17: very narrow phones — keep the KPI row and title from clipping. */
@media (max-width:440px){
  body.pv3{ padding-left:14px; padding-right:14px }
  .pv3-figures{ grid-template-columns:repeat(2,1fr) }
  .pv3-title{ font-size:clamp(26px,8vw,32px) }
  .pv3-btn-row{ flex-direction:column; align-items:stretch }
  .pv3-btn-row .pv3-btn{ justify-content:center }
}
@media (prefers-reduced-motion:reduce){
  .pv3 *{animation:none !important; transition:none !important}
}

/* ============================================================================
   U13 — print / save-PDF stylesheet
   Cleans the current view for paper: drops the page furniture and interactive
   controls, flattens shadows/gradients to ink-on-white, and keeps cards whole.
   ========================================================================== */
/* The adviser print-out carries the household's ADDRESS and, on the Call tab, the
   welfare picture. It is the paper an adviser takes into someone's home and then
   carries around in a bag; the Funder PDF is separately export-safe and needs none
   of this. A confidentiality marking on every page is the minimum a document with a
   named vulnerable resident on it should have, and a page number tells whoever finds
   a loose sheet that there is more of it somewhere. */
@page{
  margin:1.4cm;
  @top-right{ content:"CONFIDENTIAL — contains personal data"; font-family:sans-serif; font-size:8pt }
  @bottom-left{ content:"Levant · adviser copy — do not leave with the resident"; font-family:sans-serif; font-size:8pt }
  @bottom-right{ content:"Page " counter(page) " of " counter(pages); font-family:sans-serif; font-size:8pt }
}

/* ---- split workbench -------------------------------------------------------
   Case list left, open case right. The list is the thing an adviser keeps
   returning to, so it must not move: the previous layout put the detail BELOW
   the list, and opening any case scrolled the list off the screen.

   The list pane is sticky and scrolls inside itself, so a long case record on
   the right never drags the list out of reach. `align-items:start` is what
   lets sticky work here — a stretched grid item is already full height and has
   nothing to stick to.

   COLLAPSES AT 1100px, and that number is deliberate. A 4fr column of a
   1000px viewport is about 380px, which is the narrowest a case roster reads
   at; below that a single column is honestly better than a cramped split. */
.pv3-workbench{display:grid; grid-template-columns:minmax(340px, 4fr) 6fr;
  gap:22px; align-items:start; margin-top:10px}
.pv3-wb-list{position:sticky; top:14px; max-height:calc(100vh - 40px);
  overflow:auto; overscroll-behavior:contain; padding-right:4px}
.pv3-wb-detail{min-width:0}          /* or a wide table inside blows the grid */

@media (max-width:1099px){
  .pv3-workbench{grid-template-columns:1fr; gap:16px}
  .pv3-wb-list{position:static; max-height:none; overflow:visible; padding-right:0}
}

/* Status filter. Chips rather than a <select>, because the counts are the
   point: an adviser wants to see there are three visits to book without
   opening anything. A dropdown hides exactly the number they came for.

   Only statuses present in the current result get a chip, so this is a
   breakdown of what is on screen and never a row of zeroes. */
.pv3-wb-chips{display:flex; flex-wrap:wrap; gap:6px; margin:0 0 10px}
.pv3-wb-chip{display:inline-flex; align-items:center; gap:6px; padding:5px 10px;
  border:1px solid var(--hair); border-radius:9999px; background:var(--c-paper);
  font:600 12px/1.2 var(--f-body); color:var(--c-ink-soft); cursor:pointer}
.pv3-wb-chip:hover{border-color:var(--c-moss); color:var(--c-ink)}
.pv3-wb-chip:focus-visible{outline:2px solid var(--c-forest-d); outline-offset:2px}
/* Pressed state carries in the border and the ink as well as the fill, so it
   survives a bright screen and greyscale printing; aria-pressed carries it for
   a screen reader. */
.pv3-wb-chip.is-on{background:var(--c-forest-d); border-color:var(--c-forest-d); color:var(--c-paper)}
.pv3-wb-chip-n{font-variant-numeric:tabular-nums; opacity:.75; font-weight:500}
.pv3-wb-chip.is-on .pv3-wb-chip-n{opacity:.9}

/* Each household: one button, everything stacked. A single generous target
   rather than a small "Open" link at the end of a row — this is used with a
   mouse by people who are not fast with one. */
.pv3-wb-cases{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:6px}
.pv3-wb-case{display:flex; flex-direction:column; gap:4px; width:100%; text-align:left;
  padding:11px 13px; border:1px solid var(--hair); border-radius:12px;
  background:var(--c-paper); cursor:pointer; font:inherit;
  border-left:3px solid transparent}
.pv3-wb-case:hover{border-color:var(--c-moss); background:var(--page-1)}
.pv3-wb-case:focus-visible{outline:2px solid var(--c-forest-d); outline-offset:2px}
/* Selected. A tint AND a left rule AND the reference going bold — three
   signals, because a single pale tint disappears on a bright screen in a
   sunlit office, and aria-current carries it for anyone not looking. */
.pv3-wb-case.is-open{background:var(--c-moss-soft);
  border-color:var(--c-moss); border-left-color:var(--c-forest-d)}
.pv3-wb-case.is-open .pv3-ref{font-weight:700}
.pv3-wb-case-top{display:flex; align-items:center; justify-content:space-between; gap:10px}
.pv3-wb-case-name{font:600 14px/1.35 var(--f-body); color:var(--c-ink)}
.pv3-wb-case-place{font:400 12px/1.4 var(--f-body); color:var(--c-ink-soft)}
.pv3-wb-offlist{margin-top:10px; padding-top:8px; border-top:1px dashed var(--hair)}

/* ---- case reference --------------------------------------------------------
   A case reference is scanned down a column looking for EW-CASE-000023, and
   read ALOUD on the telephone. Tabular-figure monospace so the digits line up
   vertically and 0 cannot be mistaken for O. */
.pv3-ref{font:600 13px/1.4 var(--f-mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
  font-variant-numeric:tabular-nums; letter-spacing:0.01em; white-space:nowrap;
  color:var(--c-forest-d)}

/* ---- calendar — month grid and week grid -----------------------------------
   Drawn by pv3-calendar.js. Two things govern every choice here.

   COLOUR GROUPS, THE LABEL SAYS. Every chip and block carries its word — an
   hour of "Assessment" or "Review" or "Busy" — because the tint is only there
   to let the eye group them. The tokens used are the measured status pairings
   (--status-*-ink on --status-*-bg, 5.6:1 to 8.0:1 on this canvas); the brand
   colours are NOT available here, because gold carries no text on cream at
   2.40:1 and sage is a hairline at 1.39:1.

   NO :has(). pv3-core.css is loaded by the wallboard pages, and on the signage
   Chromium an unsupported :has() does not render slowly, it DROPS THE WHOLE
   RULE. State is carried on explicit classes the renderer sets.
   ------------------------------------------------------------------------- */
.pv3-cal-views{display:flex; flex-wrap:wrap; gap:6px; margin:0 0 14px}
.pv3-cal-views .pv3-wb-chip[disabled]{opacity:.45; cursor:not-allowed}
.pv3-cal-nav{display:flex; align-items:center; gap:8px; margin:0 0 12px}
.pv3-cal-title{font:var(--t-h3); color:var(--c-forest-d); margin:0 auto 0 0}

/* --- month --- */
.pv3-cal-month{border:1px solid var(--hair); border-radius:var(--r-md); overflow:hidden;
  background:var(--paper)}
.pv3-cal-dow,.pv3-cal-week-row{display:grid; grid-template-columns:repeat(7,1fr)}
.pv3-cal-dow{background:var(--panel-soft); border-bottom:1px solid var(--hair)}
.pv3-cal-dow span{padding:8px 10px; font:700 11px/1.3 var(--f-body); letter-spacing:.08em;
  text-transform:uppercase; color:var(--c-ink-soft)}
.pv3-cal-week-row{border-bottom:1px solid var(--hair-soft)}
.pv3-cal-week-row:last-child{border-bottom:0}
.pv3-cal-day{display:flex; flex-direction:column; align-items:stretch; gap:3px;
  min-height:104px; padding:6px; text-align:left; cursor:pointer;
  background:var(--paper); border:0; border-right:1px solid var(--hair-soft);
  font:var(--t-body); color:var(--c-ink); transition:background var(--motion-fast)}
.pv3-cal-day:last-child{border-right:0}
.pv3-cal-day:hover{background:var(--page-1)}
.pv3-cal-day.is-weekend{background:var(--panel-soft)}
.pv3-cal-day.is-weekend:hover{background:var(--page-2)}
/* Outside the month: present so the weeks are whole, quiet so they do not
   compete with the month you asked for. */
.pv3-cal-day.is-outside .pv3-cal-daynum{color:var(--c-ink-soft); opacity:.55}
/* Today gets an inset ring rather than a fill, so a day that is both today and
   busy still shows its chips at full contrast. */
.pv3-cal-day.is-today{box-shadow:inset 0 0 0 2px var(--c-forest)}
.pv3-cal-daynum{font:600 13px/1.2 var(--f-body); color:var(--c-forest-d);
  font-variant-numeric:tabular-nums}
.pv3-cal-ev{display:block; padding:2px 6px; border-radius:var(--r-xs);
  border-left:3px solid; font:500 11px/1.35 var(--f-body);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.pv3-cal-ev-time{font-variant-numeric:tabular-nums; font-weight:700}
.pv3-cal-more{font:500 11px/1.3 var(--f-body); color:var(--c-ink-soft); padding-left:6px}
.pv3-cal-busy-flag{align-self:flex-start; padding:1px 6px; border-radius:var(--r-pill);
  background:var(--status-neutral-bg); color:var(--status-neutral-ink);
  border:1px solid var(--status-neutral-border); font:600 10px/1.5 var(--f-body)}

/* --- the four tones, shared by month chips and week blocks --- */
.pv3-cal-ev-ok{background:var(--status-ok-bg); color:var(--status-ok-ink); border-left-color:var(--status-ok-border)}
.pv3-cal-ev-watch{background:var(--status-watch-bg); color:var(--status-watch-ink); border-left-color:var(--status-watch-border)}
.pv3-cal-ev-alert{background:var(--status-alert-bg); color:var(--status-alert-ink); border-left-color:var(--status-alert-border)}
.pv3-cal-ev-neutral{background:var(--status-neutral-bg); color:var(--status-neutral-ink); border-left-color:var(--status-neutral-border)}

/* --- week --- */
.pv3-cal-week{display:grid; grid-template-columns:52px 1fr; gap:0;
  border:1px solid var(--hair); border-radius:var(--r-md); background:var(--paper);
  overflow:hidden}
.pv3-cal-axis{display:grid; padding-top:44px; border-right:1px solid var(--hair)}
.pv3-cal-hour{height:44px; padding:0 8px; font:600 10px/1 var(--f-body);
  color:var(--c-ink-soft); font-variant-numeric:tabular-nums;
  border-top:1px solid var(--hair-soft); transform:translateY(-5px)}
.pv3-cal-cols{display:grid; grid-template-columns:repeat(7,1fr)}
.pv3-cal-col{border-right:1px solid var(--hair-soft); min-width:0}
.pv3-cal-col:last-child{border-right:0}
.pv3-cal-col.is-weekend{background:var(--panel-soft)}
.pv3-cal-col.is-today .pv3-cal-colhead{background:var(--accent-soft)}
.pv3-cal-colhead{display:flex; align-items:baseline; justify-content:center; gap:5px;
  height:44px; border-bottom:1px solid var(--hair);
  font:600 11px/44px var(--f-body); color:var(--c-forest-d)}
.pv3-cal-coldow{letter-spacing:.06em; text-transform:uppercase; color:var(--c-ink-soft)}
.pv3-cal-coldate{font-size:14px; font-variant-numeric:tabular-nums}
/* The track is the hour grid. Its height is 12 hours at 44px, matching the axis
   exactly — the two are separate elements and only agree because both are
   derived from the same 44px, so change one and change the other. */
.pv3-cal-track{position:relative; height:528px;
  background:repeating-linear-gradient(to bottom,
    var(--hair-soft) 0, var(--hair-soft) 1px, transparent 1px, transparent 44px)}
.pv3-cal-block{position:absolute; display:flex; flex-direction:column; gap:1px;
  padding:3px 5px; border-radius:var(--r-xs); border:0; border-left:3px solid;
  text-align:left; cursor:pointer; overflow:hidden; min-width:0;
  font:var(--t-body); z-index:2}
.pv3-cal-block-title{font:600 11px/1.25 var(--f-body); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.pv3-cal-block-sub{font:400 10px/1.25 var(--f-body); opacity:.85;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
/* Somebody else's committed time. Hatched as well as tinted, so it reads as
   "not ours" rather than as a fifth status, and it sits BEHIND the visits. */
.pv3-cal-busy{position:absolute; left:0; width:100%; z-index:1;
  border-top:1px solid var(--status-neutral-border);
  border-bottom:1px solid var(--status-neutral-border);
  background:repeating-linear-gradient(135deg,
    var(--status-neutral-bg) 0, var(--status-neutral-bg) 5px,
    var(--panel-soft) 5px, var(--panel-soft) 10px)}
.pv3-cal-busy-word{display:block; padding:1px 5px; font:600 9px/1.4 var(--f-body);
  letter-spacing:.06em; text-transform:uppercase; color:var(--status-neutral-ink)}
/* Visits outside the drawn day, named rather than clipped. */
.pv3-cal-outside{margin:6px 4px 8px; display:flex; flex-direction:column; gap:4px}
.pv3-cal-outside-btn{cursor:pointer; text-align:left; padding:3px 5px;
  border:1px dashed var(--status-watch-border); border-radius:var(--r-xs);
  background:var(--status-watch-bg); color:var(--status-watch-ink);
  font:600 10px/1.3 var(--f-body)}

@media print{
  body.pv3{ background:#fff !important; padding:0; color:#000 }
  /* Belt and braces: @page margin boxes are unevenly supported across print engines,
     so the marking is ALSO printed into the flow at the top of the document, where no
     engine can drop it. Hidden on screen. */
  .pv3-wrap::before{
    content:"CONFIDENTIAL — contains personal data. Adviser copy: do not leave this with the resident.";
    display:block; margin:0 0 12px; padding:6px 0; border-bottom:2px solid currentColor;
    font:700 9pt/1.4 var(--f-body); letter-spacing:.04em; text-transform:uppercase }
  /* hide navigation + interactive chrome that means nothing on paper.
     .pv3-brandbar is new to this list: it moved onto every frame in 555ad22, so
     a printed advice file had started carrying a forest nav bar with a Sign out
     button on it. The only behaviour change in this split, and it is a fix. */
  .pv3-ribbon, .pv3-back, .pv3-tabs, .pv3-support-btn, .pv3-mast-actions,
  .pv3-brandbar, .pv3-keel, [data-print], [data-contact],
  [data-checkin], .pv3-btn-row, .pv3-pd-actions{ display:none !important }
  .pv3 *{ box-shadow:none !important; text-shadow:none !important; animation:none !important; transition:none !important }
  .pv3-card, .pv3-figures, .pv3-masthead, .pv3-two > *{
    border:1px solid #ccc !important; background:#fff !important; break-inside:avoid; page-break-inside:avoid }
  .pv3-masthead{ border:0 !important; border-bottom:2px solid #333 !important; border-radius:0 !important }
  .pv3-two{ display:block }
  .pv3-two > *{ margin-bottom:14px }
  .pv3-title, .pv3-card h2, .pv3-fig-value{ color:#111 !important }
  .pv3-note, .pv3-note-soft, .pv3-fig-label{ color:#333 !important }
  a[href]::after{ content:"" }               /* don't append URLs */
}

/* --- Support mode -----------------------------------------------------------
   Guidance links that appear beside a section only when an adviser asks for them.
   Deliberately quiet: this sits on a surface people use every day, and a help
   affordance that shouts becomes furniture they stop seeing within a week.
   Uses the existing tokens only — no new colours enter the palette for this. */
.pv3-support-toggle{flex:0 0 auto; margin-left:auto; font-weight:600}
.pv3-support-toggle[aria-pressed="true"]{background:var(--c-moss-soft); color:var(--c-forest-d)}

.pv3-tip-row{margin:-4px 0 18px}
.pv3-tip{display:inline-flex; align-items:center; flex-wrap:wrap; gap:10px;
  padding:8px 14px; border-radius:12px; background:var(--c-moss-soft);
  font:500 13px/1.45 var(--f-body); color:var(--c-forest-d)}
.pv3-tip-link{color:var(--c-forest-d); text-decoration:underline; text-underline-offset:2px}
.pv3-tip-link:hover{color:var(--c-forest)}
/* The manual reference is a CITATION, not a link — NEA's manual is issued to course
   candidates and is not ours to rehost, so this names where to look in your own copy.
   Styled as text on purpose: anything that looks clickable and is not is worse than
   plain text. */
.pv3-tip-manual{color:var(--c-ink-soft); border-left:1px solid var(--c-sage); padding-left:10px}

@media (max-width:640px){
  .pv3-support-toggle{margin-left:0; width:100%}
  .pv3-tip{width:100%}
  .pv3-tip-manual{border-left:0; padding-left:0}
}
