/* =========================================================
   PANORAMIQA — Residential Complex Sales App
   Dark theme · Teal accent #5ecfca · Poppins font
   ========================================================= */

/* ---- Reset & Root ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* Size of one design pixel. viewport.js overwrites this inline on <html>;
     the 1px here is the pre-script default, i.e. the untouched 1920×1080
     design. Every length below is expressed as calc(N * var(--ui)) so the
     whole interface scales from this single value. Borders are the deliberate
     exception — a hairline must stay a crisp hairline. */
  --ui:          1px;

  --bg:          #0a0a0a;
  --bg-panel:    #141414;
  --bg-card:     #ffffff;
  --bg-card-dark:#1a1a1a;
  --border:      rgba(255,255,255,0.1);
  --accent:      #5ecfca;
  --accent-dark: #3fb5b0;
  --accent-hover:#2563eb;
  --text:        #ffffff;
  --text-dim:    rgba(255,255,255,0.55);
  --text-dark:   #111111;
  --pill-radius: calc(50 * var(--ui));
  --card-radius: calc(16 * var(--ui));
  --bar-h:       calc(64 * var(--ui));
  --topbar-h:    62px;
  --panel-w:     calc(530 * var(--ui));
  --status-avail:#d0d0d0;
  --status-sold: #c0392b;
  --status-book: #c8a050;
  --shadow:      0 calc(8 * var(--ui)) calc(32 * var(--ui)) rgba(0,0,0,0.5);
  --trans:       0.18s ease;
}

html, body {
  width: 100%; height: 100%;
  overflow: hidden;
  background: var(--bg);
  font-family: 'Poppins', system-ui, sans-serif;
  font-size: calc(14 * var(--ui));
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}


/* ---- Icons sized by HTML attributes -------------------------------------
   Inline <svg> and <img> icons carry width=/height= attributes, which no
   amount of --ui in the stylesheet would touch — at a reduced scale they
   would burst out of the buttons that contain them. These presentation
   attributes are the lowest-priority source of sizing, so one rule per value
   scales them alongside everything else. Any targeted rule elsewhere (e.g.
   html[data-orient="portrait"] .arrow-icon) still wins on specificity.
   ------------------------------------------------------------------------ */
svg[width="10"], img[width="10"]   { width:  calc(10 * var(--ui)); }
svg[width="11"], img[width="11"]   { width:  calc(11 * var(--ui)); }
svg[width="12"], img[width="12"]   { width:  calc(12 * var(--ui)); }
svg[width="13"], img[width="13"]   { width:  calc(13 * var(--ui)); }
svg[width="14"], img[width="14"]   { width:  calc(14 * var(--ui)); }
svg[width="15"], img[width="15"]   { width:  calc(15 * var(--ui)); }
svg[width="16"], img[width="16"]   { width:  calc(16 * var(--ui)); }
svg[width="18"], img[width="18"]   { width:  calc(18 * var(--ui)); }
svg[width="20"], img[width="20"]   { width:  calc(20 * var(--ui)); }
svg[width="22"], img[width="22"]   { width:  calc(22 * var(--ui)); }
svg[width="26"], img[width="26"]   { width:  calc(26 * var(--ui)); }
svg[width="28"], img[width="28"]   { width:  calc(28 * var(--ui)); }
svg[width="36"], img[width="36"]   { width:  calc(36 * var(--ui)); }
svg[width="40"], img[width="40"]   { width:  calc(40 * var(--ui)); }
svg[width="80"], img[width="80"]   { width:  calc(80 * var(--ui)); }
svg[height="10"], img[height="10"] { height: calc(10 * var(--ui)); }
svg[height="11"], img[height="11"] { height: calc(11 * var(--ui)); }
svg[height="12"], img[height="12"] { height: calc(12 * var(--ui)); }
svg[height="13"], img[height="13"] { height: calc(13 * var(--ui)); }
svg[height="14"], img[height="14"] { height: calc(14 * var(--ui)); }
svg[height="15"], img[height="15"] { height: calc(15 * var(--ui)); }
svg[height="16"], img[height="16"] { height: calc(16 * var(--ui)); }
svg[height="18"], img[height="18"] { height: calc(18 * var(--ui)); }
svg[height="20"], img[height="20"] { height: calc(20 * var(--ui)); }
svg[height="22"], img[height="22"] { height: calc(22 * var(--ui)); }
svg[height="26"], img[height="26"] { height: calc(26 * var(--ui)); }
svg[height="28"], img[height="28"] { height: calc(28 * var(--ui)); }
svg[height="36"], img[height="36"] { height: calc(36 * var(--ui)); }
svg[height="40"], img[height="40"] { height: calc(40 * var(--ui)); }
svg[height="80"], img[height="80"] { height: calc(80 * var(--ui)); }

/* ---- Background Layer ---- */
#bg-layer {
  position: fixed; inset: 0; z-index: 0;
  background-color: #0a0a0a;
  /* size/position are written by app.js applyBgTransform() from the shared
     VIEWPORT transform — in landscape they reproduce `cover` exactly, in
     portrait they focus-crop the frame onto the stage. Declared here only as
     the pre-JS fallback for the very first paint. */
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
  transition: background-image 0.4s ease;
}
/* Kept as a layer for future use, but paints NOTHING: the renders must be
   shown exactly as delivered, so no darkening veil over day or night. */
#bg-overlay {
  position: fixed; inset: 0; z-index: 1;
  background: transparent;
  pointer-events: none;
}

/* ---- Top Bar (floating window) ---- */
#topbar {
  position: fixed; top: calc(20 * var(--ui)); left: calc(20 * var(--ui)); right: calc(20 * var(--ui)); z-index: 100;
  background: #0d0d0d;
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: calc(26 * var(--ui));
  overflow: hidden;
  display: flex; flex-direction: column;
}
#topbar-row1 {
  display: flex; align-items: center; justify-content: space-between;
  height: calc(62 * var(--ui)); padding: 0 calc(20 * var(--ui)); gap: calc(12 * var(--ui)); flex-shrink: 0;
}
#topbar-row2 {
  display: flex; align-items: center; justify-content: space-between;
  height: calc(48 * var(--ui)); padding: 0 calc(20 * var(--ui));
}
#topbar-nav-left  { display: flex; align-items: center; gap: calc(10 * var(--ui)); }
#topbar-nav-right { display: flex; align-items: center; gap: calc(16 * var(--ui)); }

#topbar-left {
  display: flex; align-items: center; gap: calc(12 * var(--ui)); flex: 1; min-width: 0;
}
#logo {
  flex-shrink: 0; cursor: default;
}
#page-title {
  font-size: calc(34 * var(--ui)); font-weight: 400; letter-spacing: 0.03em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#page-title .title-bold { font-weight: 700; }

#topbar-right {
  display: flex; align-items: center; gap: calc(8 * var(--ui)); flex-shrink: 0;
}

/* Nav pill buttons (Home, Back to Building) */
.btn-nav-pill {
  display: flex; align-items: center; gap: calc(5 * var(--ui));
  padding: calc(6 * var(--ui)) calc(14 * var(--ui)) calc(6 * var(--ui)) calc(10 * var(--ui));
  border: 1.5px solid rgba(255,255,255,0.25);
  border-radius: var(--pill-radius);
  background: transparent; color: var(--text);
  font-family: inherit; font-size: calc(13 * var(--ui)); font-weight: 500;
  cursor: pointer; transition: var(--trans); white-space: nowrap;
}
.btn-nav-pill:hover { border-color: rgba(255,255,255,0.6); background: rgba(255,255,255,0.08); }
.btn-nav-pill:active { opacity: 0.7; }

/* Text action buttons (Download PDF, Copy link, Add to favorites) */
.btn-text-action {
  display: flex; align-items: center; gap: calc(6 * var(--ui));
  padding: 0 calc(4 * var(--ui));
  background: transparent; border: none;
  color: var(--text-dim); font-family: inherit; font-size: calc(13 * var(--ui));
  cursor: pointer; transition: var(--trans);
  text-decoration: underline; text-underline-offset: calc(3 * var(--ui));
  white-space: nowrap;
}
.btn-text-action:hover { color: var(--text); }
.btn-text-action.fav-active { color: #e74c3c; }
.btn-text-action.fav-active svg { fill: #e74c3c; stroke: #e74c3c; }

/* Icon buttons (share, phone, heart) */
.btn-icon {
  width: calc(40 * var(--ui)); height: calc(40 * var(--ui));
  display: flex; align-items: center; justify-content: center;
  border: 3px solid rgba(255,255,255,0.85);
  border-radius: 50%;
  background: transparent; color: var(--text);
  cursor: pointer; transition: var(--trans); flex-shrink: 0;
}
.btn-icon:hover { border-color: rgba(255,255,255,0.7); background: rgba(255,255,255,0.08); }
.btn-icon:active { opacity: 0.7; }

/* Back red button */
.btn-back-red {
  width: calc(40 * var(--ui)); height: calc(40 * var(--ui));
  display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%;
  background: #e03030; color: #111;  /* full BLACK arrow on red (per reference) */
  cursor: pointer; transition: var(--trans); flex-shrink: 0;
}
.btn-back-red:hover { background: #b52020; }
.btn-back-red:active { opacity: 0.8; }

/* ---- Browse Layout (Pages 1 & 2) ---- */
#browse-layout {
  position: fixed;
  top: calc(var(--topbar-h) + calc(20 * var(--ui))); left: 0; right: 0;
  bottom: 0;
  z-index: 10;
}

/* ---- Filter Panel (overlay) ---- */
#filter-panel {
  position: absolute;
  top: calc(20 * var(--ui)); left: calc(20 * var(--ui)); bottom: calc(20 * var(--ui));
  width: var(--panel-w);
  height: auto;
  background: #0d0d0d;
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: calc(24 * var(--ui));
  display: flex; flex-direction: column;
  overflow: hidden;
  z-index: 20;
  transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
#filter-panel.panel-hidden {
  transform: translateX(calc(-100% - calc(20 * var(--ui))));
  pointer-events: none;
}

/* Collapsed tab */
#panel-tab {
  position: absolute;
  top: calc(20 * var(--ui)); left: calc(20 * var(--ui));
  display: flex; align-items: center; gap: calc(12 * var(--ui));
  padding: calc(12 * var(--ui)) calc(14 * var(--ui)) calc(12 * var(--ui)) calc(18 * var(--ui));
  background: #0d0d0d;
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: calc(24 * var(--ui));
  z-index: 20;
  cursor: pointer;
  font-size: calc(14 * var(--ui)); font-weight: 600; color: var(--text);
  white-space: nowrap;
  transition: border-color var(--trans);
}
#panel-tab:hover { border-color: var(--accent); }
.panel-tab-btn {
  width: calc(34 * var(--ui)); height: calc(34 * var(--ui)); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid rgba(255,255,255,0.3);
  border-radius: 50%;
  background: transparent; color: var(--text);
  cursor: pointer; pointer-events: none;
}

