/* ===========================================================================
   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;
  }
}
/* ===========================================================================
   /plan/ — Planning, without the map
   ---------------------------------------------------------------------------
   Same tokens, same type, same spacing as /rent/, so the two sections of the
   site are one site. The header furniture itself is not here at all — it is
   in shared/chrome.css, which this page loads first.

   Where it deliberately differs from /rent/: the unit here is a PROCESS, not
   a thing. A rental building is a fixed object with measurements, which is
   why those cards are compact and dense. An application is a position in a
   sequence that will change, so these cards lead with a sentence and the
   application page is laid out as four questions with the questions as the
   headings. More prose, fewer numbers, wider measure.
   ========================================================================= */
:root{
  --ink:#101418;
  --ink-2:#4a5560;
  --ink-3:#7c8793;
  --line:#e6e9ec;
  --line-2:#d2d7dd;
  --bg:#fbfbfc;
  --panel:#fff;
  --panel-2:#f4f6f8;

  --accent:#0f3b43;
  --accent-ink:#0f3b43;
  /* Planning is the purple half of the site — the same #5b3dc4 the map
     explorer's Applications tab has always used. It was briefly blue here,
     which made this section look like a third thing rather than the other
     half of a pair. shared/chrome.css reads --sect* for the brand's PLANNING
     label and for whatever is selected. */
  --aic:#5b3dc4;
  --sect:#5b3dc4;
  --sect-tint:#ece6fb;
  --sect-ink:#4a2fa8;
  --amber:#c77d03;
  --red:#d64541;

  --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;} }

/* ===== Header layout =====================================================
   The furniture is shared; only the bar that holds it is per-section, and it
   is the same 62px as /rent/ and map mode.
   ========================================================================= */
.hdr{position:sticky;top:0;z-index:600;height:var(--hdr-h);
  display:flex;align-items:center;gap:12px;padding:0 16px;
  background:var(--panel);border-bottom:1px solid var(--line);}
/* .hdr-nav is in shared/chrome.css. */
.hdr-search{position:relative;flex:1 1 auto;max-width:380px;margin-left:auto;margin-right:2px;}
.hdr-search svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);
  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 33px;font:inherit;font-size:var(--fs-sm);background:var(--panel);
  color:var(--ink);outline:none;}
.hdr-search input:focus{border-color:var(--aic);box-shadow:0 0 0 3px rgba(91,61,196,.12);}
.hdr-acct{display:flex;align-items:center;gap:6px;flex:none;}
.ac{position:absolute;top:calc(100% + 6px);left:0;right:0;background:var(--panel);
  border:1px solid var(--line);border-radius:12px;padding:5px;box-shadow:var(--sh2);z-index:700;}
.ac-i{display:block;padding:9px 10px;border-radius:9px;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);}
@media (max-width:860px){ .hdr-nav{display:none;} }

/* ===== Hero ==============================================================
   One question and one input. No filters, no counts as the headline, and no
   map: someone who walked past a notice sign wants to type the address on the
   sign and nothing else.
   ========================================================================= */
.hero{background:var(--panel);border-bottom:1px solid var(--line);
  padding:76px 0 56px;overflow:hidden;}
.hero h1{font-size:clamp(32px,5.2vw,56px);line-height:1.05;letter-spacing:-.035em;
  margin:0 0 16px;font-weight:700;max-width:16ch;}
.hero h1 em{font-style:normal;color:var(--aic);}
.hero-p{font-size:var(--fs-h3);line-height:1.55;color:var(--ink-2);max-width:56ch;margin:0 0 30px;}
.hero-f{display:flex;gap:10px;max-width:620px;}
.hero-f input{flex:1 1 auto;border:1px solid var(--line-2);border-radius:11px;
  padding:14px 16px;font:inherit;font-size:var(--fs-body);background:var(--panel);outline:none;}
.hero-f input:focus{border-color:var(--aic);box-shadow:0 0 0 3px rgba(91,61,196,.12);}
.hero-f button{flex:none;border:0;border-radius:11px;background:var(--accent);
  color:#fff;font-weight:600;font-size:var(--fs-body);padding:14px 26px;cursor:pointer;}
.hero-f button:hover{background:#0b2f36;}
.hero-n{margin:16px 0 0;font-size:var(--fs-sm);color:var(--ink-3);
  font-variant-numeric:tabular-nums;}

/* ===== Page furniture ==================================================== */
.pg{padding:var(--pg-top) 24px 64px;}
.ph{position:relative;margin:0 0 var(--sp-ts);}
.ph-k{font-size:var(--fs-eyebrow);font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--aic);margin-bottom:7px;}
.ph h1{font-size:var(--h-page);line-height:var(--h-page-lh);letter-spacing:var(--h-page-ls);
  margin:0 0 var(--sp-tt);font-weight:700;max-width:22ch;}
.ph-s{font-size:var(--fs-body);line-height:1.6;color:var(--ink-2);max-width:62ch;margin:0;}
.ph-s a{color:var(--accent);}
.sect{margin:0 0 46px;}
/* A section that IS the page needs the gap; one nested inside .pg does not,
   because .pg already carries it. */
#view > .sect{padding-top:var(--pg-top);}
.sect h2{font-size:var(--fs-eyebrow);font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 15px;display:flex;align-items:center;gap:8px;}
.more{display:inline-block;margin-top:16px;font-size:var(--fs-ui);font-weight:600;
  color:var(--accent);text-decoration:none;}
.more:hover{text-decoration:underline;}
.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;}

