/* ===========================================================================
   shared/chrome.css — the furniture every section of torontopolis shares
   ---------------------------------------------------------------------------
   WHY THIS FILE EXISTS

   Map mode and the rentals section had grown their own headers: the map had a
   44px glyph, a tagline and pill tabs; /rent/ had a small logo, a section
   switcher and a search field. Both were fine on their own and together they
   read as two different websites — which is exactly what someone switching
   Map mode on and off saw.

   So the pieces that are genuinely the same thing in every section live here
   once, and nowhere else:

     .bsw      the brand, which doubles as the section switcher
     .navbtn   every header button, including Sign in and My List
     .bm-badge the saved count on My List
     .auth-*   the account menu
     .mapsw    the Map mode toggle

   These rules were deleted from index.html's inline <style> and from
   rent/app.css when they moved here. Do not copy them back: two copies is how
   the two halves drifted apart in the first place.

   It styles against the tokens both sections already define — --ink, --ink-2,
   --ink-3, --line, --line-2, --bg, --panel, --panel-2, --accent, --font — and
   uses literal shadows, because the map calls them --elev1 and rentals calls
   them --sh1.
   ========================================================================= */

/* ===== Cross-document transition ==========================================
   Switching Map mode is a real navigation between two documents, and the
   default is a white flash: the old page is thrown away before the new one
   paints. This makes the browser cross-fade them instead, and because both
   documents now draw the same header in the same place, the header appears to
   stay put while the body changes underneath it. Chrome and Safari honour it;
   Firefox ignores it and gets the old instant swap, which is what it does
   today. Nothing depends on it, so there is nothing to fall back to.
   ========================================================================= */

/* ===== The section colours ===============================================
   torontopolis has had two section colours for a long time — amber for
   rentals, purple for planning — but only the map explorer's tabs used them,
   and they used them as a solid fill. These three tokens put the same pair in
   every section's hands:

     --sect        the colour itself, for the brand's section label
     --sect-tint   a light wash of it, for whatever is currently selected
     --sect-ink    a darker version, readable as text on the wash

   A section sets them once. Everything selected — a nav item, a tab, a row in
   the switcher — then picks up its own section's colour instead of grey, and
   a glance at the page says which half of the site you are in.
   ========================================================================= */
:root{
  --rentals:#f2a900;
  --aic:#5b3dc4;
  /* Default to rentals; each section and each map mode overrides it. */
  --sect:var(--rentals);
  --sect-tint:#fdf2d9;
  --sect-ink:#8a6a00;

  /* ONE page-title size for the whole site. "All buildings", "Research",
     "My List", a neighbourhood's name, a ward's name and an application's
     address are all the same thing — the title of the page you are on — and
     they had drifted to 22, 25, 34 and 38px depending on which view drew
     them. Soham's note: the small one was never the right one. */
  /* The gap between the header and a page's title. It was 52px in /rent/ and
     nothing at all in /plan/, where a top-level section only carried a bottom
     margin — so "Research" and "Wards" sat hard against the header. */
  --pg-top:46px;
  /* A spacing scale, so gaps are a decision rather than whatever number was
     typed that day. Everything below is a multiple of 4 and sized against the
     type it separates: --sp-tt is title-to-text, --sp-ts is title-to-content,
     --sp-sec is between sections, --sp-band is a tinted band's own inset.
     These replaced 5, 12, 13, 18, 20, 26, 34 and 52px chosen ad hoc. */
  --sp-tt:10px;
  --sp-ts:26px;
  --sp-sec:52px;
  --sp-band:44px;

  --h-page:clamp(30px,3.6vw,40px);
  --h-page-lh:1.1;
  --h-page-ls:-.028em;

  /* ---- The type scale ---------------------------------------------------
     Before this there were about twenty distinct font sizes across the four
     stylesheets, 9px to 44px, including 10.5, 11.5, 12.5, 13.5, 14.5 and
     15.5 — half-pixel steps nobody can see and nobody chose, just whatever
     was typed that day. Worse, the same ROLE had different sizes in
     different sections: the footer brand was 17px in /rent/ and 19px in
     /plan/, and the "section heading" was 18, 21 or 28 depending on which
     file you happened to be in.

     Nine steps now, and every piece of text on the site is one of them.
     They are named for what the text DOES, not for how big it is, so the
     right one is usually obvious and a new component cannot invent a
     twenty-first size.

     READABILITY. Running text was 13px, which is small for a page people
     read rather than scan, and it is 15px now. The floor is 11px: that is
     the smallest this site will ask anyone to read, and the 9px and 10px
     rules are gone. Google's own guidance is that a page should not ask for
     anything smaller than about 12px for sustained reading, which is why
     prose sits well above it and only furniture — pills, axis labels, the
     legal line — goes near the floor.

     LINE HEIGHT travels with the size, because a heading set at 1.55 looks
     loose and body text at 1.15 is unreadable. Use the pair.
  */
  --fs-micro:11px;   /* the floor: legal line, axis labels, map furniture */
  --fs-xs:12px;      /* pills, badges, meta under a title */
  --fs-sm:13px;      /* secondary text, captions, dense table cells */
  --fs-ui:14px;      /* buttons, nav, form labels — text you act on */
  --fs-body:15px;    /* running text, and a heading inside a card */
  --fs-h3:17px;      /* a card's own heading */
  --fs-lede:19px;    /* an opening paragraph, and a modest heading */
  --fs-h2:21px;      /* a section heading, and the address under a name */
  --fs-h1:26px;      /* a heading that owns the page under its title */
  /* The EYEBROW: a small, bold, letter-spaced, uppercase kicker over a
     section — "THE FILE", "ABOUT BIRCH HOUSE", a footer column's heading.
     It is a heading, not body text, and it is deliberately SMALLER than the
     prose underneath it; that is the device, not a mistake. It gets its own
     token because the role was set at 11px, 12px and 13px in different
     files, which is the same inconsistency as every other size on this page
     and is more obvious than most: two eyebrows a scroll apart, at
     different sizes, read as two different kinds of thing.
     Uppercase carries more presence per pixel than lowercase, so 12px here
     sits comfortably above the 11px floor. */
  --fs-eyebrow:12px;
  /* --h-page above is the page title and the tenth step. */

  /* NUMERALS IN BOXES are deliberately not on the scale above. A score in a
     92px tile and a word in a sentence are different problems, and forcing
     them onto one ladder makes both worse. These are sized against the box
     that holds them. */
  --fs-num-xs:16px;  --fs-num-sm:20px;  --fs-num-md:23px;
  --fs-num-lg:26px;  --fs-num-xl:30px;  --fs-num-2xl:44px;

  --lh-tight:1.1;    /* display sizes */
  --lh-head:1.25;    /* headings */
  --lh-ui:1.35;      /* dense interface rows */
  --lh-body:1.55;    /* running text */
}

@view-transition{ navigation:auto; }
@media (prefers-reduced-motion:reduce){ @view-transition{ navigation:none; } }

/* ===== The brand, which is also the section switcher ======================
   <details>, so it opens with no script at all — the 3,611 static building
   pages carry this same markup and run none.
   ========================================================================= */
.bsw{position:relative;flex:none;}
.bsw > summary{display:flex;align-items:center;gap:9px;cursor:pointer;
  list-style:none;padding:4px 7px 4px 4px;border-radius:10px;}
.bsw > summary::-webkit-details-marker{display:none;}
.bsw > summary::marker{content:"";}
.bsw > summary:hover{background:var(--panel-2);}
.bsw > summary img{border-radius:7px;display:block;}
.bsw-t{display:block;font-weight:700;font-size:var(--fs-h3);letter-spacing:-.02em;
  line-height:1.05;white-space:nowrap;color:var(--ink);}
.hdr-ca{color:var(--ink-3);font-weight:600;}
/* RENTALS in amber, PLANNING in purple — the label is the clearest place on
   the page to say which half of the site this is, and it was grey. */
.bsw-sub{display:flex;align-items:center;gap:3px;margin-top:1px;
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--sect-ink);}
.bsw-sub svg{width:11px;height:11px;transition:transform .15s ease;}
.bsw[open] .bsw-sub svg{transform:rotate(180deg);}
.bsw-menu{position:absolute;top:calc(100% + 6px);left:0;z-index:1400;width:320px;
  background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:6px;
  box-shadow:0 2px 6px rgba(16,20,24,.07),0 12px 32px rgba(16,20,24,.14);}