#filter-header {
  padding: calc(24 * var(--ui)) calc(30 * var(--ui)) calc(16 * var(--ui));
  font-size: calc(20 * var(--ui)); font-weight: 700;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: space-between;
}
#panel-toggle-btn {
  width: calc(34 * var(--ui)); height: calc(34 * var(--ui)); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid rgba(255,255,255,0.3);
  border-radius: 50%;
  background: transparent; color: var(--text);
  cursor: pointer; transition: var(--trans);
}
#panel-toggle-btn:hover { background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.6); }
#filter-buttons-grid {
  padding: 0 calc(30 * var(--ui)) calc(10 * var(--ui));   /* same side margin as #apt-list, so buttons and cards line up */
  display: grid; grid-template-columns: 1fr 1fr; gap: calc(14 * var(--ui));
  flex-shrink: 0; position: relative;
}

/* Filter buttons — white pills with teal chevrons (per reference design) */
.filter-btn {
  display: flex; align-items: center; justify-content: space-between;
  padding: calc(13 * var(--ui)) calc(18 * var(--ui));
  border: none;
  border-radius: var(--pill-radius);
  background: #ffffff; color: #111;
  font-family: inherit; font-size: calc(15 * var(--ui)); font-weight: 500;
  cursor: pointer; transition: var(--trans);
  white-space: nowrap; width: 100%;
}
.filter-btn:hover { background: #f0f0f0; }
.filter-btn:active { opacity: 0.8; }
.filter-btn.active {
  background: var(--accent);
  color: #000; font-weight: 600;
}
.filter-btn.active .arrow-icon { stroke: #000; }
.filter-btn.more-active {
  background: var(--accent);
  color: #000; font-weight: 600;
}
/* open dropdown → its button turns teal too (per reference) */
.filter-btn.open {
  background: var(--accent);
  color: #000; font-weight: 600;
}
.filter-btn.open .arrow-icon { stroke: #000; }
.arrow-icon { flex-shrink: 0; transition: transform 0.2s; stroke: var(--accent); }
.filter-btn.open .arrow-icon { transform: rotate(180deg); }

/* Each filter button and its dropdown share this position:relative wrapper,
   so the dropdown is a floating popup anchored to ITS OWN button — directly
   below it, exactly as wide as it — instead of to the button grid as a whole
   (which glued every dropdown to the same spot regardless of which button
   opened it). It overlays the apartment list rather than pushing content down. */
.filter-btn-wrap { position: relative; min-width: 0; }
.filter-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + calc(10 * var(--ui)));
  left: 0;
  width: 100%;
  z-index: 30;
}
.filter-dropdown.open { display: block; }
.filter-dropdown-inner {
  background: var(--accent);
  border-radius: calc(16 * var(--ui));
  padding: calc(14 * var(--ui)) calc(16 * var(--ui)) calc(16 * var(--ui));
  box-shadow: 0 calc(10 * var(--ui)) calc(32 * var(--ui)) rgba(0,0,0,0.45);
}

/* Checkbox items */
.checkbox-item {
  display: flex; align-items: center; gap: calc(12 * var(--ui));
  padding: calc(8 * var(--ui)) calc(4 * var(--ui));
  cursor: pointer; font-size: calc(15 * var(--ui)); font-weight: 500; color: #000;
}
.checkbox-item input[type="checkbox"] {
  width: calc(22 * var(--ui)); height: calc(22 * var(--ui)); border-radius: calc(6 * var(--ui));
  accent-color: #111; cursor: pointer; flex-shrink: 0;
}
.checkbox-icon-item svg { flex-shrink: 0; stroke: #000; }

/* Range slider */
.range-label {
  font-size: calc(14 * var(--ui)); font-weight: 700; color: #000; margin-bottom: calc(10 * var(--ui));
}
.range-slider-wrap {
  position: relative; height: calc(24 * var(--ui)); margin-bottom: calc(8 * var(--ui));
}
/* The track line is drawn HERE (under both stacked inputs), not by the inputs
   themselves — otherwise the upper (max) input's track paints OVER the lower
   (min) input's thumb, "crossing it out". */
.range-slider-wrap::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 50%;
  height: calc(3 * var(--ui)); margin-top: calc(-1.5 * var(--ui));
  background: #111; border-radius: calc(4 * var(--ui));
}
.range-input {
  position: absolute; width: 100%; height: calc(4 * var(--ui));
  -webkit-appearance: none; appearance: none;
  background: transparent; pointer-events: none;
  top: 50%; transform: translateY(-50%);
}
.range-input::-webkit-slider-runnable-track {
  background: transparent; border-radius: calc(4 * var(--ui)); height: calc(3 * var(--ui));
}
.range-input::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: calc(20 * var(--ui)); height: calc(20 * var(--ui));
  margin-top: calc(-8.5 * var(--ui));  /* centre the thumb on the 3px track */
  /* opaque white circle + bold black centre dot — track must NOT show through */
  background: radial-gradient(circle, #111 0 calc(4 * var(--ui)), #fff calc(4 * var(--ui)) 100%);
  border-radius: 50%;
  border: 2.5px solid #111;
  pointer-events: all; cursor: pointer; position: relative;
}
.range-inputs-row {
  display: flex; gap: calc(12 * var(--ui)); margin-bottom: calc(12 * var(--ui));
}
.range-field {
  display: flex; flex-direction: column; gap: calc(2 * var(--ui)); flex: 1;
}
.range-lbl { font-size: calc(11 * var(--ui)); color: #000; font-weight: 500; }
.range-field input[type="number"] {
  background: #ffffff;
  border: none;
  border-radius: calc(8 * var(--ui)); padding: calc(7 * var(--ui)) calc(9 * var(--ui));
  font-family: inherit; font-size: calc(13 * var(--ui)); color: #000;
  width: 100%;
}
.range-actions { display: flex; flex-direction: column; gap: calc(8 * var(--ui)); }
.btn-clear {
  background: transparent; border: none;
  font-family: inherit; font-size: calc(13 * var(--ui)); color: #000;
  cursor: pointer; text-align: center; padding: calc(2 * var(--ui));
}
.btn-clear:hover { text-decoration: underline; }
.btn-apply {
  background: #111; border: none;
  border-radius: var(--pill-radius); padding: calc(10 * var(--ui));
  color: #fff; font-family: inherit; font-size: calc(14 * var(--ui)); font-weight: 600;
  cursor: pointer; transition: var(--trans);
}
.btn-apply:hover { background: #222; }
.btn-apply:active { opacity: 0.8; }

/* Extra filters grid */
#extra-filters {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: 1fr 1fr; gap: calc(14 * var(--ui));
}

/* Apartment list — same 30px side margin and 14px gap as the filter buttons
   above, so cards and buttons share identical width and edge alignment.
   NOTE: panel width is sized so 2×calc(228 * var(--ui)) cards + calc(14 * var(--ui)) gap + 2×calc(30 * var(--ui)) padding
   fill it exactly (no slack) — deliberately NOT justify-content:center,
   since the vertical scrollbar eats into this list's (but not the filter
   grid's) available width and centering would drift the cards left of the
   buttons above by the scrollbar's width. Left/start alignment keeps both
   grids' left edges pinned to the same 30px padding regardless. */
#apt-list {
  flex: 1; overflow-y: auto; overflow-x: hidden;  /* never scroll sideways */
  padding: calc(10 * var(--ui)) calc(30 * var(--ui)) calc(20 * var(--ui));
  display: grid; grid-template-columns: calc(228 * var(--ui)) calc(228 * var(--ui)); gap: calc(14 * var(--ui));
  align-content: start;
  scrollbar-width: auto; scrollbar-color: rgba(255,255,255,0.35) rgba(255,255,255,0.06);
}
#apt-list::-webkit-scrollbar { width: calc(10 * var(--ui)); }
#apt-list::-webkit-scrollbar-track { background: rgba(255,255,255,0.06); border-radius: calc(8 * var(--ui)); }
#apt-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.35); border-radius: calc(8 * var(--ui)); }
#apt-list::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.5); }

/* Apartment card — 228×326 (per spec), scaled ~0.8× from the previous
   285×408 card so every internal proportion (thumb, body, text) stays
   consistent rather than just clipping/cropping a bigger layout. */
.apt-card {
  width: calc(228 * var(--ui)); height: calc(326 * var(--ui));
  display: flex; flex-direction: column;
  background: #fff;
  border-radius: calc(16 * var(--ui));
  overflow: hidden;
  cursor: pointer;
  transition: transform var(--trans), box-shadow var(--trans);
  border: 2px solid transparent;
  box-shadow: 0 calc(2 * var(--ui)) calc(12 * var(--ui)) rgba(0,0,0,0.18);
}
.apt-card:hover { transform: translateY(calc(-2 * var(--ui))); box-shadow: 0 calc(6 * var(--ui)) calc(24 * var(--ui)) rgba(0,0,0,0.28); border-color: var(--accent); }
.apt-card:active { transform: translateY(0); }

.apt-card-thumb {
  width: 100%; height: calc(206 * var(--ui)); flex-shrink: 0;
  background: #ffffff; overflow: hidden; position: relative;
}
.apt-card-thumb img {
  width: 100%; height: 100%; object-fit: contain;
  padding: calc(8 * var(--ui));
}
.apt-card-fav {
  position: absolute; top: calc(8 * var(--ui)); right: calc(8 * var(--ui));
  width: calc(26 * var(--ui)); height: calc(26 * var(--ui)); border-radius: 50%;
  background: #ffffff;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: var(--trans);
  border: 1.5px solid #d5d5d5;
}
.apt-card-fav:hover { background: #fff; }
.apt-card-fav svg { stroke: #aaa; }
.apt-card-fav.is-fav svg { fill: #e74c3c; stroke: #e74c3c; }

.apt-card-body {
  flex: 1; display: flex; flex-direction: column; justify-content: center;
  padding: calc(8 * var(--ui)) calc(11 * var(--ui)) calc(18 * var(--ui)); gap: calc(8 * var(--ui));
  background: #fff;
}

.apt-card-name {
  display: block;
  background: #111; color: #fff;
  border-radius: calc(6 * var(--ui)); padding: calc(6 * var(--ui)) calc(10 * var(--ui));
  font-size: calc(13 * var(--ui)); font-weight: 700; letter-spacing: 0.04em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.apt-card-info {
  display: grid; grid-template-columns: 1fr 1fr; gap: calc(5 * var(--ui)) 0;
}
.apt-info-item {
  display: flex; align-items: center; gap: calc(6 * var(--ui));
  font-size: calc(12 * var(--ui)); color: #222; font-weight: 500;
}
.apt-info-item svg { stroke: #444; flex-shrink: 0; }
.apt-info-item img { flex-shrink: 0; }

.apt-outdoor-icons {
  display: flex; align-items: center; gap: calc(3 * var(--ui)); flex-wrap: wrap;
}
.outdoor-icon-wrap {
  display: flex; align-items: center; gap: calc(2 * var(--ui));
}
.outdoor-icon-wrap svg { stroke: #555; }
.outdoor-count { font-size: calc(10 * var(--ui)); color: #777; }

/* ---- Background Interactive Area ---- */
#bg-interactive {
  position: absolute; inset: 0;
}

/* Arrow navigation buttons */
.arrow-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: calc(52 * var(--ui)); height: calc(80 * var(--ui));
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.35); border: none;
  color: rgba(255,255,255,0.7);
  cursor: pointer; transition: var(--trans);
  border-radius: calc(8 * var(--ui));
  z-index: 5;
}
#btn-prev-section { left: calc(var(--panel-w) + calc(70 * var(--ui))); transition: left 0.35s cubic-bezier(0.4,0,0.2,1); }
#btn-next-section { right: calc(50 * var(--ui)); }
#browse-layout.panel-closed #btn-prev-section { left: calc(70 * var(--ui)); }
.arrow-nav:hover { background: rgba(0,0,0,0.6); color: #fff; }
.arrow-nav:active { opacity: 0.7; }

/* ---- 360° indicator «◄ 360° ►» (right-centre of the scene, per reference) ---- */
#hint-360 {
  position: absolute;
  top: 50%; right: calc(40 * var(--ui)); transform: translateY(-50%);
  display: none; align-items: center; gap: calc(10 * var(--ui));
  background: none; border: none; padding: 0;
  color: #ffffff; font-size: calc(24 * var(--ui)); font-weight: 700; letter-spacing: 0.04em;
  text-shadow: 0 calc(2 * var(--ui)) calc(8 * var(--ui)) rgba(0,0,0,0.6);
  pointer-events: none; z-index: 5;
  opacity: 0; transition: opacity 0.5s ease;
}
#hint-360 .hint-360-arrow {
  color: #ffffff;
  filter: drop-shadow(0 calc(2 * var(--ui)) calc(4 * var(--ui)) rgba(0,0,0,0.5));
}
#hint-360.visible { display: flex; opacity: 1; }
/* fade the indicator out once the user starts dragging */
body.pano-dragging #hint-360.visible { opacity: 0; }

/* 360 hero hot-zone tooltip (follows cursor) */
#pano-zone-tip {
  position: fixed; z-index: 90; pointer-events: none;
  padding: calc(8 * var(--ui)) calc(13 * var(--ui)); border-radius: calc(10 * var(--ui));
  background: rgba(17,17,17,0.92);
  border: 1px solid rgba(94,207,202,0.5);
  color: #fff; font-size: calc(13 * var(--ui)); font-weight: 500; white-space: nowrap;
  box-shadow: 0 calc(6 * var(--ui)) calc(24 * var(--ui)) rgba(0,0,0,0.4);
  opacity: 0; transform: translateY(calc(4 * var(--ui))); transition: opacity 0.15s ease, transform 0.15s ease;
}
#pano-zone-tip.visible { opacity: 1; transform: translateY(0); }

/* ---- Detail Layout ---- */
#detail-layout {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  padding-top: calc(var(--topbar-h) + calc(40 * var(--ui)));
  z-index: 10;
  background: #ffffff;
  display: flex; align-items: stretch;
}
#plan-viewer-wrap {
  flex: 1; padding: calc(20 * var(--ui)); display: flex; align-items: center; justify-content: center;
  background: #fafafa;
  border-right: 1px solid #e0e0e0;
}
#plan-viewer {
  width: 100%; height: 100%;
  border: 1.5px solid #e0e0e0;
  border-radius: calc(16 * var(--ui));
  overflow: hidden; position: relative;
  background: #fff;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
#plan-viewer:hover #btn-zoom { opacity: 1; }
#plan-img {
  max-width: 100%; max-height: 100%; object-fit: contain;
  padding: calc(20 * var(--ui));
}
#plan-placeholder {
  display: none; flex-direction: column; align-items: center; gap: calc(12 * var(--ui));
  color: #bbb; font-size: calc(13 * var(--ui)); text-align: center;
}
#btn-zoom {
  position: absolute; bottom: calc(14 * var(--ui)); right: calc(14 * var(--ui));
  width: calc(44 * var(--ui)); height: calc(44 * var(--ui));
  background: rgba(0,0,0,0.08); border: 1.5px solid rgba(0,0,0,0.15);
  border-radius: 50%; display: flex; align-items: center; justify-content: center;
  cursor: pointer; opacity: 0.7; transition: var(--trans);
  color: #555;
}
#btn-zoom:hover { opacity: 1; background: rgba(0,0,0,0.15); }

