/* Minimal placeholder — the definitive graphic charter (brief §7) will be applied
   once the SSR listing pages are integrated, once the mockups are validated by the
   marketing department. Colors sampled directly from the provided logo
   (srp_logo_rvb_noir+couleurs.png): black #1a1a1a, gold #b58e5b.
   Fonts taken from the real site www.swissroc-properties.com (inspected live,
   2026-08-26): Geomanist for headings (h1/h2 on the real site), Arial/Helvetica
   for body text — the site doesn't use a custom font for the body.
   Geomanist is served there from Squarespace's private CDN (Squarespace license, not
   reusable as-is); .ttf files supplied under license by the user,
   self-hosted here (wwwroot/fonts/geomanist/), see the @font-face rules below. */

:root {
  --srp-cream: #f6f3ec;
  --srp-black: #1a1a1a;
  --srp-gold: #b58e5b;
  --srp-font-sans: Arial, "Helvetica Neue", Helvetica, sans-serif;
  --srp-font-heading: "Geomanist", var(--srp-font-sans);
}

@font-face {
  font-family: "Geomanist";
  font-weight: 100;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/geomanist/geomanist-thin-webfont.ttf") format("truetype");
}

@font-face {
  font-family: "Geomanist";
  font-weight: 200;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/geomanist/geomanist-extralight-webfont.ttf") format("truetype");
}

@font-face {
  font-family: "Geomanist";
  font-weight: 300;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/geomanist/geomanist-light.ttf") format("truetype");
}

@font-face {
  font-family: "Geomanist";
  font-weight: 350;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/geomanist/geomanist-book-webfont.ttf") format("truetype");
}

@font-face {
  font-family: "Geomanist";
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/geomanist/geomanist-regular-webfont.ttf") format("truetype");
}

@font-face {
  font-family: "Geomanist";
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/geomanist/geomanist-medium-webfont.ttf") format("truetype");
}

@font-face {
  font-family: "Geomanist";
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/geomanist/geomanist-bold-webfont.ttf") format("truetype");
}

@font-face {
  font-family: "Geomanist";
  font-weight: 800;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/geomanist/geomanist-black-webfont.ttf") format("truetype");
}

@font-face {
  font-family: "Geomanist";
  font-weight: 900;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/geomanist/geomanist-ultra-webfont.ttf") format("truetype");
}

* {
  box-sizing: border-box;
}

/* The browser's own stylesheet implements [hidden] as `display: none`, so ANY author
   rule setting `display` silently defeats it — .contact-modal__property's
   `display: flex` did exactly that, leaving an empty recap band showing on the
   catalogue where no listing is attached. Several elements here are toggled purely
   through the `hidden` attribute from JS (#contact-modal, the recap and its photo and
   reference, #listing-photos), so this is fixed once, globally, rather than with a
   [hidden] override per component. */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  font-family: var(--srp-font-sans);
  background: var(--srp-cream);
  color: var(--srp-black);
}

/* Vertical centering specific to the home page (placeholder) — doesn't apply to the
   global body, so as not to break the layout of longer-content pages (e.g. the
   catalogue) that need to stack normally. */
.placeholder {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2rem;
  padding: 2rem;
  text-align: center;
}

.placeholder__logo {
  width: 100%;
  max-width: 22rem;
  height: auto;
}

.placeholder__text {
  margin: 0;
  max-width: 26rem;
  font-size: 1rem;
  line-height: 1.5;
  color: color-mix(in srgb, var(--srp-black) 65%, transparent);
}

@media (max-width: 480px) {
  .placeholder__logo {
    max-width: 16rem;
  }
}

/* --- Catalogue "Biens à vendre" (/biens) --- */
/* Modeled on a marketing mockup (white background, header logo+CTA, cards with
   icons and a heart pill, numbered pagination) — still provisional until the
   final design is validated by the marketing department (brief §7). */

.catalog-page {
  /* Same background as www.swissroc-properties.com (body background:
     rgb(246, 243, 236), measured live on the site), so the
     transition between the two sites is invisible. */
  background: var(--srp-cream);
  min-height: 100vh;
}

.site-header {
  padding: 1rem 0;
  border-bottom: 1px solid rgba(26, 26, 26, 0.08);
}