.bsw-i{display:block;padding:10px 12px;border-radius:10px;text-decoration:none;}
.bsw-i b{display:block;font-size:var(--fs-ui);font-weight:700;color:var(--ink);}
.bsw-i span{display:block;font-size:var(--fs-xs);color:var(--ink-3);line-height:1.45;margin-top:2px;}
.bsw-i:hover{background:var(--panel-2);}
/* The section you are in is marked, not hidden: it is still the way back to
   that section's own home page from a building or application page. */
.bsw-i.on{background:var(--sect-tint);box-shadow:inset 2px 0 0 var(--sect);}
/* The version number and the "not the City" line, which used to sit in the
   map header's tagline. One click away is close enough for a bug report. */
.bsw-foot{margin:4px 2px 0;padding:9px 10px 4px;border-top:1px solid var(--line);
  font-size:var(--fs-micro);line-height:1.5;color:var(--ink-3);}
.bsw-foot .app-ver{font-variant-numeric:tabular-nums;}
@media (max-width:520px){ .bsw-menu{width:min(300px,calc(100vw - 32px));} }

/* ===== Header buttons ===================================================== */
/* flex:none is the whole fix for the My List badge, and the thing earlier
   attempts missed. .hdr-acct is a flex row, so this button shrank to whatever
   was left over — 110px for 132px of content — and because its own children
   are flex:none they simply overflowed, which put the red count circle on top
   of the last letter of the word it counts. Making the children rigid without
   making the button rigid only moved the overflow around. */
.navbtn{appearance:none;border:none;background:var(--panel-2);color:var(--ink-2);
  font-family:var(--font);font-size:var(--fs-sm);font-weight:500;padding:9px 14px;
  border-radius:8px;cursor:pointer;white-space:nowrap;text-decoration:none;
  flex:none;
  display:inline-flex;align-items:center;gap:7px;transition:background .15s,box-shadow .15s,color .15s;}
