/*
 * One page summary. A document, not a screen: it is designed to be printed, posted,
 * and read by a landowner who has never heard of us.
 *
 * The design job here is hierarchy. The verdict is the only thing that must survive a
 * two second glance, so it is the largest element on the page and everything else
 * recedes beneath it in a deliberate order: verdict, evidence, facts, ask.
 *
 * Sized in pt and mm rather than px because the target is paper. Colour comes from
 * theme.css, so a different firm's palette is a change there and nothing here.
 */

.op-backdrop {
  position: fixed; inset: 0; background: rgba(10, 14, 18, 0.62);
  display: flex; flex-direction: column; align-items: center;
  overflow: auto; z-index: 100; padding: var(--s-5) var(--s-4) var(--s-16);
}
.op-bar {
  display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap;
  width: 210mm; max-width: 100%; margin-bottom: var(--s-3); flex: 0 0 auto;
  background: var(--paper); border-radius: var(--r-md);
  padding: var(--s-3) var(--s-4); box-shadow: var(--shadow-2);
}
.op-bar .grow { flex: 1; }
.op-bar button {
  font: inherit; font-size: var(--fs-sm); font-weight: 500;
  padding: var(--s-2) var(--s-4); border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--paper); color: var(--ink-800);
  cursor: pointer; transition: background .12s, border-color .12s;
}
.op-bar button:hover { background: var(--paper-sunk); border-color: var(--ink-200); }
.op-bar button.primary {
  background: var(--brand-700); color: var(--brand-contrast); border-color: var(--brand-700);
}
.op-bar button.primary:hover { background: var(--brand-900); }
.op-bar label { font-size: var(--fs-xs); color: var(--ink-500);
  display: inline-flex; align-items: center; gap: var(--s-2); }
.op-bar .locked { color: var(--bad-600); font-size: var(--fs-2xs); }

/* ------------------------------------------------------------------ the sheet */
.op {
  width: 210mm; max-width: 100%; min-height: 297mm;
  background: var(--paper); color: var(--ink-900);
  /* flex-shrink 0, or the column flex container collapses the sheet's height and the
     content spills out over the backdrop */
  flex: 0 0 auto;
  padding: 13mm 14mm; box-sizing: border-box;
  font: 10.5pt/1.45 var(--font);
  box-shadow: var(--shadow-2);
}

/* Masthead. A rule in the brand colour rather than plain black: it is the one place
   the document signs itself, and it should not look like a memo. */
.op-head {
  display: flex; justify-content: space-between; align-items: baseline;
  border-bottom: 2.5px solid var(--brand-700); padding-bottom: 5px; margin-bottom: 11px;
}
.op-brand { display: flex; align-items: baseline; gap: 9px; }
.op-mark { font-size: 15pt; font-weight: 700; letter-spacing: -0.4px; color: var(--brand-700); }
.op-tag { font-size: 7.5pt; text-transform: uppercase; letter-spacing: var(--tracking-wide);
  color: var(--ink-400); font-weight: 500; }
.op-date { font-size: 8.5pt; color: var(--ink-400); }

/* The address is context, not the headline. Deliberately quiet. */
.op-addr {
  font-size: 11pt; font-weight: 600; margin: 0 0 7px; letter-spacing: -0.1px;
  color: var(--ink-600);
}

/*
 * The verdict. The largest thing on the page by a clear margin.
 *
 * This was previously the same weight as a table row, which put the least interesting
 * element, the address, in the biggest type and the answer in the smallest. A landowner
 * gives this document about two seconds before deciding whether to keep reading, and
 * this block is what has to survive that.
 */