/* The snapshot warning. Quiet but unmissable, and repeated on every view that
   shows a status rather than stated once on the home page — most people
   arrive at a deep link and never see the home page. */
.snap{font-size:var(--fs-sm);line-height:1.55;color:var(--ink-2);background:#fffaf0;
  border:1px solid #f0dfbd;border-left:3px solid var(--amber);
  border-radius:10px;padding:11px 14px;margin:0 0 20px;max-width:78ch;}

/* ===== The application card ==============================================
   Leads with the address, because that is what was searched for, and carries
   a sentence rather than a row of codes.
   ========================================================================= */
.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));}
.pc{position:relative;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);transition:box-shadow .15s,border-color .15s;}
.pc:hover{box-shadow:var(--sh1);border-color:var(--line-2);}
/* A column that fills the card, so .pc-foot's margin-top:auto can push
   the stage badge to the bottom. As a plain block it could not: the
   badge followed the text, so in a grid row the badges sat at three
   different heights depending on how long each sentence ran. */
.pc-hit{display:flex;flex-direction:column;height:100%;padding:16px 17px;
  text-decoration:none;}
.pc-addr{font-size:var(--fs-h3);font-weight:700;letter-spacing:-.018em;
  line-height:1.25;}
.pc-dist{font-size:var(--fs-sm);color:var(--aic);font-weight:600;margin-top:3px;
  font-variant-numeric:tabular-nums;}
.pc-say{margin:9px 0 13px;font-size:var(--fs-ui);line-height:1.55;color:var(--ink-2);}
.pc-say b{color:var(--ink);font-weight:600;}
.pc-foot{display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  font-size:var(--fs-xs);color:var(--ink-3);}
.pc-when,.pc-who{font-variant-numeric:tabular-nums;}
.pc-who{font-weight:600;color:var(--ink-2);}

/* The stage, as a word rather than a City status string. Four colours,
   spaced so no two read as the same state. */
.stage{display:inline-block;font-size:var(--fs-xs);font-weight:700;letter-spacing:.02em;
  padding:2px 9px;border-radius:20px;}
.st-rev{background:#e8f0fe;color:#1a4fbd;}   /* under review — the live one */
.st-ok {background:#e4f6ec;color:#15713f;}   /* approved */
.st-app{background:#f3ecfd;color:#5b3dc4;}   /* at the tribunal */
.st-cl {background:var(--panel-2);color:var(--ink-3);} /* closed */
.st-un {background:var(--panel-2);color:var(--ink-3);}

.pc-heart{position:absolute;top:10px;right:10px;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;}
.pc-heart svg{width:17px;height:17px;display:block;}
.pc-heart:hover{background:var(--panel-2);color:var(--ink-2);}
.pc-heart:active{transform:scale(.9);}
.pc-heart.on{color:var(--red);}
.pc-heart.on svg path{fill:currentColor;}
.pc-heart:focus-visible{outline:2px solid var(--aic);outline-offset:1px;}

/* ===== One application ===================================================
   Four questions, the headings ARE the questions. Wider measure than the
   rentals pages because the answers are sentences, not figures.
   ========================================================================= */
.app .ph .pc-heart{top:0;right:0;width:40px;height:40px;}
.app .pc-heart svg{width:21px;height:21px;}
.qa{border-top:1px solid var(--line);padding:30px 0 6px;max-width:78ch;}
.qa:first-of-type{border-top:0;padding-top:0;}
.qa h2{font-size:var(--fs-eyebrow);font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 14px;}
.lede{font-size:var(--fs-lede);line-height:1.45;letter-spacing:-.012em;margin:0 0 12px;}
.lede b{font-weight:700;}
.sub{font-size:var(--fs-ui);line-height:1.62;color:var(--ink-2);margin:0 0 12px;}
.sub a{color:var(--accent);}
/* Where the City's record is silent. Marked as a gap rather than left out —
   "how many homes" is the first thing everyone asks and the dataset does not
   carry it, so the page has to say so. */
.gap{font-size:var(--fs-sm);line-height:1.6;color:var(--ink-3);border-left:2px solid var(--line-2);
  padding:2px 0 2px 13px;margin:16px 0 0;}
.file{font-size:var(--fs-sm);color:var(--ink-3);margin-top:16px;}
.file code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--fs-xs);
  background:var(--panel-2);padding:2px 6px;border-radius:5px;}

/* The stage track. The single most useful thing on the page for someone whose
   question is "is this actually happening" — a position in a sequence reads
   in a way that "NOAC Issued" never will. */
.track{display:flex;align-items:center;gap:0;margin:0 0 20px;flex-wrap:wrap;}
.tr-step{display:flex;align-items:center;gap:7px;font-size:var(--fs-sm);font-weight:600;
  color:var(--ink-3);padding:6px 14px 6px 0;}
.tr-step + .tr-step{border-left:1px solid var(--line);padding-left:14px;}
.tr-dot{width:9px;height:9px;border-radius:50%;background:var(--line-2);flex:none;}
.tr-step.on{color:var(--ink);}
.tr-step.on .tr-dot{background:var(--aic);box-shadow:0 0 0 3px rgba(91,61,196,.18);}

.acts{display:flex;flex-wrap:wrap;gap:10px;margin:18px 0 4px;}
.btn{display:inline-block;background:var(--accent);color:#fff;text-decoration:none;
  font-size:var(--fs-ui);font-weight:600;padding:11px 18px;border-radius:10px;}
.btn:hover{background:#0b2f36;}
.btn.ghost{background:var(--panel);color:var(--ink);border:1px solid var(--line-2);}
.btn.ghost:hover{background:var(--panel-2);}

/* ===== Ward / applicant index ============================================ */
.wards{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));}
.wd{display:flex;align-items:center;gap:14px;background:var(--panel);
  border:1px solid var(--line);border-radius:12px;padding:13px 15px;text-decoration:none;}