.navbtn:hover{background:var(--bg);color:var(--ink);box-shadow:0 1px 2px rgba(16,20,24,.06);}
.navbtn svg{width:15px;height:15px;flex:none;}
.navbtn.primary{background:var(--ink);color:#fff;}
.navbtn.advertise{background:linear-gradient(180deg,#ff5e54,#ff3b30);color:#fff;border:none;}
/* Signed in: the button carries the account colour so the state is readable
   without opening the menu. */
.navbtn.in{color:var(--accent,#0f3b43);}
/* flex:none on both the label and the badge. Without it the browser shrinks
   them to fit the bar, and because the label is white-space:nowrap its text
   then overflows its own box and runs under the badge — which is exactly what
   "My Lis(11)" was. A count that covers the word it counts is worse than no
   count.

   The second half of that bug was the JS: it set style.display to
   "inline-block", and an inline value beats the inline-flex here, so the
   number sat on the text baseline instead of being centred in its circle and
   the whole badge rode up over the label. Both painters now write "" and let
   this rule decide. Do not put a display value back in the JavaScript.

   Spacing comes from .navbtn's own `gap`, not from a margin here: with both,
   the badge was pushed to the edge of the pill and looked like it had fallen
   out of it. */
.navbtn .lbl{flex:none;}
.bm-badge{flex:none;align-self:center;
  background:var(--red,#d64541);color:#fff;
  font-size:var(--fs-micro);font-weight:700;line-height:1;
  min-width:19px;height:19px;padding:0 6px;border-radius:999px;
  display:inline-flex;align-items:center;justify-content:center;
  margin:0;font-variant-numeric:tabular-nums;letter-spacing:0;}

/* ===== The account menu =================================================== */
.auth-menu{position:fixed;top:56px;right:16px;background:var(--panel);
  border:1px solid var(--line);border-radius:12px;
  box-shadow:0 12px 40px rgba(0,0,0,.16);padding:8px;z-index:9500;
  display:none;min-width:232px;max-width:290px;}
.auth-menu.show{display:block;}
.auth-menu .em{white-space:normal;line-height:1.45;}
.auth-menu .who{display:flex;align-items:center;gap:10px;padding:10px;
  border-bottom:1px solid var(--line);margin-bottom:6px;}
.auth-menu .who .nm,.who-text .nm{font-weight:600;font-size:var(--fs-sm);color:var(--ink);}
.auth-menu .who .em,.who-text .em{font-size:var(--fs-xs);color:var(--ink-3);}
.auth-pic{width:40px;height:40px;border-radius:50%;object-fit:cover;flex-shrink:0;}
.auth-initials{width:40px;height:40px;border-radius:50%;background:var(--blue,#2f6fed);
  color:#fff;display:grid;place-items:center;font-size:var(--fs-ui);font-weight:700;flex-shrink:0;}
.auth-avatar{width:24px;height:24px;border-radius:50%;background:var(--blue,#2f6fed);
  color:#fff;display:grid;place-items:center;font-size:var(--fs-micro);font-weight:700;flex-shrink:0;}
.auth-menu button{width:100%;text-align:left;border:none;background:none;
  font-family:var(--font);font-size:var(--fs-sm);padding:9px 10px;border-radius:8px;
  cursor:pointer;color:var(--ink);}
.auth-menu button:hover{background:var(--bg);}
/* Google sign-in: follows Google's branding guidance — full-colour G on a
   neutral surface. */
.auth-menu button.gbtn{display:flex;align-items:center;justify-content:center;gap:9px;
  text-align:center;border:1px solid var(--line-2,var(--line));background:var(--panel);
  font-weight:600;font-size:var(--fs-sm);padding:10px;margin-top:2px;}
.auth-menu button.gbtn:hover{background:var(--bg);border-color:var(--ink-3);}
.auth-menu button.gbtn svg{flex:0 0 auto;display:block;}
.auth-menu button.gbtn[disabled]{opacity:.6;cursor:default;}
.auth-menu .gnote{font-size:var(--fs-micro);line-height:1.45;color:var(--ink-3);padding:7px 10px 3px;}

/* ===== The Map mode toggle ================================================
   An actual switch rather than a link, because it reads as one setting in two
   places — the two halves of the site are a toggle, not a one-way door out.
   ========================================================================= */
/* It was the words "Map mode" plus a 32px pill switch — the widest thing in
   the bar, for one destination. A folded map says it in 36px, and it is the
   same glyph the drawer already uses for the map explorer. The accessible
   name is still "Map mode"; see aria-label on the anchor. */
.mapsw{display:inline-grid;place-items:center;width:36px;height:36px;flex:none;
  padding:0;border:1px solid var(--line);border-radius:9px;text-decoration:none;
  color:var(--ink-2);transition:background .15s,color .15s,border-color .15s;}
.mapsw svg{width:19px;height:19px;}
.mapsw:hover{background:var(--panel-2);color:var(--ink);border-color:var(--ink-3);}
/* On the map already: filled, so the control reads as a state and not just a
   link somewhere else. */
.mapsw[aria-checked="true"]{background:var(--amber,#c77d03);color:#fff;
  border-color:var(--amber,#c77d03);}
.mapsw[aria-checked="true"]:hover{color:#fff;}

@media (max-width:1080px){ .navbtn .lbl{display:none;} .navbtn{padding:9px 11px;} }
/* Once the labels are gone these are bare glyphs, and at 31px square they
   were the smallest targets in the header. Match the Map mode button. */
@media (max-width:820px){
  .navbtn{min-width:36px;min-height:36px;justify-content:center;padding:0 10px;}
  .hdr-acct{gap:6px;}
}

/* ===== Selected items ====================================================
   One rule for "this is the one you are on", shared by /rent/'s and /plan/'s
   header nav and by the map explorer's tabs. It used to be two different
   things: a soft grey pill here, a solid purple pill with a white label and a
   3px underline on the map. Grey says nothing, and the solid fill was the
   loudest element in the header. A light wash of the section's own colour
   with the label in that colour says the same thing quietly, and says which
   section you are in at the same time.
   ========================================================================= */
/* DIRECT CHILDREN ONLY. The Tools dropdown lives inside this nav, so a bare
   ".hdr-nav a" also matched every link in its menu — and handed them
   white-space:nowrap, which meant the descriptions did not wrap and ran
   straight out of the right-hand side of the panel. It also overrode their
   font size and padding. The ">" is what keeps the nav's styling in the nav. */
.hdr-nav{display:flex;gap:4px;align-items:center;}
.hdr-nav > a{text-decoration:none;font-size:var(--fs-ui);font-weight:500;color:var(--ink-2);
  padding:7px 11px;border-radius:9px;white-space:nowrap;
  transition:background .15s,color .15s;}
.hdr-nav > a:hover{background:var(--panel-2);color:var(--ink);}
.hdr-nav > a.on{color:var(--sect-ink);background:var(--sect-tint);font-weight:600;}

/* ===== The anchored three ================================================
   My List, Sign in and Map mode are the only controls every section has, so
   they are the ones that must not move. Two things were moving them:

   1. Map mode was the FIRST button in the map explorer's cluster and the LAST
      in /rent/'s, so using it made all three jump sideways. The markup is in
      one order everywhere now — My List, Sign in, Map mode, hard against the
      right edge, with any section-only buttons pushed left of them.
   2. The Sign in button relabels itself with the user's first name once they
      are signed in, and "Sign in" and "Alexandra" are not the same width, so
      the whole row slid when auth resolved a moment after paint. A min-width
      holds the space either way.
   ========================================================================= */
.hdr-acct,.navbtns{display:flex;align-items:center;gap:8px;flex:none;margin-left:auto;}
.hdr-acct + .mapsw{margin-left:0;}
/* Reserve the widest of "Sign in" and a first name, so the row does not slide
   when auth resolves a moment after paint. */
#btnAuth{min-width:104px;justify-content:center;}

/* THE BADGE IS IN NORMAL FLOW. It used to be position:absolute at right:7px
   inside a button pinned to min-width:110px with justify-content:center, and
   22px of right padding to clear it. That works for a one-digit count and
   fails for two: the centred label grows towards a badge that cannot move,
   so "My List" + 11 collided and the red circle sat on top of the final "t".
   No amount of tuning the padding fixes that — the label and the badge were
   laid out independently and nothing made them aware of each other.

   In flow they are two flex items with a gap, so they cannot overlap at any
   count, in any font, in any language.

   NO min-width. It used to be 125px, reserving room for a badge that is not
   there yet, so with an empty list the button was a normal-sized label in an
   over-wide box with dead space hanging off the right. Soham: "the button is
   still long and has empty space on the right side, unevenly ... It should be
   a normal button."

   The width was reserved so the button would not change size the moment a
   first building is saved. That is a one-off reflow of about 24px, on the
   one click where the badge appearing is the point — and it is a far smaller
   problem than a permanently lopsided button on every page load. What stops
   the badge OVERLAPPING the label is flex:none on both, above, not this. */
#btnList{justify-content:flex-start;}
.mapsw{flex:none;}
@media (max-width:1080px){
  /* Icons only. #btnAuth still carries a width to drop; #btnList no longer
     sets one at all. */
  #btnAuth{min-width:0;}
}

/* ===== Tools ============================================================
   The fourth item in every section's nav: the things you come to a section to
   USE rather than to read. <details>, like the brand switcher, so it opens
   with no script at all.
   ========================================================================= */
.tools{position:relative;}
.tools > summary{display:inline-flex;align-items:center;gap:4px;cursor:pointer;
  list-style:none;font-size:var(--fs-ui);font-weight:500;color:var(--ink-2);
  padding:7px 11px;border-radius:9px;white-space:nowrap;
  transition:background .15s,color .15s;}
.tools > summary::-webkit-details-marker{display:none;}
.tools > summary::marker{content:"";}
.tools > summary:hover{background:var(--panel-2);color:var(--ink);}
.tools[open] > summary{background:var(--sect-tint);color:var(--sect-ink);font-weight:600;}
.tools > summary svg{transition:transform .15s ease;}
.tools[open] > summary svg{transform:rotate(180deg);}
.tools-menu{position:absolute;top:calc(100% + 6px);left:0;z-index:1400;width:310px;
  background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:6px;
  box-shadow:0 2px 6px rgba(16,20,24,.07),0 12px 32px rgba(16,20,24,.14);}
.tools-menu a{display:block;padding:10px 12px;border-radius:10px;
  text-decoration:none;white-space:normal;font-size:var(--fs-ui);font-weight:400;}
.tools-menu a:hover{background:var(--panel-2);}
.tools-menu b{display:block;font-size:var(--fs-ui);font-weight:700;color:var(--ink);}
.tools-menu span{display:block;font-size:var(--fs-xs);color:var(--ink-3);line-height:1.45;margin-top:2px;}
@media (max-width:860px){ .tools{display:none;} }

/* ===========================================================================
   Small screens
   ---------------------------------------------------------------------------
   The header has five things in it and a phone fits about three. The order of
   sacrifice, from least to most useful on a phone:

     1. the section nav      — every link in it is in the drawer
     2. the search field     — every view has its own search
     3. the Tools menu       — in the drawer too
     4. the button labels    — the icons carry them

   What survives at 375px is the burger, the brand, My List, Sign in and the
   Map mode switch, which is the smallest set that still lets someone get
   anywhere. Before this the nav simply ran off the right edge and took the
   account cluster and the Map mode switch with it — they were rendered at
   x=582 and x=710 in a 375px header, i.e. off the screen entirely.
   ========================================================================= */
@media (max-width:880px){
  .hdr-nav,.tools{display:none !important;}
}
@media (max-width:880px){
  /* The brand gives up space first, and truncates rather than pushing. */
  .bsw{min-width:0;flex:0 1 auto;}
  .bsw > summary{padding:4px;gap:7px;min-width:0;}
  .bsw-t{font-size:var(--fs-body);overflow:hidden;text-overflow:ellipsis;}
  .hdr-acct{gap:4px;}
  .navbtn{padding:9px 10px;}
  #btnAuth,#btnList{min-width:0;}
}
@media (max-width:520px){
  /* The brand is the only shrinkable item in the bar — the account cluster
     and the Map mode switch are flex:none — so it absorbs the entire deficit
     and ellipsed to "toronto…", which is not the brand. Two things give way
     before the name does: the ".ca" suffix, and then the logo mark, since the
     wordmark IS the brand and the mark is repeated in the favicon anyway. */
  .hdr-ca{display:none;}
  .bsw > summary img{display:none;}
  .bsw-t{overflow:visible;}
  /* Pinned to the viewport rather than to the brand, or a 320px menu opening
     at x=72 hangs 17px off a 375px screen. */
  .bsw-menu{left:8px;right:8px;width:auto;}
}
@media (max-width:420px){
  /* Last resort: the switch alone, no border, hard against the edge. */
  .bsw > summary img{width:26px;height:26px;}
  .bsw-t{font-size:var(--fs-ui);}
  .bsw-sub{font-size:var(--fs-micro);}
  .navbtn{padding:8px;}
}
/* The account menu is pinned to the viewport, not the button, so on a narrow
   screen it stays on screen instead of hanging off the right edge. */
@media (max-width:560px){
  .auth-menu{right:12px;left:12px;min-width:0;max-width:none;}
}

/* ===========================================================================
   Back to map mode
   ---------------------------------------------------------------------------
   Every link out of map mode carries ?from=map, and the section it lands on
   shows this bar until you use it or navigate away from the page you landed
   on. Without it the map's nav and Tools were a one-way door: you clicked
   "Buildings" or "Developer thumb rules", got what you asked for, and had to
   work out for yourself that the Map mode switch was the way back.

   Sticky under the header, in the section's own colour, so it reads as a
   state you are in rather than as a link in the page.
   ========================================================================= */
.backmap{position:sticky;top:var(--hdr-h,62px);z-index:580;
  background:var(--sect-tint);border-bottom:1px solid var(--line);}
.backmap-in{max-width:1180px;margin:0 auto;padding:9px 24px;
  display:flex;align-items:center;gap:10px;}
.backmap a{display:inline-flex;align-items:center;gap:8px;text-decoration:none;
  color:var(--sect-ink);font-size:var(--fs-sm);font-weight:700;}
.backmap a:hover{text-decoration:underline;}
.backmap svg{width:15px;height:15px;flex:none;}
.backmap span{font-size:var(--fs-sm);color:var(--ink-2);font-weight:400;}
/* The dismiss control. margin-left:auto puts it at the right end of the bar
   whether or not the sentence beside the link is showing, which it is not on
   a phone. */
.backmap-x{margin-left:auto;flex:none;display:grid;place-items:center;
  width:26px;height:26px;padding:0;border:0;border-radius:7px;cursor:pointer;
  background:transparent;color:var(--ink-3);
  transition:background .15s,color .15s;}
.backmap-x:hover{background:rgba(0,0,0,.07);color:var(--ink);}
.backmap-x:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(242,169,0,.3);}
.backmap-x svg{width:14px;height:14px;display:block;}
@media (max-width:640px){ .backmap-in{padding:9px 16px;} .backmap span{display:none;} }

/* ===========================================================================
   My List, the editable table — see shared/mylist.js
   ========================================================================= */
.ml-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:20px;}
.ml-find{position:relative;flex:1 1 260px;max-width:420px;}
.ml-find svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);
  color:var(--ink-3);pointer-events:none;}
.ml-find input{width:100%;border:1px solid var(--line-2);border-radius:10px;
  padding:9px 12px 9px 33px;font:inherit;font-size:var(--fs-sm);background:var(--panel);
  color:var(--ink);outline:none;}
.ml-find input:focus{border-color:var(--sect);box-shadow:0 0 0 3px var(--sect-tint);}
.ml-sel{border:1px solid var(--line-2);border-radius:10px;padding:9px 11px;
  font:inherit;font-size:var(--fs-sm);background:var(--panel);color:var(--ink);outline:none;}
.ml-csv{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line-2);
  background:var(--panel);color:var(--ink-2);font-family:var(--font);font-size:var(--fs-sm);
  font-weight:600;padding:9px 13px;border-radius:10px;cursor:pointer;}
.ml-csv:hover{background:var(--panel-2);color:var(--ink);}
.ml-bar .ml-sub{margin-left:auto;font-size:var(--fs-sm);color:var(--ink-3);}
.ml-sect{font-size:var(--fs-eyebrow);font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  margin:26px 0 12px;padding-left:9px;display:flex;align-items:center;gap:8px;}
.ml-sect span{background:var(--panel-2);color:var(--ink-2);border-radius:20px;
  padding:1px 8px;font-size:var(--fs-xs);letter-spacing:0;}
.ml-sect-rent{color:#8a6a00;border-left:3px solid #f2a900;}
.ml-sect-plan{color:#4a2fa8;border-left:3px solid #5b3dc4;}
.ml-none{border:1px dashed var(--line-2);border-radius:14px;padding:34px 24px;
  text-align:center;background:var(--panel);}
.ml-none-h{font-size:var(--fs-lede);font-weight:700;letter-spacing:-.02em;margin-bottom:8px;}
.ml-none p{color:var(--ink-2);font-size:var(--fs-ui);max-width:52ch;margin:0 auto 16px;line-height:1.6;}
/* The table scrolls sideways rather than squeezing: eleven columns will not
   fit a laptop, and shrinking the rent cells makes them unusable. */
.ml-scroll{overflow-x:auto;border:1px solid var(--line);border-radius:14px;
  background:var(--panel);}
.ml-table{width:100%;border-collapse:collapse;font-size:var(--fs-sm);min-width:900px;}
.ml-table th{text-align:left;font-size:var(--fs-micro);font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--ink-3);padding:11px 10px;
  border-bottom:1px solid var(--line);white-space:nowrap;}
.ml-table td{padding:9px 10px;border-bottom:1px solid var(--line);vertical-align:top;}
.ml-table tr:last-child td{border-bottom:0;}
.ml-prop{min-width:190px;}
.ml-name{border:0;background:none;padding:0;font-family:var(--font);
  font-size:var(--fs-ui);font-weight:700;color:var(--ink);cursor:pointer;text-align:left;
  letter-spacing:-.015em;}
.ml-name:hover{text-decoration:underline;}
/* Buildings you added yourself sit in the same table as the City's registry
   records, so they are marked. Without it the registry's authority quietly
   rubs off on a row you typed in. Only the map explorer asks for this tag
   (manualTag in shared/mylist.js) because only the map can add one. */
.ml-yours{display:inline-block;margin-left:6px;vertical-align:1px;
  font:600 9.5px/1 var(--font);letter-spacing:.04em;text-transform:uppercase;
  color:var(--sect-ink,var(--ink-2));border:1px dashed currentColor;
  border-radius:4px;padding:2px 4px;opacity:.85;}
.ml-addr{font-size:var(--fs-xs);color:var(--ink-3);margin-top:1px;}
.ml-stage{margin-top:6px;border:1px solid var(--line-2);border-radius:8px;
  padding:4px 7px;font:inherit;font-size:var(--fs-xs);background:var(--panel);
  color:var(--ink-3);outline:none;}
.ml-stage.set{color:var(--ink);border-color:var(--sect);font-weight:600;}
.ml-cell{width:100%;border:1px solid transparent;border-radius:8px;padding:6px 8px;
  font:inherit;font-size:var(--fs-sm);background:var(--panel-2);color:var(--ink);
  outline:none;resize:vertical;}
.ml-cell:focus{border-color:var(--sect);background:var(--panel);
  box-shadow:0 0 0 3px var(--sect-tint);}
.ml-rent{width:74px;text-align:right;font-variant-numeric:tabular-nums;}
.ml-rent::-webkit-outer-spin-button,.ml-rent::-webkit-inner-spin-button{
  -webkit-appearance:none;margin:0;}
.ml-notes{min-width:170px;}
.ml-rate{display:inline-flex;gap:3px;}
.ml-rate button{width:28px;height:28px;border:1px solid var(--line-2);
  background:var(--panel);border-radius:8px;cursor:pointer;font-size:var(--fs-sm);
  color:var(--ink-3);line-height:1;}
.ml-rate button:hover{background:var(--panel-2);color:var(--ink-2);}
.ml-rate button.on{background:var(--sect-tint);border-color:var(--sect);
  color:var(--sect-ink);font-weight:700;}
.ml-del{border:0;background:none;color:var(--ink-3);font-size:var(--fs-sm);cursor:pointer;
  padding:6px 8px;border-radius:7px;}
.ml-del:hover{background:var(--panel-2);color:var(--red,#d64541);}
.ml-plans{list-style:none;margin:0;padding:0;border:1px solid var(--line);
  border-radius:14px;background:var(--panel);overflow:hidden;}
.ml-plans li{display:flex;align-items:center;gap:14px;padding:13px 16px;}
.ml-plans li + li{border-top:1px solid var(--line);}
.ml-plan-a{font-weight:600;font-size:var(--fs-ui);flex:1 1 auto;min-width:0;}
.ml-plan-s{font-size:var(--fs-sm);color:var(--ink-3);}
.ml-plan-go{font-size:var(--fs-sm);font-weight:600;color:var(--sect-ink);
  text-decoration:none;flex:none;}
.ml-plan-go:hover{text-decoration:underline;}

/* ===== Numbered pages ======================================================
   Used by /rent/'s buildings list and /plan/'s Research view, drawn by
   shared/pager.js. One implementation, so the two halves of the site page
   the same way. Replaces a "Show 60 more" button that could not say how much
   was left or take you back.
   ========================================================================= */
.pgr{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  margin:20px 0 4px;padding-top:16px;border-top:1px solid var(--line);}
.pgr-range{font-size:var(--fs-sm);color:var(--ink-3);font-variant-numeric:tabular-nums;}
.pgr-pages{display:flex;align-items:center;gap:4px;flex-wrap:wrap;
  margin:0 auto;}
.pgr-n,.pgr-a{appearance:none;font-family:var(--font);cursor:pointer;
  border:1px solid transparent;background:transparent;color:var(--ink-2);
  min-width:34px;height:34px;padding:0 9px;border-radius:9px;
  font-size:var(--fs-sm);font-weight:600;font-variant-numeric:tabular-nums;
  display:inline-flex;align-items:center;justify-content:center;
  transition:background .15s,color .15s,border-color .15s;}
.pgr-n:hover,.pgr-a:not([disabled]):hover{background:var(--panel-2);color:var(--ink);}
.pgr-n.on{background:var(--ink);border-color:var(--ink);color:#fff;}
.pgr-a svg{width:16px;height:16px;}
.pgr-a[disabled]{opacity:.3;cursor:default;}
.pgr-gap{color:var(--ink-3);padding:0 2px;font-size:var(--fs-sm);}
.pgr-per{display:inline-flex;align-items:center;gap:7px;
  font-size:var(--fs-sm);color:var(--ink-3);white-space:nowrap;}
.pgr-per select{font-family:var(--font);font-size:var(--fs-sm);font-weight:600;
  color:var(--ink);background:var(--panel);border:1px solid var(--line-2);
  border-radius:8px;padding:5px 7px;cursor:pointer;}
@media (max-width:620px){
  .pgr{gap:10px;justify-content:center;}
  .pgr-range{width:100%;text-align:center;}
  .pgr-pages{margin:0;width:100%;justify-content:center;gap:2px;}
  .pgr-per{width:100%;justify-content:center;}
  /* A page number is a thumb target on a phone, not a mouse target: 34px
     measured is under what a thumb reliably hits, and these sit in a row of
     seven. */
  .pgr-n,.pgr-a{min-width:42px;height:42px;font-size:var(--fs-ui);}
  .pgr-a svg{width:18px;height:18px;}
  .pgr-per select{padding:9px 10px;}
}

/* ===== Text fields on a phone =============================================
   iOS Safari zooms the whole page when a focused text field is smaller than
   16px, and the page never zooms back. The map explorer's old answer to that
   was user-scalable=no in its viewport meta, which stopped the zoom by
   stopping ALL zooming — including the pinch-zoom someone with low vision
   needs on a map. Lighthouse fails it, and rightly.

   So: the fields are 16px on a phone instead. Nothing above 820px changes,
   and the designed 13–14px fields are untouched on a desktop where no zoom
   behaviour depends on them.

   !important is load-bearing here. shared/chrome.css is loaded BEFORE each
   section's app.css, and those set font-size on the same inputs at a higher
   specificity, so without it this rule loses every time. It is scoped to text
   entry only — the controls iOS actually zooms for.
   ========================================================================= */
@media (max-width:820px){
  input[type="text"],input[type="search"],input[type="email"],
  input[type="password"],input[type="number"],input[type="tel"],
  input[type="url"],input:not([type]),textarea,select{
    font-size:16px !important;
  }
}
:root{--css-build:"e3e69fbe3e";}
/* --- 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:var(--fs-h3);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:var(--fs-ui);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:var(--fs-micro);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:var(--fs-sm);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:var(--fs-micro);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:var(--fs-ui);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:var(--fs-micro);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:var(--fs-sm);font-weight:600;line-height:1.25;}
.ac-s{display:block;font-size:var(--fs-xs);color:var(--ink-3);}
.ac-empty{padding:16px;text-align:center;color:var(--ink-3);font-size:var(--fs-sm);}
/* 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:var(--fs-micro);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:var(--fs-sm);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:var(--fs-xs);font-weight:500;color:var(--ink-3);}
.hsg-all{flex:none;font-size:var(--fs-sm);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:var(--fs-num-lg);line-height:1;letter-spacing:-.03em;color:#fff;
  font-variant-numeric:tabular-nums;}
.score.sm{width:40px;height:40px;border-radius:11px;font-size:var(--fs-num-xs);}
.score.lg{width:92px;height:92px;border-radius:22px;font-size:var(--fs-num-2xl);}
.b-good{background:#1e9e5a;}
.b-mid{background:#e8871a;}
.b-poor{background:#d64541;}
.b-none{background:var(--none);font-size:var(--fs-num-sm);}

/* ===== 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:var(--fs-sm);
  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:var(--fs-num-lg);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:var(--fs-h3);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);}  /* 16px literal: below it Safari zooms on focus */
.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:var(--fs-body);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:var(--fs-num-lg);font-weight:700;letter-spacing:-.025em;line-height:var(--lh-tight);}
.hero-stat span{font-size:var(--fs-sm);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:var(--fs-ui);line-height:1.6;
  color:var(--ink-2);max-width:62ch;}
.sect-more{text-decoration:none;font-size:var(--fs-sm);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:var(--fs-num-md);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:var(--fs-sm);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. */
/* align-self:stretch, NOT height:100%. A card is a flex item of .rail and
   of the card grids, and both stretch their items; giving the item an
   explicit height, 100% included, opts it OUT of that stretch and leaves it
   at its content height. That is why one rail came out 138, 177 and 198
   pixels tall, high wherever a building carried an extra line. The
   percentage had nothing definite to resolve against either, since the rail
   has no height of its own. */
.bc{display:flex;flex-direction:column;align-self:stretch;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:var(--fs-h3);font-weight:700;letter-spacing:-.015em;line-height:1.25;
  margin-bottom:3px;overflow-wrap:anywhere;}
.bc-addr{font-size:var(--fs-sm);color:var(--ink-3);line-height:1.35;}
.bc-band{font-size:var(--fs-micro);font-weight:600;color:var(--ink-2);margin-top:6px;}
.bc-meta{display:flex;flex-wrap:wrap;gap:6px;}
.pill{font-size:var(--fs-xs);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;}
/* Social and community housing, on a card. Violet rather than a warning
   colour: it is a FACT about who rents the building out, not a mark against
   it, and plenty of readers are looking for exactly these. Private carries
   no pill at all — 3,039 of 3,611 buildings are private and labelling all of
   them would bury the 569 that are not. */
.pill-own{background:#eceaf8;color:#4b3f94;}

/* 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:var(--fs-ui);font-weight:600;line-height:1.3;}
.chip-s{display:block;font-size:var(--fs-xs);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:var(--fs-sm);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:var(--fs-micro);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:var(--fs-sm);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:var(--fs-body);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:var(--fs-sm);color:var(--ink-2);}
.rad{display:inline-flex;align-items:center;gap:8px;font-size:var(--fs-sm);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:var(--fs-sm);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:var(--fs-ui);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:var(--fs-sm);color:var(--ink-3);}

.res-bar{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:16px;}
/* "Draw this on the map" — the handoff from a walking-radius search to the
   map explorer's real isochrone. Visibly external: it opens a new tab, so it
   carries the box-arrow the same way /plan/'s research button does. */
.res-map{display:inline-flex;align-items:center;gap:4px;margin-left:auto;
  font-size:var(--fs-sm);font-weight:600;color:var(--accent);text-decoration:none;
  border:1px solid var(--line-2);border-radius:999px;padding:5px 12px;
  transition:border-color .15s,background .15s;}
.res-map:hover{border-color:var(--accent);background:#eef4f4;}
/* The attention state, shown the moment a filter is picked. Same amber ring
   as an open filter dropdown (.fdd[open] > summary), because "something is
   waiting for you here" should look like one thing across the site rather
   than a new idea per component. Thin on purpose: it is a way onward, not
   the point of the page. */
.res-map.on{border-color:var(--sect);color:var(--accent-ink);
  box-shadow:0 0 0 3px rgba(242,169,0,.18);}
.res-map.on:hover{border-color:var(--sect);background:#fff8ea;
  box-shadow:0 0 0 4px rgba(242,169,0,.26);}
.ext-a{width:12px;height:12px;flex:none;}
.res-n{font-size:var(--fs-ui);font-weight:700;}
.res-ctx{font-size:var(--fs-sm);color:var(--ink-3);}
/* "Show the other 27 operators" was a filled pill, centred, 26px clear of
   the grid — Soham: it should sit "at bottom right of the rectangle cards,
   in a more condensed/less attraction seeking way". He is right: a solid
   accent button is the loudest thing on the page, and all it does is show
   more of what is already there. It is a quiet link at the end of the grid
   now, aligned right so it reads as the end of the list rather than as the
   next thing to do. */
.more-wrap{display:flex;align-items:center;gap:9px;justify-content:flex-end;
  margin-top:12px;}
.more-btn{border:0;background:transparent;color:var(--accent-ink);
  font-family:var(--font);font-size:var(--fs-sm);font-weight:600;
  padding:5px 2px;border-radius:7px;cursor:pointer;display:inline-flex;
  align-items:center;gap:5px;transition:color .15s;}
.more-btn::after{content:"";width:9px;height:9px;flex:none;
  border-right:1.9px solid currentColor;border-bottom:1.9px solid currentColor;
  transform:rotate(45deg) translate(-1px,-1px);}
.more-btn:hover{text-decoration:underline;}
.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:var(--fs-xs);color:var(--ink-3);}
/* The report line and the "show more" share one row, so the grid ends on a
   single line of quiet text instead of two stacked blocks. */
.mgrid-foot{display:flex;align-items:center;justify-content:space-between;
  gap:16px;flex-wrap:wrap;margin-top:14px;}
.mgrid-foot .mgrid-rep{margin-top:0;}
.mgrid-foot .more-wrap{margin-top:0;}

/* 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:var(--fs-h3);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:var(--fs-h1);letter-spacing:-.025em;line-height:1.15;}
.ll p{margin:0 0 22px;font-size:var(--fs-body);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:var(--fs-ui);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:var(--fs-eyebrow);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:var(--fs-sm);}
.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:var(--fs-sm);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 var(--sp-tt);font-size:var(--h-page);font-weight:700;
  letter-spacing:var(--h-page-ls);line-height:var(--h-page-lh);}
/* THE ADDRESS IS A HEADING, not a caption. Soham: "the address text size
   should be much bigger, this is currently too small ... it is the main
   header of the page." He is right, and it was set at body size under a
   40px name, so "Birch House" read as the building and "100 Mill St" read
   as a footnote about it. For somebody searching rentals the address IS the
   building: it is what they typed, what Google matched, and what they will
   give a friend. It is --fs-h2 now, a step below the name rather than six.

   Where there is no marketing name the address is already the h1 and this
   line carries "Toronto, ON", which at this size reads as the place rather
   than as small print. */
.rc-addr{font-size:var(--fs-h2);font-weight:600;color:var(--ink-2);
  letter-spacing:-.012em;line-height:var(--lh-head);}
/* The same fact at the top of the building's own page, where it is stated
   for every building including the private ones: a reader who has landed
   here from a search should not have to infer it. */
.rc-own{margin-top:9px;}
.own-pill{display:inline-block;font-size:var(--fs-xs);font-weight:600;
  border-radius:999px;padding:4px 11px;text-decoration:none;
  border:1px solid transparent;}
.own-private{background:var(--panel-2);color:var(--ink-2);border-color:var(--line-2);}
.own-tchc,.own-social{background:#eceaf8;color:#4b3f94;border-color:#d8d3f0;}
.own-pill:hover{filter:brightness(.97);}
/* ---- The three actions, at the top of a building page -------------------
   See it on the map, look it up, take the link away. Outlined rather than
   filled: they are tools, not the point of the page, and three solid
   buttons under the address would outshout the address. Each carries the
   glyph the same action uses elsewhere on the site, so the map button here
   is recognisably the map button in the header. */
/* Station dots on the building's own map. The same mark as the full map
   explorer, one size down, so the two read as the same network rather than
   as two different conventions for the same thing. position:absolute and
   display:block are both required: the marker is a zero-size divIcon, so an
   inline span would collapse to nothing at all. */
.rcstop{position:absolute;left:0;top:0;display:block;border-radius:50%;
  background:#DA251D;border:1.5px solid #fff;box-sizing:border-box;
  box-shadow:0 0 0 .5px rgba(0,0,0,.35);cursor:default;}
.rcstop-sub{width:10px;height:10px;margin:-5px 0 0 -5px;}
.rcstop-lrt{width:8px;height:8px;margin:-4px 0 0 -4px;}
.leaflet-tooltip.tstop-tip{font:600 var(--fs-micro)/1.2 var(--font);
  padding:3px 7px;border-radius:6px;}
.tstop-tip b{display:block;font-weight:700;}
.tstop-tip i{font-style:normal;opacity:.7;font-weight:500;}

/* ---- Renters' resources -------------------------------------------------
   Cards rather than a list of links, because each entry needs a sentence
   saying what the thing DOES before it says who runs it: somebody reading
   this page is usually in trouble and reading fast. */
.rs-group{margin:0 0 var(--sp-sec);}
.rs-h{margin:0 0 12px;font-size:var(--fs-h2);font-weight:700;letter-spacing:-.018em;}
.rs-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));}
.rs-card{display:block;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:16px 18px;text-decoration:none;color:inherit;
  transition:border-color .15s,box-shadow .15s;}
.rs-card:hover{border-color:var(--sect);box-shadow:var(--sh1);}
.rs-n{font-size:var(--fs-h3);font-weight:700;letter-spacing:-.015em;color:var(--ink);
  display:flex;align-items:center;gap:5px;}
.rs-n svg{width:12px;height:12px;flex:none;color:var(--ink-3);}
.rs-card p{margin:7px 0 0;font-size:var(--fs-sm);line-height:1.55;color:var(--ink-2);}
.rs-foot{font-size:var(--fs-sm);line-height:1.6;color:var(--ink-3);max-width:70ch;}

.rc-acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px;}
.act-btn{display:inline-flex;align-items:center;gap:7px;
  font-family:var(--font);font-size:var(--fs-sm);font-weight:600;
  color:var(--ink-2);background:var(--panel);border:1px solid var(--line-2);
  border-radius:9px;padding:8px 13px;cursor:pointer;text-decoration:none;
  transition:border-color .15s,color .15s,background .15s;}
.act-btn svg{width:16px;height:16px;flex:none;color:var(--ink-3);
  transition:color .15s;}
.act-btn:hover{border-color:var(--accent);color:var(--accent);
  background:var(--panel-2);}
.act-btn:hover svg{color:var(--accent);}
.act-btn:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(15,59,67,.22);}
.act-btn.copied{border-color:var(--a);color:var(--a);}
.act-btn.copied svg{color:var(--a);}
.rc-mgmt{font-size:var(--fs-sm);color:var(--ink-3);margin-top:12px;}
.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:var(--fs-body);font-weight:600;color:var(--ink-2);margin-top:9px;}
.rc-score .y{font-size:var(--fs-xs);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:var(--fs-h3);font-weight:700;letter-spacing:-.015em;}
.card > h3 + .card-sub{margin:0 0 16px;font-size:var(--fs-sm);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:var(--fs-num-sm);font-weight:700;letter-spacing:-.025em;line-height:var(--lh-tight);}
.fact span{font-size:var(--fs-xs);color:var(--ink-3);}
.fact.na b{color:var(--ink-3);font-weight:600;font-size:var(--fs-body);}

.amen{display:flex;flex-wrap:wrap;gap:7px;}
.am{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-sm);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;}

/* What the City marked down, under the RentSafeTO score. Deliberately
   quiet: these are the things worth ASKING about, not a verdict, and a
   wall of red would read as one. A significant violation carries a filled
   dot and a minor one a hollow dot, so the two are told apart by shape as
   well as by colour. */
.rsf{margin-top:16px;padding-top:15px;border-top:1px solid var(--line);}
.rsf-h{font-size:var(--fs-sm);font-weight:650;margin:0 0 4px;}
.rsf-sub{font-size:var(--fs-xs);color:var(--ink-3);line-height:var(--lh-ui);margin:0 0 11px;}
.rsf-list{display:flex;flex-wrap:wrap;gap:7px;}
.rsf-i{display:inline-flex;align-items:center;gap:7px;font-size:var(--fs-sm);
  padding:6px 11px;border-radius:8px;background:var(--panel-2);color:var(--ink-2);}
.rsf-i::before{content:"";width:7px;height:7px;border-radius:50%;flex:none;
  border:1.5px solid #b8860b;}
.rsf-i.sig::before{background:#c0392b;border-color:#c0392b;}
.rsf-k{display:flex;gap:16px;flex-wrap:wrap;margin-top:11px;
  font-size:var(--fs-xs);color:var(--ink-3);}
.rsf-k span{display:inline-flex;align-items:center;gap:6px;}
.rsf-k i{width:7px;height:7px;border-radius:50%;border:1.5px solid #b8860b;font-style:normal;}
.rsf-k i.sig{background:#c0392b;border-color:#c0392b;}
.rsf-more{display:inline-block;margin-top:13px;font-size:var(--fs-sm);font-weight:600;}
.rsf-clean{font-size:var(--fs-sm);color:var(--ink-2);margin:0;}

.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:var(--fs-ui);}
.tr-n{flex:1;min-width:0;font-size:var(--fs-sm);font-weight:600;line-height:1.3;}
.tr-sub{font-weight:400;color:var(--ink-3);font-size:var(--fs-xs);
  line-height:var(--lh-ui);margin-top:3px;}
/* The manager's mark, where the City's score tile used to be. A column of
   green and amber tiles down the side of a list of nearby buildings turned
   it into a league table; the logo answers "who runs this one" instead, and
   the score moved into the line below where it is read as a fact rather
   than as a ranking. */
.tr-mark{flex:none;width:34px;height:34px;border-radius:9px;display:grid;
  place-items:center;color:#fff;font-weight:700;font-size:var(--fs-ui);
  letter-spacing:-.02em;overflow:hidden;}
.tr-mark.has-logo{background:#fff;border:1px solid var(--line);}
.tr-logo{width:100%;height:100%;object-fit:contain;padding:3px;display:block;}
.tr-logo.on-dark{background:#101418;}
/* The band survives as a dot, because "84" on its own does not say whether
   84 is good. */
.tr-sc{white-space:nowrap;}
.tr-dot{display:inline-block;width:7px;height:7px;border-radius:50%;
  margin-right:5px;vertical-align:baseline;}
.tr-mid{opacity:.55;}
.tr-d{font-size:var(--fs-sm);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:var(--fs-sm);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:var(--fs-ui);}
.gr-agg{font-size:var(--fs-sm);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:var(--fs-sm);font-weight:600;}
.gr-tm{font-size:var(--fs-xs);color:var(--ink-3);margin-left:auto;}
.gr-tx{font-size:var(--fs-sm);line-height:1.55;color:var(--ink-2);}
.gr-attr{font-size:var(--fs-micro);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:var(--fs-body);}
.side-cta p{margin:0 0 15px;font-size:var(--fs-sm);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:var(--fs-sm);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:var(--fs-sm);font-family:var(--font);background:var(--panel);color:var(--ink);outline:none;}
.fbar .count{margin-left:auto;font-size:var(--fs-sm);color:var(--ink-3);}

/* ===== Ads =============================================================== */
.ad{margin:34px 0;}
.ad-lbl{font-size:var(--fs-micro);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:var(--fs-xs);}
.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:var(--fs-h3);font-weight:700;letter-spacing:-.02em;margin-bottom:10px;}
.ftr-brand span{color:var(--ink-3);}
.ftr-col p{margin:0;font-size:var(--fs-sm);line-height:1.65;color:var(--ink-3);max-width:44ch;}
.ftr-col h4{margin:0 0 11px;font-size:var(--fs-eyebrow);letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700;}
.ftr-col a{display:block;text-decoration:none;font-size:var(--fs-sm);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:var(--fs-xs);
  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:var(--fs-h3);color:var(--ink-2);margin-bottom:6px;}
.note{background:#fff8e6;border:1px solid #f0dca8;border-radius:11px;padding:13px 15px;
  font-size:var(--fs-sm);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:var(--fs-xs);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:var(--fs-sm);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:var(--fs-body);font-weight:700;letter-spacing:-.015em;}
.hmap-read span{display:block;font-size:var(--fs-sm);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:var(--fs-xs);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:var(--fs-xs);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:var(--fs-sm);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:var(--fs-sm);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hl-n{font-size:var(--fs-xs);color:var(--ink-3);font-variant-numeric:tabular-nums;}
.hl-none{padding:18px;text-align:center;font-size:var(--fs-sm);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:var(--fs-sm);}
.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:var(--fs-xs);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:var(--fs-sm);font-weight:700;
  font-variant-numeric:tabular-nums;}

.pm-pop{font-family:var(--font);min-width:190px;}
.pm-pt{font-size:var(--fs-ui);font-weight:700;letter-spacing:-.015em;line-height:1.25;}
.pm-ps{font-size:var(--fs-xs);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:var(--fs-xs);color:var(--ink-2);}
.pm-pa{display:inline-block;margin-top:8px;font-size:var(--fs-sm);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;}
/* No size override: --h-page already clamps between 30 and 40px and lands
   on 34 at this layout's width, so the two rules were saying the same thing
   in two places and only one of them would be remembered next time. */
.sect-hd-map h2{line-height:var(--lh-tight);}
.sect-hd-map > div:first-child{padding-top:2px;}

.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:var(--fs-sm);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:var(--fs-micro);-webkit-text-stroke:2px rgba(255,255,255,.92);}
.km-lbl.km-here span{font-size:var(--fs-xs);color:#0b1f14;}
.km-lbl.km-near span{color:#394149;font-weight:600;}
.keymap .leaflet-control-attribution{font-size:var(--fs-micro);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:var(--fs-micro);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:var(--fs-micro);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:var(--fs-sm);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:var(--fs-h3);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:var(--fs-ui);font-weight:700;letter-spacing:-.015em;line-height:1.25;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mc-s{font-size:var(--fs-xs);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:var(--fs-xs);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:var(--fs-ui);}
.claim-b{flex:1;min-width:0;}
.claim-b h3{margin:2px 0 4px;font-size:var(--fs-h3);font-weight:700;letter-spacing:-.02em;}
.claim-sub{margin:0 0 12px;font-size:var(--fs-sm);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:var(--fs-sm);font-weight:700;}
.claim-hit-s{font-size:var(--fs-xs);color:var(--ink-3);}
.claim-none{font-size:var(--fs-sm);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:var(--fs-body);font-weight:700;letter-spacing:-.015em;}
.claim-card-t span{display:block;font-size:var(--fs-sm);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:var(--fs-sm);
  border-bottom:1px dashed var(--line);padding-bottom:5px;}
.claim-rows span{color:var(--ink-3);}
.claim-band{font-size:var(--fs-micro);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:var(--fs-sm);
  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:var(--fs-ui);
  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:var(--fs-xs);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:var(--fs-xs);
  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:var(--fs-ui);font-weight:700;margin-bottom:5px;}
.cn span{font-size:var(--fs-sm);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. */
/* The card is tinted and a little larger than its neighbours because it now
   carries what "Getting around" used to say as well: four routed walks, the
   ranking, and the two bike figures. It is the one card on the page that is
   entirely our own work, so it is allowed to look like it. The tint is the
   section's own amber, at the lightest step, so it reads as emphasis rather
   than as a warning. */
.wk-card{background:linear-gradient(180deg,var(--sect-tint) 0%,var(--panel) 78%);
  border:1px solid #efdfb4;padding:20px 22px 18px;}
.wk-card h3{font-size:var(--fs-h3);}
.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:var(--fs-num-xl);font-weight:700;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;}
.wk-x b{display:block;font-size:var(--fs-ui);font-weight:700;letter-spacing:-.015em;}
.wk-x span{display:block;font-size:var(--fs-sm);color:var(--ink-3);margin-top:3px;}
.wk-rows{display:grid;gap:10px 20px;grid-template-columns:repeat(auto-fit,minmax(228px,1fr));
  border-top:1px solid #ecdcb2;padding-top:14px;}
/* align-items:center, not baseline: the icon is a box and baseline-aligning
   a box against text drops it half a line. */
.wk-r{display:flex;align-items:center;gap:9px;font-size:var(--fs-sm);color:var(--ink-2);}
/* nowrap: "19 min" was breaking across two lines inside a tight grid column
   and dragging the row's icon out of line with its label. */
.wk-r b{font-size:var(--fs-body);font-weight:700;color:var(--ink);min-width:52px;
  white-space:nowrap;font-variant-numeric:tabular-nums;}
.wk-t{min-width:0;}
.wk-i{flex:none;display:inline-flex;width:17px;height:17px;color:var(--sect-ink);}
.wk-i svg{width:17px;height:17px;}
.wk-bike{display:flex;align-items:center;gap:9px;margin-top:14px;
  border-top:1px solid #ecdcb2;padding-top:12px;
  font-size:var(--fs-sm);line-height:1.45;color:var(--ink-3);}
.wk-none{font-size:var(--fs-sm);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:var(--fs-xs);font-weight:600;color:var(--ink-3);margin-top:3px;}
.rc-sibs{font-size:var(--fs-sm);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:var(--fs-micro);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:var(--fs-micro);font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--accent);margin-bottom:5px;}
.tp-house-t{display:block;font-size:var(--fs-h3);font-weight:700;letter-spacing:-.02em;
  color:var(--ink);}
.tp-house-s{display:block;font-size:var(--fs-sm);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:var(--fs-ui);font-weight:700;color:var(--ink);}
.tp-consent p{margin:0 0 12px;font-size:var(--fs-sm);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:var(--fs-sm);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:var(--fs-ui);max-width:62ch;}
.ml-sect{margin:0 0 34px;}
.ml-sect h2{font-size:var(--fs-eyebrow);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:var(--fs-xs);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:var(--fs-lede);font-weight:700;letter-spacing:-.02em;margin-bottom:8px;}
.ml-empty p{color:var(--ink-2);font-size:var(--fs-ui);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:var(--fs-ui);flex:1 1 auto;min-width:0;}
.ml-plan-s{font-size:var(--fs-sm);color:var(--ink-3);flex:0 1 auto;}
.ml-plan-go{font-size:var(--fs-sm);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:var(--fs-ui);max-width:62ch;margin:0 0 14px;}
.ml-foot b{color:var(--ink);}
.ml-note{font-size:var(--fs-sm);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:var(--fs-sm);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:var(--fs-xs);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:var(--fs-sm);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:var(--fs-ui);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:var(--fs-ui);font-weight:600;letter-spacing:-.012em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mg-t span{display:block;font-size:var(--fs-sm);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:var(--fs-sm);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;} }

/* ===== Buildings added by hand ===========================================
   Eight buildings are here that the City has not registered (see
   data/manual_pbr.js). They used to carry a whole explanatory panel, and
   Soham was right that it made them read as a different kind of thing. They
   look like every other building now; the only difference is this tag.
   ========================================================================= */
.pill-added{background:#eef2ff;color:#3730a3;border:1px solid #c7d2fe;}
.tag-added{display:inline-block;vertical-align:middle;margin-left:10px;
  background:#eef2ff;color:#3730a3;border:1px solid #c7d2fe;border-radius:999px;
  padding:4px 11px;font-size:var(--fs-xs);font-weight:600;letter-spacing:0;
  white-space:nowrap;}
@media (max-width:560px){
  .tag-added{display:block;margin:8px 0 0;width:max-content;}
}

/* ===========================================================================
   Standalone building pages (rentals/<address>/), appended to app.css by
   tools/build_building_pages.py. Everything else on those pages is app.css.

   The card headings are <h2> there, not the app's <h3>, so the page has a
   real outline under its <h1> — the app never needed one because nothing
   reads it without running it. Same look, different element.
   ========================================================================= */
.bp .card > h2.h3{margin:0 0 4px;font-size:var(--fs-h3);font-weight:700;letter-spacing:-.015em;}
.bp .card > h2.h3 + .card-sub{margin:0 0 16px;font-size:var(--fs-sm);color:var(--ink-3);line-height:1.5;}
.bp .side-cta h2.h4{margin:0 0 7px;font-size:var(--fs-body);}
/* The opening paragraph, at lede size — the same step /plan/ sets its own
   ledes at. It is the first thing read after the address and it carries the
   storeys, the year, the manager and the neighbourhood, so it earns the
   size; max-width keeps the measure at about 68 characters, which is where
   a line stops being comfortable to track back from. */
.bp-lede{margin:0 0 20px;font-size:var(--fs-lede);line-height:var(--lh-body);
  color:var(--ink-2);max-width:68ch;}
.bp-band{display:flex;gap:13px;align-items:center;margin-top:4px;}
.bp-band-l{font-weight:600;font-size:var(--fs-ui);}
.bp-band-t{font-size:var(--fs-sm);color:var(--ink-3);}
.bp .tr-sub{font-weight:400;color:var(--ink-3);font-size:var(--fs-xs);}
.bp a.tr-row{text-decoration:none;color:inherit;}
.bp .card .sect-more{display:block;margin-top:12px;}
/* No menu drawer on these pages (it needs script), so on a phone the bar
   keeps the brand and the one link that matters rather than going empty. */
@media (max-width:980px){ .bp .mapsw{display:inline-grid;margin-left:auto;} }
.bp-crumbs{font-size:var(--fs-sm);color:var(--ink-3);margin:0 0 14px;line-height:1.6;}
.bp-crumbs a{color:var(--ink-2);text-decoration:none;font-weight:600;}
.bp-crumbs a:hover{color:var(--ink);text-decoration:underline;}
.bp-about-h{margin:0 0 6px;font-size:var(--fs-eyebrow);font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3);}
/* The questions: a plain list that opens on tap. <details> needs no script,
   and Google reads the answers whether they are open or closed. */
.bp-qa{border-top:1px solid var(--line);}
.bp-qa:first-of-type{border-top:0;}
.bp-qa summary{cursor:pointer;list-style:none;padding:11px 0;}
.bp-qa summary::-webkit-details-marker{display:none;}
.bp-qa summary h3{display:inline;margin:0;font-size:var(--fs-sm);font-weight:600;line-height:1.4;}
.bp-qa summary:hover h3{text-decoration:underline;}
.bp-qa p{margin:0 0 12px;font-size:var(--fs-sm);line-height:1.6;color:var(--ink-2);}
.bp .tr-row .tr-d{flex:none;}
/* The directory */
.bp-lede-top{margin:10px 0 6px;}
.bp-sub{margin:0;font-size:var(--fs-sm);color:var(--ink-3);}
.bp-sub a{color:var(--accent);font-weight:600;}
.bp-toc{display:flex;flex-wrap:wrap;gap:4px 14px;padding:24px 0 8px;font-size:var(--fs-sm);}
.bp-toc a{color:var(--ink-2);text-decoration:none;}
.bp-toc a:hover{color:var(--ink);text-decoration:underline;}
.bp-toc span,.bp-hood h2 span{color:var(--ink-3);font-weight:400;}
.bp-hood{padding:22px 0 4px;border-top:1px solid var(--line);margin-top:18px;scroll-margin-top:70px;}
.bp-hood h2{margin:0 0 10px;font-size:var(--fs-lede);font-weight:700;letter-spacing:-.015em;}
.bp-hood ul{list-style:none;margin:0;padding:0;columns:3 240px;column-gap:28px;}
.bp-hood li{font-size:var(--fs-sm);line-height:1.5;padding:2px 0;break-inside:avoid;}
.bp-hood li a{color:var(--ink);text-decoration:none;font-weight:500;}
.bp-hood li a:hover{text-decoration:underline;}
.bp-hood li span{color:var(--ink-3);font-size:var(--fs-xs);}

/* The manager's mark, matched to the app's building page. */
.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:#eef1f4;}

/* Report a correction — same quiet treatment as in the app. */
.rep{display:inline-flex;align-items:center;gap:6px;margin-top:12px;
  font-size:var(--fs-xs);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;}

/* The section switcher and the map-mode switch are NOT redefined here.
   They live in shared/chrome.css, which rentals.css now loads ahead of this
   file, and the copies that used to sit at this point had already drifted:
   .bsw-sub was 12px/.04em here against 11px/.06em there, and .bsw-t had lost
   its white-space:nowrap. Because this file is concatenated LAST, those
   stale copies were WINNING on every static page — so the header that batch
   1 made identical to the app's was quietly diverging again from the only
   place it is supposed to be defined. One header, one definition. */

/* White line-art marks need a dark plate — see BRAND_DARK in brands.js. */
.rc-mgmt-logo.on-dark{background:#101418;padding:2px;box-sizing:border-box;}

/* ===== Buildings added by hand ===========================================
   The eight in data/manual_pbr.js look like every other building; the only
   difference is this tag. Mirrors .tag-added in rent/app.css.
   ========================================================================= */
.tag-added{display:inline-block;vertical-align:middle;margin-left:10px;
  background:#eef2ff;color:#3730a3;border:1px solid #c7d2fe;border-radius:999px;
  padding:4px 11px;font-size:var(--fs-xs);font-weight:600;letter-spacing:0;
  white-space:nowrap;}
@media (max-width:560px){
  .tag-added{display:block;margin:8px 0 0;width:max-content;}
}

/* What the City marked down, under the RentSafeTO score. Deliberately
   quiet: these are the things worth ASKING about, not a verdict, and a
   wall of red would read as one. A significant violation carries a filled
   dot and a minor one a hollow dot, so the two are told apart by shape as
   well as by colour. Keep in step with .rsf in rent/app.css. */
.rsf{margin-top:16px;padding-top:15px;border-top:1px solid var(--line);}
.rsf-h{font-size:var(--fs-sm);font-weight:650;margin:0 0 4px;}
.rsf-sub{font-size:var(--fs-xs);color:var(--ink-3);line-height:var(--lh-ui);margin:0 0 11px;}
.rsf-list{display:flex;flex-wrap:wrap;gap:7px;}
.rsf-i{display:inline-flex;align-items:center;gap:7px;font-size:var(--fs-sm);
  padding:6px 11px;border-radius:8px;background:var(--panel-2);color:var(--ink-2);}
.rsf-i::before{content:"";width:7px;height:7px;border-radius:50%;flex:none;
  border:1.5px solid #b8860b;}
.rsf-i.sig::before{background:#c0392b;border-color:#c0392b;}
.rsf-k{display:flex;gap:16px;flex-wrap:wrap;margin-top:11px;
  font-size:var(--fs-xs);color:var(--ink-3);}
.rsf-k span{display:inline-flex;align-items:center;gap:6px;}
.rsf-k i{width:7px;height:7px;border-radius:50%;border:1.5px solid #b8860b;font-style:normal;}
.rsf-k i.sig{background:#c0392b;border-color:#c0392b;}
.rsf-more{display:inline-block;margin-top:13px;font-size:var(--fs-sm);font-weight:600;}
.rsf-clean{font-size:var(--fs-sm);color:var(--ink-2);margin:0;}

/* ===========================================================================
   rentals-near/ and rentals-in/ — the search-intent landing pages
   ---------------------------------------------------------------------------
   Appended after building_page.css, so these pages inherit the whole rental
   building page: the same hero, the same cards, the same tr-row. Only the
   directory grid is new.
   ========================================================================= */
.sp-sect{margin:0 0 var(--sp-sec);}
.sp-sect h2{margin:0 0 14px;font-size:var(--fs-h2);font-weight:700;letter-spacing:-.018em;}
.sp-grid{display:grid;gap:2px;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));}
.sp-a{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 12px;border-radius:9px;text-decoration:none;color:var(--ink-2);
  font-size:var(--fs-sm);font-weight:600;}
.sp-a:hover{background:var(--sect-tint);color:var(--sect-ink);}
.sp-a span{flex:none;font-size:var(--fs-xs);font-weight:700;color:var(--ink-3);
  background:var(--panel-2);border-radius:999px;padding:2px 8px;}
/* The lede on a landing page sits directly in the hero rather than in a card. */
.sp .rc-hero .bp-lede{margin-top:14px;max-width:70ch;}
