/* ============================================================================
   Roaya front theme — layout & responsiveness
   ----------------------------------------------------------------------------
   main.css keeps the animations and interaction polish. This file owns every
   declaration that has to CHANGE with the viewport.

   ⚠ Why the --r-cols custom property pattern:
   the theme's markup is inline-styled, and an inline `grid-template-columns`
   beats any stylesheet. So the blades now set a *variable* (--r-cols) and this
   file owns the property itself. A media query can then override it with no
   !important and no specificity war. Keep it that way — never put
   grid-template-columns back into a style="" attribute.

   Breakpoints: 1080 (tablet landscape) · 900 (tablet / hamburger) ·
                640 (phone) · 420 (small phone)
   Everything is written with logical properties so dir="rtl" mirrors it.
   ========================================================================== */

:root {
    --r-pad: 28px;          /* page gutter, narrows with the viewport */
    --r-gap: 18px;
    --r-nav-h: 86px;        /* sticky header height, for scroll offsets */
}

/* Never let replaced content push the page wider than the screen. */
img, svg, video, iframe, canvas, table { max-width: 100%; }
img { height: auto; }

/* ─── Fluid type ──────────────────────────────────────────────────────────
   clamp() is what makes browser ZOOM work, not just narrow screens: the size
   tracks the viewport continuously instead of jumping at a breakpoint. */
.r-h1    { font-size: clamp(30px, 3.4vw + 16px, 58px); line-height: 1.06; }
.r-h1-sm { font-size: clamp(27px, 2.4vw + 15px, 46px); line-height: 1.1; }
.r-h2    { font-size: clamp(24px, 1.9vw + 15px, 38px); line-height: 1.15; }
.r-h3    { font-size: clamp(21px, 1.4vw + 14px, 34px); line-height: 1.2; }
.r-h4    { font-size: clamp(18px, 0.9vw + 13px, 24px); line-height: 1.25; }
.r-num   { font-size: clamp(24px, 1.9vw + 14px, 34px); }

/* ─── Page container ───────────────────────────────────────────────────── */
.r-wrap {
    max-width: 1180px;
    margin-inline: auto;
    padding-inline: var(--r-pad);
    width: 100%;
}

/* ─── Grids ────────────────────────────────────────────────────────────────
   Each class states its desktop shape; the media queries below collapse it. */
.r-grid-3, .r-grid-4, .r-cards-2, .r-split, .r-split-form, .r-detail, .r-footer,
.r-stats, .r-mosaic, .r-unit-row, .r-unit-head {
    display: grid;
    gap: var(--r-gap);
}

.r-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.r-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.r-cards-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Asymmetric two-column blocks. The ratio comes from the call site as
   style="--r-cols:1.55fr 1fr" so each section keeps its own proportion. */
.r-split      { grid-template-columns: var(--r-cols, 1fr 1fr); align-items: var(--r-align, stretch); }
.r-split-form { grid-template-columns: var(--r-cols, 0.85fr 1.15fr); }
.r-detail     { grid-template-columns: var(--r-cols, 1.35fr 1fr); align-items: start; }

/* Project stat strip — was repeat(count($stats),1fr), which made 60px columns
   with five stats even on a desktop. */
.r-stats { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0; }

/* Gallery mosaic. --r-cols is chosen by the blade from the tile count.

   ⚠ `grid-template-rows: minmax(0, 1fr)` and `min-height: 0` are what keep the
   photos INSIDE the box, and neither is optional.

   The mosaic had a fixed height and an implicit `auto` row. An auto row is
   sized by its content, and `align-content: stretch` can only ADD space to a
   track, never take it away — so the row grew to whatever the tiles wanted and
   the surplus painted straight over the page, because the container is
   `overflow: visible`. A tile wants a lot: `.gal-item` has no height of its
   own, so `img { height: 100% }` has no definite parent to resolve against and
   falls back to the image's own aspect ratio. Landscape photos happened to land
   under 380px and looked fine; PORTRAIT ones did not. Measured on the real
   catalogue: Glee and Layana ran the row to 700px and spilled 320px, burying
   the project's own <h1>, its developer line and most of its description under
   the pictures. Four of the thirteen projects were affected — whichever ones
   the developer supplied portrait artwork for.

   `minmax(0, 1fr)` gives the row a definite height equal to the container, and
   `min-height: 0` removes the automatic minimum size that would let an item's
   intrinsic height push the track open again. `overflow: hidden` is the belt to
   that pair of braces: if a future tile ever measures wrong it gets clipped
   rather than dropped on top of the article. */