#apt-info-panel {
  width: calc(340 * var(--ui)); flex-shrink: 0;
  padding: calc(32 * var(--ui)) calc(28 * var(--ui)) calc(28 * var(--ui));
  display: flex; flex-direction: column; gap: 0;
  overflow-y: auto; background: #fff; color: var(--text-dark);
}
#apt-detail-name {
  font-size: calc(26 * var(--ui)); font-weight: 700; color: #111; margin-bottom: calc(4 * var(--ui));
}
#apt-detail-subtitle {
  font-size: calc(14 * var(--ui)); color: #777; margin-bottom: calc(20 * var(--ui));
}
.btn-contact-manager {
  width: 100%; padding: calc(14 * var(--ui));
  background: #111; border: none; border-radius: var(--pill-radius);
  color: #fff; font-family: inherit; font-size: calc(13 * var(--ui)); font-weight: 700;
  letter-spacing: 0.08em; cursor: pointer; transition: var(--trans);
  margin-bottom: calc(20 * var(--ui));
}
.btn-contact-manager:hover { background: var(--accent-hover); }
.btn-contact-manager:active { opacity: 0.8; }

#apt-status-row {
  display: flex; align-items: center; gap: calc(10 * var(--ui)); margin-bottom: calc(18 * var(--ui));
}
#apt-status-dot {
  width: calc(20 * var(--ui)); height: calc(20 * var(--ui)); border-radius: 50%;
  background: var(--status-avail); flex-shrink: 0;
}
#apt-status-dot.sold { background: var(--status-sold); }
#apt-status-dot.booked { background: var(--status-book); }
#apt-status-text { font-size: calc(14 * var(--ui)); color: #555; }

.info-row {
  display: flex; align-items: center; gap: calc(12 * var(--ui));
  padding: calc(10 * var(--ui)) 0; border-bottom: 1px solid #f0f0f0;
  font-size: calc(14 * var(--ui)); color: #333;
}
.info-row svg { stroke: #666; flex-shrink: 0; }
.info-row:last-of-type { border-bottom: none; }

#apt-detail-outdoor-row { padding: calc(10 * var(--ui)) 0; border-bottom: 1px solid #f0f0f0; }
#apt-detail-outdoor {
  display: flex; align-items: center; gap: calc(12 * var(--ui)); flex-wrap: wrap;
}
.outdoor-detail-item {
  display: flex; align-items: center; gap: calc(6 * var(--ui)); font-size: calc(13 * var(--ui)); color: #555;
}
.outdoor-detail-item svg { stroke: #555; }

#apt-price-row {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: calc(20 * var(--ui)); padding-top: calc(16 * var(--ui));
  border-top: 1px solid #e0e0e0;
}
.price-label { font-size: calc(14 * var(--ui)); color: #888; }
.price-value { font-size: calc(22 * var(--ui)); font-weight: 700; color: #111; }

/* ---- Bottom Bar (overlay column: triangle above frame) ---- */
#bottom-bar {
  position: fixed; bottom: calc(16 * var(--ui)); left: 0; right: 0; z-index: 15;
  display: flex; flex-direction: column; align-items: flex-start;
  background: transparent; border: none; height: auto;
  gap: 0; pointer-events: none;
  transition: left 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
/* bottom bar visibility is controlled via JS (renderLayout) */

/* Triangle pointer above active dot — looping bounce animation */
@keyframes triangle-bounce {
  0%   { transform: translateY(0);   animation-timing-function: ease-in; }
  10%  { transform: translateY(calc(8 * var(--ui))); animation-timing-function: ease-out; }
  100% { transform: translateY(0); }
}
#slider-triangle {
  position: absolute;
  bottom: 100%;          /* sit just above the frame */
  left: 0;               /* exact left set by JS (frame-relative) */
  pointer-events: none;
  transition: left 0.3s ease;
  animation: triangle-bounce 2s infinite;
}

/* Transparent black frame uniting both controls */
#bottom-frame {
  position: relative;    /* positioning context for #slider-triangle */
  display: flex; flex-direction: row; align-items: center;
  gap: calc(20 * var(--ui));
  border: 1px solid rgba(255,255,255,0.12);  /* barely-visible uniting outline (ref) */
  border-radius: calc(50 * var(--ui));
  padding: calc(6 * var(--ui));
  background: rgba(20, 20, 20, 0.35);
  pointer-events: none;
  align-self: center;
}