/* Same width/margins as .catalog, so the logo and button align
   vertically with the title, the filter bar, etc. */
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: 78rem;
  margin: 0 auto;
  padding: 0 2rem;
}

.site-header__brand {
  display: flex;
  align-items: center;
  gap: 2.5rem;
}

.site-header__logo img {
  display: block;
  height: 34px;
  width: auto;
}

.site-header__nav {
  display: flex;
  align-items: center;
  gap: 1.75rem;
}

.site-header__nav a {
  color: var(--srp-black);
  font-size: 0.9rem;
  font-weight: 400;
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.09em;
}

.site-header__nav a:hover {
  color: var(--srp-gold);
}

.btn-dark {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.7rem 1.5rem;
  background: var(--srp-black);
  color: #fff;
  border: none;
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.catalog {
  max-width: 78rem;
  margin: 0 auto;
  padding: 2rem 2rem 4rem;
}

.catalog__intro {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: 1.5rem;
}

/* No bottom margin: the intro paragraph it used to separate from was removed on
   marketing request, and .catalog__intro's own align-items/gap handle the spacing
   against the count + sort control on the right. */
.catalog__title {
  margin: 0;
  font-family: var(--srp-font-heading);
  font-size: 2.5rem;
  /* Weight 500 confirmed on the real site (h1/h2 in Geomanist medium). */
  font-weight: 500;
}

.catalog__meta {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

.catalog__count {
  color: color-mix(in srgb, var(--srp-black) 65%, transparent);
  white-space: nowrap;
}

.pill-select {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.9rem;
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--srp-black) 70%, transparent);
  background: #fff;
  border: 1px solid rgba(26, 26, 26, 0.15);
  border-radius: 10px;
}

.pill-select select {
  font: inherit;
  font-weight: 600;
  color: var(--srp-black);
  background: transparent;
  border: none;
}

.catalog__filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem;
  padding: 1.25rem;
  margin-bottom: 2rem;
  background: #fff;
  border: 1px solid rgba(26, 26, 26, 0.1);
  border-radius: 12px;
}

.catalog__field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  flex: 1 1 9rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: color-mix(in srgb, var(--srp-black) 60%, transparent);
}

.catalog__field select,
.catalog__field input {
  padding: 0.55rem 0.75rem;
  font: inherit;
  font-weight: 400;
  color: var(--srp-black);
  background: #fff;
  border: 1px solid rgba(26, 26, 26, 0.18);
  border-radius: 8px;
  appearance: none;
}

.catalog__field select:disabled {
  color: color-mix(in srgb, var(--srp-black) 40%, transparent);
  background: color-mix(in srgb, var(--srp-black) 4%, #fff);
}

.catalog__field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a1a1a' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
  background-size: 1rem;
  padding-right: 2rem;
}

.pill-select select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a1a1a' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right center;
  background-size: 1rem;
  padding-right: 1.3rem;
  appearance: none;
}

.catalog__count {
  min-height: 1.2rem;
}

.catalog__grid {
  display: grid;
  /* 3 fixed columns on desktop (mockup) rather than an auto-fill that would add
     more on a large screen — leaves more room for the info under the photo. */
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

@media (max-width: 900px) {
  .catalog__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Catalogue error state (failed /api/properties/list, e.g. Realforce
   unavailable) — same structure/template as .srp-featured__state and
   .srp-projects__state in the Squarespace widgets (squarespace/*.html),
   duplicated there since Squarespace can't access this file. */
.catalog__state {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.6rem;
  padding: 3rem 1.5rem;
  background: #fff;
  border: 1px solid rgba(26, 26, 26, 0.08);
  border-radius: 14px;
  box-shadow: 0 1px 3px rgba(26, 26, 26, 0.08);
}

.catalog__state-icon {
  color: var(--srp-gold);
  width: 34px;
  height: 34px;
}

.catalog__state-icon svg {
  width: 100%;
  height: 100%;
}

.catalog__state-title {
  margin: 0;
  font-family: var(--srp-font-heading);
  font-weight: 500;
  font-size: 1.05rem;
  color: var(--srp-black);
}

.catalog__state-text {
  margin: 0;
  max-width: 28rem;
  font-size: 0.85rem;
  line-height: 1.5;
  color: rgba(26, 26, 26, 0.6);
}

.catalog__state-retry {
  margin-top: 0.4rem;
}

.catalog__card {
  position: relative;
  display: block;
  overflow: hidden;
  color: inherit;
  text-decoration: none;
  background: #fff;
  border: 1px solid rgba(26, 26, 26, 0.08);
  border-radius: 14px;
  box-shadow: 0 1px 3px rgba(26, 26, 26, 0.08);
  transition: box-shadow 0.15s ease;
}

.catalog__card:hover {
  box-shadow: 0 8px 20px rgba(26, 26, 26, 0.15);
}

.catalog__card img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
  background: var(--srp-cream);
}

.catalog__card-noimage {
  width: 100%;
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--srp-cream);
}

.catalog__card-noimage svg {
  width: 62%;
  height: auto;
  color: var(--srp-black);
}

.catalog__card-body {
  padding: 1rem 1.1rem 1.2rem;
}

.catalog__card h3 {
  margin: 0 0 0.3rem;
  font-size: 1rem;
}

.catalog__card-location {
  margin: 0 0 0.75rem;
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--srp-black) 60%, transparent);
}