.wd:hover{border-color:var(--line-2);box-shadow:var(--sh1);}
.wd-n{flex:none;min-width:36px;height:36px;padding:0 8px;border-radius:9px;
  background:var(--panel-2);color:var(--ink-2);display:grid;place-items:center;
  font-size:var(--fs-ui);font-weight:700;font-variant-numeric:tabular-nums;}
.wd-t{min-width:0;}
.wd-t b{display:block;font-size:var(--fs-ui);font-weight:600;letter-spacing:-.012em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.wd-t span{display:block;font-size:var(--fs-sm);color:var(--ink-3);
  font-variant-numeric:tabular-nums;}

/* ===== The explainer =====================================================
   Prose, at a reading measure. It is the most durable page in the section:
   it does not go stale when the data refreshes.
   ========================================================================= */
.prose{max-width:none;}
.prose h2{font-size:var(--fs-h2);letter-spacing:-.022em;font-weight:700;color:var(--ink);
  text-transform:none;margin:44px 0 14px;max-width:72ch;}
.prose p{font-size:var(--fs-body);line-height:1.68;color:var(--ink-2);max-width:72ch;margin:0 0 14px;}
.steps{max-width:72ch;padding-left:22px;margin:0 0 18px;}
.steps li{font-size:var(--fs-body);line-height:1.68;color:var(--ink-2);margin-bottom:13px;}
.steps li b{color:var(--ink);font-weight:600;}
.defs{max-width:72ch;margin:0 0 18px;}
.defs dt{font-size:var(--fs-body);font-weight:700;color:var(--ink);margin-top:16px;}
.defs dd{margin:4px 0 0;font-size:var(--fs-body);line-height:1.62;color:var(--ink-2);}

/* ===== Cards, empty states, My List ====================================== */
.cards3{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));}
.c3{display:block;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:19px 20px;text-decoration:none;}
.c3:hover{border-color:var(--line-2);box-shadow:var(--sh1);}
.c3 h3{margin:0 0 7px;font-size:var(--fs-h3);font-weight:700;letter-spacing:-.018em;}
.c3 p{margin:0;font-size:var(--fs-sm);line-height:1.55;color:var(--ink-2);}
.empty{border:1px dashed var(--line-2);border-radius:var(--r);
  padding:44px 28px;text-align:center;background:var(--panel);}
.empty h1{font-size:var(--h-page);letter-spacing:var(--h-page-ls);
  line-height:var(--h-page-lh);margin:0 0 10px;}
.empty p{color:var(--ink-2);font-size:var(--fs-ui);max-width:52ch;margin:0 auto 20px;line-height:1.6;}
.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);}
.ml-plan-go{font-size:var(--fs-sm);font-weight:600;color:var(--accent);text-decoration:none;flex:none;}
.ml-foot{border-top:1px solid var(--line);padding-top:22px;margin-top:30px;}
.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);}

/* ===== Footer — the same one /rent/ draws ================================ */
.ftr{border-top:1px solid var(--line);background:var(--panel);margin-top:40px;}
.ftr-in{max-width:1180px;margin:0 auto;padding:46px 24px 34px;display:grid;gap:34px;
  grid-template-columns:1.6fr 1fr 1fr 1fr;}
.ftr-brand{font-size:var(--fs-lede);font-weight:700;letter-spacing:-.025em;margin-bottom:11px;}
.ftr-brand span{color:var(--ink-3);}
.ftr-col p{font-size:var(--fs-sm);line-height:1.62;color:var(--ink-3);margin:0;max-width:38ch;}
.ftr-col h4{font-size:var(--fs-eyebrow);font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 11px;}
.ftr-col a{display:block;font-size:var(--fs-sm);color:var(--ink-2);text-decoration:none;
  padding:4px 0;}
.ftr-col a:hover{color:var(--ink);text-decoration:underline;}
.ftr-legal{max-width:1180px;margin:0 auto;padding:18px 24px 34px;
  border-top:1px solid var(--line);font-size:var(--fs-xs);line-height:1.6;color:var(--ink-3);}
@media (max-width:860px){ .ftr-in{grid-template-columns:1fr 1fr;} }
@media (max-width:560px){ .ftr-in{grid-template-columns:1fr;gap:26px;} }

@media (max-width:640px){
  .hero{padding:52px 0 44px;}
  .hero-f{flex-direction:column;}
  .pg{padding:28px 16px 48px;}
  .grid{grid-template-columns:1fr;}
}

/* ===========================================================================
   The hero drawing, the tinted band, featured cards, the ward map and the
   research filters — added 16 Oct 2026.
   ========================================================================= */

/* ===== Hero, now two columns ============================================= */
/* Two columns, the drawing in the half of the hero that was empty — the same
   proportions /rent/ uses, so the two heroes are one design. 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. */