/* Element A — day/night toggle (opaque window) */
#day-night-section {
  display: flex; align-items: center; gap: calc(8 * var(--ui));
  padding: calc(8 * var(--ui)) calc(16 * var(--ui));
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: calc(50 * var(--ui));
  flex-shrink: 0;
  pointer-events: all;
}
#day-night-label {
  font-size: calc(15 * var(--ui)); color: var(--text); white-space: nowrap;
}
.day-night-btn {
  width: calc(34 * var(--ui)); height: calc(34 * var(--ui)); border-radius: 50%;
  background: rgba(255,255,255,0.08); border: 1.5px solid rgba(255,255,255,0.15);
  color: var(--text-dim); display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: var(--trans);
}
.day-night-btn.active {
  background: var(--accent); border-color: var(--accent); color: #000;
}
.day-night-btn:hover:not(.active) { border-color: rgba(255,255,255,0.4); color: var(--text); }

/* Element C — Hide/Show Units toggle (opaque pill, part of the same unified
   #bottom-frame as A/B, not a separate floating element). Default ON:
   black bg + white text ("Hide Units"). Off: teal bg + black text ("Show Units"). */
.zones-toggle-btn {
  display: flex; align-items: center; justify-content: center;
  padding: 0 calc(22 * var(--ui)); height: calc(49 * var(--ui));
  border: none; border-radius: calc(50 * var(--ui));
  background: #111; color: #fff;
  font-family: inherit; font-size: calc(14 * var(--ui)); font-weight: 600; white-space: nowrap;
  cursor: pointer; transition: var(--trans);
  flex-shrink: 0; pointer-events: all;
}
.zones-toggle-btn:hover { background: #1c1c1c; }
.zones-toggle-btn.zones-off { background: var(--accent); color: #111; }
.zones-toggle-btn.zones-off:hover { background: var(--accent-dark); }

/* Element B — BG slider (opaque window) */
#bg-slider {
  position: relative;
  display: flex; align-items: center;
  padding: calc(14 * var(--ui)) calc(32 * var(--ui));
  background: var(--bg-panel);
  border: 1px solid var(--border);
  overflow: hidden;
  border-radius: calc(50 * var(--ui));
  pointer-events: all;
}
/* Floating pill indicator — absolutely positioned, never shifts layout */
#slider-pill {
  position: absolute;
  width: calc(56 * var(--ui)); height: calc(32 * var(--ui));
  border-radius: calc(50 * var(--ui));
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 56 32'%3E%3Crect width='56' height='32' rx='16' fill='%235ecfca'/%3E%3Cpolygon points='16,16 23,10 23,22' fill='%23111' opacity='0.75'/%3E%3Cpolygon points='40,16 33,10 33,22' fill='%23111' opacity='0.75'/%3E%3C/svg%3E") center/cover no-repeat;
  top: 50%; transform: translateY(-50%);
  transition: left 0.25s ease;
  pointer-events: none;
  z-index: 2;
}
#slider-track {
  display: flex; align-items: center; gap: calc(42 * var(--ui));
}
.slider-dot {
  width: calc(8 * var(--ui)); height: calc(22 * var(--ui)); border-radius: calc(4 * var(--ui));
  background: var(--accent); border: none;
  cursor: pointer; transition: var(--trans); padding: 0; flex-shrink: 0;
}
.slider-dot.active {
  /* size stays the same — visual indicator is #slider-pill overlay */
  opacity: 0;
}
.slider-dot:hover:not(.active) { background: var(--accent); opacity: 0.75; }

/* ---- Bottom menu / portrait back button --------------------------------
   Both belong to the portrait layout only — landscape keeps every one of
   these actions in the topbar, unchanged. They are switched on in the
   PORTRAIT LAYOUT block at the end of this file. */
#bottom-menu, #btn-back-page-m { display: none; }

/* ---- Plan Fullscreen ---- */
#plan-fullscreen {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(0,0,0,0.92);
  display: flex; align-items: center; justify-content: center;
  cursor: zoom-out;
}
#plan-fullscreen-img {
  max-width: 90vw; max-height: 90vh;
  object-fit: contain; border-radius: calc(12 * var(--ui));
  background: #fff; padding: calc(20 * var(--ui));
}
#btn-plan-close {
  position: absolute; top: calc(20 * var(--ui)); right: calc(20 * var(--ui));
  width: calc(44 * var(--ui)); height: calc(44 * var(--ui)); border-radius: 50%;
  background: rgba(255,255,255,0.15); border: 1.5px solid rgba(255,255,255,0.3);
  color: #fff; display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: var(--trans);
}
#btn-plan-close:hover { background: rgba(255,255,255,0.3); }

/* ---- Apartment Popup (hot-zone) ---- */
#popup-apt {
  position: fixed; z-index: 150;
  background: #fff; color: var(--text-dark);
  border-radius: calc(20 * var(--ui));
  width: calc(200 * var(--ui));
  box-shadow: var(--shadow);
  overflow: hidden;
  /* Positioned via JS */
}
#popup-apt .popup-close {
  position: absolute; top: calc(8 * var(--ui)); left: calc(8 * var(--ui)); z-index: 2;
  width: calc(28 * var(--ui)); height: calc(28 * var(--ui)); border-radius: 50%;
  background: rgba(0,0,0,0.08); border: none;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: #555; transition: var(--trans);
}
#popup-apt .popup-close:hover { background: rgba(0,0,0,0.15); }
#popup-apt-plan-wrap {
  width: 100%; aspect-ratio: 1;
  background: #f4f4f4; overflow: hidden; position: relative;
}
#popup-apt-plan {
  width: 100%; height: 100%; object-fit: contain; padding: calc(8 * var(--ui));
}
#popup-apt-name-row {
  padding: calc(8 * var(--ui)) calc(10 * var(--ui)) calc(4 * var(--ui));
}
#popup-apt-name {
  display: inline-block;
  background: #111; color: #fff;
  border-radius: calc(6 * var(--ui)); padding: calc(3 * var(--ui)) calc(8 * var(--ui));
  font-size: calc(10 * var(--ui)); font-weight: 700; letter-spacing: 0.06em;
}
#popup-apt-name.status-booked { background: var(--status-book); color: #fff; }
#popup-apt-name.status-sold   { background: var(--status-sold); color: #fff; }

