/* The paid report in the shared system (styles.css): the same fonts, tokens, tags, chips, marks
   and fill layers as the front page, laid out like a research house's location report. A dark
   cover, the summary card, numbered Contents, numbered parts that each open with their finding,
   and every chart numbered, titled, on a fixed axis and closed by its source.
   Layouts that must hold with big text switch on the report's own width in rem (container
   queries), so a reader's 150% text gets the narrower layout instead of words running together.
   Spacing steps: 4, 8, 12, 16, 24, 32, 48, 64. */

.btn-print { margin-left: auto; }
.btn-print .ps-short { display: none; }
@media (max-width: 479px) { .btn-print .ps-long { display: none; } .btn-print .ps-short { display: inline; } }
/* The name and the button share a line down to 320 px; with bigger text the button moves under the
   name instead of pushing the page sideways. */
.report-page .top-in { flex-wrap: wrap; height: auto; min-height: 64px; padding-block: 8px; row-gap: 4px; }
@media (max-width: 379px) {
  .report-page .top-in { column-gap: 10px; }
  .report-page .brand { gap: 8px; font-size: 1.0625rem; }
  .btn-print { padding-inline: 12px; }
}
/* The plain sample page (/sample-report) keeps the site's nav and "Check my site" pill, so its
   print button shows only where it fits beside them on one line: from 600 px until the nav
   arrives at 860, then again from 940 (at normal text). The points are in rem, so they move with
   the reader's text size; 860 stays in px, as it is where styles.css shows the nav. */
.btn-print-nav { display: none; }
@media (min-width: 37.5rem) { .btn-print-nav { display: inline-flex; } .btn-print-nav + .btn-nav { margin-left: 0; } }
@media (min-width: 860px) { .btn-print-nav { margin-left: 0; } }
@media (min-width: 860px) and (max-width: 58.6875rem) { .btn-print-nav { display: none; } }
@media (min-width: 37.5rem) and (max-width: 44.9375rem), (min-width: 58.75rem) and (max-width: 63.9375rem) { .btn-print-nav .ps-long { display: none; } .btn-print-nav .ps-short { display: inline; } }

.rpt {
  container: rpt / inline-size;
  padding-block: 8px 0;
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}
.rpt .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.rpt p, .rpt li, .rpt dd { text-wrap: pretty; }
/* While the report loads, hold the page's height so the footer does not jump when it renders. */
#report:has(#status) { min-height: 100vh; }
/* With JavaScript off nothing will load, so only the note shows, with no height held for it. */
@media (scripting: none) { #status { display: none; } #report:has(#status) { min-height: 0; } }
.rpt-msg { display: grid; gap: 12px; margin-top: 24px; padding: 24px; border-radius: var(--r-screen); background: var(--surface); box-shadow: var(--hair); }

.sample-banner { display: flex; gap: 12px; align-items: baseline; margin: 0 0 16px; padding: 12px 16px; border-radius: var(--r-row); background: var(--sunk); color: var(--ink-2); font-size: var(--t-small); line-height: 1.5; }
.sample-banner .tag { flex: none; }
.sample-banner b { color: var(--ink); }

/* ---------- Cover: the one dark surface, the same in both modes ---------- */
.cover { display: grid; gap: 24px; overflow: hidden; padding: clamp(22px, 5vw, 56px); border-radius: var(--r-tray); background: var(--cover); color: var(--on-cover); box-shadow: inset 0 0 0 1px var(--cover-edge); }
/* Text and map side by side once the map's column (in rem, so it grows with the text) leaves the
   words room; otherwise the map drops under the meta row. */
@container rpt (min-width: 53rem) {
  .cover.with-map { grid-template-columns: minmax(0, 1.6fr) minmax(15rem, 1fr); gap: 48px; align-items: center; }
}
.cover-text { min-width: 0; container: covertext / inline-size; }
.cover-brand { color: var(--on-cover-accent); font-size: var(--t-kicker); font-weight: 600; line-height: 1.4; letter-spacing: 0.16em; text-transform: uppercase; }
.cover h1 { margin: 14px 0 16px; color: #fff; font: 750 var(--t-title)/1.04 var(--f-display); letter-spacing: -0.025em; font-variation-settings: "opsz" 72; }
.cover-ill { display: block; margin-top: 8px; color: var(--on-cover-muted); font: 500 1.0625rem/1.4 var(--f-text); letter-spacing: 0; }
.cover-concept { max-width: 34em; color: var(--on-cover); line-height: 1.6; }
.cover-concept b { color: #fff; }
/* The facts under the title: label left, value right, one a line; three or four abreast once each
   has about 10rem. */
.cover-meta { display: grid; margin: 24px 0 0; border-top: 1px solid rgb(230 238 242 / 0.18); }
.cover-meta div { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 1px solid rgb(230 238 242 / 0.12); }
.cover-meta dt { flex: none; color: var(--on-cover-muted); font-size: var(--t-caption); line-height: 1.5; }
.cover-meta dd { margin: 0; color: #fff; font-size: var(--t-small); font-weight: 600; line-height: 1.45; text-align: right; font-variant-numeric: tabular-nums; }
/* With very big text the value moves under its label rather than run off the card's edge. */
.cover-meta div { flex-wrap: wrap; row-gap: 2px; }
.cover-meta dd { flex: 1 1 0; min-width: min-content; }
@container covertext (min-width: 30rem) {
  .cover-meta:not(.n4) { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1.1fr); }
  .cover-meta:not(.n4) div { display: block; padding: 12px 16px 2px 0; border-bottom: 0; }
  .cover-meta:not(.n4) div + div { padding-left: 16px; border-left: 1px solid rgb(230 238 242 / 0.18); }
  .cover-meta:not(.n4) dd { margin-top: 4px; text-align: left; }
}
@container covertext (min-width: 40rem) {
  .cover-meta.n4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .cover-meta.n4 div { display: block; padding: 12px 16px 2px 0; border-bottom: 0; }
  .cover-meta.n4 div + div { padding-left: 16px; border-left: 1px solid rgb(230 238 242 / 0.18); }
  .cover-meta.n4 dd { margin-top: 4px; text-align: left; }
}

/* The site map, small, on the cover: light lines on the dark card. */
.sitemap.compact { min-width: 0; margin: 0; }
.sitemap.compact svg { width: 100%; max-width: 260px; margin-inline: auto; overflow: visible; }
@container rpt (min-width: 53rem) { .sitemap.compact svg { max-width: 300px; } }
.sitemap.compact .axis { fill: none; stroke: rgb(230 238 242 / 0.14); stroke-width: 1; stroke-dasharray: 2 5; }
.sitemap.compact .area { fill: rgb(98 191 213 / 0.08); stroke: rgb(230 238 242 / 0.42); stroke-width: 1.2; stroke-dasharray: 6 5; }
.sitemap.compact .walk { fill: none; stroke: var(--on-cover-accent); stroke-width: 1.4; stroke-dasharray: 2 4; stroke-linecap: round; }
.sitemap.compact .rlabel { fill: var(--on-cover-muted); font: 600 15px var(--f-text); text-anchor: middle; paint-order: stroke; stroke: var(--cover); stroke-width: 5px; stroke-linejoin: round; }
.sitemap.compact .rival rect { fill: var(--cover); stroke: var(--on-cover); stroke-width: 1.6; }
.sitemap.compact .rival text { fill: var(--on-cover); font: 700 15px var(--f-text); text-anchor: middle; }
.sitemap.compact .draw rect { fill: rgb(98 191 213 / 0.25); stroke: var(--on-cover-accent); stroke-width: 1.5; }
.sitemap.compact .site path { fill: var(--on-cover-berry); }
.sitemap.compact .site circle { fill: var(--cover); }
.sitemap.compact .north path { fill: var(--on-cover-muted); }
.sitemap.compact .north text { fill: var(--on-cover-muted); font: 600 15px var(--f-text); text-anchor: middle; }
.cover-key { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; margin-top: 14px; color: var(--on-cover-muted); font-size: var(--t-caption); line-height: 1.4; }
.cover-key .li { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.cover-key i { flex: none; }
.ck-site { width: 10px; height: 10px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); background: var(--on-cover-berry); }
.ck-rival { width: 11px; height: 11px; border-radius: 2px; box-shadow: inset 0 0 0 1.6px var(--on-cover); }
.ck-draw { width: 8px; height: 8px; margin-inline: 1px; transform: rotate(45deg); background: rgb(98 191 213 / 0.25); box-shadow: inset 0 0 0 1.5px var(--on-cover-accent); }
.ck-area { width: 14px; height: 14px; border-radius: 50%; box-shadow: inset 0 0 0 1.2px rgb(230 238 242 / 0.5); }

/* ---------- What we found ---------- */
.summary { container: summary / inline-size; margin-top: 16px; padding: clamp(20px, 4.5vw, 48px); border-radius: var(--r-tray); background: var(--tint-sky); }
.sum-head { display: grid; gap: 24px; }
.sum-head .headline { max-width: 26em; margin-top: 12px; font: 700 clamp(1.375rem, 1.15rem + 1vw, 2rem)/1.22 var(--f-display); letter-spacing: -0.018em; font-variation-settings: "opsz" 48; }
.sum-side { display: grid; gap: 12px; align-content: start; min-width: 0; }
.sum-side .scale3 { max-width: none; }
.sum-side .scale3 > span { min-height: 48px; background: var(--surface); }
.start { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; padding: 14px 18px; border-radius: var(--r-row); background: var(--surface); color: inherit; text-decoration: none; box-shadow: var(--hair); }
.start:hover { color: inherit; box-shadow: inset 0 0 0 1.5px var(--berry); }
.start-k { color: var(--berry); font-size: var(--t-caption); font-weight: 650; }
.start-t { grid-column: 1; margin-top: 2px; color: var(--ink); font-weight: 650; line-height: 1.4; }
.start-s { grid-column: 1; margin-top: 4px; color: var(--ink-2); font-size: var(--t-small); line-height: 1.45; }
.start-a { grid-column: 2; grid-row: 1 / span 3; align-self: center; color: var(--berry); font-size: 1.375rem; }
.limits { max-width: 46em; }
.sum-grid { display: grid; gap: 28px; margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--hairline); }
.sum-grid > div { min-width: 0; }
.sum-grid h3 { margin-bottom: 10px; font-size: 1.1875rem; font-weight: 700; line-height: 1.3; letter-spacing: -0.015em; }
.sum-grid p { color: var(--ink-2); }
.sum-grid p + p { margin-top: 12px; }
.sum-grid .sure { color: var(--muted); font-size: var(--t-small); }
.sure strong { color: var(--ink); }
/* Side by side once the summary has room for both columns at this text size. */
@container summary (min-width: 46em) {
  .sum-head { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 48px; align-items: start; }
  .sum-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 48px; }
}
.findings { margin: 0; padding: 0; list-style: none; }
.findings li { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 8px; padding: 10px 0; border-top: 1px solid var(--hairline); line-height: 1.5; }
.findings li:first-child { border-top: 0; padding-top: 2px; }
.findings .mk { margin-top: 0.5em; }
.mk-key { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 6px; color: var(--muted); font-size: var(--t-caption); }
.mk-key span { display: inline-flex; align-items: center; gap: 6px; }
/* A note: a short level bar, so it reads apart from the three status marks without colour. */
.mk-note { background: linear-gradient(var(--muted), var(--muted)) center / 100% 2px no-repeat; border-radius: 0; }

/* Key figures: a ruled row, each number with what it is compared with. The row is a size
   container, so a value can shrink to its column (--cols of them) when bigger text would push it
   out. The container sits on the row: on a figure it would undo the subgrid. */
.figures { --cols: var(--n, 4); display: grid; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); margin: 0; border-block: 1px solid var(--line); container-type: inline-size; }
.figure { display: grid; grid-row: span 3; grid-template-rows: subgrid; grid-template-columns: minmax(0, 1fr); row-gap: 4px; align-content: start; min-width: 0; padding: 16px 20px 18px; }
.figure > * { min-width: 0; overflow-wrap: anywhere; }
.figure:first-child { padding-left: 0; }
.figure + .figure { border-left: 1px solid var(--line); }
.figure dt { align-self: end; color: var(--ink-2); font-size: 0.875rem; font-weight: 600; line-height: 1.35; }
/* A value is about 0.62em a character ("59,200" about 3.7em), and --len is its length, so a long
   one such as "1,230,000" shrinks more; 40px is the most a figure's padding takes. A number never
   splits across lines. */
