/* Dyer Real Estate — shared styles */

/* Palette: Alexandria Tigers maroon and gold, matched to the school's own
   site. Every color here flows through these variables — change one and it
   updates everywhere. (Three files keep their own copies, because SVG fills
   can't read CSS variables: images/logo.svg, the castle intro animation in
   index.html, and images/placeholders/*.svg.) */
:root {
  --color-bg: #ffffff;
  --color-bg-alt: #f8f6f4;
  --color-text: #20262e;
  --color-text-muted: #625d5b;
  --color-primary: #8b2332;
  --color-primary-dark: #6d1a26;
  --color-accent: #f9c132;
  /* A dark bronze rather than a darker gold: this is used as text on white
     (agent job titles, the "Price Reduced" badge), and real gold is far too
     light to read there. */
  --color-accent-dark: #8a6608;
  --color-border: #e6e2df;
  --color-success: #2e7d4f;
  --color-success-bg: #eaf6ef;
  /* A brighter, more orange red than the maroon, so error text reads as an
     error rather than as ordinary branding. */
  --color-danger: #9e3327;
  --color-danger-bg: #fbeae7;
  --font-heading: Georgia, 'Times New Roman', serif;
  --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --radius: 6px;
  --header-height: 72px;
  --max-width: 1180px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  color: var(--color-primary-dark);
  margin: 0 0 0.5em;
  line-height: 1.2;
}

p { margin: 0 0 1em; }

