/* ==========================================================================
   VOYZ — Shared surface system

   One place that carries the soft-light language across every page, instead
   of patching each screen. Three moves only:

     1. Geometry — nothing sharp sits next to something rounded.
     2. Elevation — layered diffuse shadows, no hard 1px outlines doing the
        work of depth.
     3. Controls — one input, one select, one chip vocabulary everywhere.

   Loaded after the page sheets so it can harmonise what they set, and before
   arabic.css so script corrections still win.
   ========================================================================== */

/* ---------- Geometry ---------- */
.offer-card,.directory-card,.agency-card,.moderation-card,
.detail-gallery img,.detail-gallery.single img,
.contact-panel,.modern-booking-card,.filter-panel,
.summary-grid,.dashboard-preview,.wilaya-card,.departure-tile,
.editorial-grid>a,.mood,.auth-box,.empty-state,
.atlas-search,.market-search input,.pagination a,.pagination span,
.stat-grid article,.panel,.data-table-wrap,.tips,.pro-form{
  border-radius:var(--r-lg);
}
.offer-image,.agency-cover,.detail-gallery{border-radius:var(--r-lg);overflow:hidden}
.summary-grid{overflow:hidden}
.filter-chips a,.status,.offer-badge,.places,.chip{border-radius:var(--r-full)}
.button{border-radius:var(--r-full)}
.agency-monogram,.activity-avatar,.stat-icon{border-radius:16px}

/* ---------- Elevation ---------- */
.offer-card,.directory-card,.filter-panel,.contact-panel,
.modern-booking-card,.dashboard-preview,.atlas-search{
  border-color:transparent;
  box-shadow:var(--sh-sm);
}
.offer-card:hover,.directory-card:hover{
  box-shadow:var(--sh-md);
  transform:translateY(-3px);
}
.contact-panel,.modern-booking-card{box-shadow:var(--sh-md)}

/* ---------- Page fields ---------- */
/* Soft-filled by default; lifts to white with a brand ring on focus. */
.filter-panel input:not([type=checkbox]),.filter-panel select,
.interest-form input:not([type=checkbox]),.interest-form select,.interest-form textarea,
.market-search input,.directory-search input,.directory-search select,
.atlas-search input,.atlas-search select,
.field input:not([type=checkbox]):not([type=radio]):not([type=file]),.field select,.field textarea{
  border:1px solid var(--line-strong);
  border-radius:var(--r);
  background:var(--surface-2);
  transition:border-color var(--dur-2) var(--ease-ios-soft),
             background var(--dur-2) var(--ease-ios-soft),
             box-shadow var(--dur-2) var(--ease-ios-soft);
}
.filter-panel input:hover,.filter-panel select:hover,
.interest-form input:hover,.interest-form select:hover,.interest-form textarea:hover,
.market-search input:hover,.directory-search input:hover,
.field input:not([type=file]):hover,.field select:hover,.field textarea:hover{border-color:var(--ink-2)}

.filter-panel input:focus-visible,.filter-panel select:focus-visible,
.interest-form input:focus-visible,.interest-form select:focus-visible,.interest-form textarea:focus-visible,
.market-search input:focus-visible,.directory-search input:focus-visible,.directory-search select:focus-visible,
.atlas-search input:focus-visible,.atlas-search select:focus-visible,
.field input:not([type=file]):focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:none;border-color:var(--brand);background:#fff;
  box-shadow:0 0 0 4px rgba(11,87,164,.14);
}

/* Selects share one chevron instead of the platform default. */
.filter-panel select,.interest-form select,.directory-search select,.field select,.atlas-search select{
  appearance:none;padding-inline-end:36px;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2351617a' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center;background-size:16px;
}
[dir=rtl] .filter-panel select,[dir=rtl] .interest-form select,
[dir=rtl] .directory-search select,[dir=rtl] .field select,[dir=rtl] .atlas-search select{
  background-position:left 12px center;
}

/* ---------- Chips and filters ---------- */
.filter-chips a{
  padding:9px 15px;border-color:transparent;background:var(--surface-2);
  font-weight:var(--fw-label);
  transition:background var(--dur-2) var(--ease-ios-soft),color var(--dur-2) var(--ease-ios-soft),box-shadow var(--dur-2) var(--ease-ios-soft);
}
.filter-chips a:hover{background:var(--brand-050);color:var(--brand)}
.filter-chips a.active,.filter-chips a[aria-current]{
  background:#fff;color:var(--ink);box-shadow:var(--sh-sm);
}

