/* assets/register.css
   The Island Register — shared stylesheet for /listings/ (render_register.py) and
   /listings/<id>/ (render_detail.py). Both renderers link this file directly; it is
   NOT loaded by index.html, whose own design lives inline there. Because the
   generated pages don't inherit that inline stylesheet, the tokens and base chrome
   (sidebar, footer, layout) are declared again here to match it.

   Absolute rules inherited from the live site: square corners (no border-radius
   anywhere), hairlines instead of cards, no shadows, no rounded pills, no emoji,
   and never backdrop-filter (a hard-won rule — see index.html's liquid-glass note
   on why that never holds up in Safari/iOS).

   render_register.py's own _bar_style() already inlines a minimal, tested style
   block for #reg-bar (56px height, opaque background, the density/clear/count
   hooks). This file is linked AFTER that inline block, so for any selector they
   both touch, this stylesheet's declaration wins — it is the one place the full
   design lives. Nothing here needs to duplicate the inline block's literal values;
   it only needs to not fight them where it doesn't intend to change them. */

:root{
  --navy:#1f2c47;
  --navy-deep:#182440;
  --ink:#2a3852;
  --muted:#5d6779;
  --gold:#b2925c;
  --gold-light:#d9c08e;
  --cream:#fbf9f5;
  --sand:#f3efe6;
}

/* ---------- Reset — matches index.html's base rules ---------- */
*{box-sizing:border-box}
body{margin:0;background:var(--cream);font-family:Karla,sans-serif;color:var(--navy)}
a{color:var(--navy);text-decoration:none}
img{display:block;max-width:100%}
input,textarea,button{font-family:inherit}
button{cursor:pointer;background:none;border:0;padding:0;text-align:left}
h1,h2{font-family:Marcellus,serif;font-weight:500;margin:0}
p{margin:0}
ul{margin:0;padding:0;list-style:none}
/* Any author `display` rule beats the UA stylesheet's `[hidden]{display:none}` --
   .entry{display:grid} below is exactly such a rule, so without this restated
   here (index.html carries its own copy at its own reset block, for the same
   reason -- this file isn't loaded by index.html) register.js's `el.hidden = true`
   would stop actually removing filtered-out entries from layout. */
[hidden]{display:none!important}