#popup-apt-price-row {
  padding: calc(2 * var(--ui)) calc(10 * var(--ui)) calc(6 * var(--ui));
}
#popup-apt-price {
  font-size: calc(11 * var(--ui)); color: #888;
  background: #f0f0f0; border-radius: calc(12 * var(--ui)); padding: calc(2 * var(--ui)) calc(8 * var(--ui));
  display: inline-block;
}
#popup-apt-info-row {
  display: flex; gap: calc(12 * var(--ui)); padding: calc(4 * var(--ui)) calc(10 * var(--ui)) calc(8 * var(--ui));
}
.popup-info-item {
  display: flex; align-items: center; gap: calc(4 * var(--ui));
  font-size: calc(11 * var(--ui)); color: #555;
}
.popup-info-item svg { stroke: #777; }
.btn-review {
  width: calc(100% - calc(20 * var(--ui))); margin: 0 calc(10 * var(--ui)) calc(10 * var(--ui));
  background: #111; border: none; border-radius: var(--pill-radius);
  color: #fff; padding: calc(10 * var(--ui));
  font-family: inherit; font-size: calc(12 * var(--ui)); font-weight: 700; letter-spacing: 0.08em;
  cursor: pointer; transition: var(--trans);
}
.btn-review:hover { background: var(--accent-hover); }
.btn-review:active { opacity: 0.8; }

/* ---- Contact Manager Popup ---- */
#popup-overlay {
  position: fixed; inset: 0; z-index: 160;
  background: rgba(0,0,0,0.55);
}
#popup-contact {
  position: fixed; z-index: 170;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  background: #fff; color: var(--text-dark);
  border-radius: calc(20 * var(--ui));
  width: calc(420 * var(--ui)); max-width: 95vw;
  padding: calc(32 * var(--ui)) calc(28 * var(--ui)) calc(28 * var(--ui));
  box-shadow: 0 calc(20 * var(--ui)) calc(60 * var(--ui)) rgba(0,0,0,0.4);
  display: flex; flex-direction: column; gap: calc(12 * var(--ui));
}
.popup-title {
  font-size: calc(20 * var(--ui)); font-weight: 700; text-align: center;
  margin-bottom: calc(4 * var(--ui)); color: #111;
}
.popup-close-x {
  position: absolute; top: calc(14 * var(--ui)); right: calc(14 * var(--ui));
  width: calc(32 * var(--ui)); height: calc(32 * var(--ui)); border-radius: 50%;
  background: transparent; border: none;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: #777; transition: var(--trans);
}
.popup-close-x:hover { color: #111; background: rgba(0,0,0,0.06); }

.popup-input {
  width: 100%; padding: calc(12 * var(--ui)) calc(14 * var(--ui));
  border: 1.5px solid #ddd; border-radius: var(--pill-radius);
  font-family: inherit; font-size: calc(14 * var(--ui)); color: #111;
  outline: none; transition: var(--trans);
  background: #fff;
}
.popup-input:focus { border-color: var(--accent); }
.popup-textarea {
  border-radius: calc(14 * var(--ui)); resize: none; height: calc(100 * var(--ui)); line-height: 1.5;
}
.popup-phone-wrap {
  display: flex; align-items: center; position: relative;
}
.phone-prefix {
  position: absolute; left: calc(14 * var(--ui));
  display: flex; align-items: center; gap: calc(4 * var(--ui));
  font-size: calc(12 * var(--ui)); color: #555; pointer-events: none; z-index: 1;
}
.phone-input { padding-left: calc(52 * var(--ui)); }
.btn-send {
  width: 100%; padding: calc(14 * var(--ui));
  background: #111; border: none; border-radius: var(--pill-radius);
  color: #fff; font-family: inherit; font-size: calc(14 * var(--ui)); font-weight: 700;
  letter-spacing: 0.08em; cursor: pointer; transition: background 0.3s, color 0.3s;
  margin-top: calc(4 * var(--ui));
}
.btn-send:hover { background: var(--accent); color: #000; }
.btn-send.sending { background: var(--accent); color: #000; }

/* ---- Favorites Popup ---- */
#popup-favorites {
  position: fixed; z-index: 170;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  background: #fff; color: var(--text-dark);
  border-radius: calc(20 * var(--ui)); width: calc(400 * var(--ui)); max-width: 95vw;
  max-height: 80vh;
  padding: calc(28 * var(--ui));
  box-shadow: 0 calc(20 * var(--ui)) calc(60 * var(--ui)) rgba(0,0,0,0.4);
  display: flex; flex-direction: column; gap: calc(16 * var(--ui));
}
.fav-header {
  display: flex; align-items: center; gap: calc(10 * var(--ui));
}
.fav-header h3 {
  font-size: calc(20 * var(--ui)); font-weight: 700; color: #111; margin: 0;
}
#fav-list {
  display: flex; flex-direction: column;
  overflow-y: auto; flex: 1;
  max-height: 60vh;
}
.fav-empty {
  font-size: calc(14 * var(--ui)); color: #999; text-align: center; padding: calc(20 * var(--ui)) 0;
}
.fav-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: calc(11 * var(--ui)) 0;
  border-bottom: 1px solid #f0f0f0;
}
.fav-item:last-child { border-bottom: none; }
.fav-item-name {
  background: none; border: none; cursor: pointer;
  color: #111; font-size: calc(15 * var(--ui)); font-weight: 500;
  text-align: left; padding: 0; flex: 1;
  transition: color 0.15s;
}
.fav-item-name:hover,
.fav-item-name:focus { color: #2563eb; outline: none; }
.fav-item-remove {
  background: none; border: none; cursor: pointer;
  color: #e74c3c; padding: calc(4 * var(--ui)) calc(6 * var(--ui));
  display: flex; align-items: center; border-radius: calc(6 * var(--ui));
  transition: background 0.15s;
  flex-shrink: 0;
}
.fav-item-remove:hover { background: rgba(231,76,60,0.10); }

/* ---- Hot-Zone Hover Tooltip ---- */
#hz-popup {
  display: none;
  position: fixed;
  z-index: 200;
  background: rgba(10, 12, 20, 0.90);
  color: #fff;
  border: 1px solid rgba(37, 99, 235, 0.50);
  border-radius: calc(10 * var(--ui));
  padding: calc(10 * var(--ui)) calc(14 * var(--ui)) calc(9 * var(--ui));
  min-width: calc(220 * var(--ui));
  max-width: calc(280 * var(--ui));
  box-shadow: 0 calc(6 * var(--ui)) calc(24 * var(--ui)) rgba(0,0,0,0.60);
  pointer-events: none;           /* tooltip never blocks mouse */
  backdrop-filter: blur(calc(10 * var(--ui)));
  -webkit-backdrop-filter: blur(calc(10 * var(--ui)));
  user-select: none;
}
#hz-popup-name {
  font-size: calc(14 * var(--ui));
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.01em;
  margin-bottom: calc(3 * var(--ui));
}
#hz-popup-meta {
  font-size: calc(12 * var(--ui));
  color: rgba(255,255,255,0.70);
  margin-bottom: calc(5 * var(--ui));
  line-height: 1.4;
}
#hz-popup-hint {
  font-size: calc(11 * var(--ui));
  color: rgba(94, 207, 202, 0.80);  /* teal accent */
  letter-spacing: 0.02em;
}

/* ---- Toast ---- */
#toast {
  position: fixed; bottom: calc(80 * var(--ui)); left: 50%; transform: translateX(-50%);
  z-index: 300; background: rgba(20,20,20,0.95); color: #fff;
  padding: calc(10 * var(--ui)) calc(20 * var(--ui)); border-radius: var(--pill-radius);
  font-size: calc(13 * var(--ui)); font-weight: 500;
  box-shadow: var(--shadow);
  transition: opacity 0.3s;
}

/* ---- Utility ---- */
.hidden { display: none !important; }

/* ---- Status colors on apt card name ---- */
.apt-card-name.status-sold   { background: var(--status-sold); }
.apt-card-name.status-booked { background: var(--status-book); }
.apt-card-name.status-available { background: #111; }

/* Cards have explicit height, no need for align-self: start */

/* ---- Selection page section indicator ---- */
#section-indicator {
  position: absolute; top: calc(20 * var(--ui)); left: 50%;
  transform: translateX(-50%);
  background: rgba(0,0,0,0.55);
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: var(--pill-radius);
  padding: calc(6 * var(--ui)) calc(20 * var(--ui));
  font-size: calc(14 * var(--ui)); font-weight: 600; color: var(--text);
  pointer-events: none; z-index: 5;
}

/* ---- Active filter count badge ---- */
.filter-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: calc(18 * var(--ui)); height: calc(18 * var(--ui)); border-radius: 50%;
  background: #e74c3c; color: #fff;
  font-size: calc(10 * var(--ui)); font-weight: 700;
  margin-left: calc(4 * var(--ui)); flex-shrink: 0;
}

/* ---- No results message ---- */
#no-results {
  grid-column: 1 / -1;
  text-align: center; padding: calc(32 * var(--ui)) calc(16 * var(--ui));
  color: var(--text-dim); font-size: calc(13 * var(--ui)); line-height: 1.6;
}

/* ---- Scrollbar for apt list ---- */
#apt-list::-webkit-scrollbar-track { background: transparent; }


/* =========================================================================
   TOUCH INPUT
   :hover sticks after a tap on touchscreens — a tapped card would stay
   lifted and teal-bordered until you tap elsewhere. Neutralise the states
   that actually move or recolour something.
   ========================================================================= */