/* ---------- Pagination ---------- */
.pagination a,.pagination span{
  min-width:42px;min-height:42px;display:inline-grid;place-items:center;
  border-color:transparent;background:#fff;box-shadow:var(--sh-xs);
  font-weight:var(--fw-label);
  transition:box-shadow var(--dur-2) var(--ease-ios-soft),color var(--dur-2) var(--ease-ios-soft);
}
.pagination a:hover{box-shadow:var(--sh-sm);color:var(--brand)}

/* ---------- Soft page field ----------
   The light listing surfaces pick up the same pale field as the auth pages,
   so the whole site reads as one material. */
.explore-page,.directory-page,.detail-page{
  position:relative;isolation:isolate;
  background:
    radial-gradient(55% 40% at 12% 0%, rgba(11,87,164,.06), transparent 62%),
    radial-gradient(50% 40% at 95% 8%, rgba(18,184,204,.07), transparent 60%),
    var(--surface-2);
}

/* ---------- Empty states ---------- */
.empty-state{
  border:1px solid var(--line);border-style:solid;
  background:#fff;box-shadow:var(--sh-xs);color:var(--muted);
}

@media (prefers-reduced-motion:reduce){
  .offer-card:hover,.directory-card:hover{transform:none}
}

/* ==========================================================================
   Corrections from the UI audit
   ========================================================================== */

/* The native control behind a dressed file field stays visually hidden.
   Declared here because this sheet loads last, so nothing re-inflates it. */
.file-field input[type=file]{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip-path:inset(50%);border:0;white-space:nowrap;
}

/* --- Type floor -------------------------------------------------------
   Nothing readable drops below 11.5px. The audit found 9-10px labels, well
   under the 12px body minimum. Scaled up rather than removed, so the
   hierarchy survives. */
.tile-date,.offer-badge,.places,.offer-price small,.offer-price span,
.editorial-grid small,.wilaya-card em,.wilaya-card small,.agency-row small,
.booking-agency small,.atlas-caption span,.atlas-caption small,
.contact-panel>p,.contact-panel>small,.booking-reassurance,
.summary-grid small,.verified,.status,
.side-nav small,.workspace span,.activity-list small,.stat-grid span,
.panel-head p,.data-table thead th,.agency-facts dt,.seat-legend dt,
.pass-kind,.pass-fields dt,.pass-seat dt,.doc-num,.review-meta,
.f-hint,.f-error,.auth-note,.errorlist,.tips li,.field small{
  /* Explicit, not max(…,1em): em resolves against the parent, which would
     inflate these labels to body size and flatten the hierarchy. */
  font-size:12px;
}
.signal-strip span,.tile-copy>span,.hero-proof,.quick-links,
.filter-chips a,.breadcrumbs,.offer-meta,.offer-inclusions,.offer-agency{font-size:12.5px}
.mood span{font-size:12px}

/* --- Touch targets ----------------------------------------------------
   Controls reach 44px. Inline text links keep their natural size (desktop
   convention) but gain height so they are not hairline hits. */
.icon-btn,.pw-toggle{width:44px;height:44px}
.icon-btn svg{width:18px;height:18px}
.table-actions .button,.review-actions .button,.dash-content .button{min-height:44px}
.table-actions select,.dash-content select{min-height:44px}
.language-toggle{height:40px}
.language-toggle::before,.language-toggle span{height:32px}
.dash-top-link{min-height:44px}
.cell-note>summary,.reject>summary,.manual-add>summary{min-height:44px;align-items:center}
.cell-wa,.crumb,.panel-head>a,.summary-stack a,.doc-pill{
  display:inline-flex;align-items:center;min-height:32px;
}
.side-nav a,.side-bottom a{min-height:46px}
.seg-item{min-height:40px}
.pagination a,.pagination span{min-width:44px;min-height:44px}
.auth-back{min-height:40px}

/* Stepper: matched optical weight either side of the value, real targets. */
.stepper .step{width:48px;height:48px}
.stepper-set input{height:48px;width:82px;font-size:18px}

/* --- Final type floor sweep -------------------------------------------
   The remaining sub-12px labels found by the audit. */
