:root{--css-build:"fc7ca9b60b";}
/* --- cache note, 15 Oct 2026 -------------------------------------------
   The byte below this line is what --css-build hashes. The sentinel and
   the ?v= query in index.html both come from it, and cssGuard() in app.js
   compares the two: a stylesheet that does not say it belongs to this
   page gets refetched once. See tools/stamp_rent_assets.py for why.
   ------------------------------------------------------------------- */
/* ===========================================================================
   torontopolis.ca — parallel build
   ---------------------------------------------------------------------------
   WHY THIS DOES NOT LOOK LIKE RENTALS.CA

   Rentals.ca is a marketplace: its unit is a photographed listing with a price,
   and its whole layout exists to put as many photo-price tiles on screen as
   possible. We have no listings, no prices and no photographs, and inventing
   them would be worse than not having them.

   What we do have is the City's inspection record for every rental building in
   Toronto, which nobody has ever put in front of a renter. So the unit here is
   a BUILDING, and the visual is its GRADE — a generated mark, not a photo.
   That is why this reads as a reference work (editorial type, generous
   whitespace, a lot of left alignment) rather than as a shop.

   Practically it also means ad slots sit between sections rather than between
   tiles, which is what keeps the page from feeling like a cheap listing site.
   ========================================================================= */

:root{
  --ink:#101418;
  --ink-2:#4a5560;
  --ink-3:#7c8793;
  --line:#e6e9ec;
  --line-2:#d2d7dd;
  --bg:#fbfbfc;
  --panel:#fff;
  --panel-2:#f4f6f8;

  --accent:#0f3b43;        /* deep teal: actions, brand furniture */
  --accent-ink:#0f3b43;
  --amber:#c77d03;         /* the rentals accent carried over from the map */
  /* This section is the amber half of the site. shared/chrome.css reads
     these for the brand's RENTALS label and for whatever is selected. */
  --sect:#f2a900;
  --sect-tint:#fdf2d9;
  --sect-ink:#8a6a00;

  --a:#1e9e5a;             /* City band: satisfactory */
  --b:#5a9e3f;             /* (kept: still used by the neighbourhood ramp) */
  --c:#e8871a;             /* City band: needs improvement */
  --d:#d64541;             /* City band: needs significant improvement */
  --none:#8a8f98;          /* not evaluated */

  --font:"Helvetica Neue",Helvetica,Roboto,Arial,-apple-system,BlinkMacSystemFont,sans-serif;
  --sh1:0 1px 2px rgba(16,20,24,.05),0 2px 8px rgba(16,20,24,.05);
  --sh2:0 2px 6px rgba(16,20,24,.07),0 12px 32px rgba(16,20,24,.09);
  --r:14px;
  --hdr-h:62px;
}

*{box-sizing:border-box;}
html,body{margin:0;padding:0;}
body{font-family:var(--font);background:var(--bg);color:var(--ink);
  -webkit-font-smoothing:antialiased;line-height:1.5;}
a{color:inherit;}
button{font-family:var(--font);}

.wrap{max-width:1180px;margin:0 auto;padding:0 24px;}
@media (max-width:640px){ .wrap{padding:0 16px;} }

/* ===== Legacy loader — carried over verbatim from the live site ========== */
/* Below the header, not over it. The header is static markup and paints on
   the first frame in both documents, so switching Map mode leaves the same
   bar standing in the same place and only the area under it changes. It used
   to be inset:0 over the whole viewport, which is what made the switch feel
   like arriving at a different website. [hidden] is the default now — see
   showLoader() in app.js, which only reveals it when there is a real fetch to
   wait for. */
#loader{position:fixed;top:var(--hdr-h);left:0;right:0;bottom:0;z-index:590;
  display:grid;place-items:center;background:var(--bg);
  transition:opacity .45s ease;}
#loader[hidden]{display:none;}
#loader.gone{opacity:0;pointer-events:none;}
/* Smaller than it was: at 58px it was the whole screen, and under a header it
   only has to say "this is still torontopolis, the data is on its way". */
#loader .load-mark{font-size:clamp(26px,4.4vw,40px);}
.load-wrap{display:grid;place-items:center;}
.load-mark{position:relative;display:inline-block;line-height:1;
  font-family:var(--font);font-weight:700;letter-spacing:-.025em;
  font-size:clamp(30px,6vw,58px);
  --p:0%;
  background-image:linear-gradient(90deg,#0c0d10 0%,#0c0d10 var(--p),#c9ccd2 var(--p),#c9ccd2 100%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  transition:--p .45s cubic-bezier(.4,0,.2,1);}
@property --p{syntax:'<percentage>';inherits:false;initial-value:0%;}
.load-sub{margin-top:11px;text-align:center;font-weight:600;letter-spacing:-.01em;
  font-size:clamp(12px,1.6vw,15px);color:var(--ink-3);}

/* ===== Header ============================================================ */
.hdr{position:sticky;top:0;z-index:600;height:var(--hdr-h);
  display:flex;align-items:center;gap:18px;padding:0 24px;
  background:rgba(255,255,255,.88);backdrop-filter:blur(12px);
  border-bottom:1px solid var(--line);}
.hdr-brand{display:flex;align-items:center;gap:9px;text-decoration:none;
  font-weight:700;font-size:17px;letter-spacing:-.02em;white-space:nowrap;}
.hdr-brand img{border-radius:7px;display:block;}
.hdr-ca{color:var(--ink-3);font-weight:600;}
/* ---- The section switcher in the header ----------------------------------
   The brand now says which half of the site you are standing in — Rentals in
   the rentals amber — and is the way across to Planning. It is a <details>,
   not a scripted menu, so it works identically on the app and on the static
   building pages, which run no JavaScript at all.

   The marker is removed rather than hidden with display:none, because Safari
   needs ::-webkit-details-marker and the others need list-style. */
/* The brand switcher and the Map mode toggle moved to shared/chrome.css on
   16 Oct 2026, so map mode and this page draw the identical control from
   one stylesheet instead of two that had already started to differ (this
   file had a 9px radius on the toggle, index.html had 8px). Do not copy
   them back. */
/* .hdr-nav moved to shared/chrome.css — one highlight style for the whole
   site, washed in the section's own colour instead of grey. */
/* margin-left:auto no longer pushes the search to the right edge — the
   account cluster sits after it now, so the search takes the slack and the
   buttons stay pinned to the end of the bar. */
.hdr-search{position:relative;flex:1 1 auto;max-width:430px;margin-left:auto;margin-right:2px;}
.hdr-acct{display:flex;align-items:center;gap:6px;flex:none;}
.hdr-search svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);
  width:16px;height:16px;color:var(--ink-3);pointer-events:none;}
.hdr-search input{width:100%;border:1px solid var(--line-2);border-radius:10px;
  padding:9px 12px 9px 34px;font-size:14px;font-family:var(--font);
  background:var(--panel);color:var(--ink);outline:none;}
.hdr-search input:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(15,59,67,.09);}
/* ---- The map-mode switch --------------------------------------------------
   The two halves of this site are a map and a set of pages about the same
   3,611 buildings, and until now the only way across was a link out labelled
   "Map view", with nothing coming back. It is one switch in two places now:
   off here, on over on the map, and either one takes you to the other.

   An <a> with role="switch", not a button: it navigates, so it has to be
   middle-clickable and it has to show its destination in the status bar. */
.hdr-burger{flex:none;width:36px;height:36px;border:0;background:transparent;border-radius:9px;
  display:grid;place-items:center;cursor:pointer;color:var(--ink-2);margin-left:-6px;}
.hdr-burger:hover{background:var(--panel-2);color:var(--ink);}
.hdr-burger svg{width:21px;height:21px;}

/* ===== Drawer ============================================================
   The three destinations that matter stay in the bar; everything else — the
   calculator, planning applications, resources, the old map — lives here.
   Slides from the left because that is where its button is. */
.drawer-scrim{position:fixed;inset:0;z-index:900;background:rgba(16,20,24,.40);
  opacity:0;transition:opacity .22s;}
.drawer-scrim.on{opacity:1;}

/* THE DRAWER IS LIGHT AGAIN, AND THE COLOUR IS PER CATEGORY.
   It was a solid deep-teal panel for one version. That was the wrong reading
   of "give it colour": it made the menu a different-looking product from the
   rest of the site, which is white cards on near-white with tinted chips.
   What the menu actually needed was for its three groups to be told apart —
   finding a place, tools, development — so each group now has one hue, used
   the way every other tinted chip on this site is used: pale tint behind, the
   saturated version of the same hue on the mark. Same mechanism as the
   neighbourhood dots and the score pills, so the menu reads as part of the
   same design rather than a visitor to it. */
.drawer{position:fixed;top:0;left:0;bottom:0;width:min(324px,88vw);z-index:901;
  background:var(--panel);border-right:1px solid var(--line);
  overflow-y:auto;-webkit-overflow-scrolling:touch;
  box-shadow:6px 0 34px rgba(16,20,24,.14);
  transform:translateX(-100%);transition:transform .24s cubic-bezier(.4,0,.2,1);}
.drawer.on{transform:translateX(0);}

.drawer-hd{display:flex;align-items:center;justify-content:space-between;
  padding:17px 18px;font-size:11px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3);
  position:sticky;top:0;z-index:2;background:var(--panel);
  border-bottom:1px solid var(--line);}