.figure .fv { margin: 0; overflow-wrap: normal; white-space: nowrap; font-size: var(--t-figure); font-size: min(var(--t-figure), (100cqi / var(--cols) - 40px) / max(3.6, var(--len, 6) * 0.62)); font-weight: 700; line-height: 1.1; letter-spacing: -0.025em; font-variant-numeric: tabular-nums; }
.figure .fvs { display: flex; align-items: baseline; gap: 8px; margin: 0; color: var(--muted); font-size: var(--t-caption); line-height: 1.45; }
/* The summary's four sit in a white box. */
.summary .figures { margin: 28px 0 12px; padding: 0 4px; border: 0; border-radius: var(--r-screen); background: var(--surface); box-shadow: var(--hair); }
.summary .figure, .summary .figure:first-child { padding: 20px 16px; }
.figures.compact { margin-top: 28px; }
.figures.compact .figure { padding-block: 14px 16px; }
/* The summary's figures go two by two, then one by one, as the summary narrows for its text
   size, so a label never breaks inside a word ("surroundin/g"). */
@container summary (max-width: 38em) {
  .summary .figures { --cols: 2; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .summary .figure, .summary .figure:first-child { padding: 16px 12px 16px 14px; }
  .summary .figure + .figure { border-left: 0; }
  .summary .figure:nth-child(even) { border-left: 1px solid var(--line); }
  .summary .figure:nth-child(n + 3) { border-top: 1px solid var(--line); }
  .summary .figure:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@container summary (max-width: 16em) {
  .summary .figures { --cols: 1; grid-template-columns: minmax(0, 1fr); }
  .summary .figure:nth-child(even) { border-left: 0; }
  .summary .figure:nth-child(n + 2) { border-top: 1px solid var(--line); }
}
/* A part's figures likewise: two abreast on a phone, one by one when big text leaves too little
   room for two. */
.part .body { container: section / inline-size; }
@container section (max-width: 30em) {
  .figures.compact { --cols: 2; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .figures.compact .figure, .figures.compact .figure:first-child { padding: 14px 12px 16px 0; }
  .figures.compact .figure + .figure { border-left: 0; }
  .figures.compact .figure:nth-child(even) { padding-left: 16px; border-left: 1px solid var(--line); }
  .figures.compact .figure:nth-child(n + 3) { border-top: 1px solid var(--line); }
  .figures.compact .figure:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@container section (max-width: 16em) {
  .figures.compact { --cols: 1; grid-template-columns: minmax(0, 1fr); }
  .figures.compact .figure:nth-child(even) { padding-left: 0; border-left: 0; }
  .figures.compact .figure:nth-child(n + 2) { border-top: 1px solid var(--line); }
}

/* ---------- Contents: a real sequence, so numbered, read down each column. Open from 641 px; a
   fold on phones (report.js). ---------- */
.toc { margin-top: 40px; }
.toc summary { display: flex; align-items: center; min-height: 44px; list-style: none; cursor: pointer; }
.toc summary::-webkit-details-marker { display: none; }
.toc-title { color: var(--primary); font-size: var(--t-kicker); font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; }
.toc summary .pm { margin-left: 12px; }
.toc ol { display: grid; gap: 0 32px; margin: 8px 0 0; padding: 0; list-style: none; }
@container rpt (min-width: 37rem) { .toc ol { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(var(--r2, 5), auto); grid-auto-flow: column; } }
@container rpt (min-width: 59.5rem) { .toc ol { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: repeat(var(--r3, 4), auto); } }
.toc li { min-width: 0; border-top: 1px solid var(--line); }
.toc a { display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 8px 0; color: var(--ink); font-weight: 500; line-height: 1.35; text-decoration: none; }
.toc a:hover { color: var(--primary); text-decoration: underline; }
.toc .n { flex: none; width: 1.6em; color: var(--muted); font-size: var(--t-small); font-variant-numeric: tabular-nums; }
/* The floating Contents button, once the list has scrolled away (report.js #tocButton). */
.toc-float { position: fixed; z-index: var(--z-sticky); right: var(--gutter); bottom: calc(16px + env(safe-area-inset-bottom)); min-height: 44px; padding: 0 18px; border: 0; border-radius: var(--r-pill); background: var(--nav-pill); color: var(--on-nav-pill); box-shadow: var(--sh-3); font: 600 var(--t-small) var(--f-text); cursor: pointer; }
/* Where the parts have a margin column, the button sits at its foot, clear of the report
   (report.js sets left to the column's edge). */
.toc-float.in-margin { right: auto; }
/* Out of sight, but still in the Tab order (report.js shows it again once it has focus). */
.toc-float.away { opacity: 0; transform: translateY(calc(100% + 24px)); pointer-events: none; }
.toc-dialog { width: min(100% - 32px, 420px); max-height: calc(100vh - 64px); padding: 20px; border: 0; border-radius: var(--r-tray); background: var(--surface); color: var(--ink); box-shadow: var(--sh-3); }
.toc-dialog::backdrop { background: rgb(13 32 45 / 0.4); }
.toc-dialog .toc-title { margin: 0; }
.toc-dialog ul { margin: 8px 0 16px; padding: 0; list-style: none; }
.toc-dialog a { display: flex; align-items: center; min-height: 44px; border-top: 1px solid var(--line); color: var(--ink); text-decoration: none; }
.toc-dialog .toc-close { width: 100%; }

/* ---------- A part of the report: its number and name as a kicker, in the margin when wide ---------- */
.part { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; margin-top: 48px; padding-top: 40px; border-top: 1px solid var(--line); }
.part > .body, .part > .topic { min-width: 0; }
@container rpt (min-width: 59.5rem) {
  .part { grid-template-columns: 11rem minmax(0, 1fr); gap: 40px; margin-top: 56px; padding-top: 56px; }
  .part > .topic { position: sticky; top: 24px; align-self: start; padding-top: 10px; }
}
.topic { color: var(--primary); font-size: var(--t-kicker); font-weight: 600; line-height: 1.5; letter-spacing: 0.16em; text-transform: uppercase; }
.topic .n { margin-right: 6px; color: var(--muted); letter-spacing: 0; }
.body > h2, #spotsBody > h2 { font: 750 var(--t-h2-report)/1.15 var(--f-display); letter-spacing: -0.018em; font-variation-settings: "opsz" 48; }
/* The flow inside a part: 16 px between blocks unless a block says otherwise. One class's weight,
   so it beats styles.css's element reset and any later class rule beats it. */
:where(.rpt .body, .rpt #spotsBody, .rpt .slow-start, .rpt .near-col, .rpt .two > div, .rpt .rivals, .rpt .fix > div) > :not(:first-child) { margin-top: 16px; }
:where(.rpt .body, .rpt #spotsBody, .rpt .slow-start) > h3, .rpt .two h3, .rpt .rivals h3 { margin-top: 32px; font-size: var(--t-h3); font-weight: 700; line-height: 1.3; letter-spacing: -0.015em; }
.rpt .two > div > h3:first-child, .rpt .rivals > h3:first-child, .rpt .near-col > h3:first-child { margin-top: 0; }
.near-col h3 { font-size: 1.0625rem; font-weight: 650; }
.slow-start { margin-top: 32px; }
/* Measures in em keep lines near 65 characters whatever the font. */
.rpt .lede { max-width: 38em; margin-top: 14px; color: var(--ink-2); font-size: var(--t-lead); line-height: 1.55; }
.rpt .body > p:not([class]), .rpt #spotsBody > p:not([class]), .slow-start > p, .rpt .rivals, .rpt .two > div, .rpt .notes, .rpt .howto, .rpt .spots { max-width: 38em; }
.rpt .source { max-width: 46em; color: var(--muted); font-size: var(--t-caption); line-height: 1.5; }
.chart + .pnote { margin-top: 20px; }
.pnote { max-width: 46em; color: var(--muted); font-size: var(--t-small); line-height: 1.55; }
.rpt .body :is(ul, ol):not([class]), .rpt .notes, .rpt .howto, .rpt .spots { padding-left: 1.25em; }
.rpt .body :is(ul, ol):not([class]) > li + li, .rpt .notes li + li, .rpt .howto li + li { margin-top: 8px; }
.rpt .spots li { margin: 0 0 12px; }
.spot-links { display: flex; flex-wrap: wrap; gap: 0 4px; margin-left: -8px; font-size: var(--t-small); }
/* Links in a list line ("Map", "Check it free"): a 44 px target without changing the words. */
.rpt a.go { display: inline-flex; align-items: center; min-width: 44px; min-height: 44px; padding-inline: 8px; }
.rpt .spots .chip { margin-left: 6px; vertical-align: 1px; }
.rpt .rivals ol { margin-top: 12px; }
.two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 32px; }

/* ---------- A chart: "Figure N", its title, a key, the chart, then its source ---------- */
.chart { min-width: 0; margin: 32px 0 0; }
.chart-head { display: grid; gap: 4px 16px; align-items: baseline; margin-bottom: 14px; padding-top: 12px; border-top: 2px solid var(--ink); }
.fig-n { color: var(--primary); font-size: var(--t-mock); font-weight: 650; letter-spacing: 0.12em; text-transform: uppercase; white-space: nowrap; }
.rpt .chart-t { margin: 0; font-size: var(--t-body); font-weight: 650; line-height: 1.4; letter-spacing: 0; }
@container section (min-width: 36em) {
  .chart-head { grid-template-columns: auto minmax(0, 1fr); }
  .chart-head .legend { grid-column: 2; }
}
/* A short key sits at the end of the title's line, as the mock's Figure 1. */
@container section (min-width: 52em) {
  .age-chart .chart-head, .dumbbell .chart-head { grid-template-columns: auto minmax(0, 1fr) auto; }
  .age-chart .chart-head .legend, .dumbbell .chart-head .legend { grid-column: 3; }
}
.rpt .legend { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; color: var(--muted); font-size: var(--t-caption); line-height: 1.45; }
.rpt .legend .li { display: inline-flex; align-items: center; gap: 6px; }
.rpt .legend .key { flex: none; display: inline-block; width: 12px; height: 10px; margin: 0; border-radius: 2px; vertical-align: middle; }
.key.here { background: var(--chart-here); }
.rpt .legend .key.around { height: 6px; background: var(--chart-area); }
.rpt .legend .key.dot-here, .rpt .legend .key.dot-around { width: 12px; height: 12px; border-radius: 50%; }
.key.dot-here { background: var(--chart-here); }
.key.dot-around { background: var(--surface); box-shadow: inset 0 0 0 3px var(--chart-area); }
.chart-note { color: var(--muted); font-size: 0.875rem; line-height: 1.5; }
.chart-head + .chart-note { margin-top: -6px; margin-bottom: 10px; }
.chart > .source { margin-top: 12px; }
/* The axis labels under a chart sit on the track's own width. */
.ticks { position: relative; display: block; height: 1.5em; color: var(--muted); font-size: var(--t-caption); line-height: 1.5; font-variant-numeric: tabular-nums; }
.ticks span { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.ticks span:first-child { transform: none; }
.ticks span:last-child { transform: translateX(-100%); }
/* A label needs about 3.7em of track per step: the last one sits flush with the track's end, so it
   reaches half a label further in than a centred one. On a shorter track for its number of steps
   (.n3 is 0 to 15%), every other label goes, the first and last stay; on a very short one, only those. */
.ticks { container: ticks / inline-size; }
@container ticks (max-width: 7.4em) { .ticks.n2 > :nth-child(2):not(:last-child) { display: none; } }
@container ticks (max-width: 11.1em) { .ticks.n3 > :not(:first-child, :last-child) { display: none; } }
@container ticks (max-width: 14.8em) { .ticks.n4 > :is(:nth-child(even), :nth-last-child(2)):not(:first-child, :last-child) { display: none; } }
@container ticks (max-width: 18.5em) { .ticks.n5 > :is(:nth-child(even), :nth-last-child(2)):not(:first-child, :last-child) { display: none; } }
@container ticks (max-width: 22.2em) { .ticks.n6 > :is(:nth-child(even), :nth-last-child(2)):not(:first-child, :last-child) { display: none; } }
@container ticks (max-width: 25.9em) { .ticks.n7 > :is(:nth-child(even), :nth-last-child(2)):not(:first-child, :last-child) { display: none; } }
@container ticks (max-width: 29.6em) { .ticks.n8 > :is(:nth-child(even), :nth-last-child(2)):not(:first-child, :last-child) { display: none; } }
@container ticks (max-width: 33.3em) { .ticks.n9 > :is(:nth-child(even), :nth-last-child(2)):not(:first-child, :last-child) { display: none; } }
@container ticks (max-width: 37em) { .ticks.n10 > :is(:nth-child(even), :nth-last-child(2)):not(:first-child, :last-child) { display: none; } }
@container ticks (max-width: 8em) { .ticks > :not(:first-child, :last-child) { display: none; } }

/* Share of residents by age, here against around. Fixed axis from 0 to the largest share rounded
   up to the next 5%, a gridline at every step (--grid), labels under it. Bars start square at the
   axis and grow from it. --lab is the room past the longest bar for its bold "21.0%". */
.age-chart { --lab: 3.75rem; container: ages / inline-size; }
.grow, .dline { transform-origin: left center; }
.arow { display: grid; grid-template-columns: minmax(0, 13rem) minmax(0, 1fr) 6.5rem; gap: 16px 20px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--line); }
.rows > .arow:first-child { border-top: 1px solid var(--line); }
.alabel { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; min-width: 0; color: var(--ink-2); font-size: var(--t-small); line-height: 1.35; }
.arow.w2 .alabel, .arow.w3 .alabel { color: var(--ink); font-weight: 650; }
.rpt .pull { color: var(--primary); font-size: var(--t-caption); font-weight: 650; }
.abars { display: grid; gap: 4px; min-width: 0; padding-right: var(--lab);
  background: linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0 / var(--grid, 20%) 100% repeat-x content-box,
    linear-gradient(var(--line), var(--line)) 100% 0 / 1px 100% no-repeat content-box; }
.abar { display: flex; align-items: center; gap: 3px; }
.abar i { flex: none; display: block; height: 12px; min-width: 2px; border-radius: 0 var(--r-bar) var(--r-bar) 0; background: var(--chart-here); }
.abar.around i { height: 7px; background: var(--chart-area); }
.abar b { padding: 0 3px; background: var(--bg); color: var(--ink); font-size: var(--t-caption); font-weight: 650; line-height: 1.2; white-space: nowrap; font-variant-numeric: tabular-nums; }
.abar.around b { color: var(--muted); font-weight: 500; }
.arow > .chip { justify-self: end; }
.arow.axis { padding: 6px 0 0; border: 0; }
.arow.axis .ticks { margin-right: var(--lab); }
/* The last label has the room past the track, so it centres on its line like the rest. */
.arow.axis .ticks span:last-child { transform: translateX(-50%); }
/* When the chart is narrow for its text size (a phone, a tablet, or big text beside the margin
   topic), label and tag share a line and both bars run full width under them, so a tag never
   covers a value and the axis labels keep their room. */
@container ages (max-width: 40em) {
  .arow { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "label chip" "bars bars"; gap: 8px 12px; }
  .alabel { grid-area: label; }
  .abars { grid-area: bars; }
  .arow > .chip { grid-area: chip; align-self: start; }
  .arow.axis { grid-template-areas: none; grid-template-columns: minmax(0, 1fr); }
  .arow.axis > span { display: none; }
}

/* The gap: dots on one fixed scale, the line between them is the gap. */
.dumbbell { container: gap / inline-size; }
.drow { display: grid; grid-template-columns: minmax(0, 13rem) minmax(0, 1fr) 11.5rem 6.5rem; gap: 16px; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--line); }
.chart-note + .drow { border-top: 1px solid var(--line); }
.dlabel { display: flex; flex-direction: column; gap: 2px; min-width: 0; font-weight: 650; line-height: 1.3; }
.dtrack { position: relative; height: 24px;
  background: linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0 / var(--grid, 25%) 100% repeat-x,
    linear-gradient(var(--line), var(--line)) 100% 0 / 1px 100% no-repeat; }
.dtrack::before { content: ""; position: absolute; top: 11px; right: 0; left: 0; height: 2px; border-radius: 1px; background: var(--line); }
.dline { position: absolute; top: 10px; height: 4px; border-radius: 2px; background: var(--muted); }
.drow.risk .dline { background: var(--against-mark); }
.drow.good .dline { background: var(--fits-mark); }
.dot { position: absolute; top: 4px; width: 16px; height: 16px; margin-left: -8px; border-radius: 50%; }
.dot.around { background: var(--surface); box-shadow: inset 0 0 0 3px var(--chart-area); }
.dot.here { background: var(--chart-here); box-shadow: 0 0 0 3px var(--bg); }
.dvals { font-size: var(--t-small); white-space: nowrap; font-variant-numeric: tabular-nums; }
.dvals b { font-weight: 700; }
.dvs { display: block; color: var(--muted); font-size: 0.875rem; }
.drow > .chip { justify-self: end; }
.drow.daxis { padding: 6px 0 0; border-bottom: 0; }
/* Too narrow for four columns at this text size, the dots get the row's full width, with the
   values on a line under them. */
@container gap (max-width: 40em) {
  .drow { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "label chip" "track track" "vals vals"; gap: 8px 12px; }
  .dlabel { grid-area: label; }
  .dtrack { grid-area: track; }
  .dvals { grid-area: vals; white-space: normal; }
  .dvs { display: inline; white-space: nowrap; }
  .dvs::before { content: " · "; }
  .drow > .chip { grid-area: chip; }
  .drow.daxis { grid-template-areas: "track track"; padding-top: 4px; }
  .drow.daxis > span:first-child { display: none; }
  .drow.daxis .ticks { grid-area: track; }
}
/* With very big text on a phone, the surrounding area's value may wrap too. */
@container gap (max-width: 20em) { .dvs { white-space: normal; } }
.missed { padding: 0; list-style: none; }
.missed li { display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: 16px; align-items: baseline; padding: 14px 0; border-bottom: 1px solid var(--line); }
.missed b { font-size: 1.5rem; white-space: nowrap; font-weight: 700; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.missed strong { display: block; margin-bottom: 2px; }
/* With very big text on a phone, the share sits over its words instead of beside them. */
@container section (max-width: 16em) { .missed li { grid-template-columns: minmax(0, 1fr); gap: 4px; } }
.better { display: flex; flex-wrap: wrap; gap: 8px 24px; padding: 0; list-style: none; }
.better li { padding: 4px 0; }

/* Two values as bars, nearest places, what brings people past */
.prows { display: grid; gap: 8px; }
.prow { display: grid; grid-template-columns: 10rem minmax(0, 1fr) 3rem; gap: 16px; align-items: center; font-size: var(--t-small); }
.pbar i { display: block; height: 12px; min-width: 2px; border-radius: 0 var(--r-bar) var(--r-bar) 0; background: var(--chart-here); }
.pbar.around i { background: var(--chart-area); }
.prow b { font-variant-numeric: tabular-nums; }
@container section (max-width: 30em) { .prow { grid-template-columns: 7.5rem minmax(0, 1fr) 3rem; gap: 12px; } }
@container section (max-width: 16em) { .prow { grid-template-columns: minmax(0, 1fr) 3rem; row-gap: 4px; } .prow .plabel { grid-column: 1 / -1; } }
.nearest { max-width: 40rem; padding: 0; list-style: none; }
.nearest li { position: relative; display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; gap: 14px; align-items: center; min-height: 44px; padding: 10px 0; border-bottom: 1px solid var(--line); }
/* A named place's link covers its whole row, so the tap target is the row, not the name. */
.nname a::after { content: ""; position: absolute; inset: 0; }
/* The same numbered square as the map. */
.nnum { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 5px; box-shadow: inset 0 0 0 1.6px var(--map-rival); color: var(--map-rival); font-size: 0.875rem; font-weight: 700; font-variant-numeric: tabular-nums; }
/* A long name with no spaces breaks inside its column instead of running off a phone screen. */
.nname { display: flex; flex-direction: column; min-width: 0; font-weight: 650; line-height: 1.3; overflow-wrap: anywhere; }
.nkind { color: var(--muted); font-size: 0.875rem; font-weight: 400; }
.nearest b { font-size: var(--t-small); text-align: right; font-variant-numeric: tabular-nums; }
/* Words, not figures: tabular figures would widen the hyphen in "north-east". */
.nearest b span { display: block; color: var(--muted); font-size: 0.875rem; font-weight: 400; white-space: nowrap; font-variant-numeric: normal; }
.rpt .magnets { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr)); gap: 0 32px; margin-bottom: 0; padding: 0; list-style: none; }
.rpt .magnets li { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 12px; align-items: start; padding: 14px 0; border-bottom: 1px solid var(--line); }
.rpt .magnets li::before { content: none; }
.magnets svg { width: 26px; height: 26px; margin-top: 2px; fill: none; stroke: var(--map-magnet); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.magnets b { font-size: 1.125rem; font-variant-numeric: tabular-nums; }
.mnear { display: block; color: var(--muted); font-size: 0.875rem; }
.mwhy { display: block; margin-top: 4px; color: var(--ink-2); font-size: var(--t-small); line-height: 1.45; }

/* The site map, drawn from distance and direction. The map and the nearest list sit side by side
   only while each has 17em, so big text stacks them instead of breaking names inside a word. */
.map-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(17em, 100%), 1fr)); gap: 16px 32px; align-items: start; }
.map-row:has(> :only-child) { grid-template-columns: minmax(0, 1fr); }
.rpt .map-row { margin-top: 32px; }
.map-row > * { min-width: 0; }
.map-row > .chart { margin-top: 0; }
.sitemap svg { display: block; width: 100%; max-width: 420px; overflow: visible; }
.sitemap:not(.compact) .area { fill: var(--sunk); stroke: var(--line-strong); stroke-width: 1.2; stroke-dasharray: 6 5; }
.sitemap .ring { fill: none; stroke: var(--line); stroke-width: 1.2; }
.sitemap:not(.compact) .walk { fill: none; stroke: var(--primary); stroke-width: 1.4; stroke-dasharray: 2 4; stroke-linecap: round; }
.sitemap .area, .sitemap .ring, .sitemap .walk { transform-box: fill-box; transform-origin: center; }
.sitemap .north { fill: var(--muted); }
.sitemap:not(.compact) text { fill: var(--muted); font: 600 13px var(--f-text); }
.sitemap .nlabel { text-anchor: middle; }
/* Ring labels stay readable where a ring or a place passes behind them. */
.sitemap:not(.compact) .rlabel { paint-order: stroke; stroke: var(--bg); stroke-width: 4px; stroke-linejoin: round; }
.sitemap:not(.compact) .rival rect { fill: var(--surface); stroke: var(--map-rival); stroke-width: 1.6; }
.sitemap:not(.compact) .rival text { fill: var(--map-rival); font: 700 13px var(--f-text); text-anchor: middle; }
.sitemap:not(.compact) .draw rect { fill: var(--primary-soft); stroke: var(--map-magnet); stroke-width: 1.5; }
.sitemap .icon :is(path, rect, circle) { fill: none; stroke: var(--map-magnet); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.sitemap:not(.compact) .site path { fill: var(--map-pin); }
.sitemap:not(.compact) .site circle { fill: var(--surface); }
.rpt .legend .key.k-site { width: 10px; height: 10px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); background: var(--map-pin); }
.rpt .legend .key.k-rival { width: 11px; height: 11px; background: var(--surface); box-shadow: inset 0 0 0 1.6px var(--map-rival); }
.rpt .legend .key.k-draw { width: 8px; height: 8px; margin-inline: 2px; border-radius: 1px; transform: rotate(45deg); background: var(--primary-soft); box-shadow: inset 0 0 0 1.5px var(--map-magnet); }

/* Compass of nearby spots: spokes and pins only move by transform and opacity. */
.compass svg { display: block; width: 100%; max-width: 360px; margin: 0 auto; overflow: visible; }
.compass .ring { fill: none; stroke: var(--line); stroke-dasharray: 4 5; }
.compass .spoke { stroke: var(--line-strong); stroke-width: 1.5; transform-box: view-box; transform-origin: 150px 150px; }
.compass circle { stroke-width: 2; }
.compass .pin { transform-box: fill-box; transform-origin: center; }
.compass text { fill: var(--ink); font: 700 15px var(--f-text); text-anchor: middle; font-variant-numeric: tabular-nums; }
.compass .dir { fill: var(--muted); font-size: 13px; font-weight: 600; }
.compass .site { fill: var(--primary); stroke: none; }
.compass .site-label { fill: var(--on-primary); font-size: 13px; }
.node.more circle { fill: var(--fits-bg); stroke: var(--fits-mark); }
.node.more .pin text { fill: var(--fits-fg); }
.node.same circle { fill: var(--sunk); stroke: var(--muted); }
.node.fewer circle { fill: var(--against-bg); stroke: var(--against-mark); }
.node.fewer .pin text { fill: var(--against-fg); }
.node.none circle { fill: var(--surface); stroke: var(--muted); stroke-dasharray: 3 3; }
.node.none .pin text { fill: var(--muted); }
.rpt .legend .key.more, .rpt .legend .key.same, .rpt .legend .key.fewer, .rpt .legend .key.none { width: 12px; height: 12px; border-radius: 50%; }
.key.more { background: var(--fits-bg); box-shadow: inset 0 0 0 2px var(--fits-mark); }
.key.same { background: var(--sunk); box-shadow: inset 0 0 0 2px var(--muted); }
.key.fewer { background: var(--against-bg); box-shadow: inset 0 0 0 2px var(--against-mark); }
.key.none { background: var(--surface); box-shadow: inset 0 0 0 1px var(--muted); }

/* Fixes: the one numbered sequence in the body, because the order is the advice. */
.fixes { display: grid; gap: 16px; padding: 0; list-style: none; }
.rpt .fix { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 16px; padding: 20px 24px 20px 20px; border: 0; border-radius: var(--r-screen); background: var(--surface); box-shadow: var(--hair); }
.rpt .fix > div { min-width: 0; }
.fixnum { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: var(--primary); color: var(--on-primary); font-size: 1.0625rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.rpt .fix h3 { margin: 5px 0 0; font-size: 1.1875rem; font-weight: 700; line-height: 1.3; letter-spacing: -0.015em; }
.why { max-width: 38em; color: var(--ink-2); }
.why b { color: var(--primary); }
.steps { padding: 0; list-style: none; }
.steps li { position: relative; max-width: 38em; padding: 5px 0 5px 22px; }
.steps li::before { content: ""; position: absolute; top: 0.95em; left: 4px; width: 7px; height: 7px; border-radius: 50%; background: var(--primary); }
@container section (max-width: 30em) {
  .rpt .fix { grid-template-columns: 32px minmax(0, 1fr); gap: 12px; padding: 16px 16px 16px 14px; }
  .rpt .fix h3 { margin-top: 4px; }
  .fixnum { width: 32px; height: 32px; font-size: 1rem; }
}

/* ---------- Money: customers a day, rent gauge, rent as days of takings, slow start, regulars ---------- */
.cscale .cnums, .cscale .ctrack { max-width: 44rem; }
.cnums { position: relative; height: 1.6em; margin: 2px 0; font-size: 0.875rem; font-weight: 700; line-height: 1.6; font-variant-numeric: tabular-nums; }
.cnums span { position: absolute; transform: translateX(-50%); white-space: nowrap; }
.ctrack { position: relative; height: 16px; border-radius: 8px; background: var(--sunk); box-shadow: inset 0 0 0 1px var(--line); }
.ctrack .fill { position: absolute; inset: 0 auto 0 0; border-radius: 8px; background: var(--chart-here); transform-origin: left center; }
.ctrack .cushion { position: absolute; top: 0; bottom: 0; border-block: 2px solid var(--fits-mark); background: var(--fits-bg); transform-origin: left center; }
/* A shortfall sits inside break-even, so it is drawn over the fill. */
.cscale.risk .cushion { z-index: 1; border-color: var(--against-mark); background: var(--against-bg); }
.ctrack .tick { position: absolute; z-index: 2; top: -5px; bottom: -5px; width: 2px; margin-left: -1px; background: var(--ink); }
.ctrack .tick.guess { background: var(--muted); }
.cscale .legend { margin-top: 10px; }
.cscale .legend span { display: inline-flex; align-items: center; gap: 6px; }
.cscale .legend i { flex: none; display: inline-block; width: 12px; height: 10px; border-radius: 2px; }
.cscale .legend .be { background: var(--chart-here); }
.cscale .legend .cautious, .cscale .legend .guess { width: 2px; height: 12px; border-radius: 0; background: var(--ink); }
.cscale .legend .guess { background: var(--muted); }
.cscale .legend .cushion-key { width: 14px; border-radius: 0; border-block: 2px solid var(--fits-mark); background: var(--fits-bg); }
.cscale.risk .legend .cushion-key { border-color: var(--against-mark); background: var(--against-bg); }

/* Rent against the usual range, on a fixed scale from 0. */
.gbox { max-width: 44rem; padding-top: 40px; }
.gtrack { position: relative; display: flex; height: 14px; }
.gtrack .band { height: 100%; }
/* A 3 px cut between bands, inside each band's width, so the band edges stay on 8% and 11%. */
.band.green { border-right: 3px solid var(--bg); border-radius: 7px 0 0 7px; background: var(--fits-mark); background-clip: padding-box; }
.band.amber { border-right: 3px solid var(--bg); background: var(--mixed-mark); background-clip: padding-box; }
.band.red { flex: 1; border-radius: 0 7px 7px 0; background: var(--against-mark); }
.gtrack .marker { position: absolute; bottom: -8px; display: flex; flex-direction: column; align-items: center; width: 0; }
.marker b { margin-bottom: 4px; padding: 2px 8px; border-radius: var(--r-pill); background: var(--ink); color: var(--bg); font-size: var(--t-caption); font-weight: 700; line-height: 1.45; white-space: nowrap; font-variant-numeric: tabular-nums; }
.marker::after { content: ""; width: 4px; height: 30px; border-radius: 2px; background: var(--ink); box-shadow: 0 0 0 2px var(--bg); }
.marker.lo b { align-self: flex-start; margin-left: -2px; }
.marker.hi b { align-self: flex-end; margin-right: -2px; }
/* Benchmarks: their own thin row under the bar, a triangle for one figure and a bracket for a range. */
.gbench { position: relative; height: 9px; margin-top: 4px; }
.gbench .bench { position: absolute; top: 0; width: 0; height: 0; margin-left: -5px; border: 5px solid transparent; border-top: 0; border-bottom: 7px solid var(--ink-2); }
.gbench .bench-range { position: absolute; top: 0; height: 7px; border: 2px solid var(--ink-2); border-top: 0; border-radius: 0 0 2px 2px; }
/* In em, so bigger text keeps its labels clear of the benchmark key below. */
.gscale { position: relative; height: 1.5em; margin-top: 4px; color: var(--muted); font-size: var(--t-caption); line-height: 1.5; font-variant-numeric: tabular-nums; }
.gscale span { position: absolute; transform: translateX(-50%); white-space: nowrap; }
.gscale span:first-child { left: 0; transform: none; }
.gscale .end { right: 0; transform: none; }
.gscale.tight .l1 { transform: translateX(calc(-100% - 4px)); }
.gscale.tight .l2 { transform: translateX(4px); }
/* "0%" makes way for the 8% label where that sits close to the start: on any screen when it is
   very close (near), on a phone when it is close (nozero). */
.gscale.near span:first-child { display: none; }
@container section (max-width: 30em) { .gscale.nozero span:first-child { display: none; } }
.gkey { display: flex; flex-wrap: wrap; gap: 4px 20px; margin-top: 10px; color: var(--muted); font-size: var(--t-caption); line-height: 1.5; }
.bench-item { display: inline-flex; align-items: center; gap: 8px; }
.bench-key { flex: none; width: 0; height: 0; border: 5px solid transparent; border-top: 0; border-bottom: 7px solid var(--ink-2); }
.range-key { flex: none; width: 14px; height: 7px; border: 2px solid var(--ink-2); border-top: 0; border-radius: 0 0 2px 2px; }

/* Rent as days of takings: one tile a trading day, numbered, the landlord's days filled in berry. */
.rentdays { display: grid; grid-template-columns: repeat(var(--tiles, 8), minmax(0, 1fr)); gap: 6px; max-width: min(100%, calc(var(--tiles, 8) * 70px)); }
.rentdays.many { grid-template-columns: repeat(auto-fill, minmax(2.75rem, 1fr)); max-width: 44rem; }
.rentdays .day { display: grid; gap: 4px; min-width: 0; }
.rentdays .tile { position: relative; display: block; height: 44px; overflow: hidden; border-radius: var(--r-small); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); }
.rentdays .tile i { position: absolute; inset: 0 auto 0 0; width: 100%; background: var(--berry); transform-origin: left center; }
.rentdays .day b { color: var(--muted); font-size: var(--t-caption); font-weight: 500; text-align: center; font-variant-numeric: tabular-nums; }
.rentdays + .legend { margin-top: 10px; }
.rpt .legend .key.rent { width: 12px; height: 12px; border-radius: 3px; background: var(--berry); }
.rpt .legend .key.kept { width: 12px; height: 12px; border-radius: 3px; background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); }

