/* ============================================================================
   HomeOS Dubai — service-browse UI (mobile-app idiom)
   ----------------------------------------------------------------------------
   Pattern language borrowed from the Bayut app, applied to services rather than
   listings: search-first entry, photo-forward cards with a price chip and a save
   heart, icon spec rows, a filter bottom sheet with a live result count, and a
   sticky price bar. Brand, colour, type and copy stay HomeOS: inspired by, not
   copied from. One accent (teal) for interaction, navy for identity, gold for
   material only, exactly as tokens.css locks.
   ============================================================================ */

/* ------------------------------------------------------------- search bar */
.app-search { display: grid; gap: var(--s3); }
.searchbar {
  display: flex; align-items: center; gap: var(--s3);
  background: var(--card); border: 1px solid var(--line-2); border-radius: var(--r-pill);
  padding: 6px 6px 6px 16px; box-shadow: var(--sh-1);
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.searchbar:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.searchbar svg { width: 19px; height: 19px; flex: 0 0 auto; color: var(--ink-300); }
.searchbar input {
  flex: 1 1 auto; min-width: 0; border: 0; outline: 0; background: transparent;
  font-size: var(--t-body); color: var(--ink-900); padding: 10px 0;
}
.searchbar input::placeholder { color: var(--ink-300); }
.searchbar .go { flex: 0 0 auto; }

/* segmented control (Move-in / Move-out / Landlord) */
.segs {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px;
  background: var(--paper-2); border-radius: var(--r-pill); padding: 4px;
}
.segs a, .segs button {
  text-align: center; padding: 9px 10px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--ink-400); font-size: var(--t-micro); font-weight: 580;
  cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: all var(--dur-2) var(--ease);
}
.segs .on { background: var(--card); color: var(--ink-900); box-shadow: var(--sh-1); }

/* ------------------------------------------------------------ chip rails */
.rail-title { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3); margin-bottom: var(--s3); }
.rail-title h3 { font-size: 1.02rem; }
.rail-title a { font-size: var(--t-micro); font-weight: 560; color: var(--accent); }
.rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: max-content; gap: var(--s3);
  overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: var(--s2);
  margin-inline: calc(var(--s5) * -1); padding-inline: var(--s5);
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.rail::-webkit-scrollbar { display: none; }
.rail > * { scroll-snap-align: start; }
.chiprow {
  display: grid; grid-auto-flow: column; grid-auto-columns: max-content; gap: var(--s2);
  overflow-x: auto; scrollbar-width: none; padding-bottom: 2px;
}
.chiprow::-webkit-scrollbar { display: none; }

/* category tile (circular icon + label), Bayut-style shortcut row */
.cat {
  display: grid; justify-items: center; gap: 8px; width: 84px;
  padding: var(--s3) 6px; border-radius: var(--r-tile);
  border: 1px solid transparent; background: transparent; cursor: pointer;
  font-size: 11.5px; font-weight: 550; color: var(--ink-500); text-align: center;
  transition: all var(--dur-2) var(--ease);
}
.cat .disc {
  display: grid; place-items: center; width: 52px; height: 52px; border-radius: var(--r-pill);
  background: var(--paper-2); font-size: 22px; transition: all var(--dur-2) var(--ease);
}
.cat:hover, .cat.on { background: var(--card); border-color: var(--line); box-shadow: var(--sh-1); }
.cat:hover .disc, .cat.on .disc { background: var(--accent-tint); }
.cat span { line-height: 1.25; }

