/* =====================================================================
   HOME PAGE STYLES
   =====================================================================
   The admin-tunable values these rules read (title colours, the backdrop
   and hero images, the app-bar geometry) arrive as CSS custom properties
   on :root; every var() below carries a fallback so the page still renders
   sanely if they are unavailable.

   CASCADE POSITION IS LOAD-BEARING. This is linked FIRST, before fonts.css,
   the tenant skin, site.css, news.css and the redesign overlay. Several of
   those deliberately override rules in here at equal specificity and win
   on source order alone; move this link and they stop winning.
   ===================================================================== */

    /* ============ RESET ============ */
    *, *::before, *::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    html {
      scroll-behavior: smooth;
      /* offset anchor jumps (e.g. #flights-section) by the sticky bar height
         so the target isn't hidden behind the pinned app bar */
      scroll-padding-top: 80px;
      -webkit-text-size-adjust: 100%;
    }

    body {
      font-family: 'ITF Ghroob Arabic', Tahoma, 'Noto Sans Arabic', Arial, sans-serif;
      line-height: 1.6;
      color: #242C65;
      background: #ffffff;
      min-height: 100vh;
      min-height: 100dvh;
      overflow-x: clip;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }

    /* ============ ACCESSIBILITY ============ */
    .visually-hidden {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
      white-space: nowrap;
      border: 0;
    }

    :focus-visible {
      outline: 3px solid #1E7960;
      outline-offset: 3px;
      border-radius: 4px;
    }

    /* ============ LAYOUT ============ */
    .page {
      min-height: 100vh;
      min-height: 100dvh;
      display: flex;
      flex-direction: column;
      position: relative;
      /* `clip` still hides the decorative overflow but, unlike `hidden`, does
         NOT create a scroll container — so the sticky app bar can pin to the
         viewport (fixes the missing menu at #flights-section). */
      overflow: clip;
    }

    /* ============ DECORATIVE BACKGROUND ============ */
    .bg-shape {
      position: absolute;
      pointer-events: none;
      z-index: 0;
    }

    .bg-shape--top {
      top: -200px;
      left: -200px;
      width: 600px;
      height: 600px;
      background: radial-gradient(circle, rgba(36, 44, 101, 0.06) 0%, rgba(36, 44, 101, 0) 70%);
      border-radius: 50%;
    }

    .bg-shape--bottom {
      bottom: -300px;
      right: -200px;
      width: 700px;
      height: 700px;
      background: radial-gradient(circle, rgba(30, 121, 96, 0.06) 0%, rgba(30, 121, 96, 0) 70%);
      border-radius: 50%;
    }

    /* Subtle plane silhouette */
    .bg-plane {
      position: absolute;
      top: 18%;
      left: -100px;
      width: 320px;
      opacity: 0.04;
      z-index: 0;
      pointer-events: none;
      transform: rotate(-15deg);
    }

    /* ============ HEADER ============ */
    /* When the document direction flips between AR (rtl) and EN (ltr) the
       flex children would normally swap sides. We lock the visual layout
       so the title stays top-right and the AR/EN toggle stays in its
       slot regardless of language. */
    .site-header {
      position: relative;
      z-index: 2;
      padding: 32px 48px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 16px;
      flex-wrap: wrap;
    }
    html[lang="en"] .site-header { flex-direction: row-reverse; }

    /* ============ LANG SWITCH ============ */
    /* By default, every [data-lang] element is visible — graceful no-JS
       fallback. The html[lang=...] rules then hide whichever one isn't
       active. Use !important so per-element style overrides don't
       resurrect a hidden language. */
    html[lang="ar"] [data-lang="en"] { display: none !important; }
    html[lang="en"] [data-lang="ar"] { display: none !important; }

    .lang-switch {
      display: inline-flex;
      /* Lock to LTR so AR is always the leftmost button and EN is always
         the rightmost — flipping html[dir] would otherwise reorder flex
         children, making it look like the button labels swapped. */
      direction: ltr;
      background: rgba(36, 44, 101, 0.06);
      border-radius: 999px;
      padding: 4px;
      gap: 2px;
      box-shadow: inset 0 0 0 1px rgba(36, 44, 101, 0.04);
    }
    .lang-switch a {
      font: inherit;
      font-size: 12px;
      font-weight: 700;
      letter-spacing: 0.5px;
      border: none;
      background: transparent;
      color: rgba(36, 44, 101, 0.55);
      padding: 6px 14px;
      border-radius: 999px;
      cursor: pointer;
      text-decoration: none;
      text-align: center;
      transition: background 0.15s, color 0.15s, box-shadow 0.15s;
      min-width: 38px;
    }
    .lang-switch a:hover:not(.active) { color: #242C65; }
    .lang-switch a.active {
      background: #fff;
      color: #242C65;
      box-shadow: 0 1px 4px rgba(36, 44, 101, 0.12);
    }

    .logo-area {
      display: flex;
      align-items: center;
      gap: 16px;
    }

    .logo-placeholder {
      width: 72px;
      height: 72px;
      border: 2px dashed rgba(36, 44, 101, 0.3);
      border-radius: 12px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: rgba(36, 44, 101, 0.02);
      color: rgba(36, 44, 101, 0.5);
      font-size: 11px;
      font-weight: 500;
      text-align: center;
      padding: 8px;
      transition: all 0.3s ease;
    }

    .logo-placeholder:hover {
      border-color: #1E7960;
      color: #1E7960;
    }

    .logo-text {
      display: flex;
      flex-direction: column;
      /* Always right-align the title block. text-align: start would flip
         to "left" in EN mode because the document direction changes. */
      text-align: right;
    }

    .logo-text-ar {
      font-size: 18px;
      font-weight: 700;
      color: #242C65;
      line-height: 1.2;
    }

    .logo-text-en {
      font-size: 12px;
      font-weight: 500;
      color: #1E7960;
      letter-spacing: 0.5px;
      margin-top: 2px;
    }

    /* ============ MAIN ============ */
    .main {
      flex: 1;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: flex-start;
      padding: 40px 24px;
      position: relative;
      z-index: 1;
      gap: 48px;
    }

    .hero {
      max-width: 720px;
      width: 100%;
      text-align: center;
      padding: 24px;
    }
    /* Top hero (title + subtitle only) sits flush against the flight
       board below it. Kill the hero's own bottom padding AND tighten
       the subtitle's bottom margin so the title visually anchors the
       flight board. */
    .hero-top { padding-bottom: 0; }
    .hero-top .hero-subtitle { margin-bottom: 12px; }

    /* The `hidden` attribute on a styled element loses to anything more
       specific than [hidden] (e.g. `.flights-pagination { display: flex }`).
       Force it to win so `el.hidden = true` actually hides the element. */
    [hidden] { display: none !important; }

    /* ============ FLIGHTS SECTION ============ */
    .flights-section {
      max-width: 1080px;
      width: 100%;
      padding: 0 8px;
      /* Positioning context for the floated first-load indicator
         (.flights-loading--float), which must add no height. */
      position: relative;
    }

    /* ============ HOME VIDEO ============ */
    /* Matches the flight-board panel width (max 1080px) and is fully fluid on
       smaller screens; the 16:9 frame scales with the available width. */
    .home-video {
      max-width: 1080px;
      width: 100%;
      padding: 0 8px;
      margin: 8px auto 28px;
    }
    .home-video__frame { width: 100%; }
    /* White card matching the flight-board panel (same border/radius/shadow),
       with a thin white frame (padding) around the video picture. Toggled by
       the `home_video_frame` setting (/settings → Operational). */
    .home-video__frame--framed {
      background: #fff;
      border: 1px solid rgba(36, 44, 101, var(--home-video-border-alpha, 0.1));
      border-radius: 12px;
      padding: 6px;
      box-shadow: 0 2px 8px rgba(36, 44, 101, 0.04);
    }
    .home-video__aspect {
      position: relative;
      width: 100%;
      aspect-ratio: 16 / 9;
      border-radius: 8px;
      overflow: hidden;
      background: #000;
    }
    .home-video__frame iframe {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      border: 0;
    }
    .flights-header {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 16px;
      margin-bottom: 20px;
      flex-wrap: wrap;
      text-align: center;
    }
    .flights-title {
      font-size: clamp(20px, 3.5vw, 26px);
      font-weight: 800;
      color: #242C65;
      line-height: 1.2;
      text-align: center;
    }
    .flights-title-en {
      display: block;
      font-size: 0.55em;
      font-weight: 500;
      color: #1E7960;
      letter-spacing: 0.5px;
      margin-top: 4px;
    }

    /* table layout (replaces the previous card grid) */
    .flights-table-wrap {
      background: #fff;
      border: 1px solid rgba(36, 44, 101, 0.1);
      border-radius: 12px;
      overflow: hidden;
      box-shadow: 0 2px 8px rgba(36, 44, 101, 0.04);
    }
    .flights-table-scroll { overflow-x: auto; }
    .flights-table {
      width: 100%;
      border-collapse: collapse;
      font-size: 14px;
      /* 9 columns (route text + flag + airline name + logo split out); the
         compact flag/logo columns add little. Wider than a phone, so ≤640px
         switches to the stacked card below and this never causes PAGE overflow
         (the wrap has overflow-x:auto). */
      min-width: 820px;
    }
    .flights-table th,
    .flights-table td {
      padding: 12px 14px;
      /* Flight-list content is centered (title + table cells) per design. */
      text-align: center;
      border-bottom: 1px solid rgba(36, 44, 101, 0.08);
      vertical-align: middle;
    }
    .flights-table th {
      font-size: 12px;
      font-weight: 700;
      letter-spacing: 0.3px;
      color: #1E7960;
      background: rgba(30, 121, 96, 0.04);
      white-space: nowrap;
    }
    .flights-table th .th-en {
      display: block;
      font-size: 10px;
      font-weight: 500;
      color: rgba(36, 44, 101, 0.5);
      text-transform: uppercase;
      letter-spacing: 0.5px;
      margin-top: 2px;
    }
    .flights-table tbody tr:last-child td { border-bottom: none; }
    .flights-table tbody tr:hover td { background: rgba(36, 44, 101, 0.02); }

    /* Whole flight row is a link to /flights/<uuid> (desktop rows + mobile
       cards share this DOM). Clear affordance + keyboard focus ring. */
    .flights-table tbody tr.flight-row { cursor: pointer; }
    .flights-table tbody tr.flight-row:hover td { background: rgba(36, 44, 101, 0.05); }
    .flights-table tbody tr.flight-row:focus-visible {
      outline: 2px solid #1E7960;
      outline-offset: -2px;
    }
    .flights-table tbody tr.flight-row:focus { outline: 2px solid #1E7960; outline-offset: -2px; }
    @media (hover: hover) { .flights-table tbody tr.flight-row:hover { box-shadow: inset 0 0 0 1px rgba(30,121,96,0.15); } }

    .flights-table .num    { font-weight: 800; color: #242C65; letter-spacing: 0.5px; }
    /* The board shows ONE airport — the non-tenant endpoint (source for
       arrivals, destination for departures) — with its country flag. No arrow,
       no tenant airport, no full route (that lives on the flight-details page).
       The cell inherits the page direction so the flag + name order reads
       naturally in AR (flag at the reading-start) and EN; the Latin IATA code is
       bidi-isolated so it never reverses inside an RTL line. */
    /* Destination/origin TEXT column: takes the remaining width, end-aligned so
       its text sits right next to the adjacent compact FLAG column. Long
       city/airport names wrap instead of stretching the layout. */
    .flights-table .route  { font-weight: 700; color: #242C65; text-align: end; overflow-wrap: anywhere; padding-inline-end: 6px; }
    /* Compact FLAG column — shrinks to the flag (width:1% + nowrap), start-aligned
       so the flag hugs the route text before it. */
    .flights-table .flag   { width: 1%; white-space: nowrap; text-align: start; padding-inline-start: 4px; }
    .flights-table .route .endpoint--single {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 7px;
      flex-wrap: wrap;
    }
    .flights-table .route-flag {
      width: 22px; height: 16px;
      object-fit: cover;
      border-radius: 2px;
      box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12);
      flex: 0 0 auto;
    }
    .flights-table .route-name { font-weight: 800; color: #242C65; }
    .flights-table .route-code {
      font-size: 0.82em; font-weight: 700;
      color: #6b7185; letter-spacing: 0.5px;
      unicode-bidi: isolate;
    }
    .flights-table .when   { white-space: nowrap; color: #555; }
    .flights-table .gate   { font-weight: 700; color: #242C65; }
    /* Airline NAME column: remaining width, end-aligned next to the compact LOGO
       column. Long airline names wrap rather than stretch the row. */
    .flights-table .airline { color: #555; text-align: end; overflow-wrap: anywhere; padding-inline-end: 6px; }
    /* Compact LOGO column — shrinks to the logo, start-aligned so it hugs the
       airline name before it. */
    .flights-table .logo    { width: 1%; white-space: nowrap; text-align: start; padding-inline-start: 4px; }
    /* Operating-airline logo (managed airline record; contained, fixed box so
       rows never jump; aspect ratio preserved, never stretched). */
    .flights-table .airline-logo {
      height: 22px; max-width: 60px; width: auto;
      object-fit: contain;
      vertical-align: middle;
      border-radius: 4px;
    }
    .flights-table .airline-name { vertical-align: middle; }

    /* Flight status/direction pill styles now live in the SHARED site.css
       (single source of truth), so every page — home board, destination pages,
       flight-details — renders them legibly. Only the board-specific direction
       ICON stays here. */

    /* Plane icon inside the direction pill. Two distinct silhouettes are
       injected from home.js — flight_takeoff for departures, flight_land
       for arrivals — each pre-tilted with a short runway line baked into
       the path, so no CSS rotation is needed (which kept the previous
       paper-airplane look). fill:currentColor lets each pill's text colour
       bleed into the icon so the green/navy theming stays consistent. */
    .flights-table .dir-icon {
      width: 16px; height: 16px;
      fill: currentColor;
      vertical-align: -3px;
      margin-inline-end: 5px;
    }
    /* Admin-uploaded direction icon (an <img> instead of the inline SVG). */
    .flights-table img.dir-icon { object-fit: contain; }


    /* Mobile: the 7-column board is wider than a phone (min-width: 760px),
       so on narrow screens we drop the table grid and render each flight
       as a stacked card. The desktop/tablet table above is untouched —
       these rules only apply at <= 640px. Each <td> becomes a labelled
       row inside its card: the label comes from the cell's data-label
       (stamped by home.js, matching the desktop header), the value sits
       on the opposite edge. No horizontal scroll, no overflow. */
    @media (max-width: 640px) {
      /* Card is the visual unit now — drop the table's outer chrome and
         the horizontal scroller so nothing can overflow the viewport. */
      .flights-table-wrap {
        background: transparent;
        border: none;
        border-radius: 0;
        box-shadow: none;
        overflow: visible;
      }
      .flights-table-scroll { overflow-x: visible; }
      .flights-table { min-width: 0; font-size: 14px; }

      /* Each flight becomes a card. The <table> is collapsed to a CSS grid so
         cells pair horizontally (desktop/tablet table is untouched). Every row
         is CENTERED: flight number, airline (name+logo), destination (route+flag)
         and the type/status pair each meet at the card's centre line; date/time
         is centered too. Direction-aware (RTL/LTR) via logical text-align + grid. */
      .flights-table thead { display: none; }
      .flights-table,
      .flights-table tbody { display: block; width: 100%; }

      /* Card grid — 12 tracks, placed by LINE rather than by named areas.
         A <tr> may only contain <td>s, so the three summary cells cannot be
         wrapped in a flex container; a 12-column grid is what lets one row hold
         three cells while the rows below keep their exact 50/50 pairing
         (1/7 + 7/13), which named areas could not express at two column widths.

         Rows:
           1  number · type · status   ← one summary line (requirement 7)
           2  airline logo             ← full card width so a ≥60px logo fits
           3  airline name
           4  destination text | flag  ← unchanged 50/50 pair, meeting at centre
           5  date — time

         Placement is by grid LINE, which is direction-agnostic: in RTL column 1
         is the right-hand edge and in LTR the left, so a single rule reads
         correctly both ways with no mirrored stylesheet. */
      .flights-table tr {
        display: grid;
        grid-template-columns: repeat(12, minmax(0, 1fr));
        align-items: center;
        column-gap: 8px;
        row-gap: 4px;
        background: #fff;
        border: 1px solid rgba(36, 44, 101, 0.12);
        border-radius: 12px;
        box-shadow: 0 1px 4px rgba(36, 44, 101, 0.05);
        padding: 12px 14px;
        margin-bottom: 12px;
      }
      .flights-table tbody tr:last-child { margin-bottom: 0; }
      .flights-table tbody tr:hover td { background: transparent; }

      /* Cells are plain grid items now — no table borders or ::before labels.
         width:auto + min-width:0 cancel the desktop compact-column sizing. */
      .flights-table td {
        display: block;
        width: auto;
        min-width: 0;
        padding: 2px 0;
        border-bottom: none;
        white-space: normal;
      }
      .flights-table td::before { content: none; }

      /* ---- Row 1: the summary line — number · type · status ----
         Equal thirds. The number keeps the strongest weight/size; type and
         status stay as the shared .pill badges (text + colour, never colour
         alone). Each third aligns toward its own side so the three read as one
         line rather than three stacked blocks. */
      .flights-table .num {
        grid-column: 1 / 5; grid-row: 1;
        text-align: start;
        font-size: 16px; font-weight: 800;
        /* EVERY tenant skin tints this cell on mobile (theme-navy/green/amber
           each set `.flights-table .num { background: … }` at ≤640px). That was
           designed when .num spanned the WHOLE card width as a banner row; now
           that it shares the summary line it must read as a deliberate chip
           instead of a square block clipped at the card edge.
           justify-self:start shrinks the cell to its text (logical: hugs the
           reading edge in both RTL and LTR) and the radius/padding turn the
           tenant tint into the badge that gives the flight number its emphasis.
           Only the SHAPE is set here — each skin keeps its own colour. */
        justify-self: start;
        border-radius: 999px;
        padding: 3px 10px;
      }
      .flights-table .dir    { grid-column: 5 / 9;  grid-row: 1; text-align: center; }
      .flights-table .status { grid-column: 9 / 13; grid-row: 1; text-align: end; }
      /* Narrow phones: a long status ("الصعود للطائرة", "Cancelled") wraps
         inside its own badge instead of overlapping or being clipped — the
         three values stay on their own line and keep their relationship. */
      .flights-table .dir .pill,
      .flights-table .status .pill { white-space: normal; }

      /* ---- Rows 2–3: airline logo (full width) then name ---- */
      .flights-table .logo {
        grid-column: 1 / 13; grid-row: 2;
        width: auto; padding-inline: 0;
        display: flex; align-items: center; justify-content: center;
        min-height: 60px;                     /* the required minimum logo area */
      }
      /* No logo (never uploaded, or the <img> removed itself after a load
         error): the cell is empty, so collapse it — an empty 60px band would be
         a hole in the card. :empty re-evaluates live, so this also covers the
         runtime removal. */
      .flights-table .logo:empty { display: none; min-height: 0; }
      .flights-table .airline {
        grid-column: 1 / 13; grid-row: 3;
        text-align: center; color: #555; padding-inline: 0;
      }

      /* ---- Row 4: destination text + flag, the existing 50/50 pair ---- */
      .flights-table .route { grid-column: 1 / 7;  grid-row: 4; text-align: end;   padding-inline-end: 0; }
      .flights-table .flag  { grid-column: 7 / 13; grid-row: 4; text-align: start; padding-inline-start: 0; width: auto; }

      /* ---- Row 5: date — time ---- */
      .flights-table .when { grid-column: 1 / 13; grid-row: 5; text-align: center; color: #555; }

      /* Gate is optional (frequently empty) and not part of the card. */
      .flights-table .gate { display: none; }

      /* Airline logo — minimum 60px displayed height on phones.
         height:60px + width:auto scales proportionally from the intrinsic size;
         max-width caps it at the card so a wide logo can never overflow, and
         object-fit:contain guarantees it is never cropped or stretched. A logo
         wider than ~4.3:1 hits the width cap first and is letterboxed inside
         the 60px box rather than being distorted to fill it — the honest
         trade-off, since making a 6:1 mark 60px tall would need ~360px of width
         that a 320px phone does not have. Giving the logo the FULL card width
         (row 2 above) is what buys the common 2:1–4:1 marks their full 60px. */
      .flights-table .airline-logo {
        height: 60px;
        width: auto;
        max-width: 100%;
        max-height: 60px;
        object-fit: contain;
        object-position: center;
      }

      /* The mobile 3-row filter layout lives in its own ≤768px block below (so
         it also covers small-tablet portrait, 641–768px). The date-range pills
         are hidden and the specific-date picker + airline + search are laid out
         there — kept out of this table-only block to avoid the pills reappearing
         between 641–768px. */
    }

    .flights-cta {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      background: #1E7960;
      color: #fff;
      padding: 10px 22px;
      border-radius: 10px;
      text-decoration: none;
      font-weight: 700;
      font-size: 14px;
      transition: background 0.15s, box-shadow 0.15s, transform 0.1s;
    }
    .flights-cta:hover { background: #166349; box-shadow: 0 4px 12px rgba(30, 121, 96, 0.25); }
    .flights-cta:active { transform: translateY(1px); }
    .flights-cta::before {
      content: '+';
      font-size: 18px;
      line-height: 1;
    }

    .flights-empty,
    .flights-loading,
    .flights-error {
      background: #fff;
      border: 1px dashed rgba(36, 44, 101, 0.18);
      border-radius: 12px;
      padding: 36px 24px;
      text-align: center;
      color: #555;
      font-size: 15px;
      /* Reserve a sensible area so the container appears at roughly its final
         size and the page doesn't jump much when rows arrive (reduces CLS). */
      min-height: 220px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 12px;
    }
    .flights-error__retry {
      font: inherit; font-weight: 700; font-size: 14px;
      padding: 9px 18px; border-radius: 10px; cursor: pointer;
      border: 1px solid rgba(192, 57, 43, 0.4);
      background: #fff; color: #c0392b;
    }
    .flights-error__retry:hover { background: rgba(192, 57, 43, 0.06); }

    /* Compact toolbar — date filters, direction filters, and search box
       sit on a single row. Wraps to multiple rows on narrow screens. */
    .flights-toolbar {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 8px;
      flex-wrap: wrap;
      margin-bottom: 16px;
    }
    .flights-filters {
      display: flex;
      gap: 4px;
      padding: 4px;
      background: #fff;
      border: 1px solid rgba(36, 44, 101, 0.1);
      border-radius: 999px;
      box-shadow: 0 2px 8px rgba(36, 44, 101, 0.04);
      flex-wrap: wrap;
      justify-content: center;
    }
    .filter-btn {
      font: inherit; font-weight: 700; font-size: 12px;
      padding: 6px 12px;
      border: none;
      border-radius: 999px;
      background: transparent;
      color: #555;
      cursor: pointer;
      transition: background 0.15s, color 0.15s;
      min-width: 0;
    }
    .filter-btn.active { background: #1E7960; color: #fff; }
    .filter-btn:hover:not(.active) {
      background: rgba(30, 121, 96, 0.06);
      color: #242C65;
    }

    /* Search box grows to fill the leftover toolbar space. */
    .flights-search {
      flex: 1 1 200px;
      min-width: 160px;
    }
    .flights-search input {
      width: 100%;
      font: inherit;
      font-size: 13px;
      padding: 8px 14px;
      border: 1.5px solid rgba(36, 44, 101, 0.18);
      border-radius: 999px;
      background: #fff;
      color: #242C65;
      transition: border-color 0.15s, box-shadow 0.15s;
    }
    .flights-search input:focus {
      outline: none;
      border-color: #1E7960;
      box-shadow: 0 0 0 3px rgba(30, 121, 96, 0.15);
    }
    .flights-search input::placeholder { color: rgba(36, 44, 101, 0.4); }

    /* Airline dropdown + specific-date picker — sit in the same toolbar row,
       styled to match the search box so the flight board's look is preserved. */
    .flights-airline, .flights-datepick {
      display: flex; align-items: center; gap: 6px;
      min-width: 0;
    }
    .flights-datepick__label {
      font-size: 12px; font-weight: 700; color: #555; white-space: nowrap;
    }
    .flights-airline select, .flights-datepick input {
      font: inherit; font-size: 13px;
      padding: 8px 12px;
      border: 1.5px solid rgba(36, 44, 101, 0.18);
      border-radius: 999px;
      background: #fff; color: #242C65;
      max-width: 220px;
      transition: border-color 0.15s, box-shadow 0.15s;
    }
    .flights-airline select:focus, .flights-datepick input:focus {
      outline: none; border-color: #1E7960;
      box-shadow: 0 0 0 3px rgba(30, 121, 96, 0.15);
    }

    /* =====================================================================
       MOBILE FLIGHT FILTERS — stacked full-width rows (≤768px, phones + small
       tablet portrait). Desktop (>768px) keeps the single wrapping toolbar row.
         Row 1: Arrivals | Departures            (full-width 2-col tabs)
         Row 2: Yesterday | Today | Tomorrow     (full-width 3-col tabs)
         Row 3: date picker | airline select     (two halves)
         Row 4: search                           (full width)
       Any row whose controls the admin has switched off simply isn't there.
       With the SHIPPED defaults only rows 1, 3 (date alone) and 4 survive, and
       .flights-toolbar--compact folds them into two lines — see that rule below.
       Every row fills the width with grid fr units → never overflows at 320px.
       16px inputs prevent iOS focus-zoom; 44px min-heights give comfortable
       touch targets. RTL/LTR follow DOM order (reads correctly both ways).
       ===================================================================== */
    @media (max-width: 768px) {
      /* Admin-switched-off filters (per-tenant). The class is stamped
         server-side from the settings; it takes effect ONLY inside this mobile
         block, so the desktop toolbar always shows every control. display:none
         also removes the control from the tab order and the accessibility tree
         at these widths, so nothing hidden here is still reachable.
         The date pills are a grid with grid-auto-flow:column, and a display:none
         item creates no track — so the remaining pills split the full width with
         no gap where a hidden one used to be.

         Selectors are written #id.is-mobile-off (1,1,0) on purpose: the layout
         rules further down this block are #flights-filters / #flights-datepick /
         #flights-airline (1,0,0) and set `display`, so a plain
         `.is-mobile-off` (0,1,0) would lose to them and the control would stay
         visible. */
      #flights-filters.is-mobile-off,
      #flights-datepick.is-mobile-off,
      #flights-airline.is-mobile-off,
      #flights-filters .filter-btn.is-mobile-off { display: none; }

      .flights-toolbar {
        flex-wrap: wrap;
        justify-content: flex-start;
        align-items: stretch;
        gap: 10px;
        margin-bottom: 14px;
      }

      /* Row 1 — movement tabs: two equal, full-width columns. */
      #flights-dir-filters {
        flex: 1 1 100%;
        width: 100%;
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 4px;
        border-radius: 12px;
      }
      /* Row 2 — date tabs: equal, full-width columns, ONE PER RENDERED PILL.
         Each of Yesterday/Today/Tomorrow is admin-switchable, so the count is
         1, 2 or 3 (the whole group is omitted at 0). grid-auto-columns derives
         the tracks from the children that actually exist, which redistributes
         the full width automatically — a fixed `1fr 1fr 1fr` would have left a
         blank third of the row wherever a pill was switched off. */
      #flights-filters {
        flex: 1 1 100%;
        width: 100%;
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: minmax(0, 1fr);
        gap: 4px;
        border-radius: 12px;
      }
      #flights-dir-filters .filter-btn,
      #flights-filters .filter-btn {
        min-width: 0;
        min-height: 44px;
        padding: 6px 4px;
        /* Sized so the LONGEST real label ("TOMORROW"/"DEPARTURES") fits one
           line in the narrowest track it can get — a third of the row at 320px
           — instead of breaking mid-word. Wrapping below is the safety net for
           a longer translation, not the normal case. */
        font-size: clamp(10.5px, 3.1vw, 14px);
        line-height: 1.15;
        /* WRAP rather than ellipsize. At 375px the English labels are wider
           than a third of the row ("YESTERDAY" ≈ 76px at the 12.75px this
           clamp resolves to, against ~83px of usable track), so nowrap +
           text-overflow truncated them to "YESTERD…" — an unreadable label,
           and one that also hid which filter was which. Two short lines fit
           inside the 44px touch target, so nothing is clipped and the button
           height is unchanged. */
        white-space: normal;
        overflow-wrap: break-word;
        text-align: center;
        border-radius: 9px;
      }

      /* Row 3 — date + airline, each ~half width, on one row */
      #flights-datepick,
      #flights-airline {
        flex: 1 1 calc(50% - 5px);
        min-width: 0;
        display: flex;
      }
      #flights-datepick input,
      #flights-airline select {
        width: 100%;
        max-width: none;
        min-height: 44px;
        font-size: 16px;               /* ≥16px → no iOS focus-zoom */
        border-radius: 10px;
      }

      /* ---- Compact two-line toolbar (the shipped phone default) ----
         Applies ONLY when index.php has stamped .flights-toolbar--compact, i.e.
         movement + date picker + search are the only controls left. Then:
           Line 1: [ Arrivals | Departures ]  [ date ]
           Line 2: [ search                               ]
         instead of giving each control its own full-width row.

         Both selectors are (1,1,0) — the class QUALIFIES the same #id rules
         above, which is what lets them win without !important.

         flex-basis, not percentages: the basis doubles as the wrap threshold, so
         on a 320px screen (where "DEPARTURES" plus a native date field genuinely
         do not fit side by side) the two simply fall onto separate lines instead
         of clipping the date or breaking the label mid-word. Growth is weighted
         3:2 so the extra width on a larger phone goes mostly to the two labels,
         which are the part that wraps. */
      .flights-toolbar--compact #flights-dir-filters {
        flex: 3 1 150px;
        width: auto;
      }
      .flights-toolbar--compact #flights-datepick {
        flex: 2 1 128px;
      }

      /* Row 3 — full-width search with an inline magnifier + native clear (X) */
      #flights-search {
        flex: 1 1 100%;
        min-width: 0;
      }
      #flights-search input {
        width: 100%;
        min-height: 44px;
        font-size: 16px;               /* ≥16px → no iOS focus-zoom */
        border-radius: 10px;
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23242C65' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7' opacity='.5'/%3E%3Cpath d='M21 21l-4.3-4.3' opacity='.5'/%3E%3C/svg%3E");
        background-repeat: no-repeat;
        background-size: 18px 18px;
        background-position: left 12px center;
        padding-inline-start: 38px;
      }
      html[lang="ar"] #flights-search input { background-position: right 12px center; }
    }

    /* Narrowest phones (≤360px): the filter labels are single WORDS, so when
       one is too wide it cannot wrap at a space — it either breaks mid-word
       ("TOMORRO/W") or gets clipped. Every tenant skin renders .filter-btn
       uppercase with 0.08em tracking (theme-navy/green/amber), which is what
       pushes "YESTERDAY"/"TOMORROW" past a third of a 320px row. Dropping just
       the transform and the tracking here recovers ~25% of the width and keeps
       the labels whole, readable and at full size.
       The #id selectors (1,1,0) out-rank the skins' html.theme-* .filter-btn
       (0,2,1), so this applies for every tenant without editing three skins. */
    @media (max-width: 360px) {
      #flights-dir-filters .filter-btn,
      #flights-filters .filter-btn {
        text-transform: none;
        letter-spacing: 0;
      }
    }

    /* pagination (only visible when filtered count > PAGE_SIZE) */
    .flights-pagination {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 16px;
      margin-top: 24px;
      flex-wrap: wrap;
    }
    .page-btn {
      font: inherit;
      font-weight: 600;
      font-size: 14px;
      padding: 8px 18px;
      border: 1.5px solid rgba(36, 44, 101, 0.2);
      border-radius: 10px;
      background: #fff;
      color: #242C65;
      cursor: pointer;
      transition: background 0.15s, border-color 0.15s, color 0.15s;
    }
    .page-btn:hover:not(:disabled) {
      background: rgba(30, 121, 96, 0.08);
      border-color: #1E7960;
      color: #1E7960;
    }
    .page-btn:disabled { opacity: 0.4; cursor: not-allowed; }
    .page-info {
      font-size: 14px;
      font-weight: 600;
      color: #555;
      min-width: 110px;
      text-align: center;
    }
    .flights-loading::before {
      content: '';
      display: inline-block;
      width: 14px; height: 14px;
      margin-inline-end: 10px;
      vertical-align: -2px;
      border: 2px solid rgba(30, 121, 96, 0.25);
      border-top-color: #1E7960;
      border-radius: 50%;
      animation: alp-spin 0.8s linear infinite;
    }
    @keyframes alp-spin { to { transform: rotate(360deg); } }
    /* Reduced-motion: no spin — a static ring remains, and the "Loading flights…"
       text already conveys state (never rely on animation alone). */
    @media (prefers-reduced-motion: reduce) {
      .flights-loading::before { animation: none; }
    }
    /* Optional admin loading logo (uploaded per tenant). When present it stacks
       above the text and its gentle pulse conveys activity, so the spinner ring
       is suppressed to avoid two competing spinners. */
    .flights-loading--logo { flex-direction: column; }
    .flights-loading--logo::before { display: none; }
    .flights-loading__logo {
      display: block;
      width: 72px; height: 72px;
      object-fit: contain;
      animation: alp-loading-pulse 1.4s ease-in-out infinite;
    }
    @keyframes alp-loading-pulse {
      0%, 100% { opacity: 0.5; transform: scale(0.95); }
      50%      { opacity: 1;   transform: scale(1); }
    }
    @media (prefers-reduced-motion: reduce) {
      .flights-loading__logo { animation: none; opacity: 1; }
    }

    /* ---- first-load skeleton ------------------------------------------- */
    /* The first load reserves the board's space with placeholder rows that ARE
       the real row markup (the script builds them with the same row builder).
       That is the point: the skeleton's height tracks the card grid
       automatically, instead of resting on a hardcoded pixel constant that
       would rot the next time the row layout changes. Without it the table
       lands in one insertion after first paint and pushes everything below it
       down the page.

       Placeholder TEXT is present because it is what gives a row its height —
       it is painted as blocks, and the rows are aria-hidden. */
    .flight-row--skeleton { pointer-events: none; }
    .flight-row--skeleton td { color: transparent; }
    .flight-row--skeleton .flight-num,
    .flight-row--skeleton .airline-name,
    .flight-row--skeleton .route-name,
    .flight-row--skeleton .pill,
    .flight-row--skeleton .when,
    .flight-row--skeleton .gate {
      color: transparent;
      background: rgba(36, 44, 101, 0.09);
      border-color: transparent;
      border-radius: 6px;
      box-shadow: none;
    }
    .flight-row--skeleton .pill svg,
    .flight-row--skeleton .dir-icon { visibility: hidden; }
    /* A skeleton has no logo, and `.flights-table .logo:empty` collapses an
       empty logo cell on mobile — which would make every placeholder row 60px
       shorter than the real one it is standing in for. Out-specify it (0,4,0
       against 0,3,0) so the cell holds the same box the real logo occupies.
       CARD LAYOUT ONLY: on the desktop table the logo is a 22px image inside a
       48px row, so forcing 60px there would make each placeholder TALLER than
       the row it stands in for and shift the board the other way. */
    @media (max-width: 640px) {
      .flights-table .flight-row--skeleton .logo:empty {
        display: block;
        min-height: 60px;
        background: rgba(36, 44, 101, 0.06);
        border-radius: 8px;
      }
    }
    @keyframes alp-skel-pulse {
      0%, 100% { opacity: 1; }
      50%      { opacity: 0.55; }
    }
    .flight-row--skeleton { animation: alp-skel-pulse 1.4s ease-in-out infinite; }
    @media (prefers-reduced-motion: reduce) {
      .flight-row--skeleton { animation: none; }
    }
    /* With the skeleton rows carrying the height, the loading card is lifted
       OUT OF FLOW and floated over them. In flow it would add its own height,
       which then vanishes on load — a second shift. `.flights-section` is the
       positioning context (its only other absolute descendants already resolve
       against nearer ancestors: .flights-busy → .flights-results, the video
       iframe → .home-video__aspect). */
    .flights-loading--float {
      position: absolute;
      inset-inline: 0;
      inset-block-start: 34%;
      z-index: 3;
      margin: 0;
      border: 0;
      padding: 0;
      background: transparent;
      box-shadow: none;
    }
    .flights-loading--float::before { display: none; }   /* no spinner ring */

    /* ---- scoped busy overlay (refetch feedback) ------------------------ */
    /* #flights-results is the positioning context; the overlay covers ONLY the
       list, so the toolbar/nav/header/language switch/widgets stay interactive.
       Absolutely positioned → adds no height, so showing it causes no layout
       shift (the current rows keep their box underneath the dim). */
    .flights-results { position: relative; }
    .flights-busy {
      position: absolute;
      inset: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 3;
      border-radius: 12px;
      background: rgba(255, 255, 255, 0.55);
      -webkit-backdrop-filter: blur(1px);
      backdrop-filter: blur(1px);
      animation: alp-busy-fade 0.15s ease-out;
    }
    .flights-busy[hidden] { display: none; }   /* beat the display:flex above */
    .flights-busy__spinner {
      width: 34px; height: 34px;
      border: 3px solid rgba(30, 121, 96, 0.25);
      border-top-color: #1E7960;
      border-radius: 50%;
      animation: alp-spin 0.8s linear infinite;
    }
    @keyframes alp-busy-fade { from { opacity: 0; } to { opacity: 1; } }
    /* Reduced motion: no fade, no spin — a static dim + static ring still signal
       activity, and aria-busy on #flights-results announces it to assistive tech. */
    @media (prefers-reduced-motion: reduce) {
      .flights-busy { animation: none; }
      .flights-busy__spinner { animation: none; }
    }

    .flights-error {
      color: #c0392b;
      border-color: rgba(192, 57, 43, 0.3);
      background: rgba(192, 57, 43, 0.04);
    }

    .flights-list {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
      gap: 16px;
    }

    .flight-card {
      position: relative;
      background: #fff;
      border: 1px solid rgba(36, 44, 101, 0.1);
      border-inline-start: 4px solid #1E7960;
      border-radius: 12px;
      padding: 18px 18px 14px;
      box-shadow: 0 2px 8px rgba(36, 44, 101, 0.04);
      transition: transform 0.15s, box-shadow 0.15s;
    }
    .flight-card:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 20px rgba(36, 44, 101, 0.08);
    }
    .flight-card--arrival   { border-inline-start-color: #1E7960; }
    .flight-card--departure { border-inline-start-color: #242C65; }

    .flight-card__head {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 8px;
      margin-bottom: 10px;
    }
    .flight-card__number {
      font-size: 18px;
      font-weight: 800;
      color: #242C65;
      letter-spacing: 0.5px;
    }
    .flight-card__dir {
      font-size: 11px;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.5px;
      padding: 4px 10px;
      border-radius: 999px;
      background: rgba(30, 121, 96, 0.1);
      color: #1E7960;
    }
    .flight-card--departure .flight-card__dir {
      background: rgba(36, 44, 101, 0.08);
      color: #242C65;
    }

    .flight-card__route {
      display: flex;
      align-items: center;
      gap: 10px;
      font-size: 22px;
      color: #242C65;
      margin-bottom: 12px;
      font-weight: 700;
    }
    .flight-card__arrow {
      color: #1E7960;
      font-size: 18px;
    }

    .flight-card__meta {
      display: flex;
      flex-direction: column;
      gap: 4px;
      font-size: 13px;
      color: #555;
      margin-bottom: 12px;
    }

    .flight-card__status {
      display: inline-block;
      font-size: 12px;
      font-weight: 700;
      padding: 4px 12px;
      border-radius: 999px;
      background: rgba(36, 44, 101, 0.06);
      color: #242C65;
    }
    .flight-card__status--on-time   { background: rgba(30, 121, 96, 0.12);  color: #1E7960; }
    .flight-card__status--delayed   { background: rgba(230, 126, 34, 0.12); color: #b9540a; }
    .flight-card__status--boarding  { background: rgba(41, 128, 185, 0.12); color: #1f6391; }
    .flight-card__status--departed  { background: rgba(36, 44, 101, 0.12);  color: #242C65; }
    .flight-card__status--arrived   { background: rgba(30, 121, 96, 0.12);  color: #1E7960; }
    .flight-card__status--cancelled { background: rgba(192, 57, 43, 0.12);  color: #c0392b; }
    .flight-card__status--scheduled { background: rgba(36, 44, 101, 0.06);  color: #242C65; }

    .hero-title {
      font-size: clamp(32px, 6vw, 56px);
      font-weight: 800;
      color: #242C65;
      line-height: 1.2;
      margin-bottom: 16px;
      letter-spacing: -0.5px;
    }

    .hero-subtitle {
      font-size: clamp(18px, 3vw, 22px);
      color: #1E7960;
      font-weight: 600;
      margin-bottom: 40px;
    }

    /* ============ INFO STRIP ============ */
    .info-strip {
      display: flex;
      flex-wrap: wrap;
      gap: 16px;
      justify-content: center;
      margin-top: 32px;
    }

    .info-card {
      background: white;
      border: 1px solid rgba(36, 44, 101, 0.1);
      padding: 20px 28px;
      border-radius: 12px;
      min-width: 160px;
      text-align: center;
      transition: transform 0.2s ease, box-shadow 0.2s ease;
    }

    .info-card:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 24px rgba(36, 44, 101, 0.08);
    }

    .info-card-label {
      font-size: 12px;
      color: #1E7960;
      font-weight: 600;
      text-transform: uppercase;
      letter-spacing: 0.5px;
      margin-bottom: 6px;
    }

    .info-card-value {
      font-size: 18px;
      color: #242C65;
      font-weight: 700;
    }

    /* ============ FOOTER ============ */
    .site-footer {
      position: relative;
      z-index: 2;
      padding: 24px 48px;
      text-align: center;
      border-top: 1px solid rgba(36, 44, 101, 0.08);
    }

    .footer-text {
      font-size: 14px;
      color: rgba(36, 44, 101, 0.6);
    }

    .footer-text strong {
      color: #242C65;
    }

    /* ============ RESPONSIVE ============ */
    @media (max-width: 640px) {
      .site-header {
        padding: 20px 24px;
        justify-content: center;
      }

      .logo-placeholder {
        width: 60px;
        height: 60px;
      }

      .logo-text-ar {
        font-size: 16px;
      }

      .info-card {
        flex: 1 1 calc(50% - 8px);
        min-width: 0;
        padding: 16px;
      }

      .site-footer {
        padding: 20px 24px;
      }

      .flights-list {
        grid-template-columns: 1fr;
      }
    }

    @media (prefers-reduced-motion: reduce) {
      *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
      }
    }

    @media print {
      .bg-shape, .bg-plane { display: none; }
      body { color: black; }
    }

    /* =====================================================================
       ALEPPO SIGNATURE — heritage / citadel formality
       Scoped under html.theme-navy so Damascus (theme-green) is unaffected.
       Damascus's distinct moves live in theme-green.css.
       ===================================================================== */

    /* Forest-green bar above the hero title — citadel-wall cue. */
    html.theme-navy .hero-title::before {
      content: "";
      display: block;
      width: 56px;
      height: 2px;
      background: #1E7960;
      margin: 0 auto 14px;
      opacity: 0.7;
    }

    /* Warm-stone background plane: a soft navy wash + faint banded
       texture (suggests sun on stone). Falls back gracefully on small
       screens where the .bg-shape layer is hidden anyway. */
    html.theme-navy .bg-shape--top {
      background:
        radial-gradient(ellipse 70% 50% at 30% 0%, rgba(36, 44, 101, 0.07), transparent 70%),
        repeating-linear-gradient(180deg,
          rgba(30, 121, 96, 0.018) 0 24px,
          transparent 24px 56px);
    }

    /* Info code cards: thin forest-green inline-start border, square
       corners — feels like a printed page margin. Hover is opacity-only,
       not the default lift (Aleppo is calm). */
    html.theme-navy .info-card {
      border-radius: 8px;
      border-inline-start: 3px solid #1E7960;
    }
    html.theme-navy .info-card:hover {
      transform: none;
      box-shadow: 0 4px 14px rgba(36, 44, 101, 0.06);
    }

    /* Squarer filter pills — formal print typography rhythm. */
    html.theme-navy .filter-btn { border-radius: 8px; }

    /* =====================================================================
       SHARED THIRD-COLOR + SCROLL INTERACTIVITY
       --accent-red is the cross-tenant accent (live indicator, scroll
       progress, hover tactility). Pomegranate red — distinct from
       #c0392b which is reserved for the cancelled-flight pill.
       --hero-progress (0..1) is updated by home-scroll.js inside
       requestAnimationFrame; the rules below pick it up declaratively.
       ===================================================================== */
    :root {
      --accent-red: #B33A3A;
      --hero-progress: 0;
      /* --title-gradient-start / --title-gradient-end / --title-bg-color are
         admin-tunable (/settings → Operational) and now arrive from
         theme-vars.php, which is linked before this file. The fallbacks here
         are the navy/Aleppo defaults, so the page still renders sanely if that
         endpoint ever fails to load. */
    }

    /* Translucent colored chip behind the title. color-mix gives a
       fixed ~18% tint so the admin only chooses the base hue; the
       transparency is consistent. The wrapper shrinks to the title
       text via inline-block so the chip outline tracks the heading
       width on every viewport. */
    .hero-title-bg {
      display: inline-block;
      background: color-mix(in srgb, var(--title-bg-color, #1E7960) 18%, transparent);
      padding: 10px 32px;
      border-radius: 18px;
      margin-bottom: 16px;
    }
    .hero-title-bg .hero-title {
      margin-bottom: 0;
      display: inline-block;
    }

    /* Hero background image — admin-controlled via /settings (uploaded image,
       opacity, blend mode). Two scopes:
         .hero-top::after    — opacity driven by the slider
         .hero-bottom::after — opacity locked at 0.18 so the lower
                               section stays a quiet decorative wash
                               regardless of how strong the top is set.

       This whole group used to be wrapped in `if ($heroBgUrl !== '')`, with the
       .hero-bottom selector spliced in only when the lower wash was enabled.
       The rules are unconditional now and the CONDITIONS live in the custom
       properties instead: with no hero image theme-vars.php sends
       --hero-isolation: auto and both opacities 0, so the pseudo-elements exist
       but are inert — no stacking context, nothing painted, pointer-events
       already none. Same rendering, static CSS. */
    .hero { position: relative; isolation: var(--hero-isolation, auto); }
    .hero-top::after,
    .hero-bottom::after {
      content: "";
      position: absolute;
      inset: -8% -10%;
      background: var(--hero-bg-image, none) center / cover no-repeat;
      mix-blend-mode: var(--hero-blend, normal);
      pointer-events: none;
      z-index: -1;
      mask-image: radial-gradient(ellipse 75% 65% at center, #000 45%, transparent 95%);
      -webkit-mask-image: radial-gradient(ellipse 75% 65% at center, #000 45%, transparent 95%);
    }
    .hero-top::after    { opacity: var(--hero-opacity, 0); }
    .hero-bottom::after { opacity: var(--hero-lower-opacity, 0); }

    @media (max-width: 640px) {
      .hero-top::after,
      .hero-bottom::after { display: none; }
    }
    @media (prefers-reduced-motion: reduce) {
      .hero-top::after    { opacity: var(--hero-opacity-rm, 0); }
      .hero-bottom::after { opacity: var(--hero-lower-opacity-rm, 0); }
    }

    /* The page-wide background photo (--body-bg-image) is also served by
       theme-vars.php. It is emitted there ONLY when the tenant has one, so the
       `var(--body-bg-image, <gradient>)` fallback in each tenant skin still
       fires for an install that has never uploaded a backdrop. */

    /* Title gradient applies to BOTH tenants. The .title-first /
       .title-rest selectors paint the gradient on the inner spans
       too — home-scroll.js gives them their own transform, which
       creates a render layer that breaks the parent's
       background-clip: text. */
    .hero-title,
    .hero-title .title-first,
    .hero-title .title-rest {
      /* Fallbacks matter here more than anywhere else in this file: the title
         is painted with background-clip:text over `color: transparent`, so an
         UNRESOLVED gradient variable would render the airport's name invisible
         rather than merely off-colour. The two defaults are the navy/Aleppo
         values from ALP_SETTINGS_META; theme-vars.php overrides them per
         tenant. */
      background: linear-gradient(135deg,
                  var(--title-gradient-start, #242C65) 0%,
                  var(--title-gradient-end, #B33A3A) 100%);
      -webkit-background-clip: text;
              background-clip: text;
      color: transparent;
    }

    /* Thin red strip across the very top of the viewport, fills with
       overall scroll position. Logical inset so it fills from the start
       edge in both LTR and RTL. */
    #scroll-progress {
      position: fixed;
      inset-block-start: 0;
      inset-inline-start: 0;
      height: 3px;
      width: 0%;
      background: linear-gradient(90deg, var(--accent-red), rgba(179, 58, 58, 0.5));
      z-index: 100;
      transition: width 0.06s linear;
      pointer-events: none;
    }

    /* Filter pills get a subtle red ring on hover (active state stays in
       the tenant's brand color). */
    .filter-btn:not(.active):hover {
      box-shadow: inset 0 0 0 1px rgba(179, 58, 58, 0.30);
    }

    /* Title halves split apart slightly with scroll. RTL mirrors the
       direction so the visually-leading word still moves outward. */
    .hero-title .title-first,
    .hero-title .title-rest { display: inline-block; will-change: transform; }
    .hero-title .title-first { transform: translateX(calc(var(--hero-progress) * -12px)); }
    .hero-title .title-rest  { transform: translateX(calc(var(--hero-progress) *  12px)); }
    [dir="rtl"] .hero-title .title-first { transform: translateX(calc(var(--hero-progress) *  12px)); }
    [dir="rtl"] .hero-title .title-rest  { transform: translateX(calc(var(--hero-progress) * -12px)); }

    /* Reveal-on-scroll — class added by JS, IntersectionObserver toggles
       .is-visible. Static fallback for no-JS / no-IO. */
    .reveal-on-scroll {
      opacity: 0;
      transform: translateY(20px);
      transition: opacity 0.7s ease-out, transform 0.7s ease-out;
    }
    .reveal-on-scroll.is-visible { opacity: 1; transform: none; }

    /* Tiny red dot before the brand name in the footer — small shared cue. */
    .site-footer .footer-text strong::before {
      content: "";
      display: inline-block;
      width: 6px; height: 6px;
      border-radius: 50%;
      background: var(--accent-red);
      margin-inline-end: 8px;
      vertical-align: 2px;
      opacity: 0.8;
    }

    @media (prefers-reduced-motion: reduce) {
      .hero-title .title-first,
      .hero-title .title-rest { transform: none !important; }
      .reveal-on-scroll { opacity: 1 !important; transform: none !important; }
      #scroll-progress { display: none; }
    }