/* A finding in words: a neutral well with its mark, the words wrapping as one paragraph. */
.callout { display: flex; align-items: flex-start; gap: 10px; max-width: 46em; padding: 14px 16px; border-radius: var(--r-row); background: var(--sunk); color: var(--ink-2); line-height: 1.55; }
.callout > .mk { margin-top: 0.5em; }
.callout > span { min-width: 0; }
.callout strong, .callout b { color: var(--ink); }
:where(.rpt) .chart + .callout { margin-top: 24px; }
/* What would bring rent into the usual range: three figure cells. */
.targets { display: grid; gap: 12px; padding: 0; list-style: none; }
@container section (min-width: 40em) { .targets { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); } }
.targets > .target { min-width: 0; padding: 16px 18px; border-radius: var(--r-screen); background: var(--surface); box-shadow: var(--hair); }
.targets b { display: block; margin-bottom: 6px; color: var(--ink); font-size: 1.75rem; font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.targets span { display: block; color: var(--ink-2); font-size: var(--t-small); line-height: 1.5; }
/* Covered months filled solid in the tone's strong colour with the number knocked out, empty
   months a dashed outline: it reads without colour and in black-and-white print. */
.runway { --tone: var(--mixed-fg); display: flex; flex-wrap: wrap; gap: 8px; padding-top: 4px; }
.runway.risk { --tone: var(--against-fg); }
.runway.good { --tone: var(--fits-fg); }
.runway span { position: relative; width: 44px; height: 36px; overflow: hidden; border: 1px solid var(--tone); border-radius: 6px; background: var(--surface); }
.runway i { position: absolute; inset: 0 auto 0 0; background: var(--tone); transform-origin: left center; }
.runway em { position: absolute; inset: 0; display: grid; place-items: center; color: var(--tone); font-size: 0.875rem; font-style: normal; font-weight: 700; font-variant-numeric: tabular-nums; }
.runway .full em { color: var(--surface); }
.runway .partial b { padding: 0 5px; border-radius: 4px; background: var(--surface); }
.runway .empty { border: 1.5px dashed var(--muted); }
.runway .empty em { color: var(--muted); }
.runway span.target { outline: 2px solid var(--ink); outline-offset: 2px; }
.runway .more { display: grid; place-items: center; border: 0; background: none; color: var(--muted); font-size: 0.875rem; }
/* Regulars needed: a hundred squares, the lit ones filled by their own layer. */
.waffle-wrap { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: 24px; align-items: center; max-width: 44rem; padding-top: 4px; }
.waffle-wrap p { max-width: 30em; color: var(--ink-2); }
.waffle-wrap p b { display: block; color: var(--ink); font-size: 1.875rem; font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.waffle { --tone: var(--chart-here); display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 3px; width: 160px; }
.waffle.green { --tone: var(--fits-mark); }
.waffle.amber { --tone: var(--mixed-mark); }
.waffle.red { --tone: var(--against-mark); }
.waffle i { position: relative; aspect-ratio: 1; border-radius: 2px; background: var(--sunk); box-shadow: inset 0 0 0 1px var(--line); }
.waffle i.on > b { position: absolute; inset: 0; border-radius: inherit; background: var(--tone); }
.waffle i.line { box-shadow: inset 0 0 0 1px var(--line), 0 0 0 2px var(--bg), 0 0 0 3.5px var(--ink); }
@container section (max-width: 20em) { .waffle-wrap { grid-template-columns: minmax(0, 1fr); } }
/* Six months fit on one line, so the heavy-framed sixth never wraps alone. */
@container section (max-width: 20em) { .runway { gap: 6px; } .runway span { width: 40px; } }

.workings summary, .tallies summary { display: flex; align-items: center; gap: 12px; min-height: 44px; color: var(--primary); font-weight: 600; list-style: none; cursor: pointer; }
.workings summary::-webkit-details-marker, .tallies summary::-webkit-details-marker { display: none; }
.workings summary .pm, .tallies summary .pm { margin-left: 0; }
.workings[open] > summary { margin-bottom: 8px; }
.workings ol { padding-left: 1.25em; color: var(--ink-2); }
.workings ol li + li { margin-top: 4px; }
.workings table.money { width: 100%; max-width: 36rem; margin-top: 12px; border-collapse: collapse; font-size: var(--t-small); }
.workings table.money th, .workings table.money td { padding: 8px 0; border-bottom: 1px solid var(--line); text-align: left; vertical-align: baseline; }
.workings table.money th { padding-right: 16px; color: var(--ink-2); font-weight: 500; }
.workings table.money td { color: var(--ink); font-weight: 650; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ---------- Street test: a tally sheet each session. Prints full width; on a phone it scrolls
   sideways inside its frame. ---------- */
.tallies { margin-top: 32px; padding-top: 8px; border-top: 1px solid var(--line); }
.tallies > summary { font-size: 1.0625rem; }
.sheet-frame { overflow-x: auto; border-radius: var(--r-row); background: var(--surface); box-shadow: var(--hair); }
.sheet-frame:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }
.rpt .tally { width: 100%; min-width: 640px; margin: 0; border-collapse: collapse; font-size: var(--t-caption); }
.rpt .tally th, .rpt .tally td { height: 36px; padding: 6px 10px; border: 1px solid var(--line); text-align: center; font-variant-numeric: tabular-nums; }
.rpt .tally tr > :first-child { border-left: 0; }
.rpt .tally tr > :last-child { border-right: 0; }
.rpt .tally thead th { border-top: 0; background: var(--sunk); color: var(--ink); font-weight: 650; line-height: 1.25; vertical-align: bottom; }
.rpt .tally tbody th { color: var(--ink-2); font-weight: 600; white-space: nowrap; }
.rpt .tally tr.total > * { border-top: 2px solid var(--line-strong); color: var(--ink); font-weight: 700; }
.rpt .tally tfoot th, .rpt .tally tfoot td { border-bottom: 0; background: var(--tint-sky); color: var(--ink); font-weight: 650; }
.rpt .tally tfoot td.na { color: var(--muted); font-weight: 400; }
.scroll-hint { margin-top: 8px; color: var(--muted); font-size: var(--t-caption); }
@container section (min-width: 640px) { .scroll-hint { display: none; } }

/* Before you sign: each line has an empty box to tick on paper. */
.recap { display: grid; padding: 0; list-style: none; border-top: 1px solid var(--line); }
.recap li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 4px 14px; padding: 16px 0; border-bottom: 1px solid var(--line); }
.recap li::before { content: ""; grid-row: 1 / span 2; width: 18px; height: 18px; margin-top: 3px; border-radius: 5px; box-shadow: inset 0 0 0 1.5px var(--line-strong); }
.recap b { color: var(--ink); }
.recap span { color: var(--ink-2); }
@container section (min-width: 40em) { .recap li { grid-template-columns: 22px 11rem minmax(0, 1fr); align-items: baseline; } .recap li::before { grid-row: auto; align-self: start; } }

/* How sure, method */
.rpt .body > .scale3 { max-width: 34rem; }
/* Three equal levels while their words fit; with big text on a phone the last one moves to its
   own line instead of the words running into each other. */
.rpt .scale3 { display: flex; flex-wrap: wrap; }
.rpt .scale3 > span { flex: 1 1 0; min-width: min-content; }
.defs { display: grid; max-width: 72ch; border-top: 1px solid var(--line); }
.defs div { display: grid; grid-template-columns: 13em minmax(0, 1fr); gap: 16px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.defs dt { font-weight: 650; }
.defs dd { margin: 0; color: var(--ink-2); }
@container section (max-width: 36em) {
  .two, .defs div { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .two { gap: 32px; }
}

/* The link to keep, after the summary (report.js). */
.share { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; margin-top: 16px; padding: 20px 24px; border-radius: var(--r-screen); background: var(--surface); box-shadow: var(--hair); }
.share h2 { font-size: var(--t-h3); font-weight: 700; line-height: 1.3; letter-spacing: -0.015em; }
.share p { max-width: 42em; color: var(--ink-2); }
.share-row input { min-height: 44px; padding: 0 12px; border: 1px solid var(--line-strong); border-radius: var(--r-small); background: var(--bg); color: var(--ink); font: 400 var(--t-small) var(--f-text); }
.share #copied:empty { display: none; }

.rfoot { margin-top: 64px; padding-block: 32px calc(48px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); color: var(--muted); font-size: var(--t-small); }
.rfoot p { max-width: 46em; }
.rfoot p + p { margin-top: 10px; }
.rfoot a { color: var(--ink-2); }
.rfoot .rfoot-links { margin-top: 4px; }
.rfoot-links a { display: inline-flex; align-items: center; min-height: 44px; padding-inline: 4px; }
.rfoot-links a:first-child { margin-left: -4px; }

/* Under 360 px the biggest numbers step down so they fit their column. */
@media (max-width: 359px) {
  .dvs { white-space: normal; }
  .rpt .scale3 > span { padding-inline: 4px; }
  .figure .fv { font-size: clamp(1.25rem, 7.5vw, 1.75rem); font-size: min(clamp(1.25rem, 7.5vw, 1.75rem), (100cqi / var(--cols) - 40px) / max(3.6, var(--len, 6) * 0.62)); }
}

@media print {
  /* Backgrounds print exactly, so the colours reset to the light set: a dark-mode screen would
     otherwise print light text on white paper. The cover keeps its own dark card. */
  .report-page {
    --bg: #fff; --surface: #fff; --sunk: #eef3f6; --line: #cad7de; --line-strong: #71838e;
    --ink: #0d202d; --ink-2: #2c3e4a; --muted: #4b5f6a;
    --primary: #00627a; --primary-hover: #004f63; --on-primary: #fff; --primary-soft: #dbedf2;
    --berry: #962a59; --berry-soft: #f6e3ed;
    --tint-mist: #dbedf2; --tint-sky: #e3eaf7; --tint-stone: #e6ecef; --tint-blush: #f6e3ed;
    --fits-fg: #145234; --fits-bg: #d6efdf; --fits-mark: #007047;
    --mixed-fg: #6c4302; --mixed-bg: #fbe9c2; --mixed-mark: #b6770b;
    --against-fg: #7f2117; --against-bg: #fadfda; --against-mark: #b63325;
    --chart-here: #00627a; --chart-area: #7b8c97;
    --map-pin: #962a59; --map-rival: #3b4f5b; --map-magnet: #00627a; --map-street: #fff; --map-block: #dce6eb;
    --deco: #9fc3cf; --hairline: rgb(13 32 45 / 0.08); --cover-edge: transparent;
    color-scheme: light;
  }
  .rpt { color: var(--ink); }
  .report-page main.wrap { max-width: none; }
  .toc-float, .toc-dialog { display: none !important; }
  /* With no script to open them (JavaScript off), browsers that can still print the folded
     sheets and workings. */
  details[data-print-open]::details-content { content-visibility: visible; }
  .tallies > summary, .rpt .pm { display: none; }
  /* Paper shows every chart's last frame. beforeprint finishes the plays, but the page's new
     width can wake a held play again; an important rule outranks any animation. */
  .rpt [data-r], .rpt .chip, .rpt .rlabel, .rpt .dir, .cscale .tick { opacity: 1 !important; transform: none !important; }
  /* styles.css drops every shadow on paper; the marks, levels and boxes drawn with one come back
     as lines. */
  .rpt .mk-mixed { box-shadow: inset 0 0 0 1.5px var(--mixed-mark) !important; }
  .rpt .mk-against { box-shadow: inset 0 0 0 2px var(--against-mark) !important; }
  .rpt .scale3 .lit { box-shadow: inset 0 0 0 2px var(--mixed-mark) !important; }
  .rpt .scale3 .on.fits .lit { box-shadow: inset 0 0 0 2px var(--fits-mark) !important; }
  .rpt .scale3 .on.against .lit { box-shadow: inset 0 0 0 2px var(--against-mark) !important; }
  .rpt .dot.around, .rpt .key.dot-around { box-shadow: inset 0 0 0 3px var(--chart-area) !important; }
  .rpt .nnum, .rpt .legend .key.k-rival { box-shadow: inset 0 0 0 1.6px var(--map-rival) !important; }
  .rpt .legend .key.k-draw { box-shadow: inset 0 0 0 1.5px var(--map-magnet) !important; }
  .rpt .rentdays .tile, .rpt .waffle i, .rpt .legend .key.kept, .rpt .ctrack { box-shadow: inset 0 0 0 1px var(--line-strong) !important; }
  .rpt .waffle i.line { box-shadow: inset 0 0 0 1px var(--line-strong), 0 0 0 2px #fff, 0 0 0 3.5px var(--ink) !important; }
  .rpt .recap li::before { box-shadow: inset 0 0 0 1.5px var(--ink-2) !important; }
  .rpt .key.more { box-shadow: inset 0 0 0 2px var(--fits-mark) !important; }
  .rpt .key.same { box-shadow: inset 0 0 0 2px var(--muted) !important; }
  .rpt .key.fewer { box-shadow: inset 0 0 0 2px var(--against-mark) !important; }
  .rpt .key.none { box-shadow: inset 0 0 0 1px var(--muted) !important; }
  .summary .figures, .start, .targets > .target, .rpt .fix, .sheet-frame, .scale3 > span { border: 1px solid var(--line); }
  .sheet-frame { overflow: visible; }
  .rpt .tally { min-width: 0; }
  /* The summary is too long for one sheet under the cover, so it runs on to page 2 and the next
     part follows it there. A tighter cover and summary keep the headline and the four figures on
     page 1, and the panel's padding and corners repeat on page 2. */
  .cover { padding: 20px 28px; }
  .cover h1 { margin: 8px 0; font-size: 1.875rem; }
  .cover-meta { margin-top: 12px; grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
  .cover-meta div, .cover-meta:not(.n4) div, .cover-meta.n4 div { display: block; padding: 10px 16px 0 0; border-bottom: 0; }
  .cover-meta div + div { padding-left: 16px; border-left: 1px solid rgb(230 238 242 / 0.18); }
  .cover-meta dd { margin-top: 2px; text-align: left; }
  /* The full map prints with its part; the cover keeps to the words. */
  .cover.with-map { display: block; }
  .cover .sitemap { display: none; }
  .summary { margin-top: 12px; padding: 16px 24px; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
  /* A printed page is about 700px wide, which would stack the summary as on a tablet: the
     headline keeps its side column, and the four figures stay in a row (the summary's two-by-two
     switch is for screens). */
  .summary { container-type: normal; }
  .sum-head { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px; }
  .sum-head .headline { font-size: 1.375rem; }
  .start { padding: 10px 14px; }
  /* Paper has nothing to click. */
  .start-a { display: none; }
  .summary .figures { margin: 16px 0 8px; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); }
  .summary .figure, .summary .figure:first-child { padding: 12px 12px 14px; }
  /* Key findings, then what this means, in one column, so they read in order across the page
     break. */
  .sum-grid { margin-top: 16px; padding-top: 16px; gap: 20px; }
  .findings li, .sum-grid p { break-inside: avoid; }
  .part { display: block; margin-top: 24px; padding-top: 24px; }
  /* Paper is denser than the screen. */
  .chart, .slow-start, .tallies, .rpt .map-row { margin-top: 20px; }
  :where(.rpt .body, .rpt #spotsBody, .rpt .slow-start) > h3 { margin-top: 20px; }
  .figures.compact { margin-top: 16px; }
  .part > .topic { margin-bottom: 8px; }
  .chart, .figure, .rpt .fix, .waffle-wrap, .magnets li, .arow, .drow, .missed li, .targets > .target, .recap li, .callout, .workings table.money, .map-row > div, .defs div, .rfoot p { break-inside: avoid; }
  /* The list to settle before signing reads as one page. */
  #recap .body { break-inside: avoid; }
  .body > h2, #spotsBody > h2, .rpt .lede, .sum-head, .start, .rpt .two, .rpt .rivals, .rpt .notes { break-inside: avoid; }
  .body > h2, #spotsBody > h2, .rpt h3, .rpt .topic, .rpt .lede, .chart-head { break-after: avoid; }
  /* As a grid, the list let its heading end one page and the items start the next. */
  .recap { display: block; }
  /* Each tally sheet on its own page: one sheet of paper per session. */
  .tallies { border-top: 0; }
  .tallies .tally-sheet { break-before: page; }
  /* The footer's bottom room is for screens (and their safe area); paper needs none. */
  .rfoot { margin-top: 24px; padding-bottom: 0; }
}

/* Windows high contrast (forced colours) drops backgrounds and shadows, which would leave the
   charts' numbers with no bars, dots, bands or squares. These keep their own colours there;
   styles.css does the same for the marks and the keys. */
@media (forced-colors: active) {
  .abar i, .dtrack, .pbar, .gtrack, .ctrack, .cscale .legend i, .rentdays .tile, .runway, .waffle, .nnum, .cover-key i { forced-color-adjust: none; }
}

/* Motion gate, as on the front page: only the result layers ([data-r]) wait for the script, and
   come back on their own after 2.5 s if it never runs. */
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  html:not(.mo-live) [data-r] { opacity: 0; animation: mo-failsafe 1ms 2.5s forwards; }
}
@keyframes mo-failsafe { to { opacity: 1; } }
