/* ============================================================================
   Furnobly — phone layer                              (2026-08-21)
   ============================================================================
   Loaded last, after refine.css, and everything in it lives inside a
   max-width query. Nothing here can reach a desktop viewport.

   What it is for. Measured on a 390px viewport against the live site:

     · the product page showed one photo, `object-fit: contain` inside a
       4/3.4 box with padding, of a file that spends half its pixels on empty
       background — a sofa rendered about 150px wide, with no way to see it
       bigger, and the price and the button 1,700px down the page;
     · the room-set page put 1,068px of copy and controls first, then the
       media, and only then the seven pieces of the set — in a horizontal
       carousel below the fold, which is to say the products themselves were
       effectively not on the page;
     · #products painted all 48 cards into a 15,020px scroll, each one a
       cramped row with a cover-cropped thumbnail and an arrow for a button;
     · two floating bubbles sat on top of the rent/buy toggle;
     · every route in the site was behind one hamburger.

   The fixes are structural, in this order: navigation you can reach with a
   thumb, images big enough to judge, and the price and the button in the same
   glance. Sections below follow that order.
   ========================================================================= */

/* ===========================================================================
   Components that exist at every width
   ===========================================================================
   The gallery replaced the product page's single static image, so it is not a
   phone-only thing: leaving its rules inside the phone query left the desktop
   page rendering all three pictures stacked down the column, unstyled. The
   viewer is here for the same reason — "let me see that bigger" is not a
   request only phones make.

   The phone query further down overrides sizes; it does not re-declare the
   component.
   ======================================================================== */

/* ---- The product gallery ------------------------------------------------
   One native scroll-snap track. The browser's own inertia and rubber-banding
   beat anything hand-rolled, and they keep working for a keyboard and a
   screen reader. */
.shots { position: relative; }

.shots-track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 100%;
  /* Centred, because the slides are different shapes: a 1.7:1 sofa crop and a
     0.6:1 wardrobe crop cannot share one height without one of them
     letterboxing. The track takes the height of its tallest slide and the
     rest sit in the middle of it. */
  align-items: center;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: inline mandatory;
  scrollbar-width: none;
}

.shots-track::-webkit-scrollbar { display: none; }


.shot {
  scroll-snap-align: start;
  margin: 0;
  display: grid;
  grid-template-rows: 1fr auto;
}

.shot img {
  /* Height follows the picture rather than a fixed box. The crop from
     tools/build-product-fits.py has already removed the empty plate, so a
     full-width sofa is simply 390 x 232 with no band above or below it — a
     fixed 420px box put a third of a screen of nothing around exactly the
     thing the customer came to look at. The cap keeps a wardrobe from taking
     the whole screen and pushing the price off it. */
  width: 100%;
  height: auto;
  /* Kept close to the shape of a wide piece on purpose. The track is as tall as
     its tallest slide, so letting a portrait wardrobe run to 62vh left a 2.3:1
     sofa floating in a box half again its own height. */
  max-height: 46vh;
  object-fit: contain;
  background: var(--offwhite);
  border-radius: 14px;
}

.shot-card {
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 8px;
  min-height: 220px;
  background: var(--offwhite);
  border-radius: 14px;
}

.shot-card em { font-style: normal; color: var(--muted); font-size: .85rem; }
.shot-card strong { font-size: 1.5rem; color: var(--indigo); }

.shot figcaption {
  display: grid;
  gap: 2px;
  padding: 8px 4px 0;
  text-align: center;
}

.shot figcaption b { font-size: .84rem; color: var(--indigo); }
/* With the tabs on screen, the caption's title is the tab's label repeated.
   The note under it is not, so that stays. */
.shots--multi .shot figcaption b { display: none; }
.shot figcaption span { font-size: .76rem; color: var(--muted); }

.shots-zoom {
  position: absolute;
  inset-block-start: 10px;
  inset-inline-end: 10px;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, .92);
  color: var(--indigo);
}

.shots-zoom[hidden] { display: none; }

/* Named tabs under the dots. "In the room" has to say so — an unlabelled
   lifestyle shot reads as a promise that everything in frame is included. */
.shots-tabs {
  display: flex;
  gap: 6px;
  justify-content: center;
  flex-wrap: wrap;
  margin-block-start: 10px;
}

.shots-tabs button {
  min-height: 34px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  color: var(--indigo-soft);
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
}

.shots-tabs button.active {
  border-color: var(--cobalt);
  background: var(--cobalt);
  color: #fff;
}