@media (hover: none) {
  .apt-card:hover        { transform: none; box-shadow: 0 calc(2 * var(--ui)) calc(12 * var(--ui)) rgba(0,0,0,0.18); border-color: transparent; }
  .filter-btn:hover      { background: #ffffff; }
  .filter-btn.open:hover,
  .filter-btn.active:hover,
  .filter-btn.more-active:hover { background: var(--accent); }
  .btn-icon:hover        { border-color: rgba(255,255,255,0.85); background: transparent; }
  .btn-nav-pill:hover    { border-color: rgba(255,255,255,0.25); background: transparent; }
  .btn-text-action:hover { color: var(--text-dim); }
  #panel-tab:hover       { border-color: rgba(255,255,255,0.06); }
  .zones-toggle-btn:hover{ background: #111; }
  .zones-toggle-btn.zones-off:hover { background: var(--accent); }
  #btn-zoom              { opacity: 1; }
}


/* =========================================================================
   COMPACT LANDSCAPE  (phone held sideways — [data-layout="phone-landscape"])
   The desktop layout is kept, only scaled down: a 20:9 phone in landscape is
   ~915×412, and the 530px panel plus a 62px topbar leave nothing for the
   apartment list otherwise.
   ========================================================================= */
/* --topbar-h is NOT set here: app.js writes it inline per mode, and an inline
   style would beat this rule anyway. See renderTopbar(). */
html[data-layout="phone-landscape"] { --panel-w: calc(330 * var(--ui)); }
html[data-layout="phone-landscape"] #topbar { top: calc(8 * var(--ui)); left: calc(8 * var(--ui)); right: calc(8 * var(--ui)); border-radius: calc(18 * var(--ui)); }
html[data-layout="phone-landscape"] #topbar-row1 { height: calc(46 * var(--ui)); padding: 0 calc(12 * var(--ui)); }
html[data-layout="phone-landscape"] #logo img    { height: calc(24 * var(--ui)); }
/* The trailing "RESIDENTIAL COMPLEX" is a bare text node in the markup, so it
   can only be dropped by zeroing the container's font-size and restoring it on
   the one wrapped span. */
html[data-layout="phone-landscape"] #page-title  { font-size: 0; }
html[data-layout="phone-landscape"] #page-title .title-bold { font-size: calc(15 * var(--ui)); }
html[data-layout="phone-landscape"] .btn-icon,
html[data-layout="phone-landscape"] .btn-back-red { width: calc(32 * var(--ui)); height: calc(32 * var(--ui)); border-width: 2px; }
html[data-layout="phone-landscape"] #browse-layout { top: calc(var(--topbar-h) + calc(12 * var(--ui))); }
html[data-layout="phone-landscape"] #filter-panel  { top: calc(10 * var(--ui)); left: calc(10 * var(--ui)); bottom: calc(10 * var(--ui)); border-radius: calc(18 * var(--ui)); }
html[data-layout="phone-landscape"] #filter-header { padding: calc(14 * var(--ui)) calc(16 * var(--ui)) calc(8 * var(--ui)); font-size: calc(15 * var(--ui)); }
html[data-layout="phone-landscape"] #filter-buttons-grid { padding: 0 calc(16 * var(--ui)) calc(8 * var(--ui)); gap: calc(8 * var(--ui)); }
html[data-layout="phone-landscape"] .filter-btn    { padding: calc(8 * var(--ui)) calc(12 * var(--ui)); font-size: calc(12 * var(--ui)); }
html[data-layout="phone-landscape"] .arrow-icon    { width: calc(15 * var(--ui)); height: calc(15 * var(--ui)); }
html[data-layout="phone-landscape"] #apt-list {
  padding: calc(8 * var(--ui)) calc(16 * var(--ui)) calc(14 * var(--ui)); gap: calc(10 * var(--ui));
  /* Small enough that the 330px panel still fits two columns once its
     scrollbar is accounted for — a single full-width card wastes the little
     vertical room a landscape phone has. */
  grid-template-columns: repeat(auto-fill, minmax(calc(116 * var(--ui)), 1fr));
}
html[data-layout="phone-landscape"] .apt-card       { width: 100%; height: auto; overflow: visible; }
html[data-layout="phone-landscape"] .apt-card-thumb { height: auto; aspect-ratio: 228 / 180; border-radius: calc(14 * var(--ui)) calc(14 * var(--ui)) 0 0; }
html[data-layout="phone-landscape"] .apt-card-body  { padding: calc(6 * var(--ui)) calc(8 * var(--ui)) calc(10 * var(--ui)); gap: calc(5 * var(--ui)); border-radius: 0 0 calc(14 * var(--ui)) calc(14 * var(--ui)); }
html[data-layout="phone-landscape"] .apt-card-name  { font-size: calc(11 * var(--ui)); padding: calc(4 * var(--ui)) calc(8 * var(--ui)); }
html[data-layout="phone-landscape"] .apt-info-item  { font-size: calc(10 * var(--ui)); }
html[data-layout="phone-landscape"] #day-night-label { display: none; }
html[data-layout="phone-landscape"] #bg-slider      { padding: calc(10 * var(--ui)) calc(18 * var(--ui)); }
html[data-layout="phone-landscape"] #slider-track   { gap: calc(20 * var(--ui)); }
html[data-layout="phone-landscape"] #detail-layout  { flex-direction: column; overflow-y: auto; }
html[data-layout="phone-landscape"] #plan-viewer-wrap { flex: none; height: 62vh; border-right: none; }
html[data-layout="phone-landscape"] #apt-info-panel   { width: 100%; flex: none; }


/* =========================================================================
   PORTRAIT LAYOUT  (phones and upright tablets)

   The screen splits into two stacked regions:

       ┌───────────────┐  ← floating topbar overlays the scene
       │     STAGE     │    --stage-h, set by viewport.js; shows the focus
       ├───────────────┤    region of the 1920×1080 render in full
       │  bottom bar   │
       ├───────────────┤
       │  sheet:       │    filters + apartment cards, slides down to a tab
       │  filters/list │
       └───────────────┘

   All rules key off [data-orient="portrait"], which viewport.js writes onto
   <html>, so CSS and JS can never disagree about the active mode.
   ========================================================================= */

/* ---- Scene is a band across the top, not the whole screen ---- */
html[data-orient="portrait"] #bg-layer {
  top: var(--stage-top); height: var(--stage-h); bottom: auto;
}
/* Interactive layer must span the stage (which starts at the very top, under
   the floating topbar) or the upper hot zones would be clipped away. */
html[data-orient="portrait"] #browse-layout { top: 0; }

/* ---- Topper -------------------------------------------------------------
   No longer a floating rounded window over the render: it is a full-bleed
   band that owns the top of the screen (topper_main.svg / topper_floor_plan
   .svg). Its measured height becomes --topbar-h, which is where the stage
   starts — see syncPortraitChrome() in app.js.

   It also loses its buttons. Share / contact / favorites moved to the bottom
   menu on the browse pages; only the detail page ("plan mode") keeps its own
   actions here, and those are the three text links plus a red back button at
   the far left.
   ------------------------------------------------------------------------ */
html[data-orient="portrait"] #topbar {
  top: 0; left: 0; right: 0;
  border-radius: 0; border: none;
  background: #191919;
  padding-top: env(safe-area-inset-top);
}
html[data-orient="portrait"] #topbar-row1 { height: calc(66 * var(--ui)); padding: 0 calc(18 * var(--ui)); gap: calc(9 * var(--ui)); }
/* Title left, logo hard right (the design's CGI·KITE mark) — one flex
   container, so `order` is enough to swap them without touching landscape. */
html[data-orient="portrait"] #topbar-left { gap: calc(9 * var(--ui)); }
html[data-orient="portrait"] #logo        { order: 2; margin-left: auto; }
html[data-orient="portrait"] #logo img    { height: calc(25 * var(--ui)); }
/* Both lines now show, stacked: 20/1.08, bold over regular. */
html[data-orient="portrait"] #page-title {
  display: flex; flex-direction: column; min-width: 0;
  font-size: calc(20 * var(--ui)); line-height: 1.08; letter-spacing: 0.02em;
}
html[data-orient="portrait"] #page-title .title-bold { font-size: inherit; font-weight: 700; }
html[data-orient="portrait"] #page-title .title-sub  { font-weight: 400; letter-spacing: 0.03em; }
/* Row 1 carries no actions in portrait — they live in the bottom menu now.
   (#btn-back-page is the landscape back button; portrait uses the one inside
   #topbar-left instead, so the arrow sits left of the title as designed.) */
html[data-orient="portrait"] #topbar-right { display: none; }
html[data-orient="portrait"] #btn-back-page-m {
  display: flex; order: 0; flex-shrink: 0;
  width: calc(41 * var(--ui)); height: calc(41 * var(--ui));
}
html[data-orient="portrait"] #btn-back-page-m svg { width: calc(19 * var(--ui)); height: calc(19 * var(--ui)); }
/* Row 2 (detail page): one row of three underlined text actions, spread edge
   to edge. The Home / Back-to-the-Building pills are gone — the red back
   button in row 1 replaces both. */
html[data-orient="portrait"] #topbar-row2 {
  height: calc(46 * var(--ui)); padding: 0 calc(17 * var(--ui));
}
html[data-orient="portrait"] #topbar-nav-left  { display: none; }
html[data-orient="portrait"] #topbar-nav-right { flex: 1; justify-content: space-between; gap: calc(8 * var(--ui)); }
html[data-orient="portrait"] .btn-text-action  { font-size: calc(15 * var(--ui)); color: var(--text); padding: 0; }

/* ---- Filter panel becomes a draggable bottom sheet ----------------------
   The box is ALWAYS laid out at its full height (from just under the topbar to
   the bottom of the screen) and pushed down by --sheet-y; only a transform
   moves during the drag, so there is no reflow per frame.

   --sheet-pad mirrors --sheet-y, but is only written once the sheet settles.
   Without it the panel's content box would keep ending --sheet-y px BELOW the
   viewport, and the last screenful of apartment cards could never be scrolled
   into view — which is the bug that makes cards unreachable on short screens.
   ------------------------------------------------------------------------ */
html[data-orient="portrait"] #filter-panel {
  /* written by app.js sheetOffsets(); the fallback matches its default */
  top: var(--sheet-full-top, 60px);
  left: 0; right: 0; bottom: 0;
  width: auto; height: auto;
  border-radius: calc(22 * var(--ui)) calc(22 * var(--ui)) 0 0;
  border-bottom: none;
  /* Room for the grab handle above the first row of controls, which is now the
     bottom bar rather than the filter header. */
  padding-top: calc(19 * var(--ui));
  padding-bottom: calc(var(--sheet-pad, 0px) + env(safe-area-inset-bottom));
  transform: translateY(var(--sheet-y, 0px));
}
/* Both backgrounds switched off: the sheet is the whole screen, so the rounded
   "I slide up over something" corners no longer mean anything. */
html[data-orient="portrait"][data-bg="off"] #filter-panel { border-radius: 0; }
html[data-orient="portrait"] #filter-panel.panel-hidden {
  transform: translateY(var(--sheet-y, 100%));
}
/* Finger is driving it — no easing, and no padding change mid-gesture. */
html[data-orient="portrait"] #filter-panel.sheet-dragging {
  transition: none;
}
/* Grab handle + the strip around it are the grip; the browser must not treat a
   vertical drag there as a scroll or a pull-to-refresh. */
html[data-orient="portrait"] #filter-panel::before {
  content: ''; position: absolute; top: calc(7 * var(--ui)); left: 50%;
  width: calc(42 * var(--ui)); height: calc(4 * var(--ui)); margin-left: calc(-21 * var(--ui));
  border-radius: calc(2 * var(--ui)); background: rgba(255,255,255,0.25);
  transition: background 0.15s, width 0.15s;
}
html[data-orient="portrait"] #filter-panel.sheet-dragging::before {
  background: rgba(255,255,255,0.55); width: calc(54 * var(--ui)); margin-left: calc(-27 * var(--ui));
}
html[data-orient="portrait"] #filter-header {
  padding: calc(10 * var(--ui)) calc(16 * var(--ui)) calc(10 * var(--ui)); font-size: calc(15 * var(--ui));
  touch-action: none; cursor: grab; user-select: none;
}
html[data-orient="portrait"] #filter-panel.sheet-dragging #filter-header { cursor: grabbing; }
/* The chevron collapses the sheet downwards in portrait, so point it that way. */
html[data-orient="portrait"] #panel-toggle-btn svg { transform: rotate(-90deg); }
html[data-orient="portrait"] .panel-tab-btn svg    { transform: rotate(-90deg); }