a { color: var(--color-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

img { max-width: 100%; display: block; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

.container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 24px;
}

/* Buttons */
.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 600;
  padding: 10px 20px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.btn:hover { text-decoration: none; }
.btn-primary { background: var(--color-primary); color: #fff; }
.btn-primary:hover { background: var(--color-primary-dark); }
/* Gold can't carry white text — near-black on gold, the same pairing the
   school's own gold nav bar uses. On hover the fill darkens to bronze, so
   the text flips to white. */
.btn-accent { background: var(--color-accent); color: #20262e; }
.btn-accent:hover { background: var(--color-accent-dark); color: #fff; }
.btn-outline { background: transparent; color: var(--color-primary); border-color: var(--color-primary); }
.btn-outline:hover { background: var(--color-primary); color: #fff; }
.btn-danger { background: transparent; color: var(--color-danger); border-color: var(--color-danger); }
.btn-danger:hover { background: var(--color-danger); color: #fff; }
.btn-sm { padding: 6px 14px; font-size: 0.85rem; }
.btn-block { display: block; width: 100%; text-align: center; }
.btn[disabled] { opacity: 0.6; cursor: not-allowed; }

/* Site header — two tiers, after the Alexandria-Monroe school site:
   a maroon brand bar with a gold nav bar beneath it.

   There's no hamburger menu. With only three links, they shrink to fit
   even a narrow phone, which is simpler and steadier than a menu that has
   to open and close. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--color-primary);
}
.header-top {
  background: var(--color-primary);
}
.header-top .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 13px;
  padding-bottom: 13px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 1;
  min-width: 0;
}
.brand:hover { text-decoration: none; }
.brand img, .brand svg { height: 38px; width: 38px; flex-shrink: 0; }
.brand-text {
  font-family: var(--font-heading);
  font-size: 1.25rem;
  color: #fff;
  font-weight: bold;
  white-space: nowrap;
}
.brand-text small {
  display: block;
  font-family: var(--font-body);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: rgba(255,255,255,0.8);
  text-transform: uppercase;
}
.header-phone {
  color: #fff;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
  flex-shrink: 0;
}
.header-phone:hover { text-decoration: underline; }

.header-nav {
  background: var(--color-accent);
}
.main-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 36px;
  flex-wrap: wrap;
}
.main-nav a {
  color: #20262e;
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 11px 2px;
  border-bottom: 3px solid transparent;
}
.main-nav a:hover, .main-nav a.active {
  color: var(--color-primary-dark);
  border-bottom-color: var(--color-primary-dark);
  text-decoration: none;
}

@media (max-width: 700px) {
  .brand-text { font-size: 1.05rem; }
  .brand-text small { font-size: 0.55rem; }
  .header-phone { font-size: 0.72rem; letter-spacing: 0.04em; }
  .main-nav { gap: 18px; }
  .main-nav a { font-size: 0.72rem; letter-spacing: 0.04em; }
}
@media (max-width: 420px) {
  /* The phone number moves to its own line rather than squeezing the name. */
  .header-top .container { flex-wrap: wrap; justify-content: center; gap: 8px; }
  .main-nav { gap: 12px; }
  .main-nav a { font-size: 0.68rem; letter-spacing: 0.02em; }
}

/* Footer */
.site-footer {
  background: var(--color-primary-dark);
  color: #e6bcc3;
  padding: 40px 0 24px;
  margin-top: 60px;
}
.site-footer a { color: #fff; }
.footer-grid {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr;
  gap: 32px;
  margin-bottom: 24px;
}
.footer-grid h4 {
  color: #fff;
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 10px;
}
.footer-grid p, .footer-grid a {
  font-size: 0.9rem;
  color: #e6bcc3;
}
/* Office address in the footer. <address> is italic by default everywhere;
   this is a postal address, so that's reset. */
.footer-address {
  font-style: normal;
  font-size: 0.9rem;
  color: #e6bcc3;
  line-height: 1.6;
  margin: 0 0 10px;
}
.footer-grid ul { list-style: none; padding: 0; margin: 0; }
.footer-grid li { margin-bottom: 6px; }
.footer-bottom {
  border-top: 1px solid rgba(255,255,255,0.15);
  padding-top: 16px;
  font-size: 0.8rem;
  color: #eec9cf;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}
.staff-link { font-size: 0.8rem; color: #eec9cf; }
@media (max-width: 700px) {
  /* Once the three columns stack into one, left-aligned text reads as ragged
     against the centered content above it, so the whole footer centers. */
  .footer-grid { grid-template-columns: 1fr; text-align: center; }
  .footer-bottom { justify-content: center; text-align: center; }
}

/* Hero — split panel + bright carousel */
.hero {
  display: grid;
  grid-template-columns: minmax(380px, 460px) 1fr;
  min-height: min(72vh, 580px);
  background: var(--color-primary-dark);
}
.hero-panel {
  color: #fff;
  padding: 56px 48px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background:
    radial-gradient(ellipse at top left, rgba(249,193,50,0.12), transparent 55%),
    var(--color-primary-dark);
}
.hero-badge {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #fbd166;
  border: 1px solid rgba(251,209,102,0.55);
  padding: 5px 12px;
  border-radius: 3px;
  margin-bottom: 22px;
  align-self: flex-start;
}
.hero-carousel {
  position: relative;
  overflow: hidden;
  background: #5c1520;
  min-height: 320px;
  contain: layout paint;
}
.hero-slides { position: absolute; inset: 0; }
.hero-slide {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  visibility: hidden;
  transform: scale(1.06);
  transition: opacity 1.2s ease, visibility 0s linear 1.2s;
}
/* Ken Burns zoom runs only while a slide is visible; "leaving" keeps the
   outgoing slide's zoom going during the crossfade so it doesn't snap. */
.hero-slide.active,
.hero-slide.leaving {
  visibility: visible;
  animation: heroZoom 7s linear forwards;
  will-change: transform, opacity;
}
.hero-slide.active {
  opacity: 1;
  transition: opacity 1.2s ease;
}
@keyframes heroZoom {
  from { transform: scale(1.06); }
  to { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-slide,
  .hero-slide.active,
  .hero-slide.leaving {
    animation: none;
    transform: none;
    transition: opacity 0.4s ease, visibility 0s linear 0.4s;
  }
}
.hero-title {
  font-size: clamp(1.9rem, 3.2vw, 2.5rem);
  font-weight: 400;
  color: #fff;
  line-height: 1.15;
  margin-bottom: 16px;
}
.hero-title em {
  font-style: italic;
  color: var(--color-accent);
}
.hero-sub {
  color: rgba(255,255,255,0.8);
  max-width: 420px;
  margin-bottom: 28px;
}
.hero-ctas {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 340px;
}
.hero-ctas .btn { text-align: center; }
.hero-caption {
  position: absolute;
  left: 24px;
  bottom: 24px;
  z-index: 2;
  display: block;
  background: rgba(92,21,32,0.85);
  color: #fff;
  padding: 10px 16px;
  border-radius: 5px;
  border-left: 3px solid var(--color-accent);
  text-decoration: none;
}
.hero-caption:hover { background: rgba(92,21,32,0.97); text-decoration: none; }
.hero-caption-price {
  display: block;
  font-family: var(--font-heading);
  font-size: 1.25rem;
}
.hero-caption-addr {
  display: block;
  font-size: 0.85rem;
  color: rgba(255,255,255,0.85);
}
.btn-lg { padding: 13px 28px; font-size: 1rem; }
.btn-ghost {
  background: rgba(255,255,255,0.08);
  color: #fff;
  border-color: rgba(255,255,255,0.55);
}
.btn-ghost:hover { background: #fff; color: var(--color-primary-dark); }
@media (max-width: 860px) {
  .hero { grid-template-columns: 1fr; }
  .hero-panel { padding: 40px 24px; }
  .hero-carousel { min-height: 300px; }
}
.hero-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #e6bcc3;
  font-size: 1rem;
}

/* Community bar under hero */
.hero-bar { background: var(--color-primary-dark); color: #fff; }
.hero-bar-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 24px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  text-align: center;
}
.hero-bar-inner a {
  display: block;
  padding: 18px 10px;
  border-right: 1px solid rgba(255,255,255,0.12);
  color: #fff;
  text-decoration: none;
  transition: background 0.15s ease;
}
.hero-bar-inner a:last-child { border-right: none; }
.hero-bar-inner a:hover { background: rgba(255,255,255,0.06); text-decoration: none; }
.hero-bar .town {
  display: block;
  font-family: var(--font-heading);
  font-size: 1.05rem;
  color: var(--color-accent);
}
.hero-bar .count {
  display: block;
  font-size: 0.78rem;
  color: rgba(255,255,255,0.65);
}
@media (max-width: 700px) {
  .hero-bar-inner { grid-template-columns: 1fr 1fr; }
  .hero-bar-inner a:nth-child(2) { border-right: none; }
  .hero-bar-inner a:nth-child(1),
  .hero-bar-inner a:nth-child(2) { border-bottom: 1px solid rgba(255,255,255,0.12); }
}

/* Tabs / listings browser */
.listings-section { padding: 56px 0; }
.section-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 20px;
  flex-wrap: wrap;
  gap: 12px;
}
.tabs {
  display: flex;
  gap: 6px;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 28px;
  flex-wrap: wrap;
}
.tab-btn {
  background: none;
  border: none;
  padding: 10px 18px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--color-text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tab-btn:hover { color: var(--color-primary); }
.tab-btn.active {
  color: var(--color-primary);
  border-bottom-color: var(--color-accent);
}

/* min(260px, 100%) rather than a bare 260px: on a screen narrower than the
   track minimum, a plain minmax() refuses to shrink and the whole grid
   spills off the side, giving the page a horizontal scrollbar. This matters
   below ~310px (a folded Galaxy Fold is 280px). */
.listing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
  gap: 22px;
}
.listing-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  overflow: hidden;
  background: #fff;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
  display: flex;
  flex-direction: column;
  cursor: pointer;
}
.listing-card:hover { box-shadow: 0 4px 18px rgba(62,18,28,0.12); transform: translateY(-2px); }
.listing-photo {
  height: 170px;
  background: var(--color-bg-alt);
  background-size: cover;
  background-position: center;
  position: relative;
}
.listing-photo .save-btn {
  position: absolute;
  top: 10px; right: 10px;
  background: rgba(255,255,255,0.92);
  border: none;
  border-radius: 50%;
  width: 34px; height: 34px;
  cursor: pointer;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-muted);
}
.listing-photo .save-btn.saved { color: var(--color-accent); }
.listing-photo .placeholder-icon {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--color-border);
}
.listing-photo .placeholder-icon svg { width: 48px; height: 48px; }

/* Skeleton "shimmer" shown while a photo is loading (see img-skeleton.js).
   Works two ways: as an overlay on background-image tiles (listing cards,
   hero slides, agent avatars — paired with data-bg-src), and as an opacity
   fade on real <img> tags (gallery main photo, floor plan — paired with
   class="img-fade"). Neither makes the photo download faster; it just keeps
   the layout from sitting on a blank box while it does. */
/* No "position" here on purpose — every element this is used on already
   establishes its own positioning context (relative/absolute) for other
   layout reasons except .agent-avatar, which gets position:relative added
   directly on its own rule below, so this never clobbers .hero-slide's
   position:absolute stacking. */
.img-skeleton { background-color: var(--color-bg-alt); overflow: hidden; }
.img-skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.6), transparent);
  background-size: 200% 100%;
  animation: dyer-shimmer 1.3s ease-in-out infinite;
  opacity: 1;
  transition: opacity 0.25s ease;
  pointer-events: none;
}
.img-skeleton.is-loaded::after { opacity: 0; }
@keyframes dyer-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
img.img-skeleton.img-fade { opacity: 0; transition: opacity 0.25s ease; background: none; }
img.img-skeleton.img-fade.is-loaded { opacity: 1; }
img.img-skeleton.img-fade.is-loaded::after { display: none; }

.listing-body { padding: 14px 16px 16px; flex: 1; display: flex; flex-direction: column; }
.listing-price {
  font-family: var(--font-heading);
  font-size: 1.3rem;
  color: var(--color-primary-dark);
}
.listing-address { color: var(--color-text); font-size: 0.95rem; }
.listing-city { color: var(--color-text-muted); font-size: 0.85rem; margin-bottom: 10px; }
.listing-badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 3px 8px;
  border-radius: 4px;
  background: var(--color-bg-alt);
  color: var(--color-text-muted);
  margin-bottom: 8px;
  align-self: flex-start;
}
/* "Price Reduced" used to be a red badge, which no longer stands out now
   that red is the brand color — it reads as ordinary Dyer chrome. Tan keeps
   it noticeable against a red header and a photo. */
.listing-badge.reduced { background: #fdf4d9; color: #8a6608; }
.listing-badge.open { background: var(--color-success-bg); color: var(--color-success); }
.listing-card .card-actions { margin-top: auto; padding-top: 10px; }

.empty-state {
  text-align: center;
  padding: 40px 20px;
  color: var(--color-text-muted);
}

/* Generic page sections */
.page-hero {
  background: var(--color-bg-alt);
  padding: 48px 0;
  text-align: center;
  border-bottom: 1px solid var(--color-border);
}
.page-hero p { color: var(--color-text-muted); max-width: 640px; margin: 0 auto; }

/* Centered rather than left-aligned. auto-fill kept reserving empty columns
   on wide screens, which pushed three agents to the left with a gap beside
   them; auto-fit drops the empty tracks and justify-content centers what's
   left. The 320px cap stops a small team from stretching into oversized
   cards, and min(260px, 100%) keeps a single card from overflowing a narrow
   phone. Works for any number of agents. */
.agents-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 320px));
  justify-content: center;
  gap: 24px;
  padding: 48px 0 64px;
}
.agent-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 24px;
  text-align: center;
}
/* Sized for real headshots — the initials fallback fills the same circle. */
.agent-avatar {
  width: 116px; height: 116px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  font-family: var(--font-heading);
  font-size: 1.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 14px;
  position: relative;
}
.agent-card h3 { margin-bottom: 2px; }
.agent-title { color: var(--color-accent-dark); font-weight: 600; font-size: 0.9rem; margin-bottom: 10px; }
.agent-contact { font-size: 0.9rem; color: var(--color-text-muted); }
.agent-contact a { color: var(--color-text-muted); }
.agent-contact div { margin-bottom: 3px; }
.agent-contact .phone-label {
  display: inline-block;
  min-width: 46px;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-accent-dark);
}
.agent-avatar-photo {
  background-size: cover;
  background-position: center;
  font-size: 0; /* hide initials fallback text when a photo is set */
}
.agent-initials { line-height: 1; }
/* The promise carried over from the old dyerre.net, now heading the Agents
   page. Serif italic under a short gold rule, so it reads as the brokerage
   speaking rather than as ordinary page copy.

   The selector is `p.brand-statement`, not `.brand-statement`: it has to
   outrank `.page-hero p` above, which would otherwise force the muted grey
   back on. Keep this rule below that one. */