.catalog__card-facts {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 0.75rem;
  /* Wrap rather than squeeze. Since the land-area pictogram was added, a villa can
     carry 4 facts, and next to an 8-digit Swiss price ("CHF 40'000'000.-") that no
     longer fits one row on a 3-column card — the price drops to its own line instead
     of the values breaking apart mid-unit ("11'000" above "m²"). */
  flex-wrap: wrap;
}

.catalog__card-icons {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem 0.75rem;
  font-size: 0.8rem;
  color: color-mix(in srgb, var(--srp-black) 70%, transparent);
}

.catalog__card-icons span {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  /* A surface must never break between its number and its unit. */
  white-space: nowrap;
}

/* Area/bedroom/room icons in gold (mockup), text/numbers stay gray —
   stroke="currentColor" on the SVG side reads this "color", not the parent span's. */
.catalog__card-icons svg {
  color: var(--srp-gold);
}

.catalog__card-price {
  font-weight: 700;
  white-space: nowrap;
}

.catalog__badges {
  position: absolute;
  top: 0.7rem;
  left: 0.7rem;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
}

/* Gold rather than the black of the original mockup (request, 2026-10-21), with
   white text (same request, after the contrast below was raised and accepted).
   Known trade-off: white on --srp-gold measures 3.01:1, under the 4.5:1 WCAG AA
   asks of text this size (0.7rem bold) — black would have reached 5.79:1. Darkening
   --srp-gold to about #8c6c45 would carry white past 4.5:1 if this ever needs to
   pass an accessibility audit. */
.catalog__badge {
  padding: 0.25rem 0.7rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: #fff;
  background: var(--srp-gold);
  border-radius: 999px;
}

/* No .catalog__badge--sold rule any more: "Vendu" is gold like every other badge
   (request, 2026-10-21 — it had been kept grey so that an unavailable listing
   wouldn't be highlighted). The modifier class went with it rather than being left
   as a hook with no styles. */

.catalog__pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  margin-top: 2.5rem;
}

.catalog__page,
.catalog__page-nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.25rem;
  height: 2.25rem;
  padding: 0 0.5rem;
  font: inherit;
  color: var(--srp-black);
  background: #fff;
  border: 1px solid rgba(26, 26, 26, 0.15);
  border-radius: 8px;
  cursor: pointer;
}

.catalog__page.is-active {
  color: #fff;
  background: var(--srp-black);
  border-color: var(--srp-black);
}

.catalog__page-nav:disabled {
  opacity: 0.35;
  cursor: default;
}

.catalog__page-ellipsis {
  padding: 0 0.25rem;
  color: color-mix(in srgb, var(--srp-black) 50%, transparent);
}

/* ---------- Listing detail page (/biens/{slug}) ---------- */

.listing {
  max-width: 60rem;
  margin: 0 auto;
  padding: 1.5rem 2rem 4rem;
}

.listing__back {
  display: inline-block;
  margin-bottom: 1.25rem;
  color: color-mix(in srgb, var(--srp-black) 70%, transparent);
  font-size: 0.9rem;
  text-decoration: none;
}