.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;}
/* DRAWN BIGGER THAN ITS COLUMN, AND CROPPED — the same treatment as /rent/'s
   hero drawing, down to the numbers, so the two sections read as one design.
   At 100% it is a diagram politely occupying half the hero; at this scale it
   is a drawing the page is a window onto, and the east end runs off the right
   margin on purpose.

   THE FADE HAPPENS INSIDE THE BOX. The radii are smaller than the element and
   the last stop is at 88%, so the lines are gone before they reach any edge —
   a mask whose transparent stop lands outside the box is opaque everywhere
   you can see it, and the drawing still ends at a hard cut. */
.wsk{position:relative;min-width:0;}
.wsk-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%);}
.wsk-art svg{position:absolute;top:50%;left:50%;transform:translate(-50%,-52%);
  display:block;width:124%;height:auto;}
@media (max-width:1200px){ .wsk-art{height:360px;width:calc(100% + 120px);margin-left:-30px;} }
/* The mesh is texture, not a layer you point at: same stroke as /rent/'s
   outlines, no pointer events, so the ward above it always takes the hover. */
.wsk-mesh path{fill:none;stroke:#d4d9e0;stroke-width:0.7;stroke-linejoin:round;
  pointer-events:none;}
/* The wards sit over it with no fill of their own, so what you see at rest is
   the neighbourhood mesh — identical to /rent/ — and what lights up under the
   cursor is a whole ward. */
.wsk-g path{fill:rgba(0,0,0,0);stroke:transparent;stroke-width:0.7;
  stroke-linejoin:round;cursor:pointer;transition:fill .12s ease,stroke .12s ease;}
/* The one difference from /rent/: the hatch is purple, not black. */
.wsk-g path:hover{fill:url(#wskHatch);stroke:#5b3dc4;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. */
.wsk-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;}
.wsk-cap b{display:block;font-size:var(--fs-num-lg);font-weight:700;color:var(--ink);
  letter-spacing:-.03em;line-height:1.1;}
.wsk-cap span{display:block;}
@media (max-width:1000px){ .hero-in{grid-template-columns:1fr;} .wsk{display:none;} }

/* ===== A tinted band =====================================================
   The same device /rent/ uses between home-page sections, in this section's
   purple rather than its amber. It fades to the page background rather than
   ending on a line, so the band reads as a wash and not as a coloured box.
   The cards on top stay white and lift off it. */
.sect-wash{background:linear-gradient(180deg,#f4f1fc 0%,#faf8fe 58%,var(--bg) 100%);
  border-top:1px solid #e7e0f8;border-bottom:1px solid var(--line);}
/* A tinted band needs its own inset, or its top border sits on the title.
   12px against a 40px heading was the tightest thing on the site. */
.pg-tight{padding-top:var(--sp-band);padding-bottom:calc(var(--sp-band) - 12px);}
.sect-top{border-top:1px solid #e7e0f8;padding-top:var(--sp-band);}

/* ===== Section headings, borrowed from /rent/ ============================ */
.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);
  text-transform:none;color:var(--ink);}
.sect-hd p{margin:var(--sp-tt) 0 0;font-size:var(--fs-ui);line-height:1.6;
  color:var(--ink-2);max-width:68ch;}
.sect-hd p a{color:var(--accent);}
.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;}

/* ===== Featured cards ====================================================
   Taller than an ordinary card and carrying two things the others do not: the
   project's working name where there is one, and the size that put it on the
   list — the number has to be visible or "featured" is a claim with no
   evidence behind it. */
.grid-feat{grid-template-columns:repeat(auto-fill,minmax(320px,1fr));}
.pc-feat{border-color:var(--line-2);}
.pc-feat .pc-hit{padding:18px 19px;}
.pc-proj{font-size:var(--fs-eyebrow);font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--sect-ink);margin-bottom:5px;line-height:1.3;}
/* The reserved, empty one. It holds the row so the addresses and type chips
   line up across a row of cards; min-height rather than a non-breaking
   space, so it contributes no text to a screen reader or to a copy-paste. */
.pc-proj-none{min-height:calc(var(--fs-eyebrow) * 1.3);}
.pc-size{font-size:var(--fs-sm);font-weight:600;color:var(--ink-2);margin-top:4px;
  font-variant-numeric:tabular-nums;}

/* ===== The ward map ======================================================
   Lifted from /rent/'s neighbourhoods page so the two halves behave the same.
   ========================================================================= */
.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:10px 10px 4px;}
.hmap-canvas{position:relative;z-index:0;height:540px;border-radius:11px;overflow:hidden;}
.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;}
.hmap-key{display:flex;flex-wrap:wrap;gap:4px 14px;padding:8px 4px 4px;
  font-size:var(--fs-xs);color:var(--ink-3);}
.wk-i{display:inline-flex;align-items:center;gap:5px;}
.wk-sw{width:13px;height:9px;border-radius:2px;display:inline-block;}
.hmap-list{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);}
.hl-srch{position:relative;padding:10px;border-bottom:1px solid var(--line);}
.hl-srch svg{position:absolute;left:21px;top:50%;transform:translateY(-50%);
  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:inherit;font-size:var(--fs-sm);outline:none;background:var(--panel);}
.hl-srch input:focus{border-color:var(--sect);box-shadow:0 0 0 3px rgba(91,61,196,.12);}
.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;
  width:100%;border:0;background:transparent;font-family:var(--font);
  cursor:pointer;text-align:left;}