html[data-orient="portrait"] #panel-tab {
  top: auto; bottom: 0; left: 0; right: 0;
  border-radius: calc(22 * var(--ui)) calc(22 * var(--ui)) 0 0;
  justify-content: space-between;
  padding: calc(14 * var(--ui)) calc(16 * var(--ui)) calc(calc(14 * var(--ui)) + env(safe-area-inset-bottom));
}

/* ---- Filter buttons + dropdowns ---- */
html[data-orient="portrait"] #filter-buttons-grid { padding: 0 calc(14 * var(--ui)) calc(8 * var(--ui)); gap: calc(8 * var(--ui)); }
html[data-orient="portrait"] #extra-filters { gap: calc(8 * var(--ui)); }
html[data-orient="portrait"] .filter-btn { padding: calc(10 * var(--ui)) calc(14 * var(--ui)); font-size: calc(12.5 * var(--ui)); }
html[data-orient="portrait"] .arrow-icon { width: calc(16 * var(--ui)); height: calc(16 * var(--ui)); }
/* A dropdown as narrow as its button cannot hold a dual range slider plus
   From/To fields, so drop the per-button anchor and let it span the sheet. */
html[data-orient="portrait"] .filter-btn-wrap { position: static; }
html[data-orient="portrait"] .filter-dropdown { left: calc(14 * var(--ui)); right: calc(14 * var(--ui)); width: auto; }

/* ---- Apartment cards: fluid instead of a fixed 228×326 ---- */
html[data-orient="portrait"] #apt-list {
  padding: calc(8 * var(--ui)) calc(14 * var(--ui)) calc(20 * var(--ui)); gap: calc(10 * var(--ui));
  grid-template-columns: repeat(auto-fill, minmax(calc(150 * var(--ui)), 1fr));
}
/* `overflow: hidden` (the desktop card clips its thumbnail to the rounded
   corners) makes the card contribute nothing to its grid row's intrinsic
   height, so with height:auto every row collapsed to the calc(4 * var(--ui)) border and the
   cards stacked on top of each other. Let the card overflow and round the two
   children instead — same visual result, rows size correctly. */
html[data-orient="portrait"] .apt-card       { width: 100%; height: auto; overflow: visible; }
html[data-orient="portrait"] .apt-card-thumb { height: auto; aspect-ratio: 228 / 206; border-radius: calc(14 * var(--ui)) calc(14 * var(--ui)) 0 0; }
html[data-orient="portrait"] .apt-card-body  { padding: calc(6 * var(--ui)) calc(9 * var(--ui)) calc(12 * var(--ui)); gap: calc(6 * var(--ui)); border-radius: 0 0 calc(14 * var(--ui)) calc(14 * var(--ui)); }
html[data-orient="portrait"] .apt-card-name  { font-size: calc(11.5 * var(--ui)); padding: calc(5 * var(--ui)) calc(8 * var(--ui)); }
html[data-orient="portrait"] .apt-info-item  { font-size: calc(11 * var(--ui)); gap: calc(4 * var(--ui)); }
html[data-orient="portrait"] .apt-info-item img { width: calc(20 * var(--ui)); height: calc(20 * var(--ui)); }
/* Tablets are wide enough for a third column. */
html[data-layout="tablet-portrait"] #apt-list { grid-template-columns: repeat(auto-fill, minmax(calc(190 * var(--ui)), 1fr)); }

/* ---- Bottom bar rides at the TOP of the sheet ---------------------------
   The sheet reads top-to-bottom as:

       ┌────────────────────────────────────┐
       │                ▬                   │  ← grab handle (drag zone)
       │ day/night · BG slider · Hide Units │  ← the "slider bar"; only exists
       ├────────────────────────────────────┤    while a background is on
       │ 360 view · Gallery · ⋯ · ↩         │  ← the bottom menu
       ├────────────────────────────────────┤
       │ Show the apartments: …             │  ← filters, then the card list
       └────────────────────────────────────┘

   app.js placeBottomBar() reparents #bottom-bar into the sheet for portrait
   and hands it back to <body> for landscape, where it is still the floating
   pill it always was. In the sheet it is a plain in-flow block, so it rides
   the drag transform for free — no fixed positioning to keep in sync.
   ------------------------------------------------------------------------ */
html[data-orient="portrait"] #bottom-bar {
  position: static;
  flex-direction: column; align-items: stretch; flex-shrink: 0;
  background: transparent;           /* the sheet is the surface */
  pointer-events: auto;
  transition: none;
}
/* The uniting pill outline is gone: the two rows read as one straight-edged
   block against the bar itself. */
html[data-orient="portrait"] #bottom-frame {
  gap: calc(7 * var(--ui)); padding: calc(4 * var(--ui)) calc(8 * var(--ui));
  width: 100%;
  border: none; border-radius: 0; background: transparent;
}
/* No background on screen → nothing for the slider bar to control. */
html[data-orient="portrait"][data-bg="off"] #bottom-frame { display: none; }
/* The bouncing pointer sat above the frame; from a docked bar it would poke up
   into the sheet. */
html[data-orient="portrait"] #slider-triangle { display: none; }

/* These controls' heights ARE the bar's height, which syncPortraitChrome()
   measures to place the stage and the sheet. `transition: var(--trans)` is
   shorthand for "all", so on an orientation change (which moves --ui, hence
   every size) a measurement taken mid-animation reads an intermediate height
   and the stage lands a few pixels out. Nothing here needs its geometry
   animated — only its colours. */
html[data-orient="portrait"] #bottom-bar .day-night-btn,
html[data-orient="portrait"] #bottom-bar .zones-toggle-btn,
html[data-orient="portrait"] #bottom-menu button {
  transition-property: background-color, border-color, color, opacity;
}

/* ---- Bottom menu (bottom_menu.svg) ---- */
/* The design's gutter is 17 and its gaps 6, but its type is narrower than
   Poppins: at those numbers the six controls need 420px and overflow a 412px
   phone as soon as the back button appears. 14/5 buys back the difference and
   still fits a 320px screen, where --ui bottoms out at 0.80. */
html[data-orient="portrait"] #bottom-menu {
  display: flex; align-items: center; gap: calc(5 * var(--ui));
  padding: calc(9 * var(--ui)) calc(14 * var(--ui));
  pointer-events: auto;
}
/* The two background switches. Teal = the one you are looking at; tapping it
   again switches its background off. */
.bm-pill {
  display: flex; align-items: center; justify-content: center;
  height: calc(30 * var(--ui)); padding: 0 calc(12 * var(--ui));
  border: 1px solid rgba(255,255,255,0.9); border-radius: var(--pill-radius);
  background: #000; color: #fff;
  font-family: inherit; font-size: calc(13 * var(--ui)); font-weight: 400;
  white-space: nowrap; cursor: pointer; transition: var(--trans);
  /* Degrade by ellipsis rather than a clipped half-glyph if a screen is
     narrower than anything we tuned for. */
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.bm-pill.active {
  background: var(--accent); border-color: var(--accent);
  color: #111; font-weight: 700;
}
.bm-pill:active { opacity: 0.8; }
.bm-actions { display: flex; align-items: center; gap: calc(5 * var(--ui)); margin-left: auto; flex-shrink: 0; }
.bm-icon {
  display: flex; align-items: center; justify-content: center;
  width: calc(30 * var(--ui)); height: calc(30 * var(--ui));
  border: 1px solid rgba(255,255,255,0.9); border-radius: 50%;
  background: transparent; color: #fff;
  cursor: pointer; transition: var(--trans); flex-shrink: 0;
}
.bm-icon:active { opacity: 0.7; }
.bm-icon.fav-active { border-color: #e74c3c; color: #e74c3c; }
.bm-back {
  display: flex; align-items: center; justify-content: center;
  width: calc(32 * var(--ui)); height: calc(32 * var(--ui));
  border: none; border-radius: 50%;
  background: #e03030; color: #fff;
  cursor: pointer; transition: var(--trans); flex-shrink: 0;
}
.bm-back:active { opacity: 0.8; }
html[data-orient="portrait"] #day-night-label { display: none; }
html[data-orient="portrait"] #day-night-section { padding: calc(5 * var(--ui)) calc(7 * var(--ui)); gap: calc(5 * var(--ui)); flex-shrink: 0; }
html[data-orient="portrait"] .day-night-btn { width: calc(30 * var(--ui)); height: calc(30 * var(--ui)); }
/* The slider is the only elastic element; 11 dots cannot fit a phone, so the
   track scrolls and app.js keeps the active dot centred. */
html[data-orient="portrait"] #bg-slider {
  /* 14 (not 10) so the 34-wide pill can overhang the first and last dot by 13.5
     without being clipped by this box's overflow:hidden. */
  padding: calc(9 * var(--ui)) calc(14 * var(--ui)); flex: 1; min-width: 0;
}
/* The track fills the pill and spreads its dots edge to edge — 4 keyframes on
   the hero left a wide empty gutter each side when they were merely centred.
   Once the dots outgrow the track (11 viewpoints on a phone) space-between
   stops applying by itself and the box scrolls, as before. */
html[data-orient="portrait"] #slider-track {
  flex: 1; justify-content: space-between;
  gap: calc(8 * var(--ui)); min-width: 0; overflow-x: auto; scroll-behavior: smooth;
  scrollbar-width: none; -ms-overflow-style: none;
}
html[data-orient="portrait"] #slider-track::-webkit-scrollbar { display: none; }
html[data-orient="portrait"] .slider-dot { width: calc(7 * var(--ui)); height: calc(20 * var(--ui)); }
html[data-orient="portrait"] #slider-pill {
  width: calc(34 * var(--ui)); height: calc(26 * var(--ui)); background-size: 100% 100%;
}
html[data-orient="portrait"] .zones-toggle-btn {
  height: calc(40 * var(--ui)); padding: 0 calc(11 * var(--ui)); font-size: calc(11 * var(--ui)); flex-shrink: 0;
}