.listing__back:hover {
  color: var(--srp-gold);
}

.listing__gallery-main {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  background: var(--srp-cream);
  aspect-ratio: 16 / 9;
}

.listing__gallery-main img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.listing__gallery-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.listing__gallery-placeholder svg {
  width: 45%;
  height: auto;
}

.listing__badges {
  position: absolute;
  top: 0.9rem;
  left: 0.9rem;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.listing__badge {
  padding: 0.3rem 0.8rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  border-radius: 8px;
}

/* No --available rule: the listing page no longer renders a status badge for an
   available listing at all (request, 2026-10-21) — "Disponible" was the default
   state and said nothing the rest of the page didn't. Only "Réservé" and "Vendu"
   are worth a badge now. */
.listing__badge--reserved {
  background: #fff;
  color: var(--srp-black);
}

/* Gold like the card badges, so the same listing doesn't say "Vendu" in two
   different colours between the catalogue and its own page. */
.listing__badge--sold {
  background: var(--srp-gold);
  color: #fff;
}

.listing__gallery-nav {
  position: absolute;
  top: 50%;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  transform: translateY(-50%);
  background: rgba(255, 255, 255, 0.85);
  color: var(--srp-black);
  border: none;
  border-radius: 50%;
  cursor: pointer;
}

.listing__gallery-nav:hover {
  background: #fff;
  color: var(--srp-gold);
}

.listing__gallery-nav--prev {
  left: 0.75rem;
}

.listing__gallery-nav--next {
  right: 0.75rem;
}

.listing__counter {
  position: absolute;
  bottom: 0.9rem;
  right: 0.9rem;
  padding: 0.3rem 0.7rem;
  font-size: 0.75rem;
  color: #fff;
  background: rgba(26, 26, 26, 0.6);
  border-radius: 8px;
}

.listing__thumbs {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.6rem;
  margin-top: 0.6rem;
}

.listing__thumb {
  position: relative;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  aspect-ratio: 4 / 3;
  background: none;
}

.listing__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.listing__thumb.is-active {
  border-color: var(--srp-gold);
}

.listing__thumb-more {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  background: rgba(26, 26, 26, 0.55);
}

.listing__header {
  display: flex;
  flex-wrap: wrap;
  /* baseline, not flex-start: the title is 1.8rem and the price 1.5rem, so aligning
     their boxes' tops left their text sitting 11px apart (measured on a real listing
     page) — the price visibly floating above the title. Baseline alignment lines the
     two texts up on the same seat. The left item is a block (title + city +
     reference), whose baseline is its first line's, i.e. the title's — which is what
     the price should align with. When the row wraps on a narrow screen each flex
     line aligns on its own, so nothing changes there. */
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.75rem;
}

.listing__title {
  margin: 0 0 0.3rem;
  font-family: var(--srp-font-heading);
  font-weight: 500;
  font-size: 1.8rem;
}

.listing__location {
  margin: 0;
  color: color-mix(in srgb, var(--srp-black) 60%, transparent);
}

.listing__reference {
  margin: 0.2rem 0 0;
  font-size: 0.8rem;
  color: color-mix(in srgb, var(--srp-black) 45%, transparent);
}

.listing__price {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 700;
  white-space: nowrap;
}

.listing__facts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  margin-top: 1.5rem;
}

.listing__fact {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 1.1rem 0.5rem;
  text-align: center;
  background: #fff;
  border: 1px solid rgba(26, 26, 26, 0.08);
  border-radius: 12px;
}

.listing__fact svg {
  color: var(--srp-gold);
}

.listing__fact-value {
  font-weight: 700;
  font-size: 1.1rem;
}

.listing__fact span {
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--srp-black) 55%, transparent);
}

.listing__panel {
  margin-top: 1.5rem;
  padding: 1.5rem;
  background: #fff;
  border: 1px solid rgba(26, 26, 26, 0.08);
  border-radius: 14px;
}

.listing__panel h2 {
  margin: 0 0 1rem;
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--srp-black) 60%, transparent);
}

.listing__surfaces {
  margin: 0;
}

.listing__surfaces-row {
  display: flex;
  justify-content: space-between;
  padding: 0.6rem 0;
  border-bottom: 1px solid rgba(26, 26, 26, 0.06);
}