.r-mosaic {
    grid-template-columns: var(--r-cols, 1fr);
    grid-template-rows: minmax(0, 1fr);
    height: clamp(220px, 30vw, 380px);
    overflow: hidden;
}

/* auto-rows, not a template: the side column holds one tile or two depending on
   how many photos exist, and `1fr` auto-rows share the height either way. The
   blade used to write `grid-template-rows` INLINE, which no stylesheet could
   override — so the ≤640 rule below silently did nothing on a phone. */
.r-mosaic-side { display: grid; grid-auto-rows: minmax(0, 1fr); gap: var(--r-gap); }

.r-mosaic > *, .r-mosaic-side > * { min-width: 0; min-height: 0; }

/* Unit-price table: a real grid on desktop, stacked label/value rows on a phone. */
.r-unit-head, .r-unit-row { grid-template-columns: 1.5fr 1fr 1fr 0.8fr; gap: 10px; }
.r-unit-table > .r-unit-row:not(:first-of-type) { border-top: 0; }

/* Footer */
.r-footer { grid-template-columns: 1.6fr 1fr 1fr 1.2fr; gap: 32px; }

/* ─── Horizontal rails (testimonials) ─────────────────────────────────────
   The one intentional horizontal scroller. Snap + edge padding so a phone can
   swipe it comfortably instead of half-showing a card. */
.r-rail { display: flex; gap: var(--r-gap); overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; padding-bottom: 4px; }
.r-rail::-webkit-scrollbar { display: none; }
.r-rail > * { scroll-snap-align: start; }

/* ─── Media boxes ─────────────────────────────────────────────────────────
   aspect-ratio instead of a fixed px height, so images scale with the column
   and never letterbox. The blade passes --r-ar when it wants a different one. */
.r-media { position: relative; overflow: hidden; aspect-ratio: var(--r-ar, 16 / 10); }
.r-media > img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ─── Header / mobile drawer ──────────────────────────────────────────── */
/* Language switcher. Shaped like a .nav-pill so it reads as part of the nav,
   but it is a <button> — which inherits no font — so the family is set here. */
