/* /app — subscriber-gated lookup tool. Marketing brand shell + lookup UI ported
   from crime_lookup_web/public/style.css with tokens tuned to match the
   propsafety.io palette (var(--accent) = #11457a). */

:root {
  --grade-a: #1f8a37;
  --grade-b: #5fa61f;
  --grade-c: #c79410;
  --grade-d: #d76b1b;
  --grade-f: #c02929;
  --err-bg: #fff3f3;
  --err-ink: #8a1a1a;
}

.app-main {
  padding: 48px 0 80px;
  background: var(--bg-alt);
  min-height: calc(100vh - 200px);
}

.app-header h1 {
  font-size: 30px;
  letter-spacing: -0.015em;
  margin: 0 0 6px;
}
.app-header .subtitle {
  margin: 0 0 28px;
  color: var(--ink-soft);
  font-size: 16px;
}

/* ── Quota bar ──────────────────────────────────────────────────────── */
.quota-bar {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 18px;
  margin: 0 0 20px;
}
.quota-bar-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--ink-soft);
}
.quota-bar .quota-count strong { color: var(--ink); font-size: 16px; }
.quota-track {
  height: 6px;
  background: var(--line);
  border-radius: 3px;
  overflow: hidden;
}
.quota-fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  transition: width 0.3s ease;
}
.quota-fill.warn { background: #c79410; }
.quota-fill.danger { background: #c02929; }
.quota-foot {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--muted);
}

/* ── Lookup form ───────────────────────────────────────────────────── */
.app-form {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin: 0 0 20px;
}
.app-form label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
  color: var(--ink-soft);
  font-weight: 500;
}
.app-form input {
  font: inherit;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
  color: var(--ink);
}
.app-form input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.app-form .btn-primary {
  align-self: flex-start;
}
.app-form button:disabled {
  opacity: 0.5;
  cursor: progress;
}

/* ── Status banner ─────────────────────────────────────────────────── */
#status {
  margin: 0 0 12px;
  min-height: 22px;
  font-size: 14px;
  color: var(--muted);
}
#status.error {
  background: var(--err-bg);
  color: var(--err-ink);
  padding: 12px 16px;
  border-radius: 6px;
  border-left: 3px solid var(--err-ink);
}
#status.warn {
  background: #fff8eb;
  color: #6b4a05;
  padding: 12px 16px;
  border-radius: 6px;
  border-left: 3px solid #c79410;
}

/* ── Result card (ports crime_lookup_web/style.css) ────────────────── */
#result {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
}
.row-input { font-size: 16px; margin: 0 0 2px; }
.row-matched {
  font-size: 13px;
  color: var(--muted);
  margin: 0 0 20px;
  font-style: italic;
}

.headline {
  display: flex;
  gap: 24px;
  align-items: stretch;
  padding: 20px;
  border-radius: var(--radius);
  background: var(--bg-alt);
  border: 1px solid var(--line);
}
.big-grade {
  /* WIDTH, not flex-basis. These boxes live inside .hl-col, which is a COLUMN
     flex container, so `flex: 0 0 128px` set their HEIGHT and left the width
     to stretch. It looked correct only because .headline-text could not
     shrink below its min-content width and squeezed them. */
  width: 128px;
  flex: 0 0 auto;
  min-height: 128px;
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: white;
  text-align: center;
  font-weight: 600;
}
.big-grade .letter { font-size: 56px; line-height: 1; }
.big-grade .pct { font-size: 13px; margin-top: 6px; opacity: 0.95; line-height: 1.2; }
.big-grade .pct-sub { font-size: 11px; opacity: 0.85; font-weight: 400; }

/* Market rank. Deliberately NOT a coloured chip like the grade: it is a
   different kind of claim — a position in a list, not a measurement against a
   scale — and it has to LOOK different or it reads as a second letter. */