.hl-r[hidden]{display:none;}
.hl-r:hover,.hl-r.on{background:var(--sect-tint);}
.hl-r.sel{background:var(--sect);color:#fff;}
.hl-r.sel .hl-n{color:rgba(255,255,255,.72);}
.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);}
.hres{margin-top:36px;padding:30px 0 10px;border-top:1px solid var(--line);}
.hres[hidden]{display:none;}
.hres-hd{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  margin-bottom:20px;}
.hres-hd h3{margin:0;font-size:var(--h-page);font-weight:800;
  letter-spacing:-.03em;}
.hres-hd p{margin:5px 0 0;max-width:66ch;font-size:var(--fs-sm);line-height:1.55;
  color:var(--ink-2);}
.hres-hd p a{color:var(--accent);}
.hres-x{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:8px 14px;border-radius:9px;cursor:pointer;}
.hres-x:hover{background:var(--panel-2);color:var(--ink);}
.hres-sub{font-size:var(--fs-eyebrow);font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink-3);margin:26px 0 12px;}
@media (max-width:980px){
  .hmap{grid-template-columns:1fr;}
  .hmap-canvas{height:400px;}
  .hl-scroll{max-height:300px;}
}

/* ===== The research filter panel ========================================= */
/* ---- The filter bar -------------------------------------------------------
   One row of dropdowns, matching /rent/'s buildings list. This was six
   stacked rows plus a paragraph of caveats standing above the results. See
   researchPanel() in app.js.
   -------------------------------------------------------------------------- */
.fp{margin-bottom:18px;}
.fp-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.fp-lbl{font-size:var(--fs-micro);font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:9px;display:block;}

.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(340px,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);}
.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(--sect);background:var(--sect-tint);}
.fdd.on > summary span{color:var(--ink);}
.fdd[open] > summary{border-color:var(--sect);box-shadow:0 0 0 3px rgba(91,61,196,.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:12px;box-shadow:var(--sh2);}
.fdd-menu > .fp-sel{width:100%;}
.fdd-am{width:380px;}
.fdd-stack{width:300px;display:flex;flex-direction:column;gap:12px;}
/* The caveats, folded. Open to read them; they are not worth 90px of
   standing text above every search. */
.fp-caveat{margin-top:10px;}
.fp-caveat > summary{list-style:none;cursor:pointer;display:inline-flex;
  align-items:center;gap:6px;font-size:var(--fs-sm);font-weight:600;color:var(--ink-3);}
.fp-caveat > summary::-webkit-details-marker{display:none;}
.fp-caveat > summary::marker{content:"";}
.fp-caveat > summary::before{content:"\24d8";font-size:var(--fs-sm);}
.fp-caveat > summary:hover{color:var(--ink);}
.fp-caveat p{margin:8px 0 0;font-size:var(--fs-sm);line-height:1.6;max-width:84ch;
  color:var(--ink-3);}
.fp-caveat b{color:var(--ink-2);}
.fp-reset{margin-left:auto;border:0;background:transparent;color:var(--ink-3);
  font-family:var(--font);font-size:var(--fs-sm);font-weight:600;cursor:pointer;
  padding:8px 10px;border-radius:999px;transition:color .15s,background .15s;}
.fp-reset:hover{background:var(--panel-2);color:var(--ink);}
.fp-reset[hidden]{display:none;}
@media (max-width:560px){
  .fdd,.fdd > summary{width:100%;max-width:none;}
  .fdd > summary{justify-content:space-between;}
  .fdd-menu,.fdd-am,.fdd-stack{width:100%;}
}
.fp-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;
  max-width:100%;}
.fp-sel:focus{border-color:var(--sect);box-shadow:0 0 0 3px rgba(91,61,196,.12);}
.fp-sort{min-width:220px;}
.fp-note{font-size:var(--fs-xs);color:var(--sect-ink);font-weight:600;}
.fp-clear{margin-left:auto;border:0;background:transparent;color:var(--ink-3);
  font-family:var(--font);font-size:var(--fs-sm);font-weight:600;cursor:pointer;
  padding:6px 2px;text-decoration:underline;}
.fp-clear:hover{color:var(--ink);}
.fp-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));}
.fp-f{display:block;min-width:0;}
.fp-f .fp-sel,.fp-f .fp-addr{width:100%;}
.fp-addr{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;}
.fp-addr:focus{border-color:var(--sect);box-shadow:0 0 0 3px rgba(91,61,196,.12);}
.cbx-grid{display:flex;flex-wrap:wrap;gap:8px 20px;}
/* The native input stays, so it is still a real checkbox for keyboards and
   screen readers, and .box is drawn over it. Same approach as /rent/. */
.cbx{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:var(--fs-sm);
  color:var(--ink-2);}
.cbx input{position:absolute;opacity:0;width:0;height:0;}
.cbx .box{width:18px;height:18px;border:1.5px solid var(--line-2);border-radius:5px;
  display:grid;place-items:center;color:transparent;background:var(--panel);
  transition:background .12s,border-color .12s,color .12s;flex:none;}
