/*
  The Grand-Place, building by building
  -------------------------------------
  Loaded only on /square/* pages, after style.css and places.css. The page
  head, breadcrumbs and taxonomy pill come from places.css; everything here
  is specific to the measured drawing and the building pages.

  The drawing is a survey sheet, so it borrows the site palette rather than
  introducing one: --brand for anything interactive, --accent for the two
  towers, and a gold that reads as gilding for the fourteen guild houses.
*/

:root{
  /* The elevation needs fills that separate from one another, which the theme
     palette has no equivalent for, so this four-step encoding ramp is the one
     new thing here: keyed to the theme's cool greys and its warm accent so it
     sits inside the palette rather than beside it. */
  --sq-guild:     #dcc179;   /* guild house: a muted --accent-warm, read as gilding */
  --sq-guild-ink: #8a6d1c;   /* the same gold, dark enough for rules and text */
  --sq-plain:     #d6dce4;   /* private house or shop: a step down from --surface-sunken */
  --sq-civic:     #b9c0ca;   /* Town Hall and King's House: two steps down */

  /* Everything else comes from style.css instead of being invented next to it. */
  --sq-tower: var(--accent);        /* spire and belfry: the site's red */
  --sq-sheet: var(--surface);       /* the drawing sits on a card, like .place-card */
  --sq-grid:  var(--border);        /* the site's hairline */
  --sq-num:   'Open Sans', system-ui, sans-serif;
}

/* --- Headline figures ----------------------------------------------------
   Five numbers that open the page. They were a boxed table with 17px values,
   which read as a specification sheet bolted above the drawing rather than as
   the drawing's headline. Now the figure leads at display size with its label
   underneath, and the box is gone: hairlines between the columns do the
   dividing, so the row sits in the page's own space instead of in a card. */