/* ------------------------------------------------------- listing cards */
.listings { display: grid; gap: var(--s4); }
@media (min-width: 900px) { .listings { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1240px) { .listings { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.listing {
  display: grid; grid-template-rows: auto 1fr; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r-card); overflow: hidden;
  box-shadow: var(--sh-1); text-decoration: none; color: inherit;
  transition: transform var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}
.listing:hover { transform: translateY(-3px); box-shadow: var(--sh-2); color: inherit; }
.listing .shot { position: relative; aspect-ratio: 16 / 10; background: var(--paper-3); overflow: hidden; }
.listing .shot img { width: 100%; height: 100%; object-fit: cover; }
.listing .shot .ph { position: absolute; inset: 0; display: grid; place-items: center; font-size: 34px; background: linear-gradient(150deg, var(--paper-2), var(--paper-3)); }
.listing .price {
  position: absolute; left: 12px; bottom: 12px;
  background: rgba(255, 255, 255, 0.94); color: var(--ink-900);
  font-family: var(--font-mono); font-size: var(--t-small); font-weight: 660;
  padding: 5px 11px; border-radius: var(--r-pill); box-shadow: var(--sh-1);
}
.listing .price em { font-style: normal; font-size: 10.5px; color: var(--ink-400); font-weight: 550; }
.listing .fav {
  position: absolute; right: 10px; top: 10px; width: 38px; height: 38px;
  display: grid; place-items: center; border-radius: var(--r-pill); border: 0;
  background: rgba(255, 255, 255, 0.9); color: var(--ink-500); cursor: pointer;
  box-shadow: var(--sh-1); transition: transform var(--dur-1) var(--ease-spring), color var(--dur-1) var(--ease);
}
.listing .fav svg { width: 19px; height: 19px; }
.listing .fav:hover { transform: scale(1.06); }
.listing .fav.on { color: var(--err); }
.listing .fav:active { transform: scale(0.92); }
.listing .body { padding: var(--s4); display: grid; gap: 9px; align-content: start; }
.listing h3 { font-size: 1.02rem; letter-spacing: -0.015em; }
.listing .where { font-size: var(--t-micro); color: var(--ink-400); }
.badges { display: flex; flex-wrap: wrap; gap: 6px; }
.badge-b {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px;
  border-radius: 7px; font-size: 10.5px; font-weight: 620; letter-spacing: 0.01em;
}
.b-verified { background: var(--accent-tint); color: var(--accent-700); }
.b-licensed { background: var(--brand-tint); color: var(--brand); }
.b-photo { background: var(--ok-tint); color: var(--ok); }
.b-fast { background: var(--warn-tint); color: var(--warn); }
.b-save { background: var(--err-tint); color: var(--err); }

/* icon spec row: beds · baths · sqft in Bayut, services · duration · SLA here */
.specs { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; font-size: var(--t-micro); color: var(--ink-500); }
.specs > span { display: inline-flex; align-items: center; gap: 5px; }
.specs svg { width: 15px; height: 15px; color: var(--ink-300); flex: 0 0 auto; }
.specs .sep { width: 1px; height: 14px; background: var(--line-2); }

/* rating pill */
.rate { display: inline-flex; align-items: center; gap: 5px; font-size: var(--t-micro); font-weight: 600; color: var(--ink-700); }
.rate b { font-family: var(--font-mono); }
.rate svg { width: 14px; height: 14px; color: var(--gold); }

/* ------------------------------------------------------------ result bar */
.sortbar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  flex-wrap: wrap; padding: var(--s3) 0;
}
.sortbar .count { font-size: var(--t-small); font-weight: 580; color: var(--ink-700); }
.sortbar .count span { color: var(--ink-400); font-weight: 450; }
.sortbar select {
  padding: 8px 12px; border: 1px solid var(--line-2); border-radius: var(--r-pill);
  background: var(--card); font-size: var(--t-micro); color: var(--ink-700);
}
.filter-btn { display: inline-flex; align-items: center; gap: 7px; }
.filter-btn svg { width: 16px; height: 16px; }
.filter-btn .n {
  display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px;
  background: var(--accent); color: #fff; border-radius: var(--r-pill); font-size: 10.5px; font-weight: 700;
}

/* --------------------------------------------------------- bottom sheet */
.sheet-backdrop {
  position: fixed; inset: 0; z-index: var(--z-overlay);
  background: rgba(6, 19, 25, 0.42); opacity: 0; pointer-events: none;
  transition: opacity var(--dur-2) var(--ease);
}
.sheet-backdrop.on { opacity: 1; pointer-events: auto; }
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-overlay);
  background: var(--card); border-radius: 22px 22px 0 0;
  padding: var(--s5) var(--s5) calc(var(--s5) + env(safe-area-inset-bottom));
  box-shadow: var(--sh-3); transform: translateY(105%);
  transition: transform var(--dur-3) var(--ease-out);
  max-height: 88dvh; overflow-y: auto;
}
.sheet.on { transform: none; }
@media (min-width: 900px) {
  .sheet { left: auto; right: var(--s6); bottom: var(--s6); width: 420px; border-radius: var(--r-card); transform: translateY(12px); opacity: 0; }
  .sheet.on { transform: none; opacity: 1; }
}
.sheet .grip { width: 42px; height: 4px; border-radius: var(--r-pill); background: var(--line-2); margin: 0 auto var(--s4); }
.sheet h3 { font-size: 1.05rem; margin-bottom: var(--s4); }
.sheet .group { margin-bottom: var(--s5); }
.sheet .group > h4 { margin-bottom: var(--s2); }
.sheet .range { display: flex; align-items: center; gap: var(--s3); }
.sheet .range input[type="range"] { flex: 1 1 auto; accent-color: var(--accent); }
.sheet .range output { font-family: var(--font-mono); font-size: var(--t-micro); font-weight: 620; min-width: 84px; text-align: right; }
.sheet .actions { display: grid; grid-template-columns: auto 1fr; gap: var(--s3); align-items: center; }
.sheet .apply { min-height: 46px; }