.listing__surfaces-row:last-child {
  border-bottom: none;
}

.listing__surfaces-row dt {
  color: color-mix(in srgb, var(--srp-black) 75%, transparent);
}

.listing__surfaces-row dd {
  margin: 0;
  font-weight: 700;
}

.listing__description {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-height: 1.6;
}

.listing__description.is-expanded {
  display: block;
  -webkit-line-clamp: unset;
}

.listing__description-toggle {
  margin-top: 0.75rem;
  padding: 0;
  background: none;
  border: none;
  color: var(--srp-gold);
  font-weight: 700;
  cursor: pointer;
}

.listing__broker {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.listing__broker-avatar {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  width: 66px;
  height: 66px;
  border-radius: 50%;
  background: var(--srp-cream);
  color: var(--srp-black);
  font-weight: 700;
}

.listing__broker-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.listing__broker-info {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.listing__broker-info span {
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--srp-black) 60%, transparent);
}

/* Discreet indicator (not a full-width error card like the Realforce widgets — the
   broker panel already shows usable data, just potentially incomplete): see
   PropertyCatalogService.BrokerEnrichmentFailed. */
.listing__broker-notice {
  margin: 0.6rem 0 0;
  font-size: 0.8rem;
  font-style: italic;
  color: color-mix(in srgb, var(--srp-black) 45%, transparent);
}

.listing__contact-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  margin-top: 1.5rem;
  text-transform: uppercase;
}

@media (max-width: 860px) {
  /* No hamburger menu for now — logo + 4 links + CTA don't fit on a
     narrow width; the menu stays accessible from the main site. */
  .site-header__nav {
    display: none;
  }
}

/* ---------- Contact modal ---------- */

.contact-modal-open {
  overflow: hidden;
}

.contact-modal__overlay {
  position: fixed;
  inset: 0;
  background: rgba(26, 26, 26, 0.6);
  z-index: 100;
}

.contact-modal__panel {
  position: fixed;
  inset: 0;
  z-index: 101;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  /* Bottom gap comes from .contact-modal__body's margin-bottom, not from padding
     here — see the note on that rule. */
  padding: 3vh 1rem 0;
  /* NO pointer-events: none here, however tempting it is for letting clicks on the
     empty area fall through to the overlay behind. This element is the scroll
     container, and a container that isn't hit-testable receives no gesture at all:
     it's skipped during hit-testing, so the browser finds no scrollable ancestor to
     pan and the form's lower half becomes unreachable by touch — reported on mobile,
     where the form is far taller than the viewport. Closing on an outside click is
     handled in contact-modal.js instead, by comparing event.target to this panel. */
  /* Keeps the page behind from taking over the scroll once the panel hits its end. */
  overscroll-behavior: contain;
}

.contact-modal__body {
  position: relative;
  width: 100%;
  max-width: 38rem;
  /* Nothing overflows the flex container's end padding on its own — margin-bottom
     rather than relying on the panel's bottom padding, which an overflowing flex item
     doesn't reserve room for, so the submit button can end up flush against the
     bottom edge. */
  margin-bottom: 3vh;
  padding: 2.5rem;
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(26, 26, 26, 0.25);
}

.contact-modal__close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--srp-black);
  cursor: pointer;
}

.contact-modal__body h2 {
  margin: 0 0 0.5rem;
  font-family: var(--srp-font-heading);
  font-weight: 500;
  font-size: 1.5rem;
}

.contact-modal__intro {
  margin: 0 0 1.5rem;
  color: color-mix(in srgb, var(--srp-black) 65%, transparent);
}

/* Recap of the listing the enquiry is about, above the form. Cream rather than the
   white card treatment used elsewhere: it sits *inside* a white panel, so a white
   box would need a border to exist at all — the tint reads as "context, not a
   field" without adding another outline to a form that already has many. */
.contact-modal__property {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem;
  margin: 0 0 1.5rem;
  background: var(--srp-cream);
  border-radius: 12px;
}

.contact-modal__property-photo {
  flex: 0 0 auto;
  width: 84px;
  height: 64px;
  object-fit: cover;
  border-radius: 8px;
}

/* min-width: 0 so a long title can actually ellipsize instead of stretching the
   flex item past the panel. */