.drawer-x{width:30px;height:30px;border:0;background:var(--panel-2);
  border-radius:50%;color:var(--ink-2);font-size:13px;cursor:pointer;
  display:grid;place-items:center;transition:background .15s,color .15s;}
.drawer-x:hover{background:var(--line);color:var(--ink);}

/* --c-ink is the saturated hue, --c-bg its tint. Each group sets the pair
   once and every rule below reads it, so a group is re-coloured in one line. */
.drawer-sect{padding:15px 10px 11px;}
.drawer-sect + .drawer-sect{border-top:1px solid var(--line);}
.ds-find{--c-ink:#c23b37;--c-bg:#fbeceb;}   /* same red as the TTC chips     */
.ds-tools{--c-ink:#8a5a0a;--c-bg:#f6efe2;}  /* the amber the brand already uses */
.ds-dev{--c-ink:#5b3dc4;--c-bg:#ece8f7;}    /* planning indigo, as on the map  */
.ds-more{--c-ink:#0f3b43;--c-bg:#e6f0f0;}   /* house teal                      */

.drawer-sect h4{margin:0 0 7px;padding:0 10px;font-size:10px;font-weight:700;
  letter-spacing:.11em;text-transform:uppercase;color:var(--c-ink);}
.drawer-sect a{display:flex;align-items:center;gap:12px;text-decoration:none;
  font-size:14.5px;font-weight:600;letter-spacing:-.01em;color:var(--ink);
  padding:8px 10px;border-radius:10px;transition:background .14s,color .14s;}
.drawer-sect a:hover{background:var(--c-bg);color:var(--c-ink);}

/* 28px rather than 24: at 24 a stroked glyph inside the tile has almost no
   air around it and the tile reads as a coloured square with a smudge. */
.drawer-sect .di{flex:none;width:28px;height:28px;border-radius:8px;
  display:grid;place-items:center;background:var(--c-bg);color:var(--c-ink);
  transition:background .14s;}
.drawer-sect .di svg{width:16px;height:16px;}
.drawer-sect a:hover .di{background:#fff;}

.drawer-foot{margin:4px 12px 22px;padding:14px;border-radius:12px;
  background:var(--panel-2);font-size:11px;line-height:1.65;color:var(--ink-3);}
body.drawer-open{overflow:hidden;}

/* Autocomplete */
.ac{position:absolute;top:calc(100% + 6px);left:0;right:0;background:var(--panel);
  border:1px solid var(--line-2);border-radius:12px;box-shadow:var(--sh2);
  max-height:380px;overflow-y:auto;padding:6px;}
.ac-i{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:9px;
  cursor:pointer;text-decoration:none;}
.ac-i:hover,.ac-i.sel{background:var(--panel-2);}
.ac-t{display:block;font-size:13.5px;font-weight:600;line-height:1.25;}
.ac-s{display:block;font-size:12px;color:var(--ink-3);}
.ac-empty{padding:16px;text-align:center;color:var(--ink-3);font-size:13px;}
/* Neighbourhood rows in the suggestion list. A pin where a building row has
   its City score, so the two kinds of answer are distinguishable before the
   label is read. */
.ac-hood .ac-pin{flex:none;width:28px;height:28px;border-radius:8px;
  display:grid;place-items:center;background:var(--sect-tint,#fdf4e0);color:var(--sect,#c77d03);}
.ac-hood .ac-pin svg{width:16px;height:16px;}

/* ---- "Did you mean a neighbourhood?" / "Nearby" --------------------------
   Above the filter bar on a text search and on a neighbourhood's own list.
   A search that found nothing used to be the end of the road, and a
   neighbourhood you had picked was a one-way door. */
.hsg{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:11px 14px;margin-bottom:12px;}
.hsg-l{font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink-3);flex:none;}
.hsg-row{display:flex;gap:7px;flex-wrap:wrap;flex:1 1 auto;min-width:0;}
.hsg-i{display:inline-flex;align-items:baseline;gap:7px;text-decoration:none;
  border:1px solid var(--line-2);border-radius:999px;padding:6px 13px;
  font-size:13px;font-weight:600;color:var(--ink);background:var(--panel);
  transition:border-color .15s,background .15s;}
.hsg-i:hover{border-color:var(--accent);background:#eef4f4;}
.hsg-i i{font-style:normal;font-size:11.5px;font-weight:500;color:var(--ink-3);}
.hsg-all{flex:none;font-size:12.5px;font-weight:600;color:var(--accent);
  text-decoration:none;white-space:nowrap;}
.hsg-all:hover{text-decoration:underline;}
@media (max-width:560px){ .hsg-l{width:100%;} .hsg-all{width:100%;} }

/* ===== The City's score ===================================================
   This is the thing a photo would otherwise occupy, so it is big, flat and
   legible at a glance. It used to hold an A/B/C/D we invented; it holds the
   City's own number now, on the City's own band colour, always next to the
   City's own wording for that band. See the note on BANDS in app.js. */
.score{display:inline-grid;place-items:center;flex:none;
  width:58px;height:58px;border-radius:15px;
  font-weight:700;font-size:26px;line-height:1;letter-spacing:-.03em;color:#fff;
  font-variant-numeric:tabular-nums;}
.score.sm{width:40px;height:40px;border-radius:11px;font-size:16px;}
.score.lg{width:92px;height:92px;border-radius:22px;font-size:44px;}
.b-good{background:#1e9e5a;}
.b-mid{background:#e8871a;}
.b-poor{background:#d64541;}
.b-none{background:var(--none);font-size:20px;}

/* ===== Hero ============================================================== */
.hero{padding:76px 0 56px;border-bottom:1px solid var(--line);background:var(--panel);
  overflow:hidden;}
/* Two columns, the drawing in the half of the hero that was empty. It drops
   out under 1000px: it is a hover affordance on a page that has a real map
   further down, and on a phone it would be a tall grey picture nobody can
   point at. */
.hero-in{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,520px);
  gap:48px;align-items:center;}
@media (max-width:1200px){ .hero-in{gap:32px;} }
.hero-t{min-width:0;}
@media (max-width:1000px){ .hero-in{grid-template-columns:1fr;} .hsk{display:none;} }

/* DRAWN BIGGER THAN ITS COLUMN, AND CROPPED. Soham asked for it to run off
   the edge — at 100% it read as a diagram politely occupying its half of the
   hero; at 170% it reads as a drawing the page is a window onto. The hero
   clips it, so the east end runs off the right margin on purpose. */
.hsk{position:relative;min-width:0;}
/* A fixed window the drawing is bigger than, so it crops on all four sides
   and the hero's height comes from its words again. */
/* Wider than its column so it runs into the page gutter, and it does not end
   at a cut — the whole drawing fades out towards its edges instead. A hard
   crop at 172% looked like a map someone had trimmed with scissors; at 132%
   more of the city is in frame and the mask dissolves whatever runs past the
   window, so there is no edge to notice. One radial mask does all four sides,
   with the -webkit- copy for Safari. */
/* THE FADE HAS TO HAPPEN INSIDE THE BOX. The first attempt put the
   gradient's transparent stop at 100% of a 115%-wide radius, which lands
   outside the element — so the mask was opaque everywhere you could see it
   and the drawing still ended at a hard cut along the top and right. The
   radii are smaller than the box now and the last stop is at 88%, so the
   lines are already gone before they reach any edge. */
.hsk-art{position:relative;height:420px;overflow:hidden;
  width:calc(100% + 270px);margin-left:-60px;
  -webkit-mask-image:radial-gradient(68% 70% at 50% 50%, #000 26%, rgba(0,0,0,.55) 60%, transparent 88%);
  mask-image:radial-gradient(68% 70% at 50% 50%, #000 26%, rgba(0,0,0,.55) 60%, transparent 88%);}
.hsk-art svg{position:absolute;top:50%;left:50%;transform:translate(-50%,-52%);
  display:block;width:124%;height:auto;}
@media (max-width:1200px){ .hsk-art{height:360px;width:calc(100% + 120px);margin-left:-30px;} }
.hsk-g path{fill:rgba(0,0,0,0);stroke:#d4d9e0;stroke-width:0.7;
  stroke-linejoin:round;cursor:pointer;transition:fill .12s ease,stroke .12s ease;}
.hsk-g path:hover{fill:url(#hskHatch);stroke:#101418;stroke-width:1.4;}
/* The caption is the readout; it holds its height so the hero does not jump
   as the cursor crosses a boundary. */
.hsk-cap{min-height:46px;margin-top:6px;text-align:center;font-size:13px;
  color:var(--ink-3);line-height:1.3;position:relative;z-index:2;}
/* The name is the loudest thing in the hero after the headline. */
.hsk-cap b{display:block;font-size:26px;font-weight:700;color:var(--ink);
  letter-spacing:-.03em;line-height:1.1;}
.hsk-cap span{display:block;}
.hero h1{margin:0 0 16px;font-size:clamp(32px,5.2vw,56px);line-height:1.05;
  letter-spacing:-.035em;font-weight:700;max-width:16ch;}
.hero h1 em{font-style:normal;color:var(--amber);}
.hero-p{margin:0 0 30px;font-size:17px;line-height:1.55;color:var(--ink-2);max-width:56ch;}
.hero-search{display:flex;gap:10px;max-width:620px;position:relative;}
.hero-search input{flex:1;border:1px solid var(--line-2);border-radius:12px;
  padding:15px 17px;font-size:16px;font-family:var(--font);outline:none;background:var(--panel);}
.hero-search input:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(15,59,67,.09);}
.hero-search button{border:0;border-radius:12px;background:var(--accent);color:#fff;
  font-weight:600;font-size:15px;padding:0 26px;cursor:pointer;white-space:nowrap;}
.hero-search button:hover{filter:brightness(1.12);}
.hero-stats{display:flex;gap:34px;margin-top:34px;flex-wrap:wrap;}
.hero-stat b{display:block;font-size:26px;font-weight:700;letter-spacing:-.025em;line-height:1.1;}
.hero-stat span{font-size:12.5px;color:var(--ink-3);}

/* ===== Section furniture ================================================= */
/* One gap between header and page title, shared with /plan/ — see --pg-top. */
.sect{padding:var(--sp-sec) 0;}
#view > .sect:first-child{padding-top:var(--pg-top);}
.sect-hd{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;
  margin-bottom:var(--sp-ts);flex-wrap:wrap;}
/* The page title. One size for the whole site — see --h-page in
   shared/chrome.css. */
.sect-hd h2{margin:0;font-size:var(--h-page);font-weight:700;
  letter-spacing:var(--h-page-ls);line-height:var(--h-page-lh);}
.sect-hd p{margin:var(--sp-tt) 0 0;font-size:14px;line-height:1.6;
  color:var(--ink-2);max-width:62ch;}
.sect-more{text-decoration:none;font-size:13.5px;font-weight:600;color:var(--accent);white-space:nowrap;}
.sect-more:hover{text-decoration:underline;}
.sect-alt{background:var(--panel);border-top:1px solid var(--line);border-bottom:1px solid var(--line);}

/* ---- Washed sections ------------------------------------------------------
   Two tinted bands down the home page, so it reads as layers rather than as
   one long sheet of off-white with cards on it. Both are a vertical gradient
   that gives up before the bottom edge: a flat fill would need a border to
   stop, and a border is a line the eye has to account for.

   The tints are the site's own two colours at about a twentieth strength —
   the rentals amber under Featured, the City's satisfactory green under the
   inspection scores — which is enough to separate the bands without either
   one reading as a colour choice. The cards on top stay white, so they lift
   off the wash instead of sitting in it. */
.sect-wash{position:relative;}
/* A tinted band gets its own inset, like /plan/'s. */
.sect-wash{padding-top:var(--sp-band);}
.sect-wash.warm{background:linear-gradient(180deg,#fcf6ec 0%,#fdfaf5 58%,var(--bg) 100%);}
.sect-wash.cool{background:linear-gradient(180deg,#eff6f2 0%,#f7fbf9 58%,var(--bg) 100%);}
/* A hairline at the top only, in the wash's own hue: it marks where the band
   starts, and the gradient is what ends it. */
.sect-wash.warm{border-top:1px solid #f2e6d4;}
.sect-wash.cool{border-top:1px solid #dceee5;}

/* ===== Rail (horizontal scroller) =======================================
   A rail rather than a grid for "new buildings": the set is small and ordered
   by recency, and a grid would imply there are hundreds when there are not. */
.rail{display:flex;gap:16px;align-items:stretch;overflow-x:auto;scroll-snap-type:x mandatory;
  padding:4px 0 14px;margin:0 -24px;padding-left:24px;padding-right:24px;
  scrollbar-width:thin;}
.rail::-webkit-scrollbar{height:8px;}
.rail::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:4px;}
.rail > *{scroll-snap-align:start;flex:0 0 310px;}
@media (max-width:640px){ .rail > *{flex:0 0 82%;} }

/* ===== Building card =====================================================
   The mark carries the neighbourhood colour, so scanning a list tells you
   roughly where things are before you read a word. */
/* Every mark is the same 52px square whatever is inside it. Favicons arrive at
   wildly different aspect ratios and with their own backgrounds baked in — one
   is a bare glyph, the next is a full-bleed orange tile — so each sits on an
   identical plate and is CONTAINED inside it.

   A LOGO GETS NO NEIGHBOURHOOD COLOUR. A brand mark already carries its own
   colour, and putting Tricon's orange on a green tile is two colour fields
   fighting over the same 52 pixels — it reads as a mistake. The plate goes
   neutral and the neighbourhood is carried by the dot beside its name, which
   was already there and is enough. Colour stays on the letter badge, where
   there is no brand colour to compete with and it is the only thing
   distinguishing one card from the next. */
.bc-mark{flex:none;width:52px;height:52px;border-radius:14px;display:grid;place-items:center;
  overflow:hidden;}
.bc-mark.has-logo{background:var(--panel-2)!important;border:1px solid var(--line);}
.bc-ltr{font-weight:700;font-size:23px;line-height:1;letter-spacing:-.03em;color:#fff;
  display:block;}
.bc-logo{width:36px;height:36px;min-width:36px;min-height:36px;max-width:36px;max-height:36px;
  object-fit:contain;display:block;background:#fff;border-radius:9px;padding:4px;}
.bc-hood{display:flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;
  color:var(--ink-2);margin:2px 0 3px;line-height:1.25;}
.bc-hdot{width:7px;height:7px;border-radius:50%;flex:none;}
/* Tinted, not filled. Two reasons.

   Contrast: .pill is declared after this block at the same specificity, so its
   grey text colour was winning and the score rendered dark-on-green at 2.21:1,
   against a 4.5:1 minimum. White on the palette green is only 3.45:1, so
   filling it was never going to work either. A pale tint with a deep text of
   the same hue clears 5.9-6.2:1 on every band.

   Weight: next to four neutral grey pills, one saturated block shouts. The
   tint still reads instantly as a status chip without unbalancing the row.

   .pill is repeated in the selector purely to win on specificity — a plain
   .pill-grade would lose to the later .pill rule again. */
.pill.pill-score{font-weight:700;letter-spacing:.01em;}
.pill.pill-score.b-good{background:#e7f5ed;color:#14663b;}
.pill.pill-score.b-mid{background:#fdf0e1;color:#8a4f0a;}
.pill.pill-score.b-poor{background:#fcebea;color:#a32f2b;}
.pill.pill-score.b-none{background:#f0f1f3;color:#5c6470;}

/* ===== Building card ===================================================== */
/* Column flex with the pills pushed to the bottom, so every card in a row is
   the same height whether or not it has a neighbourhood line or a manager
   line. Without this a card missing one of them sits 15px shorter and the row
   looks ragged. */
.bc{display:flex;flex-direction:column;height:100%;text-decoration:none;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--r);padding:16px;
  transition:border-color .15s,box-shadow .15s,transform .15s;}
.bc-meta{margin-top:auto;padding-top:4px;}
.bc:hover{border-color:var(--line-2);box-shadow:var(--sh2);transform:translateY(-2px);}
.bc-top{display:flex;gap:13px;align-items:flex-start;margin-bottom:13px;}
.bc-ttl{flex:1;min-width:0;}
.bc-name{font-size:16px;font-weight:700;letter-spacing:-.015em;line-height:1.25;
  margin-bottom:3px;overflow-wrap:anywhere;}
.bc-addr{font-size:12.5px;color:var(--ink-3);line-height:1.35;}
.bc-band{font-size:11px;font-weight:600;color:var(--ink-2);margin-top:6px;}
.bc-meta{display:flex;flex-wrap:wrap;gap:6px;}
.pill{font-size:11.5px;font-weight:600;color:var(--ink-2);background:var(--panel-2);
  border-radius:7px;padding:4px 8px;white-space:nowrap;}
.pill-new{background:#fff3e0;color:#9a5d00;}
/* The index's own pill. Dark, because it is the one number on the card that
   is ours: the City's score is green and bands, this one does not. */
.pill-tix{background:#101418;color:#fff;font-weight:700;letter-spacing:.01em;}
.pill-walk{background:#e8f2f3;color:#0f3b43;}

/* Grid variant for the full list */
.bgrid{display:grid;gap:16px;align-items:stretch;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));}

/* ===== Search chips ====================================================== */
.chips{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));}
.chip{display:flex;align-items:center;gap:12px;text-decoration:none;
  background:var(--panel);border:1px solid var(--line);border-radius:12px;
  padding:14px 16px;transition:border-color .15s,box-shadow .15s;}
.chip:hover{border-color:var(--accent);box-shadow:var(--sh1);}
.chip-ico{flex:none;width:34px;height:34px;border-radius:10px;display:grid;place-items:center;
  background:var(--panel-2);color:var(--accent);}
.chip-ico svg{width:17px;height:17px;}
.chip-t{display:block;font-size:14px;font-weight:600;line-height:1.3;}
.chip-s{display:block;font-size:12px;color:var(--ink-3);margin-top:1px;}

/* ===== Filter panel ======================================================
   Replaces the paging notice that used to sit here. Checkboxes combine with
   AND, which the empty state says out loud, because "nothing matched" after
   ticking six boxes otherwise reads as a bug. */
/* ---- The filter bar -------------------------------------------------------
   One row of dropdowns, not a 340px panel. Every filter is still here; what
   went is the vertical space it took to show them all open at once above a
   list that is the actual page. See filterPanel() in app.js.
   -------------------------------------------------------------------------- */
.fp{margin-bottom:16px;}
.fp-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.fp-reset{margin-left:auto;border:0;background:transparent;color:var(--ink-3);
  font-size:13px;font-weight:600;padding:9px 12px;border-radius:999px;cursor:pointer;
  transition:color .15s,background .15s;}
.fp-reset:hover{background:var(--panel-2);color:var(--ink);}
.fp-reset[hidden]{display:none;}
.fp-lbl{font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:10px;}
/* Selectable chips, not a column of system checkboxes. The native control is
   hidden rather than recoloured — accent-color still leaves the OS widget, and
   on the filter bar that is the single thing that made the panel look dated.
   The box is drawn here so it looks the same on every platform. */
.cbx-grid{display:flex;flex-wrap:wrap;gap:8px;}
.cbx{display:inline-flex;align-items:center;gap:9px;font-size:13.5px;font-weight:500;
  color:var(--ink-2);cursor:pointer;user-select:none;
  padding:8px 14px 8px 11px;border:1px solid var(--line-2);border-radius:999px;
  background:var(--panel);transition:border-color .15s,background .15s,color .15s;}
.cbx:hover{border-color:var(--ink-3);color:var(--ink);}
.cbx input{position:absolute;opacity:0;width:0;height:0;pointer-events:none;}
.cbx .box{flex:none;width:17px;height:17px;border-radius:6px;border:1.5px solid var(--line-2);
  background:var(--panel);display:grid;place-items:center;transition:all .15s;}
.cbx .box svg{width:11px;height:11px;color:#fff;opacity:0;transform:scale(.6);transition:all .15s;}
.cbx input:checked ~ .box{background:var(--accent);border-color:var(--accent);}
.cbx input:checked ~ .box svg{opacity:1;transform:scale(1);}
.cbx:has(input:checked){border-color:var(--accent);background:#eef4f4;color:var(--ink);}
.cbx input:focus-visible ~ .box{box-shadow:0 0 0 3px rgba(15,59,67,.22);}
.fp-walk{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.fp-mins{width:66px;border:1px solid var(--line-2);border-radius:10px;padding:9px 10px;
  font-size:15px;font-weight:600;font-family:var(--font);text-align:center;outline:none;
  background:var(--panel);color:var(--ink);-moz-appearance:textfield;}
.fp-mins::-webkit-outer-spin-button,.fp-mins::-webkit-inner-spin-button{
  -webkit-appearance:none;margin:0;}
.fp-mins:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(15,59,67,.09);}
.fp-unit{font-size:13.5px;color:var(--ink-2);}
.rad{display:inline-flex;align-items:center;gap:8px;font-size:13.5px;font-weight:500;
  color:var(--ink-2);cursor:pointer;user-select:none;
  padding:8px 14px;border:1px solid var(--line-2);border-radius:999px;background:var(--panel);
  transition:border-color .15s,background .15s,color .15s;}
.rad:hover{border-color:var(--ink-3);color:var(--ink);}
.rad input{position:absolute;opacity:0;width:0;height:0;pointer-events:none;}
.rad .dot{flex:none;width:15px;height:15px;border-radius:50%;border:1.5px solid var(--line-2);
  background:var(--panel);display:grid;place-items:center;transition:all .15s;}
.rad .dot::after{content:"";width:7px;height:7px;border-radius:50%;background:#fff;
  opacity:0;transform:scale(.5);transition:all .15s;}
.rad input:checked ~ .dot{background:var(--accent);border-color:var(--accent);}
.rad input:checked ~ .dot::after{opacity:1;transform:scale(1);}
.rad:has(input:checked){border-color:var(--accent);background:#eef4f4;color:var(--ink);}
.rad input:focus-visible ~ .dot{box-shadow:0 0 0 3px rgba(15,59,67,.22);}
.fp-clear{margin-left:auto;border:0;background:transparent;color:var(--ink-3);
  font-size:13px;font-weight:600;padding:8px 12px;border-radius:999px;cursor:pointer;
  transition:color .15s,background .15s;}
.fp-clear:hover{background:var(--panel-2);color:var(--ink);}
.fp-target{margin-top:11px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.fp-target:empty{display:none;margin:0;}
.fp-sel,.fp-addr{border:1px solid var(--line-2);border-radius:9px;padding:9px 12px;
  font-size:14px;font-family:var(--font);background:var(--panel);color:var(--ink);outline:none;
  min-width:260px;}
.fp-sel:focus,.fp-addr:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(15,59,67,.09);}
.fp-note{font-size:12.5px;color:var(--ink-3);}

.res-bar{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:16px;}
.res-n{font-size:14px;font-weight:700;}
.res-ctx{font-size:13px;color:var(--ink-3);}
.more-wrap{display:flex;align-items:center;gap:14px;justify-content:center;margin-top:26px;}
.more-btn{border:0;background:var(--accent);color:#fff;
  font-size:14px;font-weight:600;padding:12px 30px;border-radius:999px;cursor:pointer;
  box-shadow:0 1px 2px rgba(16,20,24,.14);transition:filter .15s,transform .1s;}
.more-btn:hover{filter:brightness(1.14);}
.more-btn:active{transform:translateY(1px);}
.more-btn:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(15,59,67,.26);}
.more-n{font-size:12.5px;color:var(--ink-3);}

/* Popular-search chips: a count on the right so the grid has a rhythm. */
.chip-txt{flex:1;min-width:0;}
.chip-n{font-size:17px;font-weight:700;letter-spacing:-.02em;flex:none;}

/* ===== Landlords ========================================================= */
.ll{background:var(--accent);color:#fff;border-radius:20px;padding:44px 40px;
  display:grid;grid-template-columns:1.15fr 1fr;gap:40px;align-items:center;}
.ll h2{margin:0 0 12px;font-size:28px;letter-spacing:-.025em;line-height:1.15;}
.ll p{margin:0 0 22px;font-size:15px;line-height:1.6;color:rgba(255,255,255,.82);}
.ll-acts{display:flex;gap:10px;flex-wrap:wrap;}
.ll-btn{text-decoration:none;font-size:14px;font-weight:600;padding:11px 20px;
  border-radius:10px;background:#fff;color:var(--accent);}
.ll-btn.ghost{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.4);}
.ll-btn:hover{filter:brightness(.95);}
.ll-card{background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);
  border-radius:14px;padding:20px;}
.ll-card h4{margin:0 0 12px;font-size:12px;letter-spacing:.07em;text-transform:uppercase;
  color:rgba(255,255,255,.65);font-weight:700;}
.ll-row{display:flex;justify-content:space-between;gap:12px;padding:9px 0;
  border-top:1px solid rgba(255,255,255,.13);font-size:13.5px;}
.ll-row:first-of-type{border-top:0;}
.ll-row b{font-weight:600;}
@media (max-width:860px){ .ll{grid-template-columns:1fr;padding:32px 24px;} }

/* ===== Report card ======================================================= */
.rc-hero{background:var(--panel);border-bottom:1px solid var(--line);padding:34px 0 30px;}
.rc-back{display:inline-flex;align-items:center;gap:6px;text-decoration:none;
  font-size:13px;font-weight:600;color:var(--ink-2);margin-bottom:20px;}
.rc-back:hover{color:var(--ink);}
.rc-top{display:flex;gap:22px;align-items:flex-start;flex-wrap:wrap;}
.rc-ttl{flex:1;min-width:260px;}
.rc-name{margin:0 0 5px;font-size:var(--h-page);font-weight:700;
  letter-spacing:var(--h-page-ls);line-height:var(--h-page-lh);}
.rc-addr{font-size:15px;color:var(--ink-2);}
.rc-mgmt{font-size:13.5px;color:var(--ink-3);margin-top:7px;}
.rc-mgmt a{color:var(--accent);font-weight:600;}
/* The manager's mark sits on the line it belongs to, not above it, so the
   block still reads as one sentence. */
.rc-mgmt-row{display:flex;align-items:center;gap:8px;}
.rc-mgmt-logo{width:22px;height:22px;object-fit:contain;flex:none;
  border-radius:5px;background:var(--panel-2);}
.rc-score{text-align:right;}
.rc-score .n{font-size:15px;font-weight:600;color:var(--ink-2);margin-top:9px;}
.rc-score .y{font-size:12px;color:var(--ink-3);}

.rc-body{display:grid;grid-template-columns:1fr 320px;gap:34px;
  align-items:start;padding:34px 0 60px;}
@media (max-width:920px){ .rc-body{grid-template-columns:1fr;} }

.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:22px;margin-bottom:18px;}
.card > h3{margin:0 0 4px;font-size:16px;font-weight:700;letter-spacing:-.015em;}
.card > h3 + .card-sub{margin:0 0 16px;font-size:12.5px;color:var(--ink-3);line-height:1.5;}

.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(118px,1fr));gap:2px;
  background:var(--line);border-radius:11px;overflow:hidden;}
.fact{background:var(--panel);padding:14px 15px;}
.fact b{display:block;font-size:20px;font-weight:700;letter-spacing:-.025em;line-height:1.15;}
.fact span{font-size:11.5px;color:var(--ink-3);}
.fact.na b{color:var(--ink-3);font-weight:600;font-size:15px;}

.amen{display:flex;flex-wrap:wrap;gap:7px;}
.am{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:500;
  padding:6px 11px;border-radius:8px;background:var(--panel-2);color:var(--ink-2);}
.am.no{opacity:.42;text-decoration:line-through;}
.am svg{width:13px;height:13px;}

.tr-row{display:flex;align-items:center;gap:12px;padding:11px 0;border-top:1px solid var(--line);}
.tr-row:first-of-type{border-top:0;}
.tr-ico{flex:none;width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  background:var(--panel-2);font-size:14px;}
.tr-n{flex:1;min-width:0;font-size:13.5px;font-weight:600;line-height:1.3;}
.tr-d{font-size:12.5px;color:var(--ink-3);white-space:nowrap;}

/* Google reviews block */
.gr-empty{border:1px dashed var(--line-2);border-radius:11px;padding:20px;
  text-align:center;color:var(--ink-3);font-size:12.5px;line-height:1.6;}
.gr-hd{display:flex;align-items:center;gap:9px;margin-bottom:14px;}
.gr-stars{color:#f0a500;letter-spacing:1px;font-size:14px;}
.gr-agg{font-size:13px;color:var(--ink-2);}
.gr-r{padding:13px 0;border-top:1px solid var(--line);}
.gr-r:first-of-type{border-top:0;}
.gr-rh{display:flex;align-items:center;gap:8px;margin-bottom:5px;}
.gr-av{width:24px;height:24px;border-radius:50%;background:var(--panel-2);flex:none;}
.gr-nm{font-size:12.5px;font-weight:600;}
.gr-tm{font-size:11.5px;color:var(--ink-3);margin-left:auto;}
.gr-tx{font-size:13px;line-height:1.55;color:var(--ink-2);}
.gr-attr{font-size:11px;color:var(--ink-3);margin-top:12px;}

.side-cta{background:var(--accent);color:#fff;border-radius:var(--r);padding:20px;
  margin-bottom:18px;}
.side-cta h4{margin:0 0 7px;font-size:15px;}
.side-cta p{margin:0 0 15px;font-size:12.5px;line-height:1.55;color:rgba(255,255,255,.8);}
.side-cta a{display:block;text-align:center;text-decoration:none;background:#fff;
  color:var(--accent);font-weight:600;font-size:13.5px;padding:10px;border-radius:9px;}

/* ===== Filter bar (list view) ============================================ */
.fbar{display:flex;gap:9px;flex-wrap:wrap;align-items:center;margin-bottom:22px;}
.fbar select,.fbar input{border:1px solid var(--line-2);border-radius:9px;padding:9px 12px;
  font-size:13.5px;font-family:var(--font);background:var(--panel);color:var(--ink);outline:none;}
.fbar .count{margin-left:auto;font-size:13px;color:var(--ink-3);}

/* ===== Ads =============================================================== */
.ad{margin:34px 0;}
.ad-lbl{font-size:9px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);opacity:.6;margin-bottom:6px;}
.ad-slot{border:1px solid var(--line);border-radius:12px;background:var(--panel);
  min-height:92px;display:grid;place-items:center;color:var(--ink-3);font-size:12px;}
.ad[hidden]{display:none;}

/* ===== Footer ============================================================ */
.ftr{background:var(--panel);border-top:1px solid var(--line);padding:46px 0 0;margin-top:20px;}
.ftr-in{max-width:1180px;margin:0 auto;padding:0 24px 34px;display:grid;
  grid-template-columns:2fr 1fr 1fr 1fr;gap:34px;}
.ftr-brand{font-size:17px;font-weight:700;letter-spacing:-.02em;margin-bottom:10px;}
.ftr-brand span{color:var(--ink-3);}
.ftr-col p{margin:0;font-size:12.5px;line-height:1.65;color:var(--ink-3);max-width:44ch;}
.ftr-col h4{margin:0 0 11px;font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700;}
.ftr-col a{display:block;text-decoration:none;font-size:13.5px;color:var(--ink-2);padding:4px 0;}
.ftr-col a:hover{color:var(--ink);}
.ftr-legal{border-top:1px solid var(--line);padding:18px 24px 26px;font-size:11.5px;
  color:var(--ink-3);line-height:1.6;max-width:1180px;margin:0 auto;}
@media (max-width:860px){ .ftr-in{grid-template-columns:1fr 1fr;} }

/* ===== Misc ============================================================== */
.empty{padding:60px 20px;text-align:center;color:var(--ink-3);}
.empty b{display:block;font-size:16px;color:var(--ink-2);margin-bottom:6px;}
.note{background:#fff8e6;border:1px solid #f0dca8;border-radius:11px;padding:13px 15px;
  font-size:12.5px;line-height:1.6;color:#6b5312;margin-bottom:22px;}
@media (prefers-reduced-motion:reduce){ *{animation:none!important;transition:none!important;} }

/* ===== Neighbourhood map ===================================================
   An inline SVG, pre-projected at build time, so everything here is paint —
   no tiles, no transforms, no layout work on hover. The shapes carry a hairline
   white stroke rather than a dark one: at this size a dark outline on 158
   small polygons turns the whole city into a grey mesh and the fill colours
   stop reading.

   The hovered shape is re-appended to the end of its group, because SVG has no
   z-index and a thick outline drawn in document order is clipped by whichever
   neighbour happens to come after it. */
.hmap{display:grid;grid-template-columns:minmax(0,1fr) 316px;gap:20px;align-items:start;}
.hmap-map{position:relative;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:14px 14px 10px;box-shadow:var(--sh1);}

/* Its own stacking context, for the same reason the home map card has one:
   Leaflet gives its controls z-index 1000 in the root context and they draw
   straight through the open menu drawer otherwise. */
.hmap-canvas{position:relative;z-index:0;height:540px;border-radius:11px;
  overflow:hidden;background:var(--panel-2);}
@media (max-width:900px){ .hmap-canvas{height:420px;} }

/* The neighbourhood name, once there is room for it. Stroke-as-halo rather
   than a background box: 173 opaque chips would hide the map the labels
   exist to sit on, and the halo keeps them readable over parks and water
   alike. pointer-events none or they eat the clicks meant for the shape.
   Which names are drawn at all is placeHoodLabels in app.js — this is only
   what one looks like. */
.hood-lbl{pointer-events:none;}
/* The span, not the marker, carries the type: Leaflet writes its own
   transform onto the marker to position it, so a transform here would be
   thrown away and the name would hang below and to the right of its point
   instead of sitting on it. */
.hood-lbl span{position:absolute;left:0;top:0;transform:translate(-50%,-50%);
  display:block;width:max-content;
  font-family:var(--font);font-size:11.5px;font-weight:700;
  letter-spacing:-.01em;color:#101418;white-space:nowrap;
  paint-order:stroke fill;-webkit-text-stroke:2.5px rgba(255,255,255,.92);
  text-shadow:0 1px 2px rgba(255,255,255,.95);
  transition:opacity .18s ease;}
/* While one neighbourhood is picked the rest of the map drops back, names
   included — a dimmed shape under a full-strength name reads as a mistake. */
.hood-lbl.dim span{opacity:.4;}
.hood-lbl.sel span{font-size:12.5px;opacity:1;}

.hmap-read{min-height:42px;padding:10px 4px 2px;border-top:1px solid var(--line);
  margin-top:8px;}
.hmap-read b{display:block;font-size:15px;font-weight:700;letter-spacing:-.015em;}
.hmap-read span{display:block;font-size:13px;color:var(--ink-2);margin-top:2px;}
/* The provenance line: whose boundary this outline is. Quieter than the
   counts above it — it is there to be checked, not read every time. */
.hmap-read .hm-src{font-size:11.5px;color:var(--ink-3);margin-top:3px;}
.hm-g{font-style:normal;font-weight:700;padding:0 5px;border-radius:5px;color:#fff;}
.hm-g.b-good{background:#1e9e5a;} .hm-g.b-mid{background:#e8871a;}
.hm-g.b-poor{background:#d64541;} .hm-g.b-none{background:#9aa3ad;}

.hmap-key{display:flex;flex-wrap:wrap;gap:4px 14px;padding:8px 4px 2px;
  border-top:1px solid var(--line);font-size:11.5px;color:var(--ink-2);}
.hm-k{display:inline-flex;align-items:center;gap:5px;font-weight:600;}
.hm-k i{width:11px;height:11px;border-radius:3px;display:inline-block;}
.hm-k em{font-style:normal;font-weight:400;color:var(--ink-3);}

.hmap-list{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--sh1);overflow:hidden;}
.hl-srch{position:relative;padding:10px;border-bottom:1px solid var(--line);}
.hl-srch svg{position:absolute;left:21px;top:50%;transform:translateY(-50%);
  width:15px;height:15px;color:var(--ink-3);pointer-events:none;}
.hl-srch input{width:100%;border:1px solid var(--line-2);border-radius:9px;
  padding:8px 10px 8px 32px;font-size:13.5px;font-family:var(--font);
  background:var(--panel);color:var(--ink);outline:none;}
.hl-srch input:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(15,59,67,.09);}
.hl-scroll{max-height:520px;overflow-y:auto;padding:6px;}
.hl-r{display:flex;align-items:center;gap:9px;padding:7px 8px;border-radius:8px;
  text-decoration:none;color:var(--ink);}
.hl-r[hidden]{display:none;}
.hl-r:hover,.hl-r.on{background:var(--panel-2);}
.hl-sw{flex:none;width:10px;height:10px;border-radius:3px;}
.hl-nm{flex:1;min-width:0;font-size:13px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hl-n{font-size:12px;color:var(--ink-3);font-variant-numeric:tabular-nums;}
.hl-none{padding:18px;text-align:center;font-size:13px;color:var(--ink-3);}

@media (max-width:900px){
  .hmap{grid-template-columns:1fr;}
  .hl-scroll{max-height:300px;}
}

/* ===== The map panel on the home page =====================================
   Same width as everything else in .wrap — deliberately not full-bleed. A map
   that runs edge to edge reads as "this page IS a map", which is the old site;
   inside the column it reads as one section among several, which is what it
   is. Taller than it is wide would waste it, so it sits at about 2:1. */
/* position+z-index is not decoration: Leaflet gives its controls z-index 1000
   in the root stacking context, so the zoom buttons drew straight through the
   open menu drawer. Making the card its own stacking context traps them. */
.pmap-card{position:relative;z-index:0;
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
  background:var(--panel);box-shadow:var(--sh1);}
.pmap{height:560px;width:100%;background:var(--panel-2);}
.pmap-off{display:grid;place-items:center;height:100%;color:var(--ink-3);font-size:13px;}
.pmap-bar{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;padding:9px 14px;border-top:1px solid var(--line);
  background:var(--panel);font-size:11.5px;color:var(--ink-3);}
.pm-hint{font-weight:500;}
.pm-key{display:flex;gap:12px;flex-wrap:wrap;}
.pm-k{display:inline-flex;align-items:center;gap:5px;font-weight:600;color:var(--ink-2);}
.pm-k i{width:10px;height:10px;border-radius:50%;display:inline-block;
  box-shadow:0 0 0 1.4px #fff,0 0 0 2.2px rgba(16,20,24,.12);}
.pm-k em{font-style:normal;font-weight:400;color:var(--ink-3);}
@media (max-width:640px){ .pmap{height:400px;} }

/* The cluster bubble, copied from the live map rather than restyled. Same
   reason as the pin: two maps of the same city on one site have to agree. */
.cluster-pin{background:rgba(255,59,48,.92);color:#fff;border-radius:50%;
  display:grid;place-items:center;font-weight:600;font-variant-numeric:tabular-nums;
  box-shadow:0 2px 8px rgba(255,59,48,.4);border:2px solid #fff;font-family:var(--font);}

/* The score in the popup, on its band colour — the same four bands the pin
   body uses, so the colour under the number is the colour of the pin that
   was clicked. */
.pm-band{display:inline-grid;place-items:center;min-width:34px;height:22px;
  padding:0 7px;border-radius:6px;color:#fff;font-size:12.5px;font-weight:700;
  font-variant-numeric:tabular-nums;}

.pm-pop{font-family:var(--font);min-width:190px;}
.pm-pt{font-size:14.5px;font-weight:700;letter-spacing:-.015em;line-height:1.25;}
.pm-ps{font-size:12px;color:var(--ink-3);margin-top:2px;}
.pm-pm{display:flex;align-items:center;gap:8px;margin:7px 0 2px;flex-wrap:wrap;}
.pm-pb{font-size:12px;color:var(--ink-2);}
.pm-pa{display:inline-block;margin-top:8px;font-size:12.5px;font-weight:700;
  color:var(--accent);text-decoration:none;}
.pm-pa:hover{text-decoration:underline;}
.leaflet-popup-content{margin:12px 14px;}
.leaflet-container{font-family:var(--font);}

/* ---- The key map on a filtered list --------------------------------------
   Sits in the section header opposite the heading, which is empty space on
   every neighbourhood page. Fixed width on desktop so the heading keeps its
   measure; full width under it on a phone, where the header wraps anyway. */
/* The heading sits level with the top of the map rather than with its
   caption, and is the size of a page title, because on these pages it is the
   page title. The map takes the height the hero was wasting. */
.sect-hd-map{align-items:flex-start;}
.sect-hd-map h2{font-size:34px;line-height:1.1;}
.sect-hd-map > div:first-child{padding-top:2px;}
@media (max-width:760px){ .sect-hd-map h2{font-size:27px;} }

.keymap{flex:none;width:380px;max-width:100%;}
.keymap-canvas{height:286px;border-radius:12px;overflow:hidden;
  border:1px solid var(--line);background:var(--panel-2);
  position:relative;z-index:0;}
.keymap-cap{margin-top:6px;font-size:12.5px;text-align:right;}
.keymap-cap a{color:var(--accent);font-weight:600;text-decoration:none;}
.keymap-cap a:hover{text-decoration:underline;}
/* Smaller type than the big map's labels, and the neighbours quieter than the
   neighbourhood being located — at this size everything at one weight reads
   as a wall of names. */
.km-lbl span{font-size:10.5px;-webkit-text-stroke:2px rgba(255,255,255,.92);}
.km-lbl.km-here span{font-size:12px;color:#0b1f14;}
.km-lbl.km-near span{color:#394149;font-weight:600;}
.keymap .leaflet-control-attribution{font-size:9px;background:rgba(255,255,255,.7);}

/* The building's own map, in the report card's side column. */
.rcmap{height:220px;border-radius:11px;overflow:hidden;margin:4px 0 12px;
  border:1px solid var(--line);background:var(--panel-2);position:relative;z-index:0;}
.rcmap .leaflet-control-attribution{font-size:9px;background:rgba(255,255,255,.7);}
/* The manager's mark on the website card. It sits on the dark panel, so it
   gets a light plate behind it — most of these marks are dark on white. */
.cta-logo{width:40px;height:40px;object-fit:contain;display:block;margin:0 0 10px;
  background:#fff;border-radius:9px;padding:4px;box-sizing:border-box;}
/* A mark drawn in white needs something to be white against. Four of the
   forty-four are line art for a dark background (BRAND_DARK in brands.js,
   picked by measuring luminance, not by eye); on the light card they were a
   few grey hairlines. */
.mc-mark.on-dark{background:#101418;}
.rc-mgmt-logo.on-dark{background:#101418;padding:2px;box-sizing:border-box;}
.cta-logo.on-dark{background:#101418;}
@media (max-width:760px){ .keymap{width:100%;} .keymap-cap{text-align:left;} }

.hm-kt{font-weight:700;color:var(--ink);text-transform:uppercase;
  letter-spacing:.06em;font-size:10px;align-self:center;}

/* The rail bleeds into the page gutter so a card can sit half-off the edge,
   and the bleed is hard-coded to the desktop gutter. Below 640px .wrap drops
   to a 16px gutter, so the rail hung 8px past the viewport on each side and
   the whole page scrolled sideways. */
@media (max-width:640px){
  .rail{margin:0 -16px;padding-left:16px;padding-right:16px;}
}

/* ===== The list under the neighbourhood map ===============================
   Selection is a persistent state, separate from hover: .on follows the
   cursor, .sel stays where it was put. Everything else fades back, which is
   what makes picking a second neighbourhood read as the map answering rather
   than the page reloading. */

/* The rows are <button> now, because they select rather than navigate; these
   undo the browser's button defaults so they still read as list rows. */
.hl-r{width:100%;border:0;background:transparent;font-family:var(--font);
  text-align:left;cursor:pointer;}
.hl-r.sel{background:var(--accent);color:#fff;}
.hl-r.sel .hl-n{color:rgba(255,255,255,.72);}

/* This panel appears because you clicked. It has to look like a thing that
   opened, not like more page: so it breaks the column with its own tinted
   band running the full width, and the neighbourhood's name is the largest
   type on the screen — bigger than the "Search by neighbourhood" heading
   above it, because at that point the name IS the heading. At 22px it sat
   below the section title and the arrival did not register. */
.hres{margin-top:36px;padding:34px 0 40px;border-top:1px solid var(--line);
  background:var(--panel-2);
  box-shadow:0 0 0 100vmax var(--panel-2);clip-path:inset(0 -100vmax);
  scroll-margin-top:calc(var(--hdr-h) + 10px);}
.hres[hidden]{display:none;}
.hres-hd{display:flex;align-items:flex-start;justify-content:space-between;
  gap:16px;flex-wrap:wrap;margin-bottom:20px;}
.hres-hd h3{margin:0;font-size:var(--h-page);font-weight:800;
  letter-spacing:-.032em;line-height:1.08;}
.hres-hd p{margin:4px 0 0;max-width:62ch;font-size:13.5px;line-height:1.55;
  color:var(--ink-2);}


/* ===== Management companies on the home page ==============================
   A grid, not the horizontal rail the building sections use: these are short
   rows rather than cards, and a rail of short rows scrolls sideways past
   things that would all have fit on screen. */
.mgrid{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(282px,1fr));}
.mc{display:flex;align-items:center;gap:12px;text-decoration:none;color:var(--ink);
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:12px 14px;transition:border-color .15s,box-shadow .15s;}
.mc:hover{border-color:var(--line-2);box-shadow:var(--sh1);}
.mc-mark{flex:none;width:38px;height:38px;border-radius:10px;display:grid;
  place-items:center;background:var(--panel-2);overflow:hidden;
  font-weight:700;font-size:16px;color:var(--accent);}
.mc-mark img{width:32px;height:32px;object-fit:contain;display:block;}
.mc-b{flex:1;min-width:0;}
.mc-n{font-size:14px;font-weight:700;letter-spacing:-.015em;line-height:1.25;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mc-s{font-size:12px;color:var(--ink-3);margin-top:2px;}
/* The operators past the first fifteen, until the button is pressed. */
.mc-more{display:none;}
.mgrid-rep{margin-top:14px;}

/* ---- Report a correction --------------------------------------------------
   Quiet on purpose. It belongs on a page whose job is to be read, so it is
   the weight of a caption, and it only takes colour on hover. */
.rep{display:inline-flex;align-items:center;gap:6px;margin-top:10px;
  font-size:12px;font-weight:600;color:var(--ink-3);text-decoration:none;
  line-height:1.3;}
.rep svg{width:14px;height:14px;flex:none;}
.rep:hover{color:var(--accent);text-decoration:underline;}
.tr-row + .rep{margin-top:12px;}
.hres-rep{margin:-6px 0 14px;}
.claim-rep{margin-top:26px;}

/* ---- Claim a building -----------------------------------------------------
   Three numbered steps down the page rather than a form in a row: the row
   version fitted on one line and told nobody what claiming involved, which is
   the thing that was actually missing. */
.claim{display:grid;gap:18px;}
.claim-step{display:flex;gap:16px;align-items:flex-start;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--r);padding:18px 20px;box-shadow:var(--sh1);}
.claim-n{flex:none;width:28px;height:28px;border-radius:50%;display:grid;place-items:center;
  background:var(--accent);color:#fff;font-weight:700;font-size:14px;}
.claim-b{flex:1;min-width:0;}
.claim-b h3{margin:2px 0 4px;font-size:17px;font-weight:700;letter-spacing:-.02em;}
.claim-sub{margin:0 0 12px;font-size:13px;color:var(--ink-3);max-width:60ch;}
.claim-srch{max-width:460px;}
.claim-hits{display:grid;gap:4px;margin-top:8px;max-width:520px;}
.claim-hit{display:flex;flex-direction:column;align-items:flex-start;gap:1px;
  text-align:left;background:var(--panel-2);border:1px solid var(--line);
  border-radius:9px;padding:8px 11px;cursor:pointer;font-family:var(--font);}
.claim-hit:hover{border-color:var(--accent);}
.claim-hit-t{font-size:13.5px;font-weight:700;}
.claim-hit-s{font-size:12px;color:var(--ink-3);}
.claim-none{font-size:12.5px;color:var(--ink-3);max-width:52ch;line-height:1.5;}
.claim-card{border:1px solid var(--line);border-radius:12px;padding:14px 16px;
  background:var(--panel-2);max-width:560px;}
.claim-card-t b{display:block;font-size:15px;font-weight:700;letter-spacing:-.015em;}
.claim-card-t span{display:block;font-size:12.5px;color:var(--ink-3);margin-top:1px;}
.claim-rows{margin:12px 0 10px;display:grid;gap:6px;}
.claim-rows > div{display:flex;justify-content:space-between;gap:16px;font-size:13px;
  border-bottom:1px dashed var(--line);padding-bottom:5px;}
.claim-rows span{color:var(--ink-3);}
.claim-band{font-size:11px;font-weight:600;padding:1px 6px;border-radius:5px;color:#fff;}
.claim-band.b-good{background:#1e9e5a;} .claim-band.b-mid{background:#e8871a;}
.claim-band.b-poor{background:#d64541;} .claim-band.b-none{background:#9aa3ad;}
.claim-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  max-width:760px;}
.claim-grid label{display:flex;flex-direction:column;gap:5px;font-size:12.5px;
  font-weight:600;color:var(--ink-2);}
.claim-grid .claim-wide{grid-column:1/-1;}
.claim-grid input,.claim-grid textarea{font-family:var(--font);font-size:14px;
  padding:9px 11px;border:1px solid var(--line);border-radius:9px;background:var(--panel);
  color:var(--ink);font-weight:400;}
.claim-grid input:focus,.claim-grid textarea:focus{outline:2px solid var(--accent);
  outline-offset:-1px;border-color:transparent;}
.claim-acts{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px;}
.claim-send{background:var(--accent);color:#fff;border:0;cursor:pointer;}
.claim-acts .ll-btn{cursor:pointer;font-family:var(--font);}
/* .ll-btn.ghost was written for the dark teal panel it normally sits on:
   white text on nothing. On this white card it was white on white, which is
   why "Copy it instead" looked like it was missing. */
.claim-acts .ll-btn.ghost{background:var(--panel);color:var(--ink-2);
  border:1px solid var(--line-2);}
.claim-acts .ll-btn.ghost:hover{color:var(--ink);border-color:var(--ink-3);filter:none;}
.claim-note{margin:10px 0 0;font-size:12px;color:var(--ink-3);max-width:60ch;line-height:1.5;}
.claim-out{width:100%;margin-top:8px;font-family:ui-monospace,Menlo,monospace;font-size:11.5px;
  border:1px solid var(--line);border-radius:8px;padding:8px;}
.claim-next{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));}
.cn{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:16px 18px;box-shadow:var(--sh1);}
.cn b{display:block;font-size:14px;font-weight:700;margin-bottom:5px;}
.cn span{font-size:13px;color:var(--ink-2);line-height:1.55;}

/* ===== What is within a walk =============================================
   The number is big because it is the summary, but the counts under it are
   the actual evidence and are never collapsed behind a toggle: this site
   publishes what it counted, so a figure nobody can check against anything
   would be exactly the kind of opaque rating it is trying not to produce. */
.wk-top{display:flex;align-items:center;gap:16px;margin:2px 0 14px;}
.wk-n{flex:none;width:72px;height:72px;border-radius:18px;display:grid;
  place-items:center;background:var(--accent);color:#fff;
  font-size:30px;font-weight:700;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;}
.wk-x b{display:block;font-size:14.5px;font-weight:700;letter-spacing:-.015em;}
.wk-x span{display:block;font-size:12.5px;color:var(--ink-3);margin-top:3px;}
.wk-rows{display:grid;gap:8px 18px;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  border-top:1px solid var(--line);padding-top:13px;}
.wk-r{display:flex;align-items:baseline;gap:9px;font-size:13px;color:var(--ink-2);}
.wk-r b{font-size:15px;font-weight:700;color:var(--ink);min-width:30px;
  font-variant-numeric:tabular-nums;}
.wk-none{font-size:13px;color:var(--ink-3);}

/* One property, one card: the line that says how many City registrations the
   card is standing for. Deliberately on the card rather than only on the
   building page — the unit count above it is the sum of all of them, and a
   number that is the sum of three buildings has to say so where it is read. */
.bc-grp{font-size:11.5px;font-weight:600;color:var(--ink-3);margin-top:3px;}
.rc-sibs{font-size:13px;line-height:1.55;color:var(--ink-2);margin:8px 0 2px;
  max-width:62ch;}
.rc-sibs a{color:var(--accent);font-weight:600;}
.rc-sibs b{color:var(--ink);}

/* ===== Advertising ========================================================
   The slot reserves its own space whether or not an ad arrives, so nothing on
   the page moves when one does. An empty mount is removed entirely rather
   than left as a grey box. */
.ad{margin:26px 0 4px;}
.ad:empty{display:none;}
.ad-lbl{font-size:10px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:6px;}
.ad-slot{display:block;min-height:90px;}

/* House promo: what a slot shows until there is a real advertiser. Styled as
   one of our own cards rather than as a fake ad — it is our page talking
   about our page, and dressing it up as bought inventory would be a lie that
   also trains people to ignore it. */
.tp-house{display:block;text-decoration:none;background:var(--panel-2);
  border:1px solid var(--line);border-radius:var(--r);padding:16px 18px;
  transition:border-color .15s,box-shadow .15s;}
.tp-house:hover{border-color:var(--line-2);box-shadow:var(--sh1);}
.tp-house-k{display:inline-block;font-size:10px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--accent);margin-bottom:5px;}
.tp-house-t{display:block;font-size:16px;font-weight:700;letter-spacing:-.02em;
  color:var(--ink);}
.tp-house-s{display:block;font-size:13px;line-height:1.5;color:var(--ink-2);margin-top:4px;
  max-width:62ch;}

/* Consent sheet. Bottom-left, not a full-screen interstitial: it has to be
   answerable without blocking the page, and an interstitial on a first visit
   from search is penalised by Google itself. */
.tp-consent{position:fixed;left:14px;bottom:14px;z-index:3000;
  width:min(420px,calc(100vw - 28px));background:var(--panel);
  border:1px solid var(--line-2);border-radius:14px;box-shadow:var(--sh2);
  padding:16px 18px;display:none;}
.tp-consent.show{display:block;}
.tp-consent h4{margin:0 0 7px;font-size:14px;font-weight:700;color:var(--ink);}
.tp-consent p{margin:0 0 12px;font-size:12.5px;line-height:1.55;color:var(--ink-2);}
.tp-consent p a{color:var(--accent);font-weight:600;}
.tp-consent-btns{display:flex;gap:8px;flex-wrap:wrap;}
.tp-consent button{flex:1 1 auto;min-width:112px;padding:9px 14px;border-radius:9px;
  border:1px solid var(--line-2);background:var(--panel);color:var(--ink);
  font-family:var(--font);font-size:13px;font-weight:600;cursor:pointer;}
.tp-consent button.primary{background:var(--accent);border-color:var(--accent);color:#fff;}
.tp-consent button:hover{filter:brightness(.97);}


/* ===========================================================================
   Saving, and My List
   ---------------------------------------------------------------------------
   The heart sits inside the card, which is a link, so it needs a stacking
   context of its own and a hit area big enough to be a target on a phone
   without covering the card's own tap area.
   ========================================================================= */
.bc{position:relative;}
.bc-heart{position:absolute;top:8px;right:8px;z-index:2;
  width:32px;height:32px;display:grid;place-items:center;
  border:0;border-radius:9px;background:transparent;cursor:pointer;
  color:var(--ink-3);transition:color .15s,background .15s,transform .12s;}
.bc-heart svg{width:17px;height:17px;display:block;}
.bc-heart:hover{background:var(--panel-2);color:var(--ink-2);}
.bc-heart:active{transform:scale(.9);}
/* Filled, in the City's own "needs significant improvement" red — which is
   the one strong colour this palette already carries, and the only place it
   means "yours" rather than a score. */
.bc-heart.on{color:var(--d);}
.bc-heart.on svg path{fill:currentColor;}
.bc-heart:focus-visible{outline:2px solid var(--accent);outline-offset:1px;}
/* The card's title must not run under the heart. */
.bc-ttl{padding-right:26px;}

.ml{padding:34px 24px 60px;}
.ml-hd h1{font-size:var(--h-page);letter-spacing:var(--h-page-ls);
  line-height:var(--h-page-lh);margin:0 0 6px;}
.ml-sub{margin:0 0 26px;color:var(--ink-2);font-size:14.5px;max-width:62ch;}
.ml-sect{margin:0 0 34px;}
.ml-sect h2{font-size:13px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 13px;display:flex;align-items:center;gap:8px;}
.ml-n{background:var(--panel-2);color:var(--ink-2);border-radius:20px;
  padding:1px 8px;font-size:12px;letter-spacing:0;font-variant-numeric:tabular-nums;}
.ml-empty{border:1px dashed var(--line-2);border-radius:var(--r);
  padding:38px 28px;text-align:center;background:var(--panel);margin-bottom:32px;}
.ml-empty-h{font-size:18px;font-weight:700;letter-spacing:-.02em;margin-bottom:8px;}
.ml-empty p{color:var(--ink-2);font-size:14px;max-width:48ch;margin:0 auto 20px;}
.ml-plans{list-style:none;margin:0;padding:0;border:1px solid var(--line);
  border-radius:var(--r);background:var(--panel);overflow:hidden;}
.ml-plan{display:flex;align-items:center;gap:14px;padding:13px 16px;}
.ml-plan + .ml-plan{border-top:1px solid var(--line);}
.ml-plan-a{font-weight:600;font-size:14.5px;flex:1 1 auto;min-width:0;}
.ml-plan-s{font-size:12.5px;color:var(--ink-3);flex:0 1 auto;}
.ml-plan-go{font-size:13px;font-weight:600;color:var(--accent);text-decoration:none;flex:none;}
.ml-plan-go:hover{text-decoration:underline;}
.ml-foot{border-top:1px solid var(--line);padding-top:22px;margin-top:8px;}
.ml-foot p{color:var(--ink-2);font-size:14px;max-width:62ch;margin:0 0 14px;}
.ml-foot b{color:var(--ink);}
.ml-note{font-size:13px;color:var(--ink-3);margin-top:14px;}
.bc-manual{opacity:.92;}
@media (max-width:640px){ .ml{padding:24px 16px 48px;} }

/* The header gained a Tools item, which left the search field shrinking
   towards its own magnifier icon on a laptop. It has a floor now and is
   dropped outright once there is not room for it — a search box too narrow to
   read an address in is worse than no search box, and every view has its own
   search anyway. */
.hdr-search{min-width:210px;}
@media (max-width:1180px){ .hdr-search{max-width:280px;} }
@media (max-width:1040px){ .hdr-search{display:none;} }

/* ===== Sorting on more than one thing ====================================
   Multi-select, collapsed into a dropdown. The question people have is
   compound — a high City score AND a high T-iX AND close to a subway — so a
   single-select could only answer half of it; but ten checkboxes in the open
   made sorting the tallest thing in the filter panel, for a control most
   people set once.

   So: a <details> whose summary carries the current order in words. Ticked
   keys apply in the order they are listed, each breaking the ties the one
   above it left, and the menu says so — with three ticked nobody can infer
   the order from the list itself.
   ========================================================================= */
.fdd{position:relative;}
.fdd > summary{display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  list-style:none;border:1px solid var(--line-2);border-radius:999px;
  padding:9px 14px;font-size:13.5px;color:var(--ink-2);
  background:var(--panel);white-space:nowrap;max-width:min(360px,80vw);
  transition:border-color .15s,background .15s,color .15s;}
.fdd > summary::-webkit-details-marker{display:none;}
.fdd > summary::marker{content:"";}
.fdd > summary:hover{border-color:var(--ink-3);color:var(--ink);}
/* The label is the question, the value is the answer: two weights on one
   line, so the bar reads as "Sort — newest first" at a glance. */
.fdd > summary b{font-weight:600;color:var(--ink);flex:none;}
.fdd > summary span{font-weight:500;color:var(--ink-3);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;min-width:0;}
.fdd > summary .fdd-c{flex:none;color:var(--ink-3);transition:transform .15s ease;}
.fdd.on > summary{border-color:var(--accent);background:#eef4f4;}
.fdd.on > summary span{color:var(--ink);}
.fdd[open] > summary{border-color:var(--sect);
  box-shadow:0 0 0 3px rgba(242,169,0,.18);}
.fdd[open] > summary .fdd-c{transform:rotate(180deg);}
.fdd-menu{position:absolute;top:calc(100% + 6px);left:0;z-index:650;
  width:330px;max-width:92vw;background:var(--panel);border:1px solid var(--line);
  border-radius:14px;padding:10px;box-shadow:var(--sh2);}
.fdd-hd{font-size:11.5px;line-height:1.5;color:var(--ink-3);
  padding:2px 6px 9px;margin-bottom:5px;border-bottom:1px solid var(--line);}
.fdd-menu .cbx{display:flex;align-items:center;gap:9px;padding:7px 6px;
  border-radius:8px;font-size:13.5px;border:0;background:none;}
.fdd-menu .cbx:hover{background:var(--panel-2);}
.fdd-menu .cbx:has(input:checked){background:none;border:0;}
.fdd-menu .fp-clear{display:block;width:100%;text-align:left;margin:6px 0 0;
  padding:8px 6px;border-top:1px solid var(--line);border-radius:0;}
/* The two filter menus keep their chips — the amenity list is nine short
   labels and reads better wrapped than as a nine-row column. */
.fdd-am{width:400px;}
.fdd-am .cbx{display:inline-flex;padding:8px 14px 8px 11px;
  border:1px solid var(--line-2);border-radius:999px;}
.fdd-am .cbx:has(input:checked){border-color:var(--accent);background:#eef4f4;}
.fdd-walk{width:360px;display:flex;flex-direction:column;gap:9px;align-items:flex-start;}
.fdd-walk .fp-walk{margin:0;}
.fdd-walk .rad{width:100%;}
.fdd-walk .fp-target{margin:0;width:100%;}
.fdd-walk .fp-sel,.fdd-walk .fp-addr{min-width:0;width:100%;}
@media (max-width:560px){
  .fdd,.fdd > summary{width:100%;max-width:none;}
  .fdd > summary{justify-content:space-between;}
  .fdd-menu{width:100%;}
  .fdd-am,.fdd-walk{width:100%;}
}

/* ===== The calculator, as a page ========================================
   Seamless: no border, no rounded box, no inner scrollbar. The frame is
   sized to its content by fitCalc() and its background is made transparent,
   so what the reader sees is one page rather than a calculator sitting in a
   window on a page.
   ========================================================================= */
.calcpage{max-width:1180px;margin:0 auto;padding:10px 8px 50px;}
.calcpage iframe{display:block;width:100%;border:0;background:transparent;
  overflow:hidden;}

/* ===== Property managers ================================================ */
.mg-grid{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));}
.mg-row{display:flex;align-items:center;gap:13px;background:var(--panel);
  border:1px solid var(--line);border-radius:12px;padding:12px 14px;
  text-decoration:none;}
.mg-row:hover{border-color:var(--line-2);box-shadow:var(--sh1);}
.mg-mark{flex:none;width:34px;height:34px;border-radius:9px;background:var(--panel-2);
  display:grid;place-items:center;font-size:14px;font-weight:700;color:var(--ink-2);
  overflow:hidden;}
.mg-mark img{display:block;object-fit:contain;}
.mg-t{min-width:0;}
.mg-t b{display:block;font-size:14px;font-weight:600;letter-spacing:-.012em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mg-t span{display:block;font-size:12.5px;color:var(--ink-3);
  font-variant-numeric:tabular-nums;}

/* ===== Save, on the building's own page =================================
   Styled like /plan/'s header action rather than inventing a third look: a
   quiet bordered button that picks up the section's own colour on hover, and
   fills in the section's red once it is on. It was a loud outlined pill
   sitting right against the score block, which made the two read as a pair
   when one is the City's number and the other is yours.

   It sits in its own row above the title with the back link, so there is a
   full row of clearance between it and the score. Same data-save hook and
   paintHeart() as the cards — the two shapes cannot disagree about state.
   ========================================================================= */
.rc-crumb{display:flex;align-items:center;justify-content:space-between;
  gap:16px;margin-bottom:14px;}
.rc-heart{display:inline-flex;align-items:center;gap:7px;flex:none;
  border:1px solid var(--line-2);background:var(--panel);color:var(--ink-2);
  font-family:var(--font);font-size:13px;font-weight:600;
  padding:9px 13px;border-radius:10px;cursor:pointer;white-space:nowrap;
  transition:background .15s,color .15s,border-color .15s;}
.rc-heart svg{width:14px;height:14px;flex:none;display:block;}
.rc-heart:hover{background:var(--sect-tint);color:var(--sect-ink);
  border-color:var(--sect);}
.rc-heart.on{color:var(--d);border-color:var(--d);background:var(--panel);}
.rc-heart.on svg path{fill:currentColor;}
.rc-heart.on:hover{background:#fdf1f1;}
.rc-heart:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
@media (max-width:560px){ .rc-heart span{display:none;} .rc-heart{padding:9px 11px;} }