.cbx .box svg{width:13px;height:13px;}
.cbx input:checked + .box{background:var(--sect);border-color:var(--sect);color:#fff;}
.cbx input:focus-visible + .box{box-shadow:0 0 0 3px rgba(91,61,196,.22);}
.cbx input:checked ~ span:last-child{color:var(--ink);font-weight:600;}
.fp-foot{color:var(--ink-3);}
.fp-foot p{margin:0;font-size:var(--fs-sm);line-height:1.6;max-width:84ch;}
.fp-foot b{color:var(--ink-2);}
.r-count{font-size:var(--fs-sm);font-weight:600;color:var(--ink-3);margin-bottom:14px;
  font-variant-numeric:tabular-nums;}
.r-more{display:block;margin:22px auto 0;border:1px solid var(--line-2);
  background:var(--panel);color:var(--ink);font-family:var(--font);font-size:var(--fs-ui);
  font-weight:600;padding:11px 22px;border-radius:10px;cursor:pointer;}
.r-more:hover{background:var(--panel-2);}

/* ===== Card head: address, type code, then the date ======================
   The submission date moved up under the address, where it reads as part of
   the heading rather than as one more chip arguing with the stage badge at
   the bottom. The type code sits beside the address because "SPA" is the
   first thing a professional reader looks for. */
/* The heart is absolutely positioned at the top right of the card, so the
   whole head row reserves its width — padding the address alone left the type
   chip sitting underneath it. */
.pc-head{display:flex;align-items:flex-start;gap:9px;padding-right:34px;}
.pc-addr{flex:1 1 auto;min-width:0;}
.pc-code{flex:none;font-size:var(--fs-micro);font-weight:700;letter-spacing:.05em;
  padding:3px 7px;border-radius:6px;background:var(--panel-2);color:var(--ink-2);
  white-space:nowrap;margin-top:2px;}
.pc-feat .pc-code{background:var(--sect-tint);color:var(--sect-ink);}
.pc-meta{display:flex;flex-wrap:wrap;align-items:center;gap:5px;margin-top:4px;
  font-size:var(--fs-sm);color:var(--ink-3);font-variant-numeric:tabular-nums;}
.pc-sep{color:var(--line-2);}
.pc-dist{color:var(--sect);font-weight:600;}
.pc-who{font-weight:600;color:var(--ink-2);}
.pc-foot{margin-top:auto;padding-top:12px;}

/* ===== The file table on an application page =============================
   First on the page and before any prose: a consultant pulling comparables
   reads this and leaves. */
.facts{margin:0 0 4px;padding:0;border:1px solid var(--line);border-radius:var(--r);
  overflow:hidden;background:var(--panel);}
.facts-r{display:grid;grid-template-columns:minmax(140px,30%) 1fr;gap:0;}
.facts-r + .facts-r{border-top:1px solid var(--line);}
.facts dt{padding:10px 14px;font-size:var(--fs-sm);font-weight:600;color:var(--ink-3);
  background:var(--panel-2);margin:0;}
.facts dd{padding:10px 14px;margin:0;font-size:var(--fs-ui);color:var(--ink);
  font-variant-numeric:tabular-nums;}
@media (max-width:560px){ .facts-r{grid-template-columns:1fr;}
  .facts dt{padding-bottom:2px;background:var(--panel);} }
/* The gloss for a reader who needs the term unpacked, set quieter than the
   technical sentence above it so a professional can skip it. */
.sub-plain{color:var(--ink-3);font-size:var(--fs-sm);}
.qa code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--fs-sm);
  background:var(--panel-2);padding:1px 5px;border-radius:4px;}
.qa-wide{max-width:none;}
.defs code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--fs-sm);
  background:var(--panel-2);padding:1px 6px;border-radius:4px;color:var(--ink-2);}
.prose ul.steps{list-style:disc;}

/* ===== The councillor line and the locator map =========================== */
.ward-cllr{margin:12px 0 0;font-size:var(--fs-ui);color:var(--ink-2);}
.ward-cllr-k{font-size:var(--fs-micro);font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--ink-3);margin-right:8px;}
.ward-cllr a{color:var(--accent);font-weight:600;}
.ward-cllr-t{font-size:var(--fs-xs);color:var(--ink-3);}
.hres-hd-map{align-items:flex-start;}
.keymap{flex:none;width:208px;}
.keymap-art{background:var(--panel);border:1px solid var(--line);border-radius:12px;
  padding:10px;}
.keymap svg{width:100%;height:auto;display:block;}
.keymap .km-off{fill:#eef0f2;stroke:#fff;stroke-width:.8;}
.keymap .km-on{fill:var(--sect);stroke:#fff;stroke-width:.9;}
.keymap-cap{margin-top:7px;text-align:center;font-size:var(--fs-xs);}
.keymap-cap a{color:var(--accent);text-decoration:none;font-weight:600;}
.keymap-cap a:hover{text-decoration:underline;}
.wk-note{color:var(--ink-3);}
@media (max-width:760px){ .keymap{display:none;} }

/* ===== The drawer — the same one /rent/ carries ========================== */
.hdr-burger{flex:none;width:36px;height:36px;border:0;background:transparent;
  border-radius:9px;color:var(--ink-2);cursor:pointer;display:grid;place-items:center;}
.hdr-burger:hover{background:var(--panel-2);color:var(--ink);}
.hdr-burger svg{width:21px;height:21px;}
.drawer-scrim{position:fixed;inset:0;z-index:900;background:rgba(16,20,24,.40);
  opacity:0;transition:opacity .24s ease;}
.drawer-scrim.on{opacity:1;}
.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;
  transform:translateX(-100%);transition:transform .24s ease;}
.drawer.on{transform:translateX(0);}
.drawer-hd{display:flex;align-items:center;justify-content:space-between;
  padding:16px 18px;border-bottom:1px solid var(--line);font-weight:700;}
.drawer-x{width:30px;height:30px;border:0;background:var(--panel-2);border-radius:8px;
  color:var(--ink-3);cursor:pointer;font-size:var(--fs-sm);}
.drawer-x:hover{background:var(--line);color:var(--ink);}
.drawer-sect{padding:15px 10px 11px;}
.drawer-sect + .drawer-sect{border-top:1px solid var(--line);}
.drawer-sect h4{margin:0 0 7px;padding:0 10px;font-size:var(--fs-micro);font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);}
.drawer-sect a{display:block;text-decoration:none;font-size:var(--fs-sm);
  color:var(--ink-2);padding:8px 10px;border-radius:9px;}