p.brand-statement {
  position: relative;
  max-width: 660px;
  margin: 22px auto 0;
  padding-top: 24px;
  font-family: var(--font-heading);
  font-style: italic;
  font-size: 1.08rem;
  line-height: 1.65;
  color: var(--color-primary-dark);
}
p.brand-statement::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 56px;
  height: 3px;
  border-radius: 2px;
  background: var(--color-accent);
}
/* On a phone this runs to six or seven lines of italic serif before the
   first agent is visible. Easing the size and the surrounding padding buys
   back roughly a third of that height without shrinking it into fine print. */
@media (max-width: 560px) {
  .page-hero { padding: 32px 0; }
  p.brand-statement {
    font-size: 0.98rem;
    margin-top: 18px;
    padding-top: 20px;
  }
}

.muted { color: var(--color-text-muted); }

/* Forms */
.form-card {
  max-width: 420px;
  margin: 56px auto;
  padding: 32px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}
.form-card h1 { font-size: 1.5rem; text-align: center; }
.form-subtext { text-align: center; color: var(--color-text-muted); margin-bottom: 24px; font-size: 0.9rem; }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 0.85rem; font-weight: 600; margin-bottom: 6px; color: var(--color-text); }
.label-optional { font-weight: 400; color: var(--color-text-muted); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font-size: 0.95rem;
  font-family: var(--font-body);
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--color-primary);
}
.field-hint { font-size: 0.8rem; color: var(--color-text-muted); margin-top: 4px; }
.form-msg {
  padding: 10px 12px;
  border-radius: var(--radius);
  font-size: 0.88rem;
  margin-bottom: 16px;
  display: none;
}
.form-msg.error { display: block; background: var(--color-danger-bg); color: var(--color-danger); }
.form-msg.success { display: block; background: var(--color-success-bg); color: var(--color-success); }
.form-switch { text-align: center; margin-top: 16px; font-size: 0.9rem; color: var(--color-text-muted); }