.r-lang {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 9px 14px; border-radius: 30px;
    border: 1px solid #ececeb; background: #f4f4f1; color: #141414;
    font-family: inherit; font-size: 14px; font-weight: 600; line-height: 1;
    white-space: nowrap; cursor: pointer; flex: none;
    transition: background .25s, color .25s, box-shadow .25s;
}
.r-lang:hover { background: #fff; color: #141414; box-shadow: 0 2px 8px rgba(0, 0, 0, .08); }

.r-burger {
    display: none;
    align-items: center; justify-content: center;
    width: 44px; height: 44px;
    border: 1px solid #ececeb; border-radius: 12px;
    background: #fff; color: #141414; cursor: pointer; flex: none;
}
.r-burger:hover { background: #f4f4f1; }

.r-drawer-backdrop {
    position: fixed; inset: 0; z-index: 60;
    background: rgba(10, 10, 10, .45); backdrop-filter: blur(2px);
    opacity: 0; pointer-events: none; transition: opacity .25s ease;
}
.r-drawer-backdrop.open { opacity: 1; pointer-events: auto; }

.r-drawer {
    position: fixed; z-index: 61;
    inset-block: 0; inset-inline-end: 0;
    width: min(320px, 86vw);
    background: #fff;
    box-shadow: 0 0 60px rgba(0, 0, 0, .18);
    padding: 18px;
    display: flex; flex-direction: column; gap: 6px;
    overflow-y: auto;
    /* Logical translate: +100% moves it off the inline-end edge in LTR, and
       dir="rtl" flips the axis for us, so one rule covers both. */
    transform: translateX(100%);
    transition: transform .28s cubic-bezier(.2, .7, .2, 1);
    visibility: hidden;
}
[dir="rtl"] .r-drawer { transform: translateX(-100%); }
.r-drawer.open { transform: translateX(0); visibility: visible; }

.r-drawer a.r-drawer-link {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 12px; border-radius: 12px;
    text-decoration: none; font-weight: 600; font-size: 16px; color: #141414;
}
.r-drawer a.r-drawer-link:hover,
.r-drawer a.r-drawer-link.active { background: #f4f4f1; color: #141414; }
.r-drawer-sep { height: 1px; background: #ececeb; margin: 10px 2px; }

body.r-locked { overflow: hidden; }

/* ─── Forms ───────────────────────────────────────────────────────────────
   The budget picker's selected state is a class now (main.js used to write
   inline styles, which no stylesheet could then restyle). */
.r-budget {
    flex: 1; min-width: 90px;
    padding: 11px 10px; border-radius: 12px;
    border: 1px solid #e7e7e3; background: #fafafa; color: #6b6b6b;
    font-family: inherit; font-size: 13px; font-weight: 600;
    cursor: pointer; transition: background .18s, color .18s, border-color .18s;
}
.r-budget:hover { border-color: #d8d8d2; }
.r-budget.on { background: #141414; border-color: #141414; color: #fff; }

/* The same control on the project page's dark inquiry card. Same markup, same
   numeric bounds — only the surface it sits on is different. */
.r-budget--dark {
    border-color: rgba(255, 255, 255, .16);
    background: rgba(255, 255, 255, .06);
    color: rgba(255, 255, 255, .7);
    font-size: 12.5px; padding: 9px 8px; min-width: 74px;
}
.r-budget--dark:hover { border-color: rgba(255, 255, 255, .3); }
.r-budget--dark.on { background: #ef5a2a; border-color: #ef5a2a; color: #fff; }

/* iOS Safari zooms the whole page when a focused input's font is under 16px —
   the classic "the site jumped when I tapped the field" bug. The theme sets
   13.5–14px inline, so this needs !important to reach it, and only on the
   screens where it matters. */
@media (max-width: 640px) {
    .field { font-size: 16px !important; }
}

/* ─── Hero search ─────────────────────────────────────────────────────── */
.r-hero-search {
    display: inline-flex; align-items: center; gap: 6px;
    background: #fff; border: 1px solid #ededea; border-radius: 18px;
    padding: 10px; box-shadow: 0 14px 40px rgba(0, 0, 0, .08);
    text-align: start; max-width: 100%;
}
.r-hero-field {
    display: flex; flex-direction: column; gap: 2px;
    padding-block: 6px; padding-inline: 14px 22px;
    min-width: 0; flex: 1;
}
.r-hero-input {
    border: 0; background: transparent; outline: none;
    font-family: inherit; font-size: 15px; font-weight: 600; color: #141414;
    padding: 0; width: 100%; min-width: 0;
}
.r-hero-input::placeholder { color: #141414; opacity: 1; }
.r-hero-go {
    width: 48px; height: 48px; flex: none;
    border: 0; border-radius: 14px;
    background: #141414; color: #fff;
    display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.r-hero-go:hover { background: #ef5a2a; }

@media (max-width: 640px) {
    .r-hero-search { display: flex; flex-wrap: wrap; width: 100%; }
    .r-hero-field { flex: 1 1 100%; border-inline-end: 0 !important; border-bottom: 1px solid #efefec; padding-inline: 12px; padding-block: 8px; }
    .r-hero-field:last-of-type { border-bottom: 0; }
    .r-hero-go { width: 100%; height: 46px; }
}

/* ─── Filter bar (projects listing) ───────────────────────────────────── */
.r-filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.r-filters .r-filter {
    display: flex; flex-direction: column; gap: 2px;
    background: #fff; border: 1px solid #ededea; border-radius: 14px;
    padding-block: 7px; padding-inline: 14px;
    min-width: 0; flex: 1 1 190px;
}
.r-filters .r-filter > span { font-size: 11px; color: #9a9a9a; font-weight: 500; }
.r-filters select, .r-filters input {
    border: 0; background: transparent; outline: none; padding: 0;
    font-family: inherit; font-size: 15px; font-weight: 600; color: #141414;
    width: 100%; min-width: 0;
}
@media (max-width: 640px) {
    .r-filters .r-filter { flex: 1 1 100%; }
    .r-filters .r-block-sm { display: flex; }
}

/* ─── Pagination ──────────────────────────────────────────────────────── */
.r-pager { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: center; margin-top: 34px; }
.r-pager a, .r-pager span {
    min-width: 40px; height: 40px; padding-inline: 12px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid #ededea; border-radius: 12px;
    font-size: 14px; font-weight: 600; text-decoration: none; color: #141414;
    background: #fff;
}
.r-pager a:hover { border-color: #141414; }
.r-pager .on { background: #141414; border-color: #141414; color: #fff; }
.r-pager .off { color: #c4c4c0; background: #fafafa; }

/* ─── Utilities ───────────────────────────────────────────────────────── */
.r-only-mobile { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   ≤ 1080 — tablet landscape
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 1080px) {
    :root { --r-pad: 22px; --r-gap: 16px; }

    .r-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* The project page: body and sidebar stop competing for width. */
    .r-detail { grid-template-columns: 1fr; }
    .r-detail > .r-detail-aside { position: static !important; top: auto !important; }

    .r-split { grid-template-columns: var(--r-cols-md, var(--r-cols, 1fr 1fr)); }
}

/* ══════════════════════════════════════════════════════════════════════════
   ≤ 900 — tablet portrait · the hamburger appears
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 900px) {
    .r-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .r-split, .r-split-form { grid-template-columns: 1fr; }
    .r-footer { grid-template-columns: 1fr 1fr; gap: 26px; }

    /* Height goes back to the content, so the row must stop being a fixed
       fraction of it — `1fr` against an indefinite height is a size with
       nothing to be a fraction OF. */
    .r-mosaic { height: auto; grid-template-rows: none; }

    /* Header: pills and CTA out, burger in. */
    .r-burger { display: inline-flex; }
    .r-nav-desktop, .r-cta-desktop { display: none !important; }
    .r-logo img { height: 52px !important; }
    :root { --r-nav-h: 66px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   ≤ 640 — phone
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
    :root { --r-pad: 18px; }

    .r-grid-3, .r-grid-4, .r-cards-2 { grid-template-columns: 1fr; }
    .r-footer { grid-template-columns: 1fr; gap: 22px; }
    .r-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* Stat cells lose the divider that only made sense in a row. */
    .r-stats > * { border-inline-end: 0 !important; }

    /* The mosaic stacks: a full-width lead image, then the rest 2-up. Three
       vertical slivers beside a big tile were unusable at this width, and
       hiding them would have meant hiding the project's photos. */
    .r-mosaic { grid-template-columns: 1fr !important; grid-template-rows: none; height: auto; }
    .r-mosaic > :not(.r-mosaic-side) { aspect-ratio: 16 / 10; }
    /* Side by side, and each tile carries its own ratio — so the rows are
       content sized again, not fractions of a height that no longer exists. */
    .r-mosaic-side { grid-auto-rows: auto; grid-template-columns: 1fr 1fr; grid-auto-flow: column; }
    .r-mosaic-side > * { aspect-ratio: 16 / 11; }

    /* Unit prices: each row becomes a card of label/value pairs. */
    .r-unit-head { display: none; }
    .r-unit-row {
        grid-template-columns: 1fr;
        gap: 4px;
        padding: 12px 14px !important;
        border: 1px solid #ededea; border-radius: 12px;
        margin-bottom: 8px;
    }
    .r-unit-row > * { display: flex; justify-content: space-between; gap: 12px; }
    .r-unit-row > *::before {
        content: attr(data-label);
        color: #9a9a9a; font-weight: 500; font-size: 12px;
    }
    .r-unit-row > :first-child::before { display: none; }
    .r-unit-row > :first-child { font-weight: 700; }

    .r-rail > * { width: min(300px, 82vw) !important; }

    .r-only-mobile { display: block; }
    .r-hide-sm { display: none !important; }

    /* Buttons and links stop being tiny targets. */
    .r-block-sm { width: 100%; justify-content: center; }

    /* Comfortable hit areas. The footer's text links were 18px tall — under
       half the 40px a thumb needs — and the rail arrows were 38px. */
    footer a { min-height: 40px; display: inline-flex; align-items: center; }
    [data-scroll] { width: 42px !important; height: 42px !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   ≤ 420 — small phone
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 420px) {
    :root { --r-pad: 14px; --r-gap: 12px; }
    .r-logo img { height: 44px !important; }

    /* Logo + language + burger is the whole header here. The globe goes so the
       language name keeps its space — the name is what makes the button
       legible to someone who cannot read the rest of the page. Lucide swaps
       the <i> for an <svg>, so both are matched: if main.js never loads, the
       un-swapped <i> must disappear too. */
    .r-lang { padding-inline: 11px; }
    .r-lang > svg, .r-lang > i { display: none; }
}