/* ---- Full-screen viewer -------------------------------------------------
   Pinch-zoom is the browser's. `touch-action: pinch-zoom` on the surface buys
   iOS Safari's real gesture handling, momentum and limits; hand-rolled pinch
   maths is where custom viewers break. */
.img-viewer {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: #0d1026;
}

.img-viewer[hidden] { display: none; }
html.is-viewing, html.is-helping { overflow: hidden; }

.iv-surface {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  overflow: auto;
  touch-action: pinch-zoom;
  padding: 44px 8px calc(20px + env(safe-area-inset-bottom, 0px));
}

.iv-surface img { max-width: 100%; height: auto; }

.iv-close {
  position: absolute;
  inset-block-start: calc(10px + env(safe-area-inset-top, 0px));
  inset-inline-end: 10px;
  z-index: 2;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, .16);
  color: #fff;
}

/* Two facts, stacked: what leaves the account each month, and what the whole
   contract costs. Everywhere, not just on a phone — the commitment figure is
   new on this page and it was landing on the same line as the buy hint. */
.pdp-sale { display: grid; gap: 3px; }
.pdp-commit { color: var(--indigo); }
.pdp-commit b { color: var(--indigo); }
.pdp-alt { color: var(--muted); }
.set-price-note { display: grid; gap: 3px; }

/* Phone chrome, parked. These four live in the shell markup on every page, so
   without an explicit default they render as ordinary blocks in the middle of a
   desktop layout the moment JS clears their `hidden` attribute. */
.tabbar,
.buybar,
.help-sheet { display: none; }