/* Filter bar (full listings page) */
.filter-bar {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  align-items: flex-end;
  padding: 24px 0;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 28px;
}
/* flex-basis 150px with grow: the four filters sit side by side on a laptop,
   then wrap and stretch to fill the row on a phone instead of leaving each
   dropdown stranded at 150px against a wide empty gap. */
.filter-bar .field { margin-bottom: 0; flex: 1 1 150px; min-width: 150px; }

/* Staff dashboard */
.dash-shell { display: flex; min-height: calc(100vh - var(--header-height)); }
.dash-sidebar {
  width: 220px;
  background: var(--color-bg-alt);
  border-right: 1px solid var(--color-border);
  padding: 24px 0;
  flex-shrink: 0;
}
.dash-sidebar a {
  display: block;
  padding: 10px 24px;
  color: var(--color-text);
  font-weight: 600;
  font-size: 0.92rem;
}
.dash-sidebar a.active { color: var(--color-primary); background: #fff; border-right: 3px solid var(--color-accent); }
.dash-main { flex: 1; padding: 32px; max-width: 980px; }
.dash-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.dash-table th, .dash-table td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--color-border);
}
.dash-table th { color: var(--color-text-muted); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; }
.dash-table .thumb { width: 48px; height: 36px; border-radius: 4px; background: var(--color-bg-alt); }
.dash-table img.thumb { object-fit: cover; }
.status-pill {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 10px;
  background: var(--color-bg-alt);
  color: var(--color-text-muted);
}
.status-pill.active { background: var(--color-success-bg); color: var(--color-success); }
.status-pill.sold { background: var(--color-danger-bg); color: var(--color-danger); }
.dash-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 12px; }
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(40,12,14,0.5);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 20px;
}
.modal-overlay.open { display: flex; }
.modal-card {
  background: #fff;
  border-radius: var(--radius);
  padding: 28px;
  max-width: 480px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
}
.modal-card h2 { font-size: 1.2rem; }
.photo-preview {
  width: 100%;
  height: 140px;
  background: var(--color-bg-alt);
  border-radius: var(--radius);
  margin-bottom: 10px;
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-muted);
  font-size: 0.85rem;
  overflow: hidden;
}