.section-tag,.beat-verb,.pass-stamp,.depart-city,.seat-edit-hint,
.hero-kicker,.auth-label,.eyebrow,.filter-panel label,
.atlas-search label,.interest-form label,.manual-hint,
.summary-stack small,.doc-chip small,.cell-wa{font-size:12px}
.footer-layout p,.footer-layout a,.dash-heading p,.dash-empty p,
.toast>span,.tile-copy p,.review-facts{font-size:13px}
.side-nav a,.side-bottom a,.workspace b,.crumb{font-size:13.5px}
.num,.depart-city{font-variant-numeric:tabular-nums}

/* --- Primary navigation targets ---------------------------------------
   Header and footer links are primary navigation, not inline prose, so they
   get a real hit area. Body-copy links keep their natural text height. */
.desktop-nav a,.header-login,.header-logo{
  display:inline-flex;align-items:center;min-height:44px;
}
.footer-layout a{display:inline-flex;align-items:center;min-height:32px}
.mobile-drawer nav a{min-height:48px;display:flex;align-items:center}

/* ==========================================================================
   Horizontal overflow guard

   overflow-x:clip, not hidden: hidden turns the element into a scroll
   container, which silently breaks every position:sticky descendant (that is
   what killed the departure scrub earlier). clip contains the paint without
   creating a scrollport, so nothing can ever scroll past the viewport.
   ========================================================================== */
html{overflow-x:clip}
body{overflow-x:clip;max-width:100%}

/* Anything that legitimately exceeds the viewport scrolls inside its own box. */
.data-table-wrap,.rail-track,.seg,.filter-chips{max-width:100%}
.data-table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}

/* Media and embeds never dictate layout width. */
img,svg,video,iframe,canvas{max-width:100%}
/* Long unbroken strings (URLs, emails, agency names) wrap instead of pushing. */
.cell-tel a,.review-body h3,.offer-card h3,.dash-heading h1,
.agency-facts dd,.auth-head h1,.doc-num{overflow-wrap:anywhere}

/* ==========================================================================
   Public mobile menu — iOS sheet

   Was a white panel of underlined rows with no scrim, so tapping outside did
   nothing and the page behind stayed fully lit. Now a proper sheet: dimmed
   blurred backdrop, grouped rows with icon tiles and chevrons, a pinned CTA,
   and safe-area padding.
   ========================================================================== */
.menu-scrim{
  position:fixed;inset:0;z-index:var(--z-backdrop);
  background:rgba(6,14,26,.42);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  opacity:0;visibility:hidden;
  transition:opacity .32s var(--ease-ios),visibility .32s var(--ease-ios);
}
.site-header.menu-open .menu-scrim{opacity:1;visibility:visible}

.mobile-drawer{
  position:fixed;z-index:var(--z-drawer);inset:0 0 0 auto;
  width:min(400px,88vw);
  padding:calc(18px + env(safe-area-inset-top)) 18px calc(18px + env(safe-area-inset-bottom));
  display:flex;flex-direction:column;
  background:var(--surface-2);
  border-radius:24px 0 0 24px;
  box-shadow:-24px 0 60px -18px rgba(2,10,22,.4);
  transform:translateX(102%);
  transition:transform .36s var(--ease-ios);
  overflow-y:auto;overscroll-behavior:contain;
}
[dir=rtl] .mobile-drawer{inset:0 auto 0 0;border-radius:0 24px 24px 0;transform:translateX(-102%)}
.site-header.menu-open .mobile-drawer{transform:none}
body.menu-open{overflow:hidden}

.mobile-drawer-head{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding-bottom:16px;
}
.mobile-drawer-head .voyz-logo-mark{height:28px}
.mobile-drawer-head .voyz-logo-word{height:17px}
.drawer-close{
  width:44px;height:44px;flex:0 0 44px;display:grid;place-items:center;
  border:0;border-radius:50%;background:rgba(16,31,48,.06);color:var(--ink);
  cursor:pointer;transition:background var(--dur-1) var(--ease-ios-soft);
}
.drawer-close:hover{background:rgba(16,31,48,.12)}
.drawer-close svg{width:20px;height:20px}
.mobile-language-toggle{margin:0 0 18px}