.op-hero {
  padding: 11px 14px 12px; margin: 0 0 10px;
  background: var(--paper-sunk); border-radius: var(--r-md);
  border-left: 5px solid var(--ink-300);
}
.op-hero.op-good { border-left-color: var(--good-600); background: var(--good-050); }
.op-hero.op-watch { border-left-color: var(--warn-600); background: var(--warn-050); }
.op-hero.op-neutral { border-left-color: var(--ink-300); background: var(--paper-sunk); }
.op-line {
  margin: 0; font-size: 15.5pt; font-weight: 700; line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight); color: var(--ink-900);
}
.op-hero.op-good .op-line { color: var(--good-700); }
.op-hero.op-watch .op-line { color: var(--warn-700); }
.op-sub { margin: 6px 0 0; font-size: 9pt; color: var(--ink-600); line-height: 1.45; }

/* What the neighbours have done, sitting with the verdict as its evidence. */
.op-nearby-line {
  margin: 8px 0 0; padding-top: 7px; font-size: 8.5pt; color: var(--ink-700);
  border-top: 1px solid rgba(16, 22, 29, .11);
}

/* ------------------------------------------------------------------- aerial */
.op-aerial { margin: 0 0 10px; }
.op-aerial-wrap {
  position: relative; line-height: 0; border: 1px solid var(--line);
  border-radius: var(--r-md); overflow: hidden;
}
.op-aerial img { width: 100%; height: auto; display: block; }
.op-overlay { position: absolute; inset: 0; width: 100%; height: 100%; }
.op-parcel { fill: rgba(29, 122, 79, .14); stroke: var(--good-600); stroke-width: 2.5; }
.op-aerial figcaption { font-size: 7pt; color: var(--ink-400); margin-top: 4px; }

/* --------------------------------------------------------------- fact grid */
.op-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 8px 22px; margin: 0 0 11px;
}
.op-cell { border-top: 1px solid var(--line); padding-top: 6px; }
.op-label {
  display: block; font-size: 7.5pt; text-transform: uppercase;
  letter-spacing: var(--tracking-wide); color: var(--ink-400); font-weight: 600;
  margin-bottom: 1px;
}
.op-value { display: block; font-size: 12pt; font-weight: 650; letter-spacing: -0.2px;
  line-height: 1.2; }
.op-note { display: block; font-size: 8pt; color: var(--ink-400); margin-top: 1px; }

/* ---------------------------------------------------------------- sections */
.op-sec { margin: 0 0 10px; }
.op-sec h2, .op-cta h2 {
  font-size: 8pt; margin: 0 0 5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--ink-400);
}
.op-list { margin: 0; padding-left: 15px; font-size: 9.5pt; }
.op-list li { margin: 2px 0; }

/*
 * The ask. This is the revenue mechanic, so it is the second strongest block on the
 * page: a brand tinted panel rather than a plain outline, which is the difference
 * between a document that ends and a document that asks for something.
 */
.op-cta {
  position: relative;
  border: 1px solid var(--brand-200); background: var(--brand-050);
  border-radius: var(--r-md); padding: 11px 14px; margin: 0 0 10px;
}
.op-cta h2 { color: var(--brand-700); }
.op-ask { margin: 9px 0 0; font-size: 9.5pt; color: var(--ink-800); }
.op-contact { margin: 5px 0 0; font-size: 9.5pt; font-weight: 700; color: var(--brand-700); }

/* QR sits to the right of the ask so it never pushes the sheet to a second page. */
.op-qr { position: absolute; right: 13px; bottom: 11px; width: 96px; text-align: center; }
.op-qr-img svg { display: block; width: 82px; height: 82px; margin: 0 auto;
  border-radius: 2px; }
.op-qr-cap { font-size: 6pt; line-height: 1.3; margin: 3px 0 0; color: var(--ink-500); }
.op-cta .op-list, .op-ask, .op-contact { padding-right: 106px; }

/* ------------------------------------------------------------------- footer */
.op-foot {
  border-top: 1px solid var(--line); padding-top: 7px;
  font-size: 6.8pt; line-height: 1.4; color: var(--ink-400);
}
.op-foot p { margin: 0 0 3px; }