/* Focal-point picker — wraps .photo-preview in the photo upload modals */
.focal-wrap { position: relative; }
.focal-wrap.has-photo .photo-preview { cursor: crosshair; }
.focal-dot {
  display: none;
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid #fff;
  background: var(--color-accent);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.35);
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.focal-hint {
  display: none;
  color: var(--color-text-muted);
  font-size: 0.78rem;
  margin-top: 6px;
}

/* First-visit intro — castle builds brick by brick, door glows, flash into site */
html.intro-lock, html.intro-lock body { overflow: hidden; }
.intro-overlay {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: #fcf9f2;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: introFadeOut 0.45s ease 2.75s forwards;
}
.intro-overlay[hidden] { display: none; }
.intro-inner { text-align: center; }
.intro-castle { width: 132px; height: 132px; overflow: visible; }
.intro-castle rect {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transform: translateY(-14px);
  animation: introBrick 0.3s cubic-bezier(0.3, 1.4, 0.5, 1) forwards;
  animation-delay: var(--d);
}
.intro-castle .intro-door {
  animation:
    introBrick 0.3s cubic-bezier(0.3, 1.4, 0.5, 1) 1.05s forwards,
    introDoorGlow 0.5s ease 1.35s forwards;
}
.intro-name {
  margin-top: 14px;
  font-family: var(--font-heading);
  color: var(--color-primary-dark);
  font-size: 1.35rem;
  letter-spacing: 0.04em;
  opacity: 0;
  animation: introName 0.5s ease 0.85s forwards;
}
/* Tamra's line, arriving after the name so it reads as the payoff to the
   castle building itself. The tagline fades in at 1.2s and the flash comes
   at 2.6s, leaving it fully visible for about 0.9s. To give it longer, push
   the flash and fade-out delays back and raise the matching setTimeout in
   index.html by the same amount — all three move together. */