/* ---------- Page frame: sidebar + content column, matches index.html ---------- */
.layout{display:flex;flex-wrap:nowrap;align-items:stretch;min-height:100vh}
.sidebar{flex:0 0 260px;min-width:220px;background:var(--navy);color:#fff}
.sidebar-inner{position:sticky;top:0;padding:40px 32px;display:flex;flex-direction:column;gap:40px}
.brand{display:block;color:#fff}
.brand .brand-name{transition:color .2s}
.brand:hover .brand-name{color:var(--gold-light)}
.brand:focus-visible{outline:2px solid var(--gold);outline-offset:6px}
.brand-name{font-family:Marcellus,serif;font-size:22px;font-weight:600;letter-spacing:1px;line-height:1.3}
.brand-domain{font-size:9px;letter-spacing:1.8px;color:rgba(255,255,255,.5);margin-top:10px}
.brand-rule{width:26px;height:1px;background:var(--gold);margin-top:22px}
.side-nav{display:flex;flex-direction:column;gap:22px;font-size:11.5px;letter-spacing:1.8px;font-weight:600}
.side-nav a{color:rgba(255,255,255,.75);transition:color .2s}
.side-nav a:hover{color:var(--gold-light)}
.side-contact{display:inline-block;border:1px solid rgba(255,255,255,.5);color:#fff;padding:12px 20px;font-size:10.5px;letter-spacing:2.2px;font-weight:700;text-align:center;white-space:nowrap;transition:background .2s,color .2s}
.side-contact:hover{background:#fff;color:var(--navy)}
.side-tagline{padding-top:22px;border-top:1px solid rgba(255,255,255,.18);font-family:Marcellus,serif;font-style:italic;font-size:15px;line-height:1.6;color:var(--gold-light)}

.content{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;container:register / inline-size}

.site-footer{background:var(--navy-deep);color:#fff;padding:28px clamp(24px,6vw,120px);display:flex;flex-wrap:wrap;gap:14px;align-items:center;justify-content:space-between;margin-top:auto}
.footer-brand{font-family:Marcellus,serif;font-size:19px;letter-spacing:1px;color:#fff;transition:color .2s}
.footer-brand:hover{color:var(--gold-light)}
.footer-copy{font-size:11px;letter-spacing:2px;color:rgba(255,255,255,.55)}
.footer-exp{display:flex;align-items:center;gap:14px}
.footer-exp .exp{font-weight:800;font-size:16px}
.footer-exp .sep{width:1px;height:22px;background:rgba(255,255,255,.35)}
.footer-exp .lux{font-size:13px;letter-spacing:5px;color:var(--gold-light)}

@media (max-width:900px){
  .layout{flex-wrap:wrap}
  .sidebar{flex:1 1 100%;min-width:0}
  /* .content is a size container, so its intrinsic width is 0: with a bare
     flex-basis:auto it fits on the sidebar's line and collapses to nothing. */
  .content{flex-basis:100%}
  .sidebar-inner{position:static;padding:20px 24px;flex-direction:row;flex-wrap:wrap;align-items:center;gap:18px;justify-content:space-between}
  /* Same fix as index.html's copy: wrap the nav rather than overflow a phone. */
  .side-nav{flex-direction:row;flex-wrap:wrap;gap:12px 16px}
  .side-nav a{white-space:nowrap}
  .side-tagline{display:none}
  .brand-rule{display:none}
}

/* ---------- Eyebrow — shared small-caps label idiom ---------- */
.eyebrow{font-size:10.5px;letter-spacing:3.5px;color:var(--gold);text-transform:uppercase}

/* ================================================================
   REGISTER — /listings/
   ================================================================ */

/* ---------- Filter bar refinements ---------------------------------------
   _bar_style() already sets #reg-bar's height/position/opacity/hairline and
   the bare-input/bare-select/is-active rules — those stay. This block only
   adds what that minimal inline pass didn't: the gold chevron on the selects
   (never a native widget), the live count's real size, and the clear/sort
   spacing the brief calls for. */
#reg-bar{padding:0 4px 0 clamp(16px,2.4vw,32px)}
#reg-bar select{
  background-image:linear-gradient(45deg,transparent 50%,var(--gold) 50%),
                    linear-gradient(135deg,var(--gold) 50%,transparent 50%);
  background-position:calc(100% - 12px) 55%,calc(100% - 7px) 55%;
  background-size:5px 5px,5px 5px;
  background-repeat:no-repeat;
  padding-right:20px;
}
#reg-count{font-size:18px}
/* NEW THIS WEEK toggle: the bar's small-caps idiom; pressed = the gold underline
   PLATES/LIST uses for its active label. */
#reg-bar .reg-new{border:0;background:transparent;padding:6px 0;cursor:pointer;white-space:nowrap;font:600 11px Karla,sans-serif;letter-spacing:.14em;text-transform:uppercase;color:var(--navy);transition:color .2s}
#reg-bar .reg-new:hover{color:var(--gold)}
#reg-bar .reg-new[aria-pressed="true"]{color:var(--gold);text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
#reg-bar .reg-new:focus-visible{outline:2px solid var(--gold);outline-offset:3px}
#reg-bar .reg-right{padding-right:clamp(16px,2.4vw,32px)}

/* The bar needs ~1,259px of .content for one row (1,111px before the NEW THIS
   WEEK toggle joined it, 2026-09-13), and its row of search +
   selects alone needs ~647px. These tiers key off .content's own width, not
   the viewport: with the sidebar showing, a 901px window leaves .content at
   641px, and the old max-width:760px media query never fired there -- the
   bar ran 236-390px past the column and the page scrolled sideways. The
   chapter headings stick directly under the bar; their matching offsets sit
   after the .chapter>h2 rule below, since @container adds no specificity. */
@container register (660px <= width < 1260px){
  #reg-bar{height:96px;flex-wrap:wrap;align-content:stretch;row-gap:0}
  #reg-bar .reg-right{flex-basis:100%;justify-content:flex-end}
}
/* Phones (spec): the bar is a sticky 52px row -- search plus FILTERS -- and the
   controls live in the #reg-sheet dialog while it is open. */
.reg-filters-btn{display:none}
@container register (width < 660px){
  #reg-bar{height:52px;flex-wrap:nowrap;gap:14px;padding:0 16px}
  #reg-bar .reg-fields,#reg-bar .reg-right{display:none}
  #reg-bar .reg-q{flex:1 1 auto;min-width:0;max-width:none}
  #reg-bar .reg-filters-btn{display:inline-flex;align-items:center;flex:none;border:1px solid rgba(31,44,71,.35);
    background:transparent;padding:9px 14px;cursor:pointer;font:700 11px Karla,sans-serif;letter-spacing:.14em;
    text-transform:uppercase;color:var(--navy)}
  .reg-filters-n{color:var(--gold);white-space:pre}
}

/* The sheet: full screen, controls stacked as full-width rows, APPLY pinned at the
   foot above the iPhone home indicator. */
.reg-sheet{width:100%;max-width:100%;height:100%;max-height:100%;margin:0;padding:0;border:0;
  background:var(--cream);color:var(--navy)}
.reg-sheet[open]{display:flex;flex-direction:column}
.reg-sheet::backdrop{background:rgba(15,20,35,.5)}
.reg-sheet-head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;
  border-bottom:1px solid rgba(31,44,71,.14)}
.reg-sheet-title{font-family:Marcellus,serif;font-weight:400;font-size:26px;color:var(--navy)}
.reg-sheet-close{border:0;background:none;padding:8px 0;cursor:pointer;font:600 11px Karla,sans-serif;
  letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.reg-sheet-body{flex:1 1 auto;overflow-y:auto;padding:4px 20px 20px}
.reg-sheet-body .reg-fields,.reg-sheet-body .reg-right{display:flex;flex-direction:column;align-items:stretch}
.reg-sheet-body select,.reg-sheet-body .reg-new,.reg-sheet-body .reg-density,.reg-sheet-body .reg-clear{
  display:block;width:100%;padding:17px 0;border:0;border-bottom:1px solid rgba(31,44,71,.14);border-radius:0;
  background-color:transparent;text-align:left;font:600 12px Karla,sans-serif;letter-spacing:.14em;
  text-transform:uppercase;color:var(--navy);-webkit-appearance:none;appearance:none}
.reg-sheet-body select{background-image:linear-gradient(45deg,transparent 50%,var(--gold) 50%),
  linear-gradient(135deg,var(--gold) 50%,transparent 50%);background-position:calc(100% - 12px) 55%,calc(100% - 7px) 55%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat}
.reg-sheet-body .reg-new[aria-pressed="true"]{color:var(--gold)}
.reg-sheet-body .reg-count{display:none}
.reg-sheet-body .reg-density .is-active{color:var(--gold);text-decoration:underline;text-underline-offset:3px}
.reg-sheet-body .reg-clear{color:var(--muted)}
.reg-sheet-foot{padding:12px 20px calc(12px + env(safe-area-inset-bottom));border-top:1px solid rgba(31,44,71,.14)}
.reg-apply{display:block;width:100%;height:52px;border:0;background:var(--navy);color:#fff;cursor:pointer;
  font:700 12px Karla,sans-serif;letter-spacing:.16em;text-transform:uppercase}
.reg-apply:focus-visible,.reg-sheet-close:focus-visible,.reg-filters-btn:focus-visible{outline:2px solid var(--gold);outline-offset:3px}

/* ---------- Masthead ------------------------------------------------------ */
.masthead{padding:clamp(40px,6vw,72px) clamp(24px,4vw,64px) clamp(28px,4vw,44px)}
.masthead .eyebrow{margin-bottom:16px}
.masthead h1{font-size:clamp(30px,3.8vw,46px);line-height:1.15;color:var(--navy);text-wrap:pretty}
.masthead-sub{margin-top:14px;font-size:15px;line-height:1.7;color:var(--muted)}
.masthead-colophon{margin-top:18px;font:600 11px Karla,sans-serif;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.masthead-colophon .colophon-dot{color:var(--gold)}
/* The island sits right of the text (spanning its rows) and moves above it when the
   column narrows. Navy land, gold dots; filtered-out listings drop their dot. */
.masthead{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:clamp(24px,4cqi,56px);align-items:center}
.masthead>*{grid-column:1}
.masthead-island{grid-column:2;grid-row:1/span 4;width:150px;height:auto;overflow:visible}
.isl-land{fill:var(--navy)}
.isl-dot{fill:var(--gold-light);stroke:var(--navy);stroke-width:3}
.isl-dot.isl-off{display:none}
@container register (width < 660px){
  .masthead{grid-template-columns:minmax(0,1fr)}
  .masthead-island{grid-column:1;grid-row:1;width:120px;margin-bottom:18px}
}

/* ---------- Empty state ---------------------------------------------------
   #reg-empty already carries the tested padding/color/link rules inline;
   this only widens its measure to match the rest of the column. */
#reg-empty{padding:56px clamp(24px,4vw,64px)}

/* ---------- The ledger ------------------------------------------------------
   Sand ground, one row per district, all bars sharing the scale baked into
   .ledger's data-scale-lo/hi. Visual column order (name, count, bar, prices,
   mix) is set with an explicit grid-column per class rather than DOM order,
   since the mix and price-range spans are emitted in a different sequence
   than they read on screen.

   The tracks live on .ledger and every row inherits them through subgrid, so
   a column can size to its widest cell across all rows and still line up.
   Priority when space runs short: prices never clip (max-content), the bar
   keeps at least 96px, and only the property mix gives way (ellipsis). The
   rows used to be independent grids with fixed tracks: 132px for a 165px
   "$13,880,000 – $36,500,000", and 572px of fixed width that left the bar
   track at 0px whenever the column narrowed. */
.ledger{
  background:var(--sand);padding:clamp(20px,3vw,32px) clamp(24px,4vw,64px);
  container:ledger / inline-size;
  display:grid;
  grid-template-columns:max-content max-content minmax(96px,1fr) max-content minmax(0,max-content);
  column-gap:16px;
}
.led-row{
  grid-column:1/-1;
  display:grid;
  grid-template-columns:subgrid;
  align-items:center;
  padding:11px 0;
  border-bottom:1px solid rgba(31,44,71,.13);
  transition:opacity .2s;
}
.led-row:last-child{border-bottom:0}
.led-name{grid-column:1;font-family:Marcellus,serif;font-size:17px;color:var(--navy);white-space:nowrap}
.led-count{grid-column:2;text-align:right;font:600 13px Karla,sans-serif;color:var(--gold)}
.led-scale{grid-column:3;position:relative;height:16px}
.led-fill{position:absolute;top:50%;height:2px;background:var(--gold-light);transform:translateY(-50%)}
.led-median{position:absolute;top:50%;width:2px;height:7px;background:var(--navy);transform:translate(-50%,-50%)}
.led-prices{grid-column:4;text-align:right;font:500 13px Karla,sans-serif;font-variant-numeric:tabular-nums;color:var(--ink);white-space:nowrap}
.led-mix{grid-column:5;min-width:0;text-align:right;font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* One line per district. The mix span comes before the bar and prices in the
   markup but sits in column 5, so auto-placement pushed the bar and prices
   onto a second implicit row. The stacked tier's grid-area rules come later
   and still win. */
.led-row>*{grid-row:1}
a.led-name{transition:color .2s}
a.led-name:hover{color:var(--gold)}
a.led-name:focus-visible{outline:2px solid var(--gold);outline-offset:3px}
/* Dimmed, not gone: at .25 a district name read as blank on an iPad (1.6:1). */
.led-row.led-dim{opacity:.65}

/* Legend: order buttons on their own line (spanning every track, so they never widen
   the name/count columns the rows share), then a 3-tick axis over the bar column and a
   range/median key over the prices. */
.led-legend{grid-column:1/-1;display:grid;grid-template-columns:subgrid;row-gap:10px;align-items:end;
  padding:2px 0 12px;border-bottom:1px solid rgba(31,44,71,.22)}
.led-sorts{grid-column:1/-1;grid-row:1;display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 16px}
.led-sorts-label{font:600 10.5px Karla,sans-serif;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.led-sort{border:0;background:none;padding:2px 0;cursor:pointer;font:600 10.5px Karla,sans-serif;
  letter-spacing:.14em;text-transform:uppercase;color:var(--navy);transition:color .2s}
.led-sort:hover{color:var(--gold)}
.led-sort[aria-pressed="true"]{color:var(--gold);text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
.led-sort:focus-visible{outline:2px solid var(--gold);outline-offset:3px}
.led-axis{grid-column:3;grid-row:2;position:relative;height:26px;border-bottom:1px solid rgba(31,44,71,.28)}
.led-tick{position:absolute;bottom:6px;transform:translateX(-50%);white-space:nowrap;
  font:500 10.5px Karla,sans-serif;font-variant-numeric:tabular-nums;color:var(--muted)}
.led-tick::after{content:"";position:absolute;left:50%;bottom:-7px;width:1px;height:5px;background:rgba(31,44,71,.45)}
.led-tick:first-child{transform:none}
.led-tick:first-child::after{left:0}
.led-tick:last-child{transform:translateX(-100%)}
.led-tick:last-child::after{left:auto;right:0}
.led-key{grid-column:4/-1;grid-row:2;justify-self:end;display:flex;align-items:center;gap:6px;contain:inline-size;
  width:100%;justify-content:flex-end;white-space:nowrap;font:500 10.5px Karla,sans-serif;letter-spacing:.06em;color:var(--muted)}
.led-key-range{width:18px;height:2px;background:var(--gold-light)}
.led-key-median{width:2px;height:8px;margin-left:10px;background:var(--navy)}

/* Stack on the ledger's own width, not the viewport's: with the sidebar
   showing, a 901-1000px window leaves the ledger narrower than a 860px phone
   does, and the old max-width:860px media query never fired there. */
@container ledger (width < 620px){
  .led-row{
    grid-template-columns:1fr auto;
    grid-template-areas:"name count" "scale scale" "prices mix";
    row-gap:6px;column-gap:12px;
  }
  .led-name{grid-area:name;white-space:normal}
  .led-count{grid-area:count}
  .led-scale{grid-area:scale;margin:2px 0}
  .led-prices{grid-area:prices}
  .led-mix{grid-area:mix;text-align:right}
  .led-legend{grid-template-columns:1fr}
  .led-sorts{grid-column:1;grid-row:1}
  .led-axis{grid-column:1;grid-row:2}
  .led-key{grid-column:1;grid-row:3;justify-content:flex-start}
}

/* ---------- Chapters --------------------------------------------------------
   Alternating cream/sand grounds, counted purely among .chapter siblings
   (the ledger and the quiet band are also <section>s, so a plain nth-child
   would miscount) — :nth-child(of S) is scoped correctly and this codebase
   already relies on similarly modern-only CSS (text-wrap:balance, aspect-
   ratio) elsewhere, so the fallback below (all-cream) only matters on an
   engine old enough that nothing else on the page would render right either. */
.chapter{background:var(--cream);padding-bottom:8px}
.chapter:nth-child(odd of .chapter){background:var(--cream)}
.chapter:nth-child(even of .chapter){background:var(--sand)}

.chapter>h2{
  position:sticky;top:56px;z-index:3;
  height:64px;
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  background-color:inherit;
  padding:0 clamp(24px,4vw,64px);
  border-bottom:1px solid rgba(31,44,71,.14);
}
/* Follow #reg-bar's height tiers (see the filter bar block). */
@container register (660px <= width < 1260px){.chapter>h2{top:96px}}
@container register (width < 660px){.chapter>h2{top:52px}}

/* Ledger names jump to #ch-<slug> on the chapter section; land it just below
   the sticky bar rather than behind it, in each of the bar's tiers. */
.chapter,.reg-sorted-band{scroll-margin-top:56px}
@container register (660px <= width < 1260px){.chapter,.reg-sorted-band{scroll-margin-top:96px}}
@container register (width < 660px){.chapter,.reg-sorted-band{scroll-margin-top:52px}}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
.chapter-head{font-family:Marcellus,serif;font-size:clamp(26px,2.6vw,34px);color:var(--navy);cursor:default}
/* The head is a disclosure button (register.js): styled as the heading it was, with
   a small gold chevron that turns when the chapter is collapsed. */
button.chapter-head{border:0;background:none;padding:0;margin:0;cursor:pointer;text-align:left;line-height:inherit;
  display:inline-flex;align-items:center;gap:12px}
button.chapter-head::after{content:"";width:7px;height:7px;flex:none;border-right:1.5px solid var(--gold);
  border-bottom:1.5px solid var(--gold);transform:translateY(-3px) rotate(45deg);transition:transform .2s}
button.chapter-head[aria-expanded="false"]::after{transform:translateY(1px) rotate(-45deg)}
button.chapter-head:hover{color:var(--gold)}
button.chapter-head:focus-visible{outline:2px solid var(--gold);outline-offset:4px}
/* Safari has no hidden="until-found"; register.js falls back to this class there. */
.chapter-body.is-collapsed{display:none}
/* Before register.js runs, a phone-width column shows collapsed chapters rather than
   flashing all 23 open. html.js comes from the head script (never set without JS);
   register.js adds chapters-ready once it owns the state, and a 4s timer adds it if
   register.js never runs. */
@container register (width < 660px){html.js:not(.chapters-ready) .chapter-body{display:none}}
.chapter-link{margin-left:4px;font:600 11px Karla,sans-serif;letter-spacing:.14em;text-transform:uppercase;color:var(--navy);border-bottom:1px solid var(--gold);padding-bottom:2px;white-space:nowrap;transition:color .2s,border-color .2s}
.chapter-link:hover{color:var(--gold);border-color:var(--gold)}

.chapter-desc{
  margin:20px clamp(24px,4vw,64px) 0;
  font-family:Marcellus,serif;font-style:normal;font-size:15px;line-height:1.6;color:var(--ink);
  max-width:640px;
}
.chapter-desc::before{content:"";display:block;width:26px;height:1px;background:var(--gold);margin-bottom:14px}
.chapter-stat{
  margin:10px clamp(24px,4vw,64px) 0;
  font:600 11px Karla,sans-serif;letter-spacing:.1em;text-transform:uppercase;color:var(--gold);
}
.chapter-entries{margin-top:18px}

/* Collapse rule: an empty chapter shows only its sticky h2 band (name + the
   "no matches" badge JS writes into .chapter-count) — everything else in the
   section is removed from layout, not merely dimmed. */
.chapter.chapter-empty .chapter-desc,
.chapter.chapter-empty .chapter-stat,
.chapter.chapter-empty .promoted,
.chapter.chapter-empty .chapter-entries{display:none}
.chapter.chapter-empty{padding-bottom:0}

/* ---------- The entry --------------------------------------------------- */
.entry{
  display:grid;
  grid-template-columns:168px minmax(0,1fr) 210px;
  column-gap:20px;
  align-items:center;
  min-height:124px;
  padding:14px clamp(24px,4vw,64px);
  border-bottom:1px solid rgba(31,44,71,.12);
  color:inherit;
}
.entry.entry-plated{grid-template-columns:minmax(0,1fr) 210px}
.plate{width:168px;height:112px;aspect-ratio:3/2;object-fit:cover}
.plate.no-plate{background:var(--sand);outline:1px solid var(--gold);outline-offset:-5px}
.entry-body{display:flex;flex-direction:column;gap:6px;min-width:0}
.entry-addr{font-family:Marcellus,serif;font-size:22px;color:var(--navy);text-wrap:balance}
.entry-meta{font:500 13px Karla,sans-serif;font-variant-numeric:tabular-nums;color:var(--muted)}
.entry-new{margin-right:10px;font:700 10.5px Karla,sans-serif;letter-spacing:.14em;color:var(--gold)}
.entry-extract{
  font-size:13px;line-height:1.5;color:var(--muted);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-clamp:2;overflow:hidden;
}
.entry-rail{display:flex;flex-direction:column;align-items:flex-end;gap:6px;text-align:right}
.entry-price{font:500 22px Karla,sans-serif;font-variant-numeric:tabular-nums;color:var(--navy)}
.entry-office{font-size:11.5px;letter-spacing:.02em;color:var(--muted)}
.entry:hover .entry-addr{color:var(--gold)}

@media (max-width:860px){
  .entry{
    grid-template-columns:96px minmax(0,1fr);
    grid-template-rows:auto auto;
    row-gap:10px;
    padding:14px clamp(16px,4vw,32px);
    min-height:0;
  }
  .entry.entry-plated{grid-template-columns:minmax(0,1fr)}
  .plate{width:96px;height:64px}
  .entry-rail{
    grid-column:1/-1;
    flex-direction:row;
    align-items:baseline;
    justify-content:space-between;
    text-align:left;
  }
}

/* ---------- Promoted plate ------------------------------------------------ */
.promoted{display:block;margin:20px clamp(24px,4vw,64px) 0}
.promoted figure{margin:0}
.promoted img{width:100%;height:300px;object-fit:cover}
.promoted figcaption{margin-top:12px;font:600 11px Karla,sans-serif;letter-spacing:.14em;color:var(--muted);transition:color .2s}
.promoted:hover figcaption{color:var(--gold)}
.promoted:focus-visible{outline:2px solid var(--gold);outline-offset:4px}
.promoted figcaption::before{content:"";display:block;width:26px;height:1px;background:var(--gold);margin-bottom:10px}

/* ---------- Density: .compact is toggled on .content by register.js ------ */
.content.compact .plate,
.content.compact .entry-extract{display:none}
.content.compact .entry{
  grid-template-columns:1fr 150px 210px;
  min-height:0;
  padding-top:10px;padding-bottom:10px;
}
.content.compact .entry.entry-plated{grid-template-columns:1fr 210px}
.content.compact .entry-body{gap:2px}

@media (max-width:860px){
  .content.compact .entry{grid-template-columns:minmax(0,1fr);row-gap:6px}
  .content.compact .entry.entry-plated{grid-template-columns:minmax(0,1fr)}
}

/* ---------- Quiet band ------------------------------------------------------
   Navy ground, white type — districts with a guide but nothing on the market
   today. The list itself carries the button-adjacent hover idiom used
   elsewhere on the site (color to gold); the band's own lead-gen moment is the
   outlined CTA at its foot, lifted from index.html's .hero-cta — same single
   outlined link on a dark ground, no gold sibling to pair against. */
.quiet{background:var(--navy);color:#fff;padding:clamp(40px,6vw,64px) clamp(24px,4vw,64px)}
.quiet-intro{font-size:15px;line-height:1.75;color:rgba(255,255,255,.78);max-width:640px}
.quiet-list{
  margin-top:clamp(28px,4vw,40px);
  display:grid;grid-template-columns:repeat(3,1fr);gap:14px 32px;
}
.quiet-list li{border-top:1px solid rgba(255,255,255,.16);padding-top:12px}
.quiet-list a{font-family:Marcellus,serif;font-size:16px;color:#fff;transition:color .2s}
.quiet-list a:hover{color:var(--gold-light)}

@media (max-width:760px){
  .quiet-list{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:480px){
  .quiet-list{grid-template-columns:1fr}
}

.quiet-cta{
  display:inline-block;margin-top:clamp(28px,4vw,40px);
  padding:16px 38px;border:1px solid rgba(255,255,255,.65);color:#fff;
  font:600 11px Karla,sans-serif;letter-spacing:2.5px;white-space:nowrap;
  transition:background .2s,color .2s;
}
.quiet-cta:hover{background:#fff;color:var(--navy)}

/* ---------- LINK compliance block — shared by both page types ------------ */
.link-block{
  font:400 12.5px Karla,sans-serif;line-height:1.7;color:var(--muted);
  padding:32px clamp(24px,4vw,64px) 48px;
}

/* ================================================================
   DETAIL — /listings/<id>/  (render_detail.py's .detail/.panel/.sheet)
   ================================================================ */

.detail{display:grid;grid-template-columns:1fr;}

@media (min-width:1000px){
  .detail{grid-template-columns:420px 1fr;column-gap:0;align-items:start}
}

.panel{
  background:var(--navy);color:#fff;
  padding:44px 40px;
}
@media (min-width:1000px){
  .panel{position:sticky;top:0;height:100vh;overflow-y:auto}
}
.panel-home{display:inline-block;margin-bottom:28px;font-family:Marcellus,serif;font-size:18px;letter-spacing:1px;color:#fff;transition:color .2s}
.panel-home::after{content:"";display:block;width:26px;height:1px;background:var(--gold);margin-top:12px}
.panel-home:hover{color:var(--gold-light)}
.panel-home:focus-visible{outline:2px solid var(--gold);outline-offset:4px}
.panel-price{font-family:Marcellus,serif;font-size:40px;color:#fff;font-variant-numeric:tabular-nums}
.panel-addr{font-family:Marcellus,serif;font-size:22px;font-weight:500;color:#fff;margin-top:10px;text-wrap:balance}

/* Departed listings. The page stays and changes state, so the band sits where
   the price was: a sold listing shows what it got over what it asked, and a
   non-sale says only that it is off the market. Links on this panel are navy by
   default (a{color:var(--navy)}), which is why the tags restate their colour. */
.panel-status{display:flex;flex-wrap:wrap;align-items:baseline;gap:14px;margin-bottom:16px}
.status-tag{font-size:10.5px;letter-spacing:2.2px;font-weight:700;padding:7px 12px;border:1px solid}
.panel-status.is-sold .status-tag{color:var(--navy);background:var(--gold-light,#d9c08e);border-color:var(--gold-light,#d9c08e)}
.panel-status.is-off .status-tag{color:rgba(255,255,255,.82);border-color:rgba(255,255,255,.4)}
.status-when{font-size:13.5px;color:rgba(255,255,255,.72)}

/* Fisher's three figures: what it got, when, and what it asked. */
.panel-figures{display:flex;flex-wrap:wrap;gap:10px 30px;margin-bottom:4px}
/* The departed CTA label is long; let it wrap rather than overflow a 320px phone. */
.panel-cta-past .panel-cta-ask{white-space:normal;line-height:1.5;text-align:center}
.pf{display:flex;flex-direction:column;gap:6px}
.pf-k{font-size:9.5px;letter-spacing:2px;font-weight:700;color:var(--gold-light,#d9c08e)}
.pf-v{font-family:Marcellus,serif;font-size:27px;color:#fff;font-variant-numeric:tabular-nums;line-height:1}

/* "You are viewing past data" — a light banner in normal flow, not a modal.
   It scrolls away by itself in every browser; the fade below is enhancement
   only. animation-timeline/-range are declared AFTER the shorthand, which would
   otherwise reset them, and the @supports test includes animation-range to
   exclude browsers with partial scroll-timeline support. */
.past-data{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 16px;
  padding:12px clamp(16px,4vw,40px);background:var(--sand);color:var(--navy);
  border-bottom:1px solid rgba(31,44,71,.14);font-size:13.5px}
.past-data-line{margin:0;color:var(--muted)}
.past-data-cta{color:var(--navy);font-size:11px;letter-spacing:1.6px;font-weight:700;
  text-decoration:underline;text-underline-offset:3px}
.past-data-cta:hover{color:var(--gold)}
@keyframes past-data-fade{to{opacity:0}}
@supports ((animation-timeline:scroll()) and (animation-range:0% 100%)){
  @media (prefers-reduced-motion:no-preference){
    .past-data{animation:past-data-fade auto linear both;
      animation-timeline:scroll(root);animation-range:0 140px}
  }
}
.panel-office{margin-top:14px;font-size:13.5px;color:rgba(255,255,255,.72)}
.panel-office-courtesy{margin-top:18px;font-size:12px;color:rgba(255,255,255,.55)}

.facts{margin-top:28px;border-top:1px solid rgba(255,255,255,.18)}
.fact{display:flex;justify-content:space-between;gap:16px;padding:11px 0;border-bottom:1px solid rgba(255,255,255,.18);font-size:13px}
.fact-k{color:rgba(255,255,255,.6);letter-spacing:.03em}
.fact-v{color:#fff;font-variant-numeric:tabular-nums;text-align:right}

.district-link{display:inline-block;margin-top:22px;font:600 11px Karla,sans-serif;letter-spacing:.12em;text-transform:uppercase;color:#fff;border-bottom:1px solid var(--gold);padding-bottom:3px;transition:color .2s}
.district-link:hover{color:var(--gold-light)}

.remarks{margin-top:24px}
.remarks p{font-size:14px;line-height:1.8;color:rgba(255,255,255,.82)}

/* ---------- Panel CTAs -----------------------------------------------------
   The panel's only two actions, lifted straight from the contact form's own
   SEND / REQUEST A HOME VALUATION pairing (.btn-send / .btn-valuation in
   index.html) rather than invented fresh — same gold-solid-primary +
   white-outlined-secondary idiom, just as full-width links instead of
   form buttons, since the panel is a single narrow column. */
.panel-cta{margin-top:28px;display:flex;flex-direction:column;gap:12px}
.panel-cta-ask,.panel-cta-show{
  display:block;box-sizing:border-box;width:100%;text-align:center;
  font:700 11px Karla,sans-serif;letter-spacing:2.5px;white-space:nowrap;
  padding:15px 26px;transition:background .2s;
}
.panel-cta-ask{background:var(--gold);color:var(--navy-deep);border:none}
.panel-cta-ask:hover{background:#c8a96a}
.panel-cta-show{background:transparent;border:1px solid rgba(255,255,255,.4);color:#fff;font-weight:600}
.panel-cta-show:hover{background:rgba(255,255,255,.1)}

/* The LINK compliance block, relocated here from the page-level handoff
   footer (it now belongs at the panel's foot, per spec) — same shared
   .link-block rule, just re-colored and un-padded for the navy ground and
   the panel's own 40px side padding instead of the page's cream-ground gutters. */
.panel .link-block{padding:24px 0 0;color:rgba(255,255,255,.55)}

.sheet{background:var(--cream);display:flex;flex-direction:column;gap:4px}
.sheet-photo{width:100%;height:auto;cursor:zoom-in}
.sheet-empty{
  min-height:60vh;
  display:flex;align-items:center;justify-content:center;text-align:center;padding:32px;
  background:repeating-linear-gradient(-45deg,#e7e2d6 0 14px,#efebe1 14px 28px);
}
.sheet-empty p{font-family:Marcellus,serif;font-size:18px;color:var(--muted);max-width:360px}
.sheet-more{
  align-self:center;margin:20px 0;
  padding:14px 30px;border:1px solid var(--navy);
  font:600 11px Karla,sans-serif;letter-spacing:.14em;color:var(--navy);
  background:var(--cream);
  transition:background .2s,color .2s;
}
.sheet-more:hover{background:var(--navy);color:#fff}

/* Below 1000px: one column, nothing sticky, nothing horizontal. The first
   photo needs to land ABOVE the navy panel while the rest stay below it, but
   .sheet is one contiguous block after .panel in the markup — display:contents
   drops .sheet's own box (without touching the DOM) so its photos become
   direct items of .detail's flow and can be given an order independently of
   one another; :first-of-type still resolves against .sheet's real children,
   not the flattened set, so it reliably picks the first photo. */
@media (max-width:999px){
  .detail{display:flex;flex-direction:column}
  .panel{order:2}
  .sheet:not(.sheet-empty){display:contents}
  .sheet-photo{order:3}
  .sheet-photo:first-of-type{order:1}
  .sheet-more{order:3}
  .sheet-empty{order:3;min-height:0;padding:40px 24px}
}

/* ---------- Photo lightbox — vanilla script in render_detail.py's page() ---
   Full-viewport overlay opened on a .sheet-photo click, showing the untouched
   original (data-full, never the CDN crop). Esc and a click on the scrim
   itself close it (the img itself swallows the click via its own listener,
   so only a genuine click-out reaches the overlay). */
.lightbox{position:fixed;inset:0;z-index:20;background:rgba(15,20,35,.92);display:flex;align-items:center;justify-content:center;padding:24px;cursor:zoom-out}
.lightbox-img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;cursor:default}

/* ---------- Siblings — reuses render_register.py's .entry markup --------- */
.siblings{padding:clamp(32px,5vw,56px) clamp(24px,4vw,64px);background:var(--sand)}
.siblings h2{font-size:clamp(22px,2.6vw,28px);color:var(--navy)}
.siblings-list{margin-top:20px}
.siblings .entry{padding-left:0;padding-right:0}

/* ---------- Handoff footer ------------------------------------------------
   The LINK compliance block used to live here too; it moved into .panel's
   foot (see the DETAIL section above), so this footer now carries only the
   hand-off line. */
.handoff{padding:clamp(32px,5vw,56px) clamp(24px,4vw,64px) 24px;background:var(--cream)}
.handoff-line{font-family:Marcellus,serif;font-size:17px;color:var(--ink);max-width:640px}