.sq-meta{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  margin: 0 0 44px;
}
.sq-meta > div{
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 2px 26px;
  border-right: 1px solid var(--border);
}
.sq-meta > div:first-child{ padding-left: 0; }
.sq-meta > div:last-child{ border-right: 0; }
.sq-meta dt{
  order: 2;                       /* the label reads under its figure */
  margin: 0;
  font-family: 'Montserrat', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.sq-meta dd{
  order: 1;
  margin: 0;
  font-family: 'Montserrat', system-ui, sans-serif;
  font-size: 40px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 767px){
  /* Five items do not divide into two columns, so the last one would carry a
     rule into empty space. The gap separates them instead. */
  .sq-meta{
    grid-template-columns: repeat(2, 1fr);
    gap: 26px 0;
    margin-bottom: 34px;
  }
  .sq-meta > div{
    padding: 0;
    border-right: 0;
  }
  .sq-meta dd{ font-size: 30px; }
}

/* --- Section furniture ---------------------------------------------------
   The page shows the same survey three ways: unrolled as an elevation, seen
   from overhead as a plan, and lifted into a model. The eyebrow names which
   one a section is, so the reader can tell the three apart at a glance
   instead of reading three similar headings. It is a label, not decoration:
   where a section is not a drawing it does not get one. */

.sq-eyebrow{
  margin: 0 0 11px;
  font-family: 'Montserrat', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* The plan and the model are one light band rather than two alternating
   stripes: same data, two views, so they group. Each section in the band
   drops its own bottom padding and takes a smaller gap from the one above;
   the last carries .sq-zone-end to give the band its closing space back,
   which is a class rather than :has() so it holds in older browsers.
   Both follow the theme's own two-step section rhythm below. */
.sq-zone{ padding-bottom: 0; }
.sq-zone + .sq-zone{ padding-top: 56px; }
.sq-zone-end{ padding-bottom: 100px; }

/* The three category sections all sit on white now, so a full-bleed hairline
   does the separating that an alternating background used to. They are also
   closer together than a lone section would be: three lists of the same kind
   of thing want to read as one group, and the theme's full section lead-in
   between each of them made three identical bands instead. */
.sq-cat-section{
  padding-top: 72px;
  padding-bottom: 72px;
}
.sq-cat-section + .sq-cat-section{ border-top: 1px solid var(--border); }

@media (min-width: 768px){
  /* Matching the step .section itself takes at this width. */
  .sq-zone + .sq-zone{ padding-top: 72px; }
  .sq-zone-end{ padding-bottom: 140px; }
  .sq-cat-section{
    padding-top: 100px;
    padding-bottom: 100px;
  }
}

/* --- The sheet ----------------------------------------------------------- */

.sq-sheet{
  background: var(--sq-sheet);
  border: 1px solid var(--border);
  border-radius: 4px;
}
.sq-scroller{
  overflow-x: auto;
  overflow-y: hidden;
  padding: 14px 0 4px;
}
.sq-panel-view{ display: none; }
.sq-panel{
  padding: 12px 0 0;
  border-bottom: 1px solid var(--sq-grid);
}
.sq-panel:last-child{ border-bottom: 0; }

.elev{
  display: block;
  height: auto;
}
.sq-strip-view .elev{ width: var(--elev-w); max-width: none; }
.sq-panel .elev{ width: 100%; }

/* --- Drawing furniture --------------------------------------------------- */

.g-grid  { stroke: var(--sq-grid); stroke-width: 1; }
.g-ground{ stroke: var(--text); stroke-width: 1.6; }
.g-corner{ stroke: var(--sq-grid); stroke-width: 1; stroke-dasharray: 3 4; }
.g-scale{
  font: 400 10.5px var(--sq-num);
  fill: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.g-side{
  font: 700 11px 'Montserrat', system-ui, sans-serif;
  fill: var(--text);
  letter-spacing: .1em;
  text-transform: uppercase;
}
.g-sidesub{
  font-weight: 400;
  fill: var(--text-muted);
  letter-spacing: .03em;
  text-transform: none;
}
.g-num{
  font: 400 10px var(--sq-num);
  fill: var(--text-muted);
  text-anchor: start;
  font-variant-numeric: tabular-nums;
}

/* --- The buildings ------------------------------------------------------- */

.house{ cursor: pointer; }
.house .hit{ fill: transparent; }
.house .msk rect,
.house .msk polygon{ stroke: var(--text); stroke-width: .9; }
.house .tower{ stroke: var(--text); stroke-width: .9; fill: var(--sq-tower); }

.f-plain .msk rect, .f-plain .msk polygon{ fill: var(--sq-plain); }
.f-guild .msk rect, .f-guild .msk polygon{ fill: var(--sq-guild); }
.f-civic .msk rect, .f-civic .msk polygon{ fill: var(--sq-civic); }

.house:hover .msk rect,
.house:hover .msk polygon,
.house:hover .tower,
.house:focus .msk rect,
.house:focus .msk polygon,
.house:focus .tower,
.house.is-current .msk rect,
.house.is-current .msk polygon,
.house.is-current .tower{ fill: var(--brand); }

.house:hover .g-num,
.house:focus .g-num,
.house.is-current .g-num{ fill: var(--brand); font-weight: 600; }

.house:focus{ outline: none; }
.house:focus-visible .hit{
  fill: var(--brand-wash);
  stroke: var(--brand);
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
}

/* --- Key and method note ------------------------------------------------- */

.sq-key{
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  align-items: center;
  margin: 0;
  padding: 10px 16px 13px;
  border-top: 1px solid var(--sq-grid);
  font-size: 13px;
  color: var(--text-muted);
}
.sq-k{ display: inline-flex; align-items: center; gap: 7px; }
.sq-sw{
  width: 22px;
  height: 11px;
  border: 1px solid var(--text);
  display: inline-block;
}
.sq-sw-g{ background: var(--sq-guild); }
.sq-sw-p{ background: var(--sq-plain); }
.sq-sw-c{ background: var(--sq-civic); }
.sq-sw-t{ background: var(--sq-tower); }
.sq-hint{ font-style: italic; }

.sq-method,
.sq-credit{
  margin: 18px 0 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
}
.sq-method{ max-width: 68em; }
.sq-credit-section{ padding-top: 0; }

/* The drawing is the first thing under the hero band, so it does not want the
   theme's full 100px section lead-in above it. */
.sq-sheet-section{ padding-top: 44px; }

/* --- Category sections --------------------------------------------------
   The listing is the directory's own .place-card grid, so there is almost
   nothing here: one override for the media box, because a building
   photograph is either a portrait facade or a 4:3 detail and both have to
   sit in the same card without a fifth derived file per building. */

.sq-count{
  display: inline-block;
  margin-left: 6px;
  font-family: 'Open Sans', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  vertical-align: 2px;
}

.sq-card .place-card-media{
  aspect-ratio: 4 / 3;
}
.sq-card .place-card-media img{
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Only the height is overridden. Fourteen of the thirty-four buildings have
   no photograph yet, so this state is on screen a lot, and it had been shrunk
   to a 34px glyph at half opacity inside a 358 by 269 box: a twelfth of the
   area, faint enough that the card read as a broken image rather than as one
   we have not photographed. The directory's own empty state is legible, and
   using it is also what partials/square-card.php says happens here. */
.sq-card .place-card-media--empty{
  height: 100%;
}

/* --- One building -------------------------------------------------------- */

.sq-names{ font-style: italic; opacity: .9; }

/* The building's own prose, above the city's survey text. */
.sq-own{ font-size: 17px; line-height: 1.7; }
.sq-own > :first-child{ margin-top: 0; }

/* The width is derived, not surveyed. Saying so beside the number is the
   honest place for it: a reader who copies the figure should copy the caveat
   with it, and the method note on the homepage may never be read. */
.sq-derived{
  display: block;
  margin-top: 1px;
  font-size: 11.5px;
  font-weight: 400;
  letter-spacing: .02em;
  color: var(--text-muted);
}

.sq-city{
  margin: 30px 0 0;
  padding: 4px 0 0;
  border-top: 1px solid var(--border);
}
.sq-city h2{
  font-size: 15px;
  letter-spacing: .02em;
  margin: 26px 0 8px;
}
.sq-city p{ color: var(--text-body); }
.sq-city-credit{
  margin: 22px 0 0;
  font-size: 12.5px;
  color: var(--text-muted);
}

.sq-outlinks{
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  margin: 26px 0 0;
  font-size: 14px;
  font-weight: 600;
}

/* --- Walk the square ----------------------------------------------------- */

.sq-walk{ padding-top: 0; }
.sq-walk-list{
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.sq-walk-list a{
  display: block;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  text-decoration: none;
  color: inherit;
}
.sq-walk-list a:hover,
.sq-walk-list a:focus{ border-color: var(--brand); background: var(--brand-wash); }
.sq-walk-next{ text-align: right; }
.sq-walk-dir{
  display: block;
  font-family: 'Montserrat', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 3px;
}
.sq-walk-name{
  display: block;
  font-family: 'Montserrat', system-ui, sans-serif;
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
}

/* --- Narrow screens ------------------------------------------------------
   The strip is 333 m of facade, which is a long sideways scroll on a phone.
   Below the theme's 767px breakpoint each side gets its own panel instead.
   Every panel shares one viewBox width, so they stay at one scale however
   narrow the screen is. Matching 767px rather than picking our own number
   keeps the switch in step with the navbar collapsing. */

@media (max-width: 767px){
  .sq-strip-view{ display: none; }
  .sq-panel-view{ display: block; }
  .sq-scroller{ padding: 0; }
  .sq-hint{ display: none; }
  .sq-walk-list{ grid-template-columns: 1fr; }
  .sq-walk-next{ text-align: left; }
}

/* --- Photographs ---------------------------------------------------------
   A guild house is roughly 7 m wide and 25 m tall, so a facade photograph is
   strongly portrait and gets a column of its own beside the figures rather
   than a full-width band, which would either crop the gable off or leave the
   page scrolling past one very tall picture. */

.sq-facade{
  margin: 0 0 26px;
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
  background: var(--surface-sunken);
}
.sq-facade img{
  display: block;
  width: 100%;
  height: auto;
}

.sq-detailshot{
  margin: 28px 0 0;
}
.sq-detailshot img{
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: 4px;
}
.sq-detailshot figcaption{
  margin: 9px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-muted);
}

@media (max-width: 767px){
  .sq-facade{ margin-bottom: 20px; }
}

/* --- Hover name on the elevation ----------------------------------------
   One label per building, shown only while that building is hovered or
   focused, so no script is involved and nothing overlaps. paint-order draws
   the halo under the glyphs, which keeps a name legible wherever it lands. */

.g-hover{
  opacity: 0;
  pointer-events: none;
  font: 600 12.5px 'Montserrat', system-ui, sans-serif;
  fill: var(--brand);
  paint-order: stroke fill;
  stroke: var(--sq-sheet);
  stroke-width: 3.5px;
  stroke-linejoin: round;
  transition: opacity .08s linear;
}
.house:hover .g-hover,
.house:focus .g-hover,
.house:focus-visible .g-hover{ opacity: 1; }

/* --- Key plan ------------------------------------------------------------ */

.sq-plan{
  margin: 0;
  padding: 4px 0 0;
}
.sq-plan figcaption{
  margin: 2px 0 0;
  font-size: 11.5px;
  letter-spacing: .04em;
  color: var(--text-muted);
}
.plan{
  display: block;
  width: 100%;
  height: auto;
  max-width: 420px;
}
.p-ring{
  fill: var(--surface-sunken);
  stroke: var(--sq-grid);
  stroke-width: 1;
}

/* A hairline through the facade line, so a corner with a street opening still
   reads as a corner rather than a break. */
.p-guide{
  fill: none;
  stroke: var(--sq-grid);
  stroke-width: 1;
}

/* Each building's frontage: as long as the facade is wide. Thickness is a
   line weight, deliberately not a depth — the survey has no footprints and a
   uniform invented depth would read as data. */
.p-front{
  stroke-width: 7;
  stroke-linecap: butt;
}
.p-front.p-guild{ stroke: var(--sq-guild); }
.p-front.p-civic{ stroke: var(--sq-civic); }
.p-front.p-house{ stroke: var(--sq-plain); }

.p-hit{
  stroke: transparent;
  stroke-width: 16;
  stroke-linecap: butt;
}

.p-corner{ fill: none; stroke: var(--text-muted); stroke-width: 1.1; }

.pin{ cursor: pointer; }
.pin:hover .p-front,
.pin:focus .p-front,
.pin.is-current .p-front{ stroke: var(--brand); }

.p-name{
  opacity: 0;
  pointer-events: none;
  font: 700 11.5px 'Montserrat', system-ui, sans-serif;
  fill: var(--text);
  paint-order: stroke fill;
  stroke: var(--sq-sheet);
  stroke-width: 3.5px;
  stroke-linejoin: round;
  transition: opacity .08s linear;
}
.pin:hover .p-name,
.pin:focus .p-name,
.pin:focus-visible .p-name{ opacity: 1; }
.pin:focus{ outline: none; }
.pin:focus-visible .p-hit{ stroke: var(--brand-wash); }

.p-north{
  font: 600 11px 'Open Sans', system-ui, sans-serif;
  fill: var(--text-muted);
}

/* Plan beside the drawing, stacking under it on a phone. */
.sq-planrow{
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: 22px;
  align-items: center;
  padding: 14px 16px 4px;
  border-bottom: 1px solid var(--sq-grid);
}
.sq-planrow p{
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
}
.sq-planrow b{ color: var(--text); font-weight: 600; }

@media (max-width: 767px){
  .sq-planrow{
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 12px 14px 4px;
  }
  .plan{ max-width: none; }
}

/* The plan is rotated to lay the square's long axis flat, so the compass is
   rotated with it. North is down and to the right. */
.p-compass line{ stroke: var(--text-muted); stroke-width: 1.3; }
.p-compass polygon{ fill: var(--text-muted); }

/* --- Reading order on a phone -------------------------------------------
   On a wide screen the drawings earn their place directly under the hero:
   the plan, then the elevation, are the one thing here nobody else has. On a
   phone the strip is replaced by four stacked panels, which put roughly two
   screens of drawing between the hero and the first building, and somebody
   standing on the cobbles wants the list. So below 767px the drawings move
   after the three category sections, using flex order rather than a second
   copy of the markup.

   Every child carries an explicit order, so this sequence holds whatever
   order the sections appear in the markup. Moving a section on the desktop
   page therefore does not disturb the phone one, which is the point.

   Scoped to .sq-home because .content is shared by every template. */

@media (max-width: 767px){
  .sq-home{
    display: flex;
    flex-direction: column;
  }
  .sq-home > #guild,
  .sq-home > #civic,
  .sq-home > #house{ order: 1; }
  .sq-home > #plan{ order: 2; }
  /* Every section needs a number here. An unordered flex item defaults to 0,
     so #model was added to the page and silently landed above all of these. */
  .sq-home > #model{ order: 3; }
  .sq-home > .sq-sheet-section{ order: 4; }
  .sq-home > #how-drawn{ order: 5; }
  .sq-home > .sq-credit-section{ order: 6; }
  .sq-home > .banner{ order: 7; }
}

/* --- Full-width footprint plan ------------------------------------------
   Drawn from OpenStreetMap footprints (ODbL) rather than the CC BY survey,
   which is why the caption carries two attributions and the partial refuses
   to render without them.

   Line work, not colour: a plan reads as outlines, so the footprints are
   hairlines on the sunken ground and the category rides on the numbered
   discs instead. */

.sq-fp{
  margin: 26px 0 0;
}

.sq-fp-frame{
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 6px;
  overflow: hidden;
}

.fp{
  display: block;
  width: 100%;
  height: auto;
}

.fp-shape{
  fill: var(--surface-sunken);
  stroke: var(--text-muted);
  stroke-width: 1;
  stroke-linejoin: round;
}

.fp-pin{ cursor: pointer; }
.fp-hit{ fill: transparent; }

.fp-disc{
  stroke: var(--surface);
  stroke-width: 1.5;
}
.fp-disc.fp-guild{ fill: var(--sq-guild); }
.fp-disc.fp-civic{ fill: var(--sq-civic); }
.fp-disc.fp-house{ fill: var(--sq-plain); }

.fp-num{
  font: 700 10px 'Open Sans', system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  fill: var(--brand-dark);
  pointer-events: none;
}

.fp-name{
  opacity: 0;
  pointer-events: none;
  font: 700 12.5px 'Montserrat', system-ui, sans-serif;
  fill: var(--text);
  paint-order: stroke fill;
  stroke: var(--surface);
  stroke-width: 4px;
  stroke-linejoin: round;
  transition: opacity .08s linear;
}

.fp-pin:hover .fp-disc,
.fp-pin:focus .fp-disc,
.fp-pin.is-current .fp-disc{ fill: var(--brand); }
.fp-pin:hover .fp-num,
.fp-pin:focus .fp-num,
.fp-pin.is-current .fp-num{ fill: var(--text-on-dark); }

/* The building whose page this is. Its disc is drawn at r 13 instead of 9
   (partials/square-footprint-plan.php), so the numeral grows with it; the
   heavier ring separates it from a neighbour it may now be touching. */
.fp-pin.is-current .fp-num{ font-size: 13.5px; }
.fp-pin.is-current .fp-disc{ stroke-width: 2; }
.fp-pin:hover .fp-name,
.fp-pin:focus .fp-name,
.fp-pin:focus-visible .fp-name{ opacity: 1; }
.fp-pin:focus{ outline: none; }
.fp-pin:focus-visible .fp-hit{
  fill: var(--brand-wash);
  stroke: var(--brand);
  stroke-width: 1.5;
}

.fp-compass line{ stroke: var(--text-muted); stroke-width: 1.4; }
.fp-compass polygon{ fill: var(--text-muted); }
.fp-north{
  font: 700 12px 'Open Sans', system-ui, sans-serif;
  fill: var(--text-muted);
}

.sq-fp-key{
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  align-items: center;
  margin: 14px 0 0;
  font-size: 13px;
  color: var(--text-muted);
}
.sq-fp-hint{ font-style: italic; }

.sq-fp figcaption{
  margin: 14px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 84ch;
}

/* On a phone the plan pans rather than shrinking. Scaled down to fit 375px
   the numbered discs render about 3px across, which is no use to anybody; a
   plan is two-dimensional and will not break into panels the way the
   elevation strip does, so it keeps its size and the reader swipes. */
@media (max-width: 767px){
  .sq-fp-frame{
    padding: 3px;
    overflow-x: auto;
    overflow-y: hidden;
  }
  .fp{
    width: 1100px;
    max-width: none;
  }
  .sq-fp-hint::after{ content: ' Swipe the plan sideways.'; }
}

/* --- The model ------------------------------------------------------------
   A turnable massing model of the square (partials/square-massing.php,
   js/square-3d.js). Same card, hairline and radius as the two plans: it is
   another drawing of the same survey, not a widget, so it is not framed like
   one. The stage keeps a fixed aspect so the page does not jump when the
   canvas replaces the button. */

.sq-3d{
  margin: 26px 0 0;
}

.sq-3d-stage{
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
}

/* Browsers without aspect-ratio fall back to a height that is close enough. */
@supports not (aspect-ratio: 1){
  .sq-3d-stage{ height: 520px; }
}

.sq-3d-placeholder{
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 24px;
  text-align: center;
}

.sq-3d-note{
  max-width: 32em;
  margin: 0;
  color: var(--text-muted);
}

.sq-3d-fallback{
  margin: 0;
  font-size: 13px;
  color: var(--text-muted);
}
/* Only worth saying once the button has proved useless. */
.sq-3d .sq-3d-fallback{ display: none; }
.sq-3d.is-unsupported .sq-3d-fallback{ display: block; }

.sq-3d-canvas{
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
  touch-action: none;       /* the gestures are the model's, not the page's */
}
.sq-3d-canvas:active{ cursor: grabbing; }
.sq-3d-canvas:focus{ outline: none; }
.sq-3d-canvas:focus-visible{
  outline: 2px solid var(--brand);
  outline-offset: -2px;
}

.sq-3d-bar{
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  align-items: center;
  justify-content: space-between;
  margin: 12px 0 0;
  font-size: 13px;
  color: var(--text-muted);
}

/* The readout is one line of live text, so it holds its height rather than
   shifting the controls under it every time the cursor crosses a building. */
.sq-3d-readout{
  flex: 1 1 16em;
  min-height: 1.5em;
}

.sq-3d-views{
  display: flex;
  gap: 6px;
}
.sq-3d-views button{
  min-width: 30px;
  padding: 3px 9px;
  font: 600 12px var(--sq-num);
  color: var(--text-muted);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
}
.sq-3d-views button:hover,
.sq-3d-views button:focus-visible{
  color: var(--brand);
  border-color: var(--brand);
}
/* The controls do nothing until the model is live. */
.sq-3d:not(.is-live) .sq-3d-bar{ display: none; }

.sq-3d figcaption{
  margin: 12px 0 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-muted);
}

@media (max-width: 767px){
  .sq-3d-stage{ aspect-ratio: 4 / 3; }
  @supports not (aspect-ratio: 1){
    .sq-3d-stage{ height: 380px; }
  }
  .sq-3d-bar{ justify-content: flex-start; }
}

@media (prefers-reduced-motion: reduce){
  /* Nothing here animates on its own; the note stays accurate either way. */
  .sq-3d-canvas{ cursor: default; }
}

/* --- Street labels on the model ------------------------------------------
   HTML over the canvas, not geometry in it (see js/square-3d.js). Each label
   marks the point where a street meets the square, so they sit on the
   openings and name which corner the reader is looking at. */

.sq-3d-labels{
  position: absolute;
  inset: 0;
  pointer-events: none;       /* the model underneath stays draggable */
}

.sq-3d-label{
  position: absolute;
  transform: translate(-50%, -50%);
  padding: 2px 7px;
  border-radius: 4px;
  /* The same 11px uppercase label as the drawings' side names and the
     eyebrows, on a wash of the page ground so it stays readable over both
     the pavement and a wall. */
  font: 700 11px 'Montserrat', system-ui, sans-serif;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text);
  background: rgba(255, 255, 255, 0.82);
  box-shadow: 0 0 0 1px var(--border);
}

@media (max-width: 767px){
  /* Smaller, because the stage is 343px wide on a phone and seven names at
     11px crowd the middle of the square. */
  .sq-3d-label{
    font-size: 10px;
    padding: 1px 5px;
    letter-spacing: .04em;
  }
}

/* --- The homepage masthead -----------------------------------------------
   Same component as the apartment's hero, on a different photograph, so it
   takes a different height. The apartment's is a 4:3 room and fills 100vh
   happily; this one is a 2400 by 1000 panorama of the square, and at 100vh
   on an ordinary desktop `cover` would crop about a third of its width away
   -- which is the whole point of a panorama. Sized to keep the sweep and
   trim sky and cobbles instead.

   The opener is absolutely positioned inside a masthead with overflow
   hidden, so its padding has to fit the shorter image: the theme's 240/160
   at this width is 400px of padding before a word of text, which a 500px
   hero cannot hold. Written mobile-first, in the same shape and with the
   same numbers as partials/critical.css, which has to repeat all of it for
   first paint because this file loads asynchronously. */

.sq-masthead .masthead-photo img{
  height: clamp(300px, 44vh, 430px);
  object-position: 50% 50%;
}
.sq-masthead .opener{
  padding: 108px 0 26px;

  /* A stronger scrim than the theme's. The apartment's hero is a dimly lit
     room, so rgba(0,0,0,.42) fading to transparent at 70% is enough there;
     this panorama is a bright sky over pale stone, and the lead sits about a
     third of the way down where that gradient has already faded to roughly
     .35 -- legible in a screenshot, not on the page. These are the same two
     stops partials/page-head.php uses on its photo band, for the same
     reason, and they stop before the bottom of the frame so the cobbles and
     the people stay clear. */
  background: linear-gradient(180deg,
              rgba(20, 24, 33, 0.82) 0%,
              rgba(20, 24, 33, 0.62) 70%,
              rgba(20, 24, 33, 0.30) 100%);
}

@media (min-width: 768px){
  .sq-masthead .masthead-photo img{
    height: clamp(400px, 56vh, 660px);
    object-position: 50% 44%;     /* the gables, not the sky */
  }
  .sq-masthead .opener{
    padding: 150px 0 56px;
    /* Wider screens give the lead a short measure high in the frame, so the
       scrim can lift sooner and leave more of the photograph alone. On a
       phone the same text is four lines filling most of the hero, which is
       why the base rule above stays dark much further down. */
    background: linear-gradient(180deg,
                rgba(20, 24, 33, 0.78) 0%,
                rgba(20, 24, 33, 0.55) 48%,
                rgba(20, 24, 33, 0.12) 100%);
  }
}

/* --- Photo credit ---------------------------------------------------------
   Shown whenever a photograph is not ours. CC BY-SA and CC BY both require
   the attribution to be visible and the licence named, so this is a condition
   of use rather than a caption, and it is never hidden on small screens. */

.sq-photo-credit{
  display: block;
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}

.sq-photo-credit a{
  color: inherit;
  border-bottom: 1px solid var(--border);
}

.sq-photo-credit a:hover,
.sq-photo-credit a:focus{
  color: var(--brand);
  border-bottom-color: currentColor;
}