.intro-tagline {
  margin-top: 6px;
  font-family: var(--font-heading);
  font-style: italic;
  color: var(--color-accent-dark);
  font-size: 0.95rem;
  max-width: 20em;
  margin-left: auto;
  margin-right: auto;
  padding: 0 16px;
  opacity: 0;
  animation: introName 0.5s ease 1.2s forwards;
}
.intro-flash {
  position: absolute;
  inset: 0;
  background: #fff;
  opacity: 0;
  pointer-events: none;
  animation: introFlash 0.3s ease-in 2.6s forwards;
}
@keyframes introBrick { to { opacity: 1; transform: none; } }
@keyframes introName { to { opacity: 1; } }
@keyframes introDoorGlow {
  0% { filter: none; }
  60% { filter: drop-shadow(0 0 10px var(--color-accent)) brightness(1.8); }
  100% { filter: drop-shadow(0 0 5px var(--color-accent)) brightness(1.35); }
}
@keyframes introFlash { to { opacity: 1; } }
@keyframes introFadeOut { to { opacity: 0; visibility: hidden; } }
@media (prefers-reduced-motion: reduce) {
  .intro-overlay { display: none; }
}
/* ============================================================
   Professional listing cards — stats row, chips, photo overlays
   ============================================================ */
.listing-price-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.neighborhood-chip {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--color-primary);
  background: var(--color-bg-alt);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: 2px 10px;
  white-space: nowrap;
  max-width: 45%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.listing-stats {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 6px 0 8px;
  color: var(--color-text);
  font-size: 0.88rem;
}
.listing-stats .stat { display: inline-flex; align-items: center; gap: 5px; }
.listing-stats .stat b { font-weight: 700; }
.listing-stats .stat svg { width: 17px; height: 17px; color: var(--color-primary); flex-shrink: 0; }
.listing-stats .stat-sep { width: 1px; height: 14px; background: var(--color-border); }
.listing-badge.on-photo {
  position: absolute;
  top: 10px; left: 10px;
  margin: 0;
  background: rgba(255,255,255,0.94);
  box-shadow: 0 1px 4px rgba(62,18,28,0.18);
  z-index: 1;
}
.listing-badge.on-photo.reduced { background: #fdf4d9; }
.listing-badge.on-photo.open { background: var(--color-success-bg); }
.photo-count {
  position: absolute;
  bottom: 8px; right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(58,14,24,0.72);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: 4px;
  padding: 2px 7px;
}
.photo-count svg { width: 13px; height: 13px; }
.listing-agent-line {
  margin-top: auto;
  padding-top: 8px;
  font-size: 0.8rem;
  color: var(--color-text-muted);
}
.listing-agent-line a { font-weight: 600; }

/* Admin: "+ Add Listing" card at the end of the grid */
.add-listing-card {
  border: 2px dashed var(--color-border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 240px;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
  background: transparent;
  font: inherit;
}
.add-listing-card:hover { border-color: var(--color-accent); color: var(--color-accent-dark); }
.add-listing-card .plus { font-size: 2.2rem; line-height: 1; font-family: var(--font-heading); }

/* ============================================================
   Inline editing (admin view)
   ============================================================ */
.ie-editable { position: relative; cursor: pointer; border-radius: 4px; }
.ie-editable:hover { outline: 2px dashed var(--color-accent); outline-offset: 3px; }
.ie-editable .ie-pencil {
  display: none;
  position: absolute;
  top: -10px; right: -10px;
  width: 22px; height: 22px;
  background: var(--color-accent);
  color: #fff;
  border-radius: 50%;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 4px rgba(62,18,28,0.3);
  z-index: 2;
}
.ie-editable:hover .ie-pencil { display: inline-flex; }
.ie-pencil-svg { width: 12px; height: 12px; }
.ie-editing { cursor: auto; }
.ie-editing:hover { outline: none; }
.ie-editing .ie-pencil { display: none !important; }
.ie-input {
  font: inherit;
  color: inherit;
  width: 100%;
  max-width: 100%;
  border: 2px solid var(--color-accent);
  border-radius: 4px;
  padding: 2px 6px;
  background: #fff;
}
.ie-error { color: var(--color-danger); font-size: 0.78rem; margin-top: 4px; }
.ie-hint {
  font-size: 0.78rem;
  color: var(--color-accent-dark);
  background: #fdf8ee;
  border: 1px solid #eadfc9;
  border-radius: 4px;
  padding: 6px 10px;
  margin-bottom: 14px;
}

/* ============================================================
   Listing detail page — gallery, facts, sections, agent panel
   ============================================================ */
.detail-layout {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 32px;
  margin-top: 16px;
  align-items: start;
}
@media (max-width: 820px) {
  .detail-layout { grid-template-columns: 1fr; }
}

.gallery-main {
  position: relative;
  height: 380px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--color-bg-alt);
  background-size: cover;
  background-position: center;
  cursor: zoom-in;
}
@media (max-width: 820px) { .gallery-main { height: 260px; } }
.gallery-main .placeholder-icon {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--color-border);
}
.gallery-main .placeholder-icon svg { width: 96px; height: 96px; }
.gallery-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255,255,255,0.92);
  border: none;
  border-radius: 50%;
  width: 40px; height: 40px;
  font-size: 1.2rem;
  cursor: pointer;
  color: var(--color-primary-dark);
  box-shadow: 0 1px 6px rgba(62,18,28,0.25);
  display: flex; align-items: center; justify-content: center;
}
.gallery-nav:hover { background: #fff; }
.gallery-nav.prev { left: 12px; }
.gallery-nav.next { right: 12px; }
.gallery-counter {
  position: absolute;
  bottom: 10px; right: 10px;
  background: rgba(58,14,24,0.72);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 600;
  border-radius: 4px;
  padding: 2px 8px;
}
.gallery-thumbs {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  overflow-x: auto;
  padding-bottom: 4px;
}
.gallery-thumb {
  position: relative;
  width: 84px; height: 60px;
  flex-shrink: 0;
  border-radius: 4px;
  background-size: cover;
  background-position: center;
  background-color: var(--color-bg-alt);
  cursor: pointer;
  border: 2px solid transparent;
}
.gallery-thumb.active { border-color: var(--color-accent); }
.gallery-thumb .thumb-x {
  position: absolute;
  top: -6px; right: -6px;
  width: 18px; height: 18px;
  border: none;
  border-radius: 50%;
  background: var(--color-danger);
  color: #fff;
  font-size: 0.7rem;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.gallery-add-btn {
  width: 84px; height: 60px;
  flex-shrink: 0;
  border: 2px dashed var(--color-border);
  border-radius: 4px;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 1.3rem;
  cursor: pointer;
}
.gallery-add-btn:hover { border-color: var(--color-accent); color: var(--color-accent-dark); }

/* Full-screen lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 400;
  background: rgba(30,12,14,0.94);
  display: none;
  align-items: center;
  justify-content: center;
}
.lightbox.open { display: flex; }
.lightbox img {
  max-width: 92vw;
  max-height: 88vh;
  object-fit: contain;
  border-radius: 4px;
}
.lightbox .gallery-nav { background: rgba(255,255,255,0.85); }
.lightbox-close {
  position: absolute;
  top: 16px; right: 20px;
  background: none;
  border: none;
  color: #fff;
  font-size: 2rem;
  cursor: pointer;
  line-height: 1;
}
.lightbox-caption {
  position: absolute;
  bottom: 18px; left: 50%;
  transform: translateX(-50%);
  color: #fff;
  font-size: 0.9rem;
  background: rgba(0,0,0,0.45);
  padding: 4px 14px;
  border-radius: 999px;
}

/* Key facts grid */
.facts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr));
  gap: 10px;
  margin: 18px 0;
}
.fact-tile {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 10px 12px;
  background: #fff;
}
.fact-tile .fact-label {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  margin-bottom: 2px;
}
.fact-tile .fact-value { font-size: 0.95rem; font-weight: 600; color: var(--color-text); }
.fact-tile .fact-value .muted { color: var(--color-text-muted); font-weight: 400; }