/* Grouped list, iOS style: one inset card per group. */
.drawer-nav{display:flex;flex-direction:column;gap:2px}
.drawer-caption{
  margin:14px 4px 6px;
  font-size:12px;font-weight:var(--fw-label);letter-spacing:.05em;
  text-transform:uppercase;color:var(--muted);
}
.drawer-caption:first-child{margin-top:0}
.drawer-nav a{
  min-height:52px;padding:10px 12px;
  display:flex;align-items:center;gap:13px;
  border:0;border-radius:14px;background:#fff;
  color:var(--ink);font-size:15.5px;font-weight:var(--fw-medium);
  box-shadow:var(--sh-xs);
  transition:background var(--dur-1) var(--ease-ios-soft),transform var(--dur-tap) var(--ease-ios-tap);
}
.drawer-nav a:active{transform:scale(.985);background:var(--surface-3)}
.drawer-nav a>svg,.drawer-nav a>i{
  width:32px;height:32px;flex:0 0 32px;display:grid;place-items:center;
  border-radius:9px;background:var(--brand-050);color:var(--brand);
}
.drawer-nav a>svg,.drawer-nav a>i>svg{width:17px;height:17px}
.drawer-nav a>span{flex:1;min-width:0}
.drawer-nav a .chev{
  width:auto;height:auto;flex:0 0 auto;background:none;color:var(--muted);
}
.drawer-nav a .chev svg{width:17px;height:17px}
[dir=rtl] .drawer-nav a .chev svg{transform:scaleX(-1)}

.drawer-foot{margin-top:auto;padding-top:22px}
.drawer-foot .button{width:100%;min-height:52px}

@media (prefers-reduced-motion:reduce){
  .mobile-drawer,.menu-scrim{transition:none}
}

/* ==========================================================================
   Rendering cost

   Profiling the production build under 4x CPU throttling showed main-thread
   time dominated by browser work (style/layout/paint), not scripts. The
   homepage is long and carries expensive effects, so the browser was laying
   out and painting everything up front.

   content-visibility lets it skip rendering for sections that are still
   off-screen. contain-intrinsic-size supplies a placeholder height so the
   scrollbar stays stable and skipping costs no layout shift.
   ========================================================================== */
/* Excluded by :not() rather than a later override, because an override would
   need to out-specify this selector — the same specificity trap that broke the
   toast icon and the sidebar z-index earlier. The exclusions are:
     .takeoff-section / .signal-strip  above the fold, must render immediately
     .departure / .clarity-section     position:sticky drives their layout, and
                                       skipping a sticky subtree strands it. */
/* The exclusions are:
     .takeoff-section / .signal-strip  above the fold, must render immediately
     .departure / .clarity-section     position:sticky drives their layout
     .destination-rail                 60px marquee; skipping it buys nothing
   They live in :not() rather than a later override because an override at
   (0,2,1) would lose to this selector at (0,3,1) — the specificity trap that
   already cost us the toast icon and the sidebar z-index. */
.voyz-home > section:not(.takeoff-section):not(.signal-strip):not(.departure):not(.clarity-section):not(.destination-rail){
  content-visibility:auto;
  /* The placeholder must match what the section really measures, or the page
     grows a false scroll height and then jumps when the content renders. Read
     through a custom property so each section can set its own measured height
     from a low-specificity rule without having to out-specify this one. */
  contain-intrinsic-size:auto var(--cv-h,600px);
}
/* Measured at 412px wide. `auto` above keeps the real size after first render. */
.voyz-home > .wilaya-section{--cv-h:1140px}
.voyz-home > .live-departures{--cv-h:870px}
.voyz-home > .why-voyz{--cv-h:975px}
.voyz-home > .mood-editorial{--cv-h:880px}
.voyz-home > .intent-section{--cv-h:865px}
.voyz-home > .confidence-section{--cv-h:865px}
.voyz-home > .agency-cta{--cv-h:630px}

/* Expensive filters are a paint cost per frame. Keep the glow on desktop,
   drop it where the CPU is weakest and the effect is least visible. */
@media (max-width:900px){
  .flight-trail,.flight-plane{filter:none}
  .pass-main,.pass-stub{box-shadow:0 18px 40px -22px rgba(2,10,22,.7)}
}
@media (prefers-reduced-motion:reduce){
  .flight-trail,.flight-plane{filter:none}
}