/* ---- Scene overlays ---- */
/* 26px wide, 4px from the edge — NOT arbitrary. Together with FOCUS_SECTION
   this is the largest arrow that keeps both gutters completely free of hot
   zones on all 8 section viewpoints at screen widths 320…600. Widen either
   value and the arrows start covering clickable units again (section_2 is the
   binding case, with only 10px of slack at 412px). */
html[data-orient="portrait"] .arrow-nav {
  top: calc(var(--stage-top) + var(--stage-h) / 2);
  width: calc(26 * var(--ui)); height: calc(56 * var(--ui));
  border-radius: calc(6 * var(--ui));
}
html[data-orient="portrait"] .arrow-nav svg { width: calc(18 * var(--ui)); height: calc(18 * var(--ui)); }
html[data-orient="portrait"] #btn-prev-section,
html[data-orient="portrait"] #browse-layout.panel-closed #btn-prev-section { left: calc(4 * var(--ui)); }
html[data-orient="portrait"] #btn-next-section { right: calc(4 * var(--ui)); }
html[data-orient="portrait"] #hint-360 {
  top: auto; bottom: calc(var(--vh) - var(--stage-top) - var(--stage-h) + calc(10 * var(--ui)));
  right: calc(14 * var(--ui)); transform: none; font-size: calc(17 * var(--ui)); gap: calc(7 * var(--ui));
}
html[data-orient="portrait"] #hint-360 .hint-360-arrow { width: calc(10 * var(--ui)); height: calc(12 * var(--ui)); }
/* Stage collapsed to nothing — its overlays have no scene to sit on. */
html[data-orient="portrait"][data-bg="off"] .arrow-nav,
html[data-orient="portrait"][data-bg="off"] #hint-360 { display: none !important; }

/* ---- Detail page: two cards on a white page ----------------------------
   Per Unit Detail Page Mobile part-1…3: the plan and the apartment facts are
   separate white cards, 18.5px gutters, 19.5px radius, 1px black outline, on a
   plain white scrolling page. The plan card is square with the plan contained
   inside it; the price row is pinned to the bottom of the info card.
   ---------------------------------------------------------------------- */
html[data-orient="portrait"] #detail-layout {
  flex-direction: column;
  padding: calc(var(--topbar-h) + calc(18.5 * var(--ui))) calc(18.5 * var(--ui))
           calc(calc(24 * var(--ui)) + env(safe-area-inset-bottom));
  gap: calc(19 * var(--ui));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
html[data-orient="portrait"] #plan-viewer-wrap {
  flex: none; padding: 0;
  background: transparent; border-right: none; border-bottom: none;
}
html[data-orient="portrait"] #plan-viewer {
  height: auto; aspect-ratio: 1 / 1;
  border: 1px solid #000; border-radius: calc(19.5 * var(--ui));
  /* The inset belongs to the CARD, not to the image. On the image it is applied
     inside a box that max-height has already clamped to the card, so the plan
     gets shrunk twice and floats in the middle at ~half width. (#btn-zoom is
     unaffected: an absolutely positioned child is laid out against the padding
     edge, which padding does not move.) */
  padding: calc(23 * var(--ui));
}
html[data-orient="portrait"] #plan-img {
  width: 100%; height: 100%; padding: 0; object-fit: contain;
}
/* Always visible: there is no hover on a phone to reveal it. */
html[data-orient="portrait"] #btn-zoom {
  bottom: calc(9 * var(--ui)); right: calc(8 * var(--ui));
  width: calc(44 * var(--ui)); height: calc(42 * var(--ui));
  border-radius: calc(14.5 * var(--ui));
  background: var(--accent); border: 1px solid #000; color: #111;
  opacity: 1;
}
html[data-orient="portrait"] #apt-info-panel {
  width: 100%; flex: none; overflow: visible;
  min-height: calc(500 * var(--ui));
  border: 1px solid #000; border-radius: calc(19.5 * var(--ui));
  padding: calc(31 * var(--ui)) calc(20 * var(--ui)) calc(34 * var(--ui));
}
html[data-orient="portrait"] #apt-detail-name     { font-size: calc(21 * var(--ui)); margin-bottom: calc(5 * var(--ui)); }
html[data-orient="portrait"] #apt-detail-subtitle { font-size: calc(15 * var(--ui)); color: #555; margin-bottom: calc(17 * var(--ui)); }
html[data-orient="portrait"] .btn-contact-manager {
  height: calc(50 * var(--ui)); padding: 0;
  font-size: calc(16 * var(--ui)); letter-spacing: 0.02em;
  margin-bottom: calc(28 * var(--ui));
}
/* The status marker is a wide outlined capsule in the new design, tinted by
   status, not a small filled dot. */
html[data-orient="portrait"] #apt-status-row { gap: calc(10 * var(--ui)); margin-bottom: calc(14 * var(--ui)); }
html[data-orient="portrait"] #apt-status-dot {
  width: calc(43 * var(--ui)); height: calc(37 * var(--ui));
  border-radius: calc(18.5 * var(--ui));
  background: #fff; border: 2px solid #C2C2C2;
}
html[data-orient="portrait"] #apt-status-dot.sold   { background: #fff; border-color: var(--status-sold); }
html[data-orient="portrait"] #apt-status-dot.booked { background: #fff; border-color: var(--status-book); }
html[data-orient="portrait"] #apt-status-text { font-size: calc(16 * var(--ui)); color: #333; }
/* 45px icons, 53px pitch, and no rules between the rows — the only divider is
   the one above the price. */
html[data-orient="portrait"] .info-row,
html[data-orient="portrait"] #apt-detail-outdoor-row {
  gap: calc(9 * var(--ui)); padding: calc(4 * var(--ui)) 0;
  border-bottom: none; font-size: calc(16 * var(--ui));
}
html[data-orient="portrait"] .info-row img { width: calc(45 * var(--ui)); height: calc(45 * var(--ui)); }
html[data-orient="portrait"] #apt-detail-outdoor > div {
  display: flex; align-items: center; flex-wrap: wrap; gap: calc(9 * var(--ui));
}
html[data-orient="portrait"] .outdoor-detail-item     { gap: calc(9 * var(--ui)); font-size: calc(16 * var(--ui)); }
html[data-orient="portrait"] .outdoor-detail-item img { width: calc(45 * var(--ui)); height: calc(45 * var(--ui)); }
html[data-orient="portrait"] #apt-price-row {
  margin-top: auto; padding-top: calc(16 * var(--ui));
  border-top: 1px solid #000;
}
html[data-orient="portrait"] .price-label { font-size: calc(19 * var(--ui)); color: #111; }
html[data-orient="portrait"] .price-value { font-size: calc(21 * var(--ui)); }

/* Narrow phones (≤380px): the logo, title and four icon buttons no longer fit
   one row, and "PANORAMIQA" was being ellipsised to "PANORA". */
/* The hand-written ≤380px block that used to live here (smaller title, logo
   and icons so "PANORAMIQA" stopped being ellipsised to "PANORA") is gone:
   --ui now does the same job continuously. At 360px it resolves to 0.874, so
   the 16px title becomes 14px and the 34px icons 29.7px — within a pixel of
   what that block hard-coded, but without a cliff at the breakpoint. */

/* ---- Popups ---- */
/* app.js positions #popup-apt inline near the click, which is meaningless on a
   phone — pin it to the bottom as a wide card instead. */
html[data-orient="portrait"] #popup-apt {
  left: calc(12 * var(--ui)) !important; right: calc(12 * var(--ui)) !important;
  top: auto !important; bottom: calc(calc(12 * var(--ui)) + env(safe-area-inset-bottom));
  width: auto;
  display: grid; gap: calc(2 * var(--ui)) calc(10 * var(--ui)); padding: calc(10 * var(--ui));
  grid-template-columns: calc(108 * var(--ui)) 1fr;
  grid-template-areas: "plan name" "plan price" "plan info" "plan btn";
  align-content: start;
}
html[data-orient="portrait"] #popup-apt-plan-wrap { grid-area: plan; border-radius: calc(12 * var(--ui)); align-self: center; }
html[data-orient="portrait"] #popup-apt-name-row  { grid-area: name;  padding: 0; }
html[data-orient="portrait"] #popup-apt-price-row { grid-area: price; padding: calc(4 * var(--ui)) 0 0; }
html[data-orient="portrait"] #popup-apt-info-row  { grid-area: info;  padding: calc(6 * var(--ui)) 0; }
html[data-orient="portrait"] #popup-apt .btn-review { grid-area: btn; width: 100%; margin: calc(4 * var(--ui)) 0 0; }
html[data-orient="portrait"] #popup-apt .popup-close { top: calc(6 * var(--ui)); left: calc(6 * var(--ui)); }

html[data-orient="portrait"] #popup-contact,
html[data-orient="portrait"] #popup-favorites {
  width: calc(100vw - calc(24 * var(--ui))); padding: calc(24 * var(--ui)) calc(18 * var(--ui)) calc(20 * var(--ui));
  max-height: calc(var(--vh) - calc(40 * var(--ui)));
}
html[data-orient="portrait"] .popup-textarea { height: calc(76 * var(--ui)); }
html[data-orient="portrait"] #toast { bottom: calc(calc(20 * var(--ui)) + env(safe-area-inset-bottom)); }
/* Hover tooltip is meaningless without a mouse — a tap goes straight through
   to the apartment (see hotzones.js onUp). */
@media (hover: none) { #hz-popup, #pano-zone-tip { display: none !important; } }