.detail-stats { font-size: 1.05rem; margin: 10px 0 4px; }
.detail-stats .stat svg { width: 20px; height: 20px; }

/* Detail page content sections */
.detail-section { margin-top: 36px; }
.detail-section > h2 {
  font-size: 1.25rem;
  border-bottom: 2px solid var(--color-border);
  padding-bottom: 8px;
}
.tour-frame {
  width: 100%;
  aspect-ratio: 16 / 9;
  border: none;
  border-radius: 8px;
  background: var(--color-bg-alt);
}
.floor-plan-img {
  max-height: 480px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  cursor: zoom-in;
  background: #fff;
}

/* Agent panel */
.agent-panel {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 18px;
  margin-top: 20px;
  background: var(--color-bg-alt);
  display: flex;
  gap: 14px;
  align-items: flex-start;
}
.agent-panel .agent-avatar {
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-heading);
  font-size: 1.1rem;
  flex-shrink: 0;
}
.agent-panel h3 { margin-bottom: 2px; font-size: 1.05rem; }
.agent-panel .agent-title { color: var(--color-text-muted); font-size: 0.82rem; margin-bottom: 6px; }
.agent-panel .agent-contact { font-size: 0.85rem; }
.agent-panel .agent-links { margin-top: 8px; font-size: 0.85rem; }