/* ------------------------------------------------------- sticky price bar */
.sticky-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-nav);
  display: none;
  align-items: center; justify-content: space-between; gap: var(--s3);
  padding: 10px var(--s5) calc(10px + env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, 0.94); border-top: 1px solid var(--line);
  backdrop-filter: blur(14px) saturate(160%);
}
@media (max-width: 1024px) {
  /* An action bar never replaces the navigation: it sits ABOVE the tab bar, and
     the page is padded to clear both. Hiding the tab bar here was a mistake — it
     stranded anyone on the booking or detail screen with no way back. */
  /* the default bottom bar is a floating capsule ending ~74px up, so action bars
     stack above that rather than above the old edge-to-edge bar */
  .sticky-bar { display: flex; bottom: calc(78px + env(safe-area-inset-bottom)); }
  /* `body.has-*` not `.has-*`: app.css sets `body.app { padding-bottom: 66px }`,
     and an element+class selector beats a bare class, so the shorter padding won
     and page content slid under the two bars. */
  body.has-sticky { padding-bottom: calc(152px + env(safe-area-inset-bottom)); }
  body.has-sticky .site-foot { padding-bottom: calc(152px + env(safe-area-inset-bottom)); }
}
/* The basket bar stacks ABOVE the tab bar when a page has both: a cart should
   never hide the navigation. */
@media (max-width: 1024px) {
  .basket-bar.with-tabs { bottom: calc(78px + env(safe-area-inset-bottom)); border-radius: 0; }
  body.has-basket { padding-bottom: calc(152px + env(safe-area-inset-bottom)); }
  .has-basket .tabbar { display: flex; }
  body.has-basket .site-foot { padding-bottom: calc(212px + env(safe-area-inset-bottom)); }
}
.sticky-bar .price { display: grid; gap: 1px; }
.sticky-bar .price b { font-family: var(--font-mono); font-size: 1.05rem; font-weight: 680; }
.sticky-bar .price span { font-size: 10.5px; color: var(--ink-400); }
.sticky-bar .btn { flex: 0 0 auto; min-height: 46px; }

/* --------------------------------------------------------- stat strip */
.stat-strip {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--s2);
  background: var(--paper-2); border: 1px solid var(--line); border-radius: var(--r-tile);
  padding: var(--s3); text-align: center;
}
.stat-strip div { display: grid; gap: 2px; }
.stat-strip b { font-family: var(--font-mono); font-size: 1rem; }
.stat-strip span { font-size: 10.5px; color: var(--ink-400); }