.drawer-sect a:hover{background:var(--sect-tint);color:var(--sect-ink);}
.drawer-foot{margin:4px 12px 22px;padding:14px;border-radius:12px;
  background:var(--panel-2);font-size:var(--fs-xs);line-height:1.55;color:var(--ink-3);}
body.drawer-open{overflow:hidden;}

/* 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;} }

/* ===== The header actions on an application page ========================= */
/* In the flow, not pinned to the top right. Two buttons fitted in a 220px
   gutter; four do not, and an absolutely positioned row that overflows is
   the kind of thing that only shows up on somebody else's screen. It also
   makes this row the same thing as .rc-acts on a rental building page —
   same position, same order, same glyphs. */
.ph-acts{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:18px;}
.ph-ext{display:inline-flex;align-items:center;gap:7px;text-decoration:none;
  border:1px solid var(--line-2);background:var(--panel);color:var(--ink-2);
  font-size:var(--fs-sm);font-weight:600;padding:9px 13px;border-radius:10px;
  white-space:nowrap;transition:background .15s,color .15s,border-color .15s;}
.ph-ext svg{width:14px;height:14px;flex:none;}
.ph-ext:hover{background:var(--sect-tint);color:var(--sect-ink);border-color:var(--sect);}
.ph-ext:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(242,169,0,.30);}
button.ph-ext{font-family:var(--font);cursor:pointer;}
.ph-ext.copied{border-color:#1e9e5a;color:#1e9e5a;}
.app .ph .pc-heart{position:static;}

/* ===== Thumb rules, as a page ============================================
   Reuses the .facts table from an application page — same two-column label /
   value shape, so a reference table reads the same wherever it appears. */
.tr-sect{margin:0 0 30px;max-width:78ch;}
.tr-sect h2{font-size:var(--fs-sm);font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--sect-ink);margin:0 0 12px;}
.tr-sect .facts dd{font-variant-numeric:normal;}

/* ===== A capped group of cards ============================================
   Six, then a button. See cardGroup() in app.js for why.

   The heading is the thing the eye should land on when scrolling a ward page,
   so it is no longer the same 13px grey uppercase label as every other
   section title — it takes the stage's own colour, the one the cards already
   carry, and a size that reads as a divider rather than a caption.
   ========================================================================= */
.grp{margin-bottom:34px;}
.grp-hd{display:flex;align-items:center;gap:10px;margin:0 0 14px;flex-wrap:wrap;}
.grp-t{margin:0;font-size:var(--fs-h3);font-weight:700;letter-spacing:-.01em;
  text-transform:none;color:var(--ink);display:inline-flex;align-items:center;gap:9px;}
/* The dot is the stage colour; .st-* set a background, which is exactly what
   is wanted on a 9px round. */
.grp-t::before{content:"";width:9px;height:9px;border-radius:50%;flex:none;
  background:currentColor;}