@media (max-width: 560px) {

  /* ---- 1. App shell ------------------------------------------------------
     A bottom tab bar, and room made for it. `--tab-h` is the single number the
     rest of the file offsets against, so the bar's height is stated once. */
  :root {
    --tab-h: 62px;
    --bar-safe: env(safe-area-inset-bottom, 0px);
  }

  html.has-tabbar body {
    padding-block-end: calc(var(--tab-h) + var(--bar-safe));
  }

  .tabbar {
    display: grid;
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 60;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    background: rgba(255, 255, 255, .96);
    backdrop-filter: saturate(1.4) blur(12px);
    border-block-start: 1px solid var(--line);
    padding-block-end: var(--bar-safe);
    box-shadow: 0 -10px 30px -26px rgba(27, 33, 67, .8);
  }

  .tabbar[hidden] { display: none; }

  .tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    /* 62px of target, not a 24px icon with padding around it: the bar is the
       primary navigation now and every entry has to be hittable in a hurry. */
    min-height: var(--tab-h);
    padding: 6px 2px;
    border: 0;
    background: none;
    color: var(--muted);
    font: inherit;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
  }

  .tab .icon { width: 22px; height: 22px; }
  .tab-ic { position: relative; display: block; line-height: 0; }
  .tab-label { font-size: .68rem; font-weight: 600; letter-spacing: .01em; }
  .tab.active { color: var(--cobalt); }
  .tab.active .tab-label { font-weight: 700; }

  .tab-badge {
    position: absolute;
    inset-block-start: -5px;
    inset-inline-end: -9px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--cobalt);
    color: #fff;
    font-size: .64rem;
    font-style: normal;
    font-weight: 700;
    line-height: 17px;
    text-align: center;
  }

  .tab-badge[hidden] { display: none; }

  /* The two launchers the tab bar replaces. They are not merely moved: on this
     width they were overlapping the rent/buy toggle and the first product card,
     which is a conversion bug, not a spacing one. The Help tab opens both. */
  .wa-fab,
  .fb-chat-launch { display: none !important; }

  .help-sheet {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    align-items: flex-end;
  }

  .help-sheet[hidden] { display: none; }
  .help-scrim { position: absolute; inset: 0; background: rgba(20, 24, 48, .5); }

  .help-card {
    position: relative;
    width: 100%;
    display: grid;
    gap: 8px;
    padding: 20px 16px calc(20px + var(--bar-safe));
    background: #fff;
    border-start-start-radius: 18px;
    border-start-end-radius: 18px;
  }

  .help-card h2 { margin: 0 0 4px; font-size: 1.1rem; }

  .help-row {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 52px;
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--offwhite);
    color: var(--indigo);
    font: inherit;
    font-weight: 600;
    text-align: start;
    text-decoration: none;
  }

  .help-row .icon { color: var(--cobalt); flex: none; }

  /* ---- 2. Product page ---------------------------------------------------
     The description used to sit between the title and the decision box, pushing
     the price and the button off the first screen. Ordering the column moves it
     under the button: still there, no longer in the way. */
  .pdp { padding-block: 14px 26px; gap: 20px; }
  .pdp-gallery { margin-block-end: 4px; }
  /* The old single-image frame. galleryMarkup() replaces it; these rules would
     otherwise re-add a border and padding around the new track. */
  .pdp-main { border: 0; background: none; }

  .pdp-info { display: flex; flex-direction: column; }

  .pdp-info h1 { order: 1; font-size: 1.6rem; line-height: 1.2; }
  .pdp-info .name-en { order: 2; margin-bottom: 10px; }
  .pdp-tags { order: 3; }
  .pdp-decision { order: 4; }
  .pdp-price { order: 5; }
  .pdp-sale { order: 6; }
  .eta-line--pdp { order: 7; }
  .pdp-buy { order: 8; }
  .pdp-intro { order: 9; margin-block: 18px 0; }
  .pdp-perks { order: 10; }
  .pdp-room-cta { order: 11; }
  .pdp-acc { order: 12; }

  /* The order summary is what the buyer is about to be charged, and on a phone
     it sat behind the whole shipping form. Pull it above the form so the price
     is the second thing seen, not the last. */
  .checkout-layout { display: flex; flex-direction: column; }
  .checkout-layout .summary { order: -1; margin-bottom: 20px; }

  .pdp-price .big { font-size: 2.1rem; }

  .pdp-sale { margin-bottom: 16px; }
  .pdp-commit { font-size: .9rem; }
  .pdp-alt { font-size: .84rem; }

  .pdp-buy { display: grid; grid-template-columns: auto 1fr auto; gap: 8px; }
  .pdp-buy .btn--primary { min-width: 0; min-height: 52px; }
  .pdp-buy .qty { min-height: 52px; }
  .prod-fav-btn { width: 52px; padding: 0; }

  /* The purchase bar. It carries the decision — price and term — because
     someone who has scrolled past the toggle can no longer see either. It sits
     where the tab bar sits, and `has-buybar` hides the tab bar, so the bottom
     edge is never navigation stacked on top of a purchase. */
  html.has-buybar .tabbar { display: none; }
  html.has-buybar body { padding-block-end: calc(74px + var(--bar-safe)); }

  .buybar {
    display: grid;
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 70;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 12px;
    padding: 10px 14px calc(10px + var(--bar-safe));
    background: rgba(255, 255, 255, .97);
    backdrop-filter: saturate(1.4) blur(12px);
    border-block-start: 1px solid var(--line);
    box-shadow: 0 -12px 34px -26px rgba(27, 33, 67, .9);
  }

  .buybar[hidden] { display: none; }
  .buybar-price { display: grid; gap: 1px; min-width: 0; }
  .buybar-price b { font-size: 1.25rem; color: var(--cobalt); font-family: var(--font-head); }
  .buybar-price span { font-size: .74rem; color: var(--muted); }
  .buybar .btn { min-height: 48px; padding-inline: 20px; }

  /* ---- 3. Room-set page --------------------------------------------------
     Order was: copy, media, pieces. The room — the thing being sold — was not
     on the first screen at all, and the pieces were last, in a sideways
     carousel. Now: the room, then the price and the button, then the pieces as
     a vertical list you scroll rather than one you have to discover. */
  .set-pdp--with-products .set-pdp-media { order: 0 !important; }
  .set-pdp--with-products .set-pdp-info { order: 1 !important; }
  .set-pdp--with-products .set-pdp-products { order: 2 !important; }

  .set-media-card img { max-height: min(58vh, 430px); }

  /* The dimension drawing is per piece, and each piece now carries its
     measurements in its own row and a drawing in its own product gallery.
     A second full-width image of a technical sketch under the room shot was
     pushing the price down for no decision it helps with. */
  .set-media-card--dim { display: none; }

  .set-product-panel { padding: 0; background: none; box-shadow: none; }

  .set-product-list {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    overflow: visible;
    gap: 10px;
    padding: 0;
  }

  /* Three bands, not five stacked full-width controls. Giving the add button,
     the details link, the quantity box and a delete button a row each made one
     piece 360px tall — an eight-piece set became a 2,800px scroll of buttons
     with four small photographs somewhere inside it. */
  .set-product-row {
    display: grid;
    grid-template-columns: 118px minmax(0, 1fr);
    grid-template-areas:
      "pick pick"
      "qty  add"
      "det  det";
    gap: 10px;
    min-height: 0;
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: #fff;
  }

  .set-product-row.is-removed { opacity: .45; }

  .set-product-pick { grid-area: pick; grid-template-columns: 88px minmax(0, 1fr); gap: 12px; }
  .set-product-thumb { height: 88px; }
  .set-product-thumb img { object-fit: contain; }

  .set-product-qty { grid-area: qty; width: 118px; }
  .set-product-add { grid-area: add; justify-content: center; min-height: 46px; }
  .set-product-details { grid-area: det; justify-self: start; font-size: .84rem; }

  /* The quantity box already goes to zero — which dims the row and drops it from
     the set total — so a separate delete button is a second control for one
     decision. */
  .set-product-remove { display: none; }

  /* ---- Checkout phone verification -------------------------------------
     Three columns of `minmax(0,1fr) auto auto` leaves the code box about 110px
     at this width — a six-digit field showing "000". The code gets its own
     row and the two buttons split the one under it. */
  .co-phone-otp > div {
    grid-template-columns: 1fr 1fr !important;
  }

  .co-phone-otp #f_phone_code {
    grid-column: 1 / -1;
    min-height: 48px;
    text-align: center;
    letter-spacing: .4em;
    font-size: 1.1rem;
  }

  .co-phone-otp .btn { min-height: 46px; padding-inline: 8px; }

  /* ---- 4. Catalogue grid -------------------------------------------------
     Two across, square plates. The old single-column row gave the image about
     36% of a 390px screen and cover-cropped it — the top and bottom of every
     bed were cut off. */
  .prod-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

  .prod-card {
    display: flex;
    flex-direction: column;
    min-height: 0;
    border-radius: 14px;
    overflow: hidden;
  }

  .prod-media {
    aspect-ratio: 1;
    height: auto;
    min-height: 0;
    background: var(--offwhite);
  }

  .prod-media img { object-fit: contain; padding: 6px; }

  .prod-body { flex: 1; display: flex; flex-direction: column; padding: 10px; }
  .prod-name { font-size: .88rem; }
  .prod-name-en, .prod-meta { font-size: .66rem; }

  /* The specification list and the delivery line are the first things to go at
     half width: they wrapped to five lines under a two-word product name and
     pushed the price out of the card. Both are on the product page. */
  .prod-card .card-pieces,
  .prod-card .card-accessories,
  .prod-card .eta-line--card { display: none; }

  /* Stacked, not side by side. A price and a button sharing one 165px card foot
     wrapped "١٣٦ ر.س / شهرياً" onto two lines under every card in the grid. */
  .prod-foot {
    display: grid;
    gap: 8px;
    margin-block-start: auto;
    padding-block-start: 8px;
  }

  .price { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; }
  .price .amount { font-size: 1.05rem; }
  .price .unit { font-size: .7rem; }

  .prod-add {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: auto;
    min-height: 40px;
    border-radius: 10px;
    font-size: .8rem;
    font-weight: 600;
  }

  .prod-add-label { display: inline; }
  .prod-tag { font-size: .62rem; padding: 3px 7px; }

  .more-row { display: grid; margin-block-start: 18px; }
  .more-row .btn { width: 100%; }
  .more-row span { color: var(--muted); font-weight: 500; }

  /* Filters were four wrapped rows of chips — 700px of controls above the first
     product at 320px. One scrolling row each. `flex-wrap` has to be named
     explicitly: the base rule sets `wrap`, and overriding display alone left
     every group still wrapping. */
  .filters-bar { padding-block: 12px; gap: 8px; }

  .filters-bar .filter-group {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 6px;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    scrollbar-width: none;
    padding-block-end: 2px;
  }

  .filters-bar .filter-group::-webkit-scrollbar { display: none; }
  .filters-bar .filter-group .glabel { flex: none; }

  .filters-bar .chip {
    flex: none;
    min-height: 40px;
    padding-inline: 14px;
    font-size: .84rem;
  }

  /* Badges scaled to the card they sit on. At 165px wide the 38px heart and the
     style pill were nearly touching across the top of the picture. */
  .prod-tag { inset-block-start: 8px; inset-inline-start: 8px; }
  .prod-fav { inset-block-start: 6px; inset-inline-end: 6px; width: 32px; height: 32px; }
}

/* The narrowest phones still in use. Only the things that actually run out of
   room at 360px — the grid stays two across, because one across is the layout
   this change exists to replace. */
@media (max-width: 360px) {
  .tab-label { font-size: .62rem; }
  .prod-grid { gap: 9px; }
  .buybar { gap: 8px; padding-inline: 10px; }
  .buybar .btn { padding-inline: 14px; }
}