.market-rank {
  width: 128px; flex: 0 0 auto;   /* width, not basis - see .big-grade */
  min-height: 128px; border-radius: 8px;
  align-self: flex-start;
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; text-align: center;
  background: #fff; border: 1px solid var(--line); padding: 10px 8px;
}
.market-rank .mr-n { font-size: 34px; font-weight: 700; line-height: 1; color: #333; }
.market-rank .mr-sub { font-size: 11px; margin-top: 7px; line-height: 1.35; color: #666; }
.market-rank .mr-agency { color: #999; font-size: 10px; }

/* Headline scope labels. The card shows three different geographies -- this
   block, this city, the wider market -- and until 2026-08-09 only the block
   said so. Two big numbers pointing opposite ways with no scope named read
   as a contradiction. */
.hl-col { display: flex; flex-direction: column; align-self: flex-start;
  flex: 0 0 auto; }
.hl-scope {
  font-size: 9.5px; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--muted); font-weight: 700; margin: 0 0 5px;
}
/* The sentence the two numbers jointly make, which the reader used to have to
   assemble. Only rendered on a wide divergence -- see _CITY_MARKET_DIVERGENCE. */
.city-market {
  margin: 0 0 10px; font-size: 14px; font-weight: 600; line-height: 1.4;
  background: #eef6ee; border-left: 3px solid var(--grade-a);
  padding: 8px 12px; border-radius: 0 6px 6px 0;
}
.grad-base { color: var(--muted); font-weight: 700; }

.grade-A, .grade-Aplus, .grade-Aminus { background: var(--grade-a); }
.grade-B, .grade-Bplus, .grade-Bminus { background: var(--grade-b); }
.grade-C, .grade-Cplus, .grade-Cminus { background: var(--grade-c); }
.grade-D, .grade-Dplus, .grade-Dminus { background: var(--grade-d); }
.grade-F { background: var(--grade-f); }
.grade-NA { background: #888; }

.headline-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* THE ROOT CAUSE OF THE MOBILE OVERFLOW, and not a mobile-only bug: a flex
     item's min-width defaults to `auto`, i.e. its min-content width, so this
     column would not shrink below the longest unbreakable run of its summary
     text -- it stayed 427px wide at 390px, 430px and 500px alike. */
  min-width: 0;
}
.summary {
  margin: 0 0 10px;
  font-size: 18px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink);
}
.recommendation {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-soft);
}

.details {
  margin-top: 20px;
  border-top: 1px solid var(--line);
  padding-top: 16px;
}
.details > summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--accent);
  font-weight: 500;
  padding: 4px 0;
  list-style: none;
}
.details > summary::-webkit-details-marker { display: none; }
.details > summary::before {
  content: "▸ ";
  display: inline-block;
  transition: transform 0.15s ease;
}
.details[open] > summary::before { transform: rotate(90deg); }

.metrics-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin-top: 12px;
}
.metrics-table th, .metrics-table td {
  text-align: left;
  padding: 8px 10px 8px 0;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
.metrics-table th {
  font-weight: 500;
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.metrics-table tr:last-child td { border-bottom: 0; }

.grade-chip {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 3px;
  color: white;
  font-size: 11px;
  font-weight: 600;
  margin-left: 4px;
  vertical-align: middle;
}

.yoy-up { color: var(--grade-f); }
.yoy-down { color: var(--grade-a); }
.yoy-flat { color: var(--muted); }

.meta-dl {
  margin: 16px 0 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 16px;
  font-size: 12px;
}
.meta-dl dt { color: var(--muted); }
.meta-dl dd { margin: 0; }

.methodology-note {
  margin-top: 16px;
  padding: 12px;
  background: #f0f3f7;
  border-left: 3px solid var(--accent);
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-soft);
  border-radius: 0 4px 4px 0;
}
.methodology-note strong { color: var(--ink); }

/* ── Out-of-coverage waitlist capture ─────────────────────────────── */
.out-of-coverage h2 {
  margin: 0 0 10px;
  font-size: 18px;
  font-weight: 600;
  line-height: 1.3;
}
.out-of-coverage > p {
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-soft);
}
.out-of-coverage p.muted {
  margin-top: 10px;
  font-size: 12px;
  color: var(--muted);
}
#notify-form {
  margin: 0;
  padding: 16px;
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
#notify-form label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
  color: var(--ink-soft);
  font-weight: 500;
}
#notify-form input {
  font: inherit;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
}
#notify-form button {
  align-self: flex-start;
  padding: 10px 18px;
  background: var(--accent);
  color: white;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
}
#notify-status {
  margin: 8px 0 0;
  min-height: 20px;
  font-size: 13px;
}
#notify-status.success { color: var(--grade-a); font-weight: 500; }
#notify-status.error { color: var(--err-ink); }