.grp-t.st-rev{color:#1a4fbd;}
.grp-t.st-ok {color:#15713f;}
.grp-t.st-app{color:#5b3dc4;}
.grp-t.st-cl, .grp-t.st-un{color:var(--ink-3);}
.grp-n{background:var(--panel-2);color:var(--ink-2);border-radius:20px;
  padding:2px 9px;font-size:var(--fs-xs);font-weight:700;
  font-variant-numeric:tabular-nums;}
.grp-note{font-size:var(--fs-sm);color:var(--ink-3);}
/* Each card is wrapped so the pager can hide it, and display:contents keeps
   the card itself as the grid item — otherwise the wrapper becomes the item
   and the whole grid changes shape. */
.grp-i{display:contents;}
.grp-i[hidden]{display:none;}
.grp-pager:empty{display:none;}
.grp-pager .pgr{margin-top:16px;}
.grp-all{display:inline-block;margin-top:4px;font-size:var(--fs-ui);font-weight:600;
  color:var(--accent);text-decoration:none;}
.grp-all:hover{text-decoration:underline;}

/* ===========================================================================
   applications/<address>/ — the static development-site pages
   ---------------------------------------------------------------------------
   Appended to shared/chrome.css + plan/app.css, so everything here is either
   new or a deliberate override. These pages run no JavaScript except the
   shared header layer, which is why nothing below depends on a class being
   toggled at runtime.
   ========================================================================= */
.ap{background:var(--bg);color:var(--ink);font-family:var(--font);margin:0;}
.ap main{padding-bottom:var(--sp-sec);}

.ap-hero{background:var(--panel);border-bottom:1px solid var(--line);
  padding:var(--pg-top) 0 26px;}
.ap-crumbs{font-size:var(--fs-sm);color:var(--ink-3);margin-bottom:18px;}
.ap-crumbs a{color:var(--ink-3);text-decoration:none;}
.ap-crumbs a:hover{color:var(--accent);text-decoration:underline;}
.ap-k{font-size:var(--fs-eyebrow);font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--sect-ink);margin-bottom:8px;}
.ap-name{margin:0;font-size:var(--h-page);font-weight:700;
  letter-spacing:var(--h-page-ls);line-height:var(--h-page-lh);}
/* The address is the H1; this line is the place, at heading size rather than
   caption size for the same reason as .rc-addr on a rental page. */
.ap-sub{margin-top:var(--sp-tt);font-size:var(--fs-h2);font-weight:600;
  color:var(--ink-2);letter-spacing:-.012em;line-height:var(--lh-head);}
.ap-pills{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px;align-items:center;}
.ap-count{font-size:var(--fs-sm);color:var(--ink-3);}

/* The stage, in the colours /plan/ already uses for it. */
.ap-stage{display:inline-block;font-size:var(--fs-xs);font-weight:700;
  padding:4px 11px;border-radius:999px;white-space:nowrap;}
.ap-stage.st-rev{background:#e8f1fd;color:#1b4f9c;}
.ap-stage.st-ok{background:#e7f6ec;color:#176b38;}
.ap-stage.st-app{background:#f3ecfb;color:#5b3391;}
.ap-stage.st-cl{background:var(--panel-2);color:var(--ink-3);}
.ap-stage.st-un{background:var(--panel-2);color:var(--ink-3);}

.ap-acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px;}
.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(--sect);color:var(--sect-ink);background:var(--sect-tint);}
.act-btn:hover svg{color:var(--sect-ink);}
.act-btn:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(242,169,0,.30);}
.act-btn.copied{border-color:#1e9e5a;color:#1e9e5a;}

.ap-body{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:26px;
  padding-top:var(--sp-ts);align-items:start;}
@media (max-width:900px){ .ap-body{grid-template-columns:minmax(0,1fr);} }

.ap-about{margin-bottom:var(--sp-ts);}
.ap-about-h{margin:0 0 6px;font-size:var(--fs-eyebrow);font-weight:700;
  letter-spacing:.07em;text-transform:uppercase;color:var(--ink-3);}
.ap-lede{margin:0;font-size:var(--fs-lede);line-height:var(--lh-body);
  color:var(--ink-2);max-width:68ch;}

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

/* One application inside a site's page. The heading row keeps the stage
   beside the name so the two are read together rather than as a title and a
   stray badge. */
.ap-app-hd{display:flex;align-items:center;justify-content:space-between;
  gap:12px;margin-bottom:4px;}
.ap-app-hd h3{margin:0;font-size:var(--fs-h3);font-weight:700;letter-spacing:-.015em;}
.ap-scale{margin:0 0 12px;font-size:var(--fs-body);color:var(--ink-2);}
.ap-scale b{color:var(--ink);}
.ap-facts{margin:0;display:grid;gap:0;border-top:1px solid var(--line);}
.ap-fr{display:grid;grid-template-columns:minmax(120px,38%) 1fr;gap:12px;
  padding:9px 0;border-bottom:1px solid var(--line);}
.ap-fr dt{margin:0;font-size:var(--fs-sm);color:var(--ink-3);}
.ap-fr dd{margin:0;font-size:var(--fs-sm);color:var(--ink);font-weight:600;}
.ap-alias{margin:12px 0 0;font-size:var(--fs-xs);color:var(--ink-3);line-height:1.5;}
.ap-alias b{color:var(--ink-2);font-weight:600;}
.ap-app-acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px;}

.ap-qa{border-top:1px solid var(--line);}
.ap-qa:first-of-type{border-top:0;}
.ap-qa > summary{list-style:none;cursor:pointer;padding:12px 0;}
.ap-qa > summary::-webkit-details-marker{display:none;}
.ap-qa summary h3{display:inline;margin:0;font-size:var(--fs-body);font-weight:700;}
.ap-qa p{margin:0 0 14px;font-size:var(--fs-sm);line-height:1.6;color:var(--ink-2);}
.ap-gap p{margin:0;font-size:var(--fs-sm);line-height:1.6;color:var(--ink-3);}

.ap .tr-row{display:flex;align-items:center;gap:12px;padding:11px 0;
  border-top:1px solid var(--line);text-decoration:none;color:inherit;}
.ap .tr-row:first-of-type{border-top:0;}
.ap .tr-row:hover .tr-n{color:var(--accent);}
.ap .tr-n{flex:1;min-width:0;font-size:var(--fs-sm);font-weight:600;line-height:1.3;}
.ap .tr-sub{font-weight:400;color:var(--ink-3);font-size:var(--fs-xs);margin-top:3px;}
.ap .tr-d{font-size:var(--fs-xs);color:var(--ink-3);white-space:nowrap;}

/* The directory */
.ap-ix-sect{margin:0 0 var(--sp-sec);}
.ap-ix-sect h2{margin:0 0 14px;font-size:var(--fs-h2);font-weight:700;
  letter-spacing:-.018em;}
.ap-ix-grid{display:grid;gap:2px;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));}
.ap-ix-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;}
.ap-ix-a:hover{background:var(--sect-tint);color:var(--sect-ink);}
.ap-ix-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;}