/* Print. The controls and the rest of the app disappear; only the sheet remains. */
@media print {
  @page { size: A4; margin: 0; }
  /* EVERY overlay backdrop must be excluded here, in this ONE rule.
     This was two separate rules, one per print block: "hide everything that is not
     .op-backdrop" and "hide everything that is not .mr-backdrop". Each hid the other's
     container, so together they hid the entire document and printing produced blank
     pages. It affected the single sheet print too, which had worked until the mail run
     block was added. Invisible on screen and only ever visible on paper.
     The views also remove each other on open, so only one is ever present.
     The teaser (.tz-backdrop) was added on 5 August 2026 and went straight into this
     rule for the same reason: a fourth `body > *:not(...)` block in teaser.css would
     have reproduced the blank page bug exactly. If another printable view is ever
     added, extend THIS selector. Do not write a new one. */
  body > *:not(.op-backdrop):not(.mr-backdrop):not(.tz-backdrop) { display: none !important; }
  .op-backdrop { position: static; padding: 0; background: none; overflow: visible;
    display: block; }
  .op-bar { display: none !important; }
  .op { width: auto; min-height: auto; box-shadow: none; padding: 12mm 14mm; }
  .op-cta { break-inside: avoid; }
  .op-aerial { break-inside: avoid; }
  .op-qr { break-inside: avoid; }
  /* Tinted panels must actually print, or the ask loses its emphasis on paper. */
  .op-hero, .op-cta { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ---------------------------------------------------------------- narrow screens
 * The sheet is an A4 print artefact, so it is laid out in pt and mm. Previewed on a
 * phone at 375px that leaves the masthead tagline wrapping onto three lines and
 * colliding with the date. These rules only apply on screen: the print block above
 * is untouched, so a PDF produced from a phone is identical to one from a laptop.
 */
@media screen and (max-width: 560px) {
  .op { padding: 9mm 7mm; font-size: 10pt; }
  .op-head { flex-wrap: wrap; gap: 2px 8px; }
  .op-brand { flex: 1 1 100%; }
  /* Decorative, and the document says what it is in the body. First thing to go. */
  .op-tag { display: none; }
  .op-date { flex: 1 1 100%; font-size: 8pt; }
  .op-addr { font-size: 10pt; }
  .op-line { font-size: 13pt; }
  .op-grid { grid-template-columns: 1fr; gap: 0; }
  .op-cell { padding: 6px 0; }
  .op-bar { position: sticky; top: 0; z-index: 2; }
  .op-bar button { flex: 1 1 auto; }
  /* The QR would sit on top of the text once the column narrows. */
  .op-qr { position: static; width: auto; margin: 10px 0 0; }
  .op-cta .op-list, .op-ask, .op-contact { padding-right: 0; }
}

/* ---------------------------------------------------------------- mail run
 * A stack of sheets, one per page. Reuses the sheet styles above; only the wrapper
 * and the progress reporting are new.
 */
.mr-backdrop { position: fixed; inset: 0; background: rgba(16,22,28,.55);
  overflow: auto; padding: 18px; z-index: 60; }
.mr-panel { max-width: 900px; margin: 0 auto; }
.mr-head { position: sticky; top: 0; z-index: 2; display: flex; gap: 8px;
  align-items: center; background: #fff; border-radius: 10px;
  padding: 10px 14px; margin-bottom: 14px; box-shadow: 0 2px 10px rgba(16,22,28,.18); }
.mr-head h2 { font-size: 15px; margin: 0; }
.mr-head .grow { flex: 1; }
.mr-status { color: #fff; margin: 0 0 6px; font-size: 14px; }
.mr-bar { height: 5px; background: rgba(255,255,255,.25); border-radius: 3px;
  overflow: hidden; margin-bottom: 12px; }
.mr-fill { height: 100%; width: 0; background: #6bb28a; transition: width .2s; }
.mr-problems > div, .mr-warn { background: #fff; border-radius: 8px; padding: 10px 14px;
  margin-bottom: 12px; font-size: 13px; line-height: 1.45; }
.mr-warn { color: #8a5a12; }
.mr-fail { border-left: 4px solid #a3261f; }
.mr-changed { border-left: 4px solid #9a6a12; }
.mr-problems ul { margin: 6px 0 0; padding-left: 18px; }
.mr-sheets .op { margin: 0 auto 18px; }

@media print {
  /* The body-child hiding rule lives in the single sheet print block above and covers
     both backdrops. Repeating it here with the other class was the bug. */
  .mr-backdrop { position: static; padding: 0; background: none; overflow: visible;
    display: block; }
  .mr-head, .mr-status, .mr-bar, .mr-problems { display: none !important; }
  .mr-panel { max-width: none; }
  /* One letter per page. `break-after` on every sheet but the last avoids a trailing
     blank page, which on a 200 letter run is 200 wasted sheets of paper. */
  .mr-sheets .op { margin: 0; break-after: page; page-break-after: always; }
  .mr-sheets .op:last-child { break-after: auto; page-break-after: auto; }
}

/* ---------------------------------------------------------------- re-check
 * The change radar's report. Deliberately not a table: what matters is which
 * properties moved and what moved on them, not a grid to scan.
 */
.rc-backdrop { position: fixed; inset: 0; background: rgba(16,22,28,.55);
  overflow: auto; padding: 18px; z-index: 70; }
.rc-panel { max-width: 760px; margin: 0 auto; }
.rc-head { position: sticky; top: 0; z-index: 2; display: flex; gap: 8px; align-items: center;
  background: #fff; border-radius: 10px; padding: 10px 14px; margin-bottom: 14px;
  box-shadow: 0 2px 10px rgba(16,22,28,.18); }
.rc-head h2 { font-size: 15px; margin: 0; }
.rc-head .grow { flex: 1; }
.rc-status { color: #fff; margin: 0 0 6px; font-size: 14px; }
.rc-bar { height: 5px; background: rgba(255,255,255,.25); border-radius: 3px;
  overflow: hidden; margin-bottom: 14px; }
.rc-fill { height: 100%; width: 0; background: #6bb28a; transition: width .2s; }
.rc-card { background: #fff; border-radius: 8px; padding: 12px 16px; margin-bottom: 10px;
  font-size: 13.5px; line-height: 1.5; }
.rc-card h3 { font-size: 14px; margin: 0 0 6px; }
.rc-card ul { margin: 0; padding-left: 18px; }
.rc-changed { border-left: 4px solid #9a6a12; }
.rc-fail { border-left: 4px solid #a3261f; }
.rc-none { border-left: 4px solid #2f8f5b; }
@media print { .rc-backdrop { display: none !important; } }

/* Masthead mark on the printed sheet. */
.op-brand { display: flex; align-items: center; gap: 7px; }
.op-logo { width: 26px; height: 26px; display: block; }
@media print { .op-logo { width: 24px; height: 24px; } }

/*
 * The schematic subdivision diagram, under the near-miss headline. Abstract bar
 * comparison, deliberately not a site plan: see app/gapDiagram.js.
 */
.op-gap { margin: 10px 0 0; }
.gap-d-svg { width: 100%; max-width: 420px; height: auto; display: block; }
.gap-d-label { font-size: 8pt; fill: var(--ink-500); }
.gap-d-figure { font-size: 8pt; font-weight: 650; fill: var(--ink-800); }
.gap-d-needed { fill: var(--paper-sunk); stroke: var(--line); stroke-width: 1; }
.gap-d-available { fill: var(--good-600); }
.gap-d-gap {
  fill: var(--warn-050); stroke: var(--warn-600); stroke-width: 1; stroke-dasharray: 3 2;
}
.gap-d-bracket { fill: none; stroke: var(--warn-600); stroke-width: 1.5; }
.gap-d-shortfall { font-size: 8pt; font-weight: 650; fill: var(--warn-700); }
.gap-d-caption { margin-top: 4px; font-size: 7.5pt; color: var(--ink-500); }
@media print { .op-gap { -webkit-print-color-adjust: exact; print-color-adjust: exact; } }