/* -------------------------------------------------- detail page pieces */
.detail-hero { position: relative; border-radius: var(--r-card); overflow: hidden; border: 1px solid var(--line); aspect-ratio: 16 / 9; background: var(--ink-800); }
.detail-hero img { width: 100%; height: 100%; object-fit: cover; }
.detail-hero .ph { position: absolute; inset: 0; display: grid; place-items: center; font-size: 56px; background: linear-gradient(150deg, var(--paper-2), var(--paper-3)); }
.detail-hero .back {
  position: absolute; left: 12px; top: 12px; width: 40px; height: 40px; border-radius: var(--r-pill);
  display: grid; place-items: center; background: rgba(255, 255, 255, 0.92); color: var(--ink-700);
  box-shadow: var(--sh-1); text-decoration: none; font-size: 17px;
}
.detail-hero .fav { right: 12px; top: 12px; left: auto; }
.incl { display: grid; gap: 0; }
.incl li {
  display: grid; grid-template-columns: 22px 1fr; gap: var(--s3); align-items: start;
  padding: 12px 0; border-bottom: 1px solid var(--line); font-size: var(--t-small); color: var(--ink-600);
}
.incl li:last-child { border-bottom: 0; }
.incl svg { width: 17px; height: 17px; color: var(--accent); margin-top: 3px; }
.incl b { color: var(--ink-900); font-weight: 580; }

/* ------------------------------------------------------------------- misc */
/* ---------------------------------------------------------------- icons
   The size scale lives in tokens.css (every page loads it, including the ops
   console, which needs .ico-sm without the marketplace layer). Only the
   marketplace-specific placements are set here. */
.disc svg { width: 23px; height: 23px; color: var(--accent); }
.cat:hover .disc svg, .cat.on .disc svg { color: var(--accent-700); }
.listing .shot .ph svg { width: 30px; height: 30px; color: var(--ink-300); }
.detail-hero .ph svg { width: 46px; height: 46px; color: var(--ink-300); }
.tile-ph svg { width: 30px; height: 30px; color: #fff; }

/* add/remove stepper: one control, two gestures (Urban Company's card action).
   Single-unit only: the pricing engine prices per service for a home size, and
   pretending a second tap doubles the price would be a lie. */
.stepper {
  display: inline-grid; grid-auto-flow: column; align-items: center;
  background: var(--accent); border-radius: var(--r-pill); overflow: hidden;
  min-height: 34px; box-shadow: var(--sh-1);
}
.stepper .tick-step {
  width: 34px; height: 34px; border: 0; background: transparent; color: #fff;
  font-size: 16px; font-weight: 700; line-height: 1; cursor: pointer;
  transition: background var(--dur-1) var(--ease);
}
.stepper .tick-step:hover { background: rgba(0, 0, 0, 0.14); }
.stepper .tick-step:active { background: rgba(0, 0, 0, 0.22); }
.stepper b { color: #fff; font-family: var(--font-mono); font-size: var(--t-small); padding-inline: 7px; }

.sk-card { border-radius: var(--r-card); overflow: hidden; border: 1px solid var(--line); background: var(--card); }

/* Branded tile: used wherever we have no honest photograph of the work. A brand
   panel with the service glyph and its label — deliberately NOT a stock photo
   pretending to depict a service we have not shot. Real photography drops in and
   replaces these; see assets/img/CREDITS.md. */
.tile-ph {
  position: absolute; inset: 0; display: grid; place-items: center; gap: 8px;
  background: linear-gradient(155deg, var(--brand) 0%, var(--ink-700) 58%, var(--accent-700) 100%);
  color: #fff; font-size: 30px; line-height: 1;
}
.tile-ph span { font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(255, 255, 255, 0.74); }
.sk-card .a { aspect-ratio: 16 / 10; }
.sk-card .b { padding: var(--s4); display: grid; gap: 10px; }
.sk-line { height: 12px; border-radius: 6px; }
.w-70 { width: 70%; } .w-45 { width: 45%; } .w-90 { width: 90%; }