.app-foot {
  margin-top: 32px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--muted);
}

/* ── Subscription-inactive paywall ─────────────────────────────────── */
.paywall {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 32px;
  text-align: center;
  margin: 0 0 20px;
}
.paywall h2 { margin: 0 0 12px; font-size: 22px; }
.paywall p { color: var(--ink-soft); margin: 0 0 16px; }

/* ── Responsive ────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .app-header h1 { font-size: 24px; }
  /* WRAP, not column. Stacking made each box full-width and burned a screen
     of height; wrapping puts the grade and the market rank side by side on
     their own row with the summary beneath. Matches the internal site, which
     renders the same card. Predates the market-rank box, which is why it
     only handled .big-grade. */
  .headline { flex-wrap: wrap; gap: 14px; padding: 14px; align-items: flex-start; }
  .headline-text { flex-basis: 100%; }
  .big-grade, .market-rank { width: 108px; min-height: 108px; }
  .big-grade .letter { font-size: 44px; }
  .market-rank .mr-n { font-size: 28px; }
  .summary { font-size: 16px; }
  .block-label { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
  .block-grade { margin-left: 0; }
  .meta-dl { grid-template-columns: 1fr; gap: 2px 0; }
  .meta-dl dt { margin-top: 6px; }
  #result { padding: 16px; }
}


/* ── Print / save as PDF (MVP 1.5) ──────────────────────────────────────
   The point of the print path is that a figure can leave the tool with its
   provenance attached, so this stylesheet is mostly about NOT losing things:
   disclosures are forced open by the click handler, and everything that is
   interface rather than evidence is removed. Backgrounds are forced to print
   because the grade colour carries meaning. */
.result-actions { display: flex; gap: 10px; align-items: center;
                  margin: 18px 0 4px; flex-wrap: wrap; }