.contact-modal__property-info {
  min-width: 0;
}

.contact-modal__property-name {
  margin: 0;
  font-family: var(--srp-font-heading);
  font-weight: 500;
  font-size: 0.95rem;
  line-height: 1.3;
  color: var(--srp-black);
  /* Two lines maximum: some real Realforce titles are very long, and this recap
     must not push the form's first field off screen. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.contact-modal__property-reference {
  margin: 0.2rem 0 0;
  font-size: 0.75rem;
  color: color-mix(in srgb, var(--srp-black) 55%, transparent);
}

.contact-modal__property-price {
  margin: 0.2rem 0 0;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--srp-black);
}

#contact-modal-form {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.contact-modal__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem;
}

.contact-modal__field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 0.85rem;
  font-weight: 600;
}

.contact-modal__radios {
  border: none;
  margin: 0;
  padding: 0;
}

.contact-modal__radios legend {
  padding: 0;
  font-size: inherit;
  font-weight: inherit;
}

.contact-modal__radio-group {
  display: flex;
  gap: 1.5rem;
  margin-top: 0.4rem;
}

.contact-modal__radios .contact-modal__radio {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-weight: 400;
}

.contact-modal__radios .contact-modal__radio input {
  width: auto;
}

.contact-modal__field input,
.contact-modal__field textarea,
.contact-modal__field select {
  padding: 0.65rem 0.8rem;
  font: inherit;
  font-weight: 400;
  color: var(--srp-black);
  background: #fff;
  border: 1px solid rgba(26, 26, 26, 0.2);
  border-radius: 8px;
}

.contact-modal__field textarea {
  resize: vertical;
}

.contact-modal__phone {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.6rem;
}

.contact-modal__legal-text {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.5;
  color: color-mix(in srgb, var(--srp-black) 55%, transparent);
}

.contact-modal__checkbox {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: 0.85rem;
}

.contact-modal__checkbox input {
  margin-top: 0.2rem;
  flex: none;
}

.contact-modal__submit {
  align-self: flex-start;
  margin-top: 0.5rem;
}

.contact-modal__submit:disabled {
  opacity: 0.6;
  cursor: default;
}

.contact-modal__error {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.6rem 0.8rem;
  background: color-mix(in srgb, #b3261e 8%, transparent);
  border-radius: 8px;
  color: #b3261e;
  font-size: 0.85rem;
}

.contact-modal__error svg {
  flex: none;
  width: 18px;
  height: 18px;
}

/* Taken from www.swissroc-properties.com's footer (measured live,
   2026-08-28) — #36302a has no equivalent among the existing --srp-*
   variables (a color specific to the footer, not reused elsewhere). */
.site-footer {
  background: #36302a;
  color: var(--srp-cream);
  padding: 3rem 0;
}

.site-footer__inner {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 2rem;
  max-width: 78rem;
  margin: 0 auto;
  padding: 0 2rem;
}

.site-footer__columns {
  display: flex;
  flex-wrap: wrap;
  gap: 3rem;
}

.site-footer__col h3 {
  margin: 0 0 1rem;
  font-family: var(--srp-font-heading);
  font-weight: 500;
  font-size: 1.5rem;
  color: var(--srp-cream);
}

.site-footer__col p {
  margin: 0;
  line-height: 1.8;
}

.site-footer__col a {
  color: var(--srp-cream);
  text-decoration: underline;
}

.site-footer__logo {
  height: 32px;
  width: auto;
  align-self: flex-start;
}

@media (max-width: 640px) {
  .site-header__inner {
    padding: 0 1rem;
    /* Last resort below roughly 340px: the CTA drops to its own row rather than
       being clipped. .btn-dark is nowrap and can't shrink, and the header has
       overflow clipped rather than scrollable, so without this the label is simply
       cut off at the right edge — which is what happened on a listing page, where
       the CTA reads "Contacter le courtier" (228px) instead of the catalogue's
       shorter "Nous contacter". Measured at 320px: 96px of overflow, zero right
       margin. Above ~340px the row still fits and nothing wraps. */
    flex-wrap: wrap;
    row-gap: 0.75rem;
  }

  /* Shrunk together so the long "Contacter le courtier" label fits on one row at
     the common phone widths (verified at 375px: 119 + 190 + the 16px padding, no
     overflow) — the wrap above only ever kicks in on very narrow screens. */
  .site-header__logo img {
    height: 26px;
  }

  .site-header .btn-dark {
    padding: 0.6rem 1rem;
    font-size: 0.7rem;
  }

  .catalog {
    padding: 1.5rem 1rem 3rem;
  }

  .catalog__grid {
    grid-template-columns: 1fr;
  }

  .catalog__intro {
    align-items: flex-start;
  }

  .listing {
    padding: 1.5rem 1rem 3rem;
  }

  .listing__thumbs {
    /* Only the large photo on mobile — the prev/next navigation on
       it (.listing__gallery-nav) stays the only way to browse the
       photos, no extra row of thumbnails. */
    display: none;
  }

  .listing__facts {
    gap: 0.6rem;
  }

  .listing__fact {
    padding: 0.9rem 0.3rem;
  }

  .contact-modal__body {
    padding: 1.75rem;
  }

  .contact-modal__row {
    grid-template-columns: 1fr;
  }

  .site-footer__inner {
    padding: 0 1rem;
  }

  .site-footer__columns {
    flex-direction: column;
    gap: 1.5rem;
  }
}

/* ---------------------------------------------------------------------------
   Error/status page (Pages/ErrorStatus.cshtml, route /erreur/{code}) — in
   practice the 404, on an unknown route or an unknown listing slug. Same shell
   as the catalogue (header, cream background, footer) so a visitor landing on a
   dead link visibly stays on the site instead of falling onto a bare framework
   page. The card itself reuses the .catalog__state treatment (white, 14px
   radius, hairline border, soft shadow) rather than inventing a second one. */
.error-page {
  background: var(--srp-cream);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* flex: 1 so the footer sits at the bottom of the viewport even though this page
   has far less content than the catalogue. */
.error-page__main {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 78rem;
  margin: 0 auto;
  padding: 4rem 2rem 5rem;
}

.error-page__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.75rem;
  width: 100%;
  max-width: 34rem;
  padding: 3.5rem 2.5rem;
  background: #fff;
  border: 1px solid rgba(26, 26, 26, 0.08);
  border-radius: 14px;
  box-shadow: 0 1px 3px rgba(26, 26, 26, 0.08);
}

/* Gold rather than black: the code is decorative here, the heading below carries
   the actual message — keeps the 404 from reading as an alarm. */
.error-page__code {
  margin: 0;
  font-family: var(--srp-font-heading);
  font-weight: 500;
  font-size: clamp(3.5rem, 12vw, 5.5rem);
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--srp-gold);
}