/* Never break a nav label across two lines — "Homes for Sale" stays whole
   and the row tightens instead. The narrow-screen sizes live with the rest
   of the header rules above; this only guards the wrapping. */
.main-nav a { white-space: nowrap; }

/* Detail-page gallery: show the whole photo, box fits the image (no crop).
   These override the fixed-height rules above. */
.gallery-main {
  height: auto;
  min-height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden; /* contains the crop overlay's grey mask */
}
@media (max-width: 820px) { .gallery-main { height: auto; } }
.gallery-img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 540px;
  object-fit: contain;
}

/* Card-crop overlay: draggable card-shaped window, outside area greyed out */
.crop-layer { position: absolute; inset: 0; z-index: 3; }
.crop-box {
  position: absolute;
  border: 2px solid #fff;
  border-radius: 2px;
  box-shadow: 0 0 0 9999px rgba(36, 16, 18, 0.62);
  cursor: grab;
  touch-action: none;
}
.crop-box:active { cursor: grabbing; }
.crop-bar {
  position: absolute;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(255, 255, 255, 0.96);
  border-radius: 6px;
  padding: 6px 12px;
  box-shadow: 0 2px 10px rgba(62, 18, 28, 0.3);
  font-size: 0.8rem;
  color: var(--color-text-muted);
  white-space: nowrap;
  max-width: calc(100% - 24px);
}

/* Circular variant of the crop box, used for agent photo cropping — same
   drag mechanics as the card-crop tool above, just round. */
.crop-box-circle { border-radius: 50%; }

/* Agent photo crop popup: shows the full photo with the draggable circle
   sized to hug the image exactly (no letterboxing math needed) since the
   inner wrapper shrinks to the rendered <img> size. */
.photo-crop-stage {
  display: flex;
  justify-content: center;
  align-items: center;
  background: var(--color-bg-alt);
  border-radius: var(--radius);
  padding: 12px;
}
.photo-crop-inner {
  position: relative;
  display: inline-block;
  line-height: 0;
}
.photo-crop-inner img {
  display: block;
  max-width: 100%;
  max-height: 55vh;
  border-radius: 4px;
}

/* ---------------------------------------------------------------------------
   "Stop by our office" section at the bottom of the Agents page.

   The photo and the map sit side by side and stack on narrow screens at the
   same 860px breakpoint the hero uses. Both panes are locked to the photo's
   native 600x385 proportions so the two never disagree in height, and the
   map gets that shape via aspect-ratio rather than a fixed pixel height —
   otherwise the iframe reflows the footer as it loads.
   --------------------------------------------------------------------------- */
.office-section {
  /* The site header is sticky, so without this an /agents.html#office jump
     parks the headline underneath it. */
  scroll-margin-top: calc(var(--header-height) + 24px);
  background: var(--color-bg-alt);
  border-top: 1px solid var(--color-border);
  padding: 56px 0 64px;
  text-align: center;
}
.office-section h2 { margin: 0 0 12px; }

/* The Dyer team's invitation line. Capped and auto-centered so it breaks into
   comfortable lines instead of running the full width of the container. */
.office-invite {
  max-width: 470px;
  margin: 0 auto 20px;
  color: var(--color-text-muted);
  line-height: 1.6;
}

/* <address> italicizes by default in every browser; this is a postal address,
   not an aside, so it's reset to normal and laid out as stacked lines. */
.office-address {
  font-style: normal;
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 0 28px;
  color: var(--color-text-muted);
  font-size: 1.05rem;
}
.office-address .office-street { font-weight: 600; color: var(--color-text); }
.office-address a { font-weight: 600; }
/* "Main line:" sits a touch quieter than the number it introduces. */
.office-address .office-phone { margin-top: 6px; }

.office-media {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  align-items: stretch;
}
.office-photo,
.office-map {
  margin: 0;
  aspect-ratio: 600 / 385;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: #fff;
}
/* The photo is only 600px wide, so it fills the column and is cropped
   rather than letterboxed. object-fit keeps it from stretching out of
   proportion on columns that aren't exactly 600x385. */
.office-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 60%;
}
.office-map iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
.office-cta { margin-top: 24px; }

@media (max-width: 860px) {
  /* Stacked, a full-width pane would blow the 600px photo up past its native
     size and leave the pair looking edge-to-edge. Capping at the photo's real
     width keeps it sharp, and the auto margins center the column. */
  .office-media {
    grid-template-columns: 1fr;
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
  }
}
@media (max-width: 700px) {
  .office-section { padding: 40px 0 48px; }
}