.action-btn { font: inherit; font-size: 13px; padding: 7px 13px;
              border: 1px solid #c9ced6; border-radius: 6px; background: #fff;
              color: #24292f; cursor: pointer; }
.action-btn:hover { background: #f3f5f8; border-color: #a9b0bb; }
.action-note { font-size: 12px; color: #57606a; }
.citation-fallback { width: 100%; margin-top: 10px; font: 12px/1.45 ui-monospace,
                     SFMono-Regular, Menlo, monospace; padding: 10px;
                     border: 1px solid #c9ced6; border-radius: 6px; }
.print-stamp { display: none; }

/* ── Comparison set ─────────────────────────────────────────────────────
   An underwriter evaluates a deal against comps, never a lone address. The
   form keeps comps behind a toggle because a single lookup is still the
   common case and an empty five-row grid on arrival reads as work to do. */
.comps { margin: -4px 0 4px; }
.comps-toggle { font: inherit; font-size: 13px; padding: 0; border: 0;
                background: none; color: #0969da; cursor: pointer; }
.comps-toggle:hover { text-decoration: underline; }
.comps-panel { margin: 10px 0 4px; padding: 14px 16px; border: 1px solid #d0d7de;
               border-radius: 10px; background: #f6f8fa; }
.comps-hint { margin: 0 0 10px; font-size: 13px; color: #57606a; }
.comp-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.comp-row > span { flex: 0 0 62px; font-size: 13px; color: #57606a; }
.comp-input { flex: 1 1 auto; padding: 8px 11px; border: 1px solid #c9ced6;
              border-radius: 6px; font: inherit; font-size: 14px; }
.comp-remove { flex: 0 0 auto; width: 28px; height: 28px; line-height: 1;
               border: 1px solid #c9ced6; border-radius: 6px; background: #fff;
               color: #57606a; font-size: 16px; cursor: pointer; }
.comp-remove:hover { background: #fff0f0; border-color: #e5a0a0; color: #b31d28; }
.comps-add { font: inherit; font-size: 13px; padding: 0; border: 0;
             background: none; color: #0969da; cursor: pointer; }
.comps-add:hover { text-decoration: underline; }

.set-title { font-size: 18px; margin: 0 0 12px; }
.set-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.set-table th, .set-table td { padding: 8px 9px; border-bottom: 1px solid #e3e6ea;
                               text-align: right; vertical-align: top; }
.set-table th:first-child, .set-table td:first-child { text-align: left; }
.set-table th { font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
                color: #57606a; border-bottom: 1px solid #c9ced6; font-weight: 600; }
.set-table tbody tr:last-child td { border-bottom: 0; }
.row-subject { background: #f2f7ff; }
.row-subject td { border-bottom-color: #cfe0f7; }
.subject-tag { display: inline-block; margin-left: 6px; padding: 1px 6px;
               border-radius: 10px; background: #1f6feb; color: #fff;
               font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
               vertical-align: 2px; }
.cell-addr { display: inline; font-weight: 600; }
.cell-agency { display: block; font-size: 11px; color: #57606a; font-weight: 400; }
/* The block column is a DIFFERENT SOURCE at a DIFFERENT RESOLUTION from the
   FBI columns beside it, so it is set apart rather than blended into them —
   a reader who takes it for a finer version of the agency figure will draw
   the wrong conclusion when the two disagree. A row without the measure says
   "agency level"; a dash would read as a missing number instead of a
   different resolution. */
.set-table th:last-child, .set-table td.cell-block { border-left: 1px solid #d0d7de;
                                                     padding-left: 12px; }
.cell-block b { font-weight: 600; }
.cell-sub { display: block; font-size: 10.5px; color: #57606a; font-weight: 400; }
.cell-none { color: #8b949e; font-style: italic; font-size: 11.5px; }
.row-failed td { color: #57606a; }
.row-error { text-align: left !important; font-style: italic; }
.set-note { margin: 12px 0 0; font-size: 11.5px; line-height: 1.5; color: #57606a; }
.set-detail { margin-top: 22px; }
.set-detail > summary { cursor: pointer; font-size: 14px; font-weight: 600;
                        color: #24292f; padding: 8px 0; }
.set-card { margin-top: 26px; padding-top: 22px; border-top: 2px solid #d0d7de; }
.card-label { margin: 0 0 6px; font-size: 11px; text-transform: uppercase;
              letter-spacing: .06em; color: #57606a; font-weight: 600; }

@media print {
  .no-print, form, header nav, footer, .action-btn, .action-note,
  .citation-fallback, .comps, .trial-note, .trial-gate { display: none !important; }
  .print-stamp { display: block !important; margin-top: 18px;
                 font-size: 9px; color: #57606a;
                 border-top: 1px solid #d0d7de; padding-top: 6px; }
  details > summary { display: none !important; }
  details { border: 0 !important; padding: 0 !important; }
  body { background: #fff !important; padding: 0 !important; }
  a[href]:after { content: ""; }
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
  .headline, .metrics-table, .meta-dl, table { page-break-inside: avoid; }

  /* ONE PAGE PER PROPERTY, and the table gets its own page ahead of them.
     Done with a page break before each card rather than CSS running
     headers/footers, which are not dependable across browsers: "one card per
     page" plus "a footer at the bottom of each card" puts source, basis size
     and data date on every page using no browser feature at all. A page torn
     out of an IC memo has to be defensible on its own. */
  .set-card { break-before: page; page-break-before: always;
              margin-top: 0; padding-top: 0; border-top: 0; }
  .ps-card { break-inside: auto; }
  /* Scroll containers do not exist on paper; unreverted they clip the
     table at the box width instead of letting it use the sheet. */
  .table-scroll { overflow: visible !important;
                                   background: none !important; }
  .table-scroll > .set-table, .table-scroll > .block-table {
                                   min-width: 0 !important; }
  .set-table-wrap { break-inside: avoid; }
  .set-table { font-size: 10px; }
  .set-table th, .set-table td { padding: 5px 6px; }
  .set-note { font-size: 9px; }

  /* Fit a single property on a single page. The card carries a headline, a
     block pane, a metrics table and a definitions list; at screen sizes that
     is comfortably two pages, which is one page more than an attachment
     should be. */
  @page { margin: 10mm 11mm 8mm; }
  .app-header, .quota-bar, .app-foot, #trial-panel { display: none !important; }
  .ps-card { font-size: 10px; }
  .card-label { font-size: 8.5px; margin-bottom: 2px; }
  .row-input { font-size: 12.5px; margin: 0 0 1px; }
  .row-matched { font-size: 9px; margin: 0 0 6px; }
  .headline { margin: 0 0 7px; gap: 12px; }
  .big-grade { flex: 0 0 86px; min-height: 0; padding: 10px 8px; }
  .big-grade .letter { font-size: 34px; line-height: 1; }
  .big-grade .pct { font-size: 10px; margin-top: 3px; }
  .big-grade .pct-sub { font-size: 8.5px; }
  .summary, .recommendation { font-size: 10px; line-height: 1.4; margin: 0 0 5px; }
  .metrics-table, .block-table { font-size: 9px; }
  .metrics-table th, .metrics-table td,
  .block-table th, .block-table td { padding: 3px 5px; }
  .meta-dl { font-size: 9px; gap: 2px 10px; margin: 6px 0; }
  .methodology-note { font-size: 8.5px; line-height: 1.4; margin: 6px 0 0; }
  .block-pane { margin: 6px 0; padding: 6px 8px; }
  .block-label { font-size: 9px; margin: 0 0 4px; }
  .block-src, .grad-read { font-size: 8px; line-height: 1.35; }

  /* The offence mix is a dozen single-line items — a column of mostly empty
     row. Three columns turn ~12 lines into 4 and are what buys the Mesa
     cards their one-page fit. `columns` also lets the browser balance them,
     so a short mix does not leave two empty columns. */
  .block-mix ul { columns: 3; column-gap: 14px; margin: 3px 0 0; }
  .block-mix li { font-size: 8.5px; line-height: 1.5; break-inside: avoid; }
  .block-grad ul { columns: 2; }

  /* details/summary is display:none in print, but the details element itself
     still generates a box. Collapse its spacing so the methodology block
     starts immediately under the headline. */
  .details { margin: 0 !important; }
}


/* ── Free-lookup trial (MVP 1.6) ────────────────────────────────────────
   Shown only when the API says so; the page tracks no trial state of its
   own, so these panels cannot disagree with the server about how many
   lookups are left. */
#trial-panel:empty { display: none; }
.trial-note { margin: 14px 0; font-size: 13px; color: #57606a; }
.trial-note a { color: #0969da; }
.trial-gate { margin: 18px 0; padding: 18px 20px; border: 1px solid #d0d7de;
              border-radius: 10px; background: #f6f8fa; }
.trial-gate h3 { margin: 0 0 6px; font-size: 16px; }
.trial-gate p { margin: 0 0 10px; font-size: 14px; color: #24292f; }
.trial-gate form { display: flex; gap: 8px; flex-wrap: wrap; }
.trial-gate input[type="email"] { flex: 1 1 240px; padding: 9px 11px;
              border: 1px solid #c9ced6; border-radius: 6px; font: inherit; }
.trial-gate button { padding: 9px 16px; border: 0; border-radius: 6px;
              background: #1f6feb; color: #fff; font: inherit; cursor: pointer; }
.trial-gate button:disabled { opacity: .6; cursor: default; }
.trial-status { min-height: 1em; font-size: 13px; color: #57606a; }
.trial-alt { font-size: 13px; color: #57606a; }
.trial-cta { display: inline-block; padding: 9px 16px; border-radius: 6px;
             background: #1f6feb; color: #fff; text-decoration: none; }
.trial-paywall { background: #fff8e6; border-color: #e6c86e; }

/* The 1-mile row is the baseline the inner rings are measured against, so it
   gets its own line AND stacks its caption beneath the numbers instead of
   competing with them for width. See the comment beside it in app.js. */
/* Own line, but the caption sits INLINE when there is room -- exactly like
   the 0.25 mi row's caption. flex-wrap only drops it beneath when there is
   not. Measured across every cached payload at rates from 17.4 to 2,625.0:
   24px, the same height as the 0.25 mi row. */
.block-grad li.grad-baseline { flex-basis: 100%; flex-wrap: wrap; }

/* Wide content scrolls inside its OWN container; the page body never scrolls
   horizontally. The right-edge fade only paints while there is more to
   scroll to -- background-attachment:local pins the white cover to the
   content so it slides away at the end. No JS, nothing to keep in sync. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll > .block-table { min-width: 380px; }
.table-scroll > .set-table { min-width: 560px; }
.table-scroll {
  background:
    linear-gradient(to right, #fff 30%, rgba(255,255,255,0)) left center,
    linear-gradient(to left, #fff 30%, rgba(255,255,255,0)) right center,
    linear-gradient(to right, rgba(0,0,0,.10), rgba(0,0,0,0) 12px) left center,
    linear-gradient(to left, rgba(0,0,0,.10), rgba(0,0,0,0) 12px) right center;
  background-repeat: no-repeat;
  background-size: 28px 100%, 28px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}


/* How the natives feel — metro-level perception (schema v46).
   Visually SUBORDINATE to the measured figures on purpose: a different kind
   of claim at a coarser resolution, and it must never read as a second
   opinion about the address the customer typed. The qualifier is styled to
   stay legible rather than to disappear — it is load-bearing copy, not fine
   print. */
.perception {
  margin: 14px 0 0;
  padding: 12px 14px;
  border-left: 3px solid #b9c2cc;
  background: #f6f8fa;
  border-radius: 0 4px 4px 0;
}
.perception .hl-scope { margin: 0 0 6px; }
.perc-lead { margin: 0 0 6px; font-size: 0.95rem; line-height: 1.45; }
.perc-peer { margin: 0 0 6px; font-size: 0.88rem; color: #3d464f; }
.perc-diverge { margin: 0 0 6px; font-size: 0.9rem; line-height: 1.45; }
.perc-qual { margin: 0; font-size: 0.78rem; color: #5b6670; line-height: 1.4; }

@media print {
  /* The pane travels into the printed card and the exported citation, so the
     qualifier must survive both. One card per page — never let it split. */
  .perception { break-inside: avoid; background: none; border-left: 2px solid #999; }
}

/* Incomplete-window warning — see crime_lookup_web/public/style.css. Edited in
   place: this file has no canonical upstream. */
.window-short {
  margin: 0 0 10px; padding: 8px 10px;
  border-left: 3px solid #b8860b; background: #fdf6e3;
  font-size: 0.86rem; line-height: 1.45;
}
@media print { .window-short { background: none; border-left: 2px solid #666; } }

/* Block-level year-over-year. Fires for a minority of addresses by design. */
.block-trend { margin: 0 0 10px; font-size: 0.9rem; line-height: 1.45; }

/* Market-rank band. What the eye lands on first; the exact ordinal stays
   above it for anyone comparing two deals. Absent in the middle third. */
.mr-band { display:block; font-size:10.5px; font-weight:700; color:#8a2f2f;
           margin-top:3px; letter-spacing:.01em; }