.error-page__title {
  margin: 0.25rem 0 0;
  font-family: var(--srp-font-heading);
  font-weight: 500;
  font-size: 1.5rem;
  color: var(--srp-black);
}

.error-page__text {
  margin: 0;
  max-width: 26rem;
  font-size: 0.9rem;
  line-height: 1.6;
  color: rgba(26, 26, 26, 0.6);
}

.error-page__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

/* 5xx only — deliberately quiet: useful to quote to support, but it must not
   compete with the actions above it. */
.error-page__ref {
  margin: 1.25rem 0 0;
  font-size: 0.75rem;
  line-height: 1.5;
  color: rgba(26, 26, 26, 0.45);
}

.error-page__ref code {
  font-size: 0.75rem;
  word-break: break-all;
  color: rgba(26, 26, 26, 0.6);
}

/* Same pill geometry as .btn-dark, outlined instead of filled — secondary action
   next to it, so the two never compete. */
.btn-outline {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.7rem 1.5rem;
  background: transparent;
  color: var(--srp-black);
  border: 1px solid rgba(26, 26, 26, 0.25);
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.btn-outline:hover {
  border-color: var(--srp-black);
}

@media (max-width: 600px) {
  .error-page__main {
    padding: 2.5rem 1rem 3.5rem;
  }

  .error-page__card {
    padding: 2.5rem 1.5rem;
  }

  /* Stacked full-width buttons rather than two cramped pills side by side. */
  .error-page__actions {
    flex-direction: column;
    align-self: stretch;
  }

  .error-page__actions > * {
    justify-content: center;
  }
}
