/* =====================================================================
   Ibra Travel — site stylesheet
   Base is the approved design reference (brief/design-reference/*.html),
   kept verbatim. Everything after "SITE ADDITIONS" extends that system
   using the same tokens; no new design system, no new hues on Ibra pages.
   ===================================================================== */

:root{
  /* Brand guidelines v1: these three are the entire palette. */
  --blue:#4188DC;
  --white:#FFFFFF;
  --black:#000000;

  /* Tints derived from the three, nothing invented. */
  --blue-ink:#1E4C86;
  --blue-05:rgba(65,136,220,.05);
  --blue-08:rgba(65,136,220,.08);
  --blue-14:rgba(65,136,220,.14);
  --blue-28:rgba(65,136,220,.28);
  --grey:#5C6470;
  --grey-soft:#8A929C;
  --rule:rgba(0,0,0,.10);
  --rule-light:rgba(255,255,255,.18);
  --paper:#F7F9FC;

  /* Optima is the brand display face (brand guidelines p.6). brand/fonts/
     holds Inter + Montserrat, not licensed Optima files, so the documented
     fallback stack is used: Optima renders natively on macOS/iOS, Marcellus
     is the web substitute elsewhere. Drop licensed Optima webfonts into
     assets/fonts/ and add an @font-face block here to upgrade. */
  --display:Optima,"Optima nova","Marcellus",Candara,"Gill Sans MT",Georgia,serif;
  --body:"Source Sans 3",Optima,Candara,"Gill Sans MT",system-ui,-apple-system,sans-serif;

  --pad:clamp(18px,4.6vw,64px);
  --maxw:1280px;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--white);color:var(--black);
  font-family:var(--body);font-size:17px;line-height:1.62;-webkit-font-smoothing:antialiased}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
.wrap{max-width:var(--maxw);margin:0 auto;padding-left:var(--pad);padding-right:var(--pad)}

/* ---------- type ---------- */
.eyebrow{font-size:11.5px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;
  margin:0 0 16px;color:var(--blue);display:flex;align-items:center;gap:10px}
.eyebrow::before{content:"";width:22px;height:1px;background:var(--blue);flex:none}
.eyebrow--plain::before{display:none}
h1,h2,h3,h4{font-family:var(--display);font-weight:500;margin:0}
/* Phase 2 type scale: display sizes up, leading towards 1.0, tracking tightened.
   The gap between display and body (17px) is now wide enough to read hierarchy
   at a glance rather than by comparison. */
h1{font-size:clamp(40px,6.6vw,92px);line-height:1.0;letter-spacing:-.028em}
h2{font-size:clamp(29px,3.5vw,48px);line-height:1.06;letter-spacing:-.022em}
h3{font-size:21px;line-height:1.22;letter-spacing:-.012em}
h4{letter-spacing:-.012em}
.lede{font-size:clamp(16.5px,1.75vw,20px);color:var(--grey);margin:20px 0 0;max-width:52ch;
  line-height:1.55}
/* Longhand, never the `padding` shorthand: these classes are routinely combined
   with .wrap (`class="wrap section"`), and the shorthand wiped out .wrap's own
   horizontal padding, dropping whole sections flush to the viewport edge.
   Scale tightened per the punch-list so sections read as one continuous page. */
.section{padding-top:clamp(44px,5.4vw,76px);padding-bottom:clamp(44px,5.4vw,76px)}
.section--tight{padding-top:clamp(32px,4vw,52px);padding-bottom:clamp(32px,4vw,52px)}
.section--tall{padding-top:clamp(56px,7vw,104px);padding-bottom:clamp(56px,7vw,104px)}

/* ---------- section tone utilities (Phase 2 rhythm) ----------
   No two adjacent sections may share a treatment. Tones are flat colour or
   photography only: no radial/gradient washes. */
.tone-white{background:var(--white)}
.tone-paper{background:var(--paper)}
.tone-dark{background:var(--black);color:var(--white)}
.tone-blue{background:var(--blue);color:var(--white)}
.tone-dark .eyebrow,.tone-blue .eyebrow{color:var(--white)}
.tone-dark .eyebrow::before,.tone-blue .eyebrow::before{background:var(--white)}
.tone-dark h1,.tone-dark h2,.tone-dark h3,.tone-blue h1,.tone-blue h2,.tone-blue h3{color:var(--white)}
.tone-dark .lede{color:rgba(255,255,255,.74)}
.tone-blue .lede{color:var(--white)}

/* ---------- full-bleed + overlap (Phase 2) ----------
   .bleed breaks the container to the viewport edge. Used once on the page. */
.bleed{width:100vw;margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw)}
.bleed-panel{position:relative;min-height:clamp(360px,52vw,620px);display:grid;align-items:end;
  overflow:hidden;background:var(--black)}
.bleed-panel>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* Scrim carries text over photography at 4.5:1. Tuned against the apron and
   in-flight shots, both of which are bright in the upper half. */
.bleed-panel::after{content:"";position:absolute;inset:0;
  background:linear-gradient(0deg,rgba(0,0,0,.88) 0%,rgba(0,0,0,.66) 38%,rgba(0,0,0,.28) 68%,rgba(0,0,0,.12) 100%)}
.bleed-panel>.wrap{position:relative;z-index:1;padding-top:clamp(44px,5.4vw,76px);padding-bottom:clamp(38px,4.6vw,64px);
  width:100%;color:var(--white)}
.bleed-panel h2,.bleed-panel h3{color:var(--white)}
.bleed-panel .lede{color:rgba(255,255,255,.88)}
/* One deliberate overlap: a panel crossing a section boundary. Not a motif. */
.overlap-up{margin-top:clamp(-120px,-9vw,-56px);position:relative;z-index:2}
.section-head{max-width:60ch}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;
  font-family:var(--body);font-size:16px;font-weight:600;padding:14px 26px;border-radius:3px;
  border:1.5px solid transparent;transition:background .2s,color .2s,border-color .2s,transform .2s;cursor:pointer}
.btn svg{width:18px;height:18px;flex:none}
.btn:hover{transform:translateY(-1px)}
.btn--primary{background:var(--blue);color:var(--white)}
.btn--primary:hover{background:var(--blue-ink)}
.btn--outline{border-color:rgba(0,0,0,.22);color:var(--black);background:transparent}
.btn--outline:hover{border-color:var(--blue);color:var(--blue)}
.btn--light{background:var(--white);color:var(--blue)}
.btn--ghost{border-color:var(--rule-light);color:var(--white)}
.btn--ghost:hover{background:rgba(255,255,255,.14)}
.btn--sm{padding:10px 18px;font-size:14.5px}
.btn:focus-visible{outline:2px solid var(--blue);outline-offset:3px}

/* ---------- header ---------- */
.hdr{position:sticky;top:0;z-index:60;background:rgba(255,255,255,.94);
  backdrop-filter:saturate(1.5) blur(10px);border-bottom:1px solid var(--rule)}
.hdr-in{max-width:var(--maxw);margin:0 auto;padding:12px var(--pad);
  display:flex;align-items:center;gap:22px}
.brand{display:flex;align-items:center;gap:11px;margin-right:auto}
.brand svg{width:38px;height:38px;flex:none}
.brand-txt{font-family:var(--display);font-size:23px;line-height:1;letter-spacing:.005em}
.brand-txt i{font-style:normal;color:var(--blue)}
.brand-sub{display:block;font-family:var(--body);font-size:9.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--grey-soft);margin-top:3px}
.nav{display:none;gap:26px;font-size:15.5px;color:var(--black)}
.nav a{padding:6px 0;border-bottom:1.5px solid transparent;transition:border-color .2s,color .2s}
.nav a:hover,.nav a.is-on{color:var(--blue);border-color:var(--blue)}
.hdr-act{display:flex;align-items:center;gap:14px}
.lang{font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--grey)}
.lang:hover{color:var(--blue)}
.hdr .btn--sm{display:none}
@media(min-width:940px){.nav{display:flex}.hdr .btn--sm{display:inline-flex}}

/* ---------- HERO shared ---------- */
.hero{position:relative;border-bottom:1px solid var(--rule)}
.hero .eyebrow{margin-bottom:18px}
/* The hero headline is a headline, not a wall of type: it runs a full step below
   the global h1 scale so the map beside it can hold its own. */
.hero h1{font-size:clamp(32px,4.3vw,56px);line-height:1.06;max-width:17ch}
.hero p.sub{font-size:clamp(16px,1.7vw,19px);color:var(--grey);max-width:46ch;margin:18px 0 0}
.hero-cta{display:flex;flex-wrap:wrap;gap:11px;margin-top:26px}

/* ---------- HERO A: route map ---------- */
.heroA{background:var(--paper)}
.heroA-in{display:grid;grid-template-columns:1fr;gap:clamp(18px,3vw,30px);align-items:center;
  padding-top:clamp(30px,4vw,52px);padding-bottom:clamp(26px,3.4vw,46px)}
@media(min-width:1000px){
  /* 5:7 in the map's favour — it is the section's picture, not a decoration. */
  .heroA-in{grid-template-columns:5fr 7fr;gap:clamp(28px,3.4vw,52px);
    padding-top:clamp(36px,4vw,60px);padding-bottom:clamp(32px,3.6vw,54px)}
}
.heroA-map{min-width:0}
.map{width:100%;height:auto;overflow:visible}
.map .grid-l{stroke:var(--blue-14);stroke-width:1;fill:none}
.map .arc{fill:none;stroke-linecap:round}
.map .arc-main{stroke:var(--blue);stroke-width:2.6;
  stroke-dasharray:var(--L);stroke-dashoffset:var(--L);animation:draw 2s .25s ease-out forwards}
.map .arc-onward{stroke:var(--blue);stroke-width:1.4;opacity:.5;stroke-dasharray:var(--L);
  stroke-dashoffset:var(--L);animation:draw 1.5s ease-out forwards}
/* Level 3. Same hue, a lighter tint and a thinner stroke, so the region arrows
   read as the same network seen further out rather than as a different kind of
   thing. The arrowhead is what says "and beyond": no node is drawn, because a
   region is a direction and not a destination. `color` is set here rather than
   `stroke` on the marker so the marker inherits it through currentColor. */
.map .arc-region{stroke:var(--blue);stroke-width:1.1;opacity:.34;color:var(--blue);
  marker-end:url(#map-tip);stroke-dasharray:var(--L);
  stroke-dashoffset:var(--L);animation:draw 1.4s ease-out forwards}
.map .node{fill:var(--white);stroke:var(--blue);stroke-width:2.4}
.map .node-main{fill:var(--blue);stroke:var(--blue)}
/* transform-box defaults to view-box on SVG, so transform-origin:center was the
   centre of the whole map rather than of the circle: the Mogadishu halo pulsed
   itself clean out of the artwork and into the copy column. */
.map .halo{fill:var(--blue);opacity:.16;transform-box:fill-box;transform-origin:center;
  animation:pulse 3s ease-in-out infinite}
/* Sizes are SVG user units on a 640-wide viewBox, so at the rendered width they
   land at roughly 15px / 12px CSS — legible, which the old map was not. */
.map .lbl{font-family:var(--body);font-size:16px;font-weight:600;fill:var(--black)}
/* The two endpoints are the product; everything else on the map is context.
   They get the size step and the brand blue, and nothing else does, so the
   hierarchy is legible at a glance and not by comparison (punch-list 3.0 §1). */
.map .lbl-end{font-size:23px;font-weight:700;fill:var(--blue-ink);letter-spacing:-.01em}
.map .lbl-region{font-family:var(--body);font-size:12.5px;font-weight:600;fill:var(--blue);
  opacity:.62;letter-spacing:.16em;text-transform:uppercase}
.map .lbl-sm{font-family:var(--body);font-size:11.5px;font-weight:600;fill:var(--grey-soft);
  letter-spacing:.14em;text-transform:uppercase}
.map .lbl-route{font-family:var(--body);font-size:12px;font-weight:600;fill:var(--blue);
  letter-spacing:.1em;text-transform:uppercase}
.map-note{margin:14px 0 0;font-size:13.4px;line-height:1.5;color:var(--grey-soft);max-width:60ch}
/* The whole map scales down with the column, so on a phone the labels need to be
   set larger in user units just to stay readable. */
@media(max-width:760px){
  .map .lbl{font-size:22px}
  .map .lbl-end{font-size:30px}
  .map .lbl-sm{font-size:14px}
  .map .lbl-route{font-size:14px}
  .map .lbl-region{font-size:16px;letter-spacing:.12em}
}
.map .fade{opacity:0;animation:fadein .7s ease-out forwards}
.map .plane{fill:var(--black);offset-rotate:auto;animation:travel 5.5s 1.4s cubic-bezier(.5,0,.5,1) infinite}
@keyframes draw{to{stroke-dashoffset:0}}
@keyframes fadein{to{opacity:1}}
@keyframes pulse{0%,100%{transform:scale(1);opacity:.16}50%{transform:scale(1.7);opacity:.04}}
@keyframes travel{0%{offset-distance:0%;opacity:0}6%{opacity:1}88%{opacity:1}100%{offset-distance:100%;opacity:0}}

/* ---------- HERO B: video ---------- */
.heroB{position:relative;min-height:min(86svh,720px);display:flex;align-items:flex-end;
  overflow:hidden;background:var(--black)}
.heroB-media{position:absolute;inset:0;background:
  linear-gradient(180deg,#1D5FA8 0%,#4188DC 30%,#9CC0E6 56%,#E7EDF3 74%,#B9C0C4 88%,#8E9599 100%)}
.heroB-media::after{content:"";position:absolute;inset:0;
  background:radial-gradient(110% 55% at 68% 66%,rgba(255,255,255,.34),transparent 62%)}
.heroB-scrim{position:absolute;inset:0;background:
  linear-gradient(94deg,rgba(0,0,0,.80) 0%,rgba(0,0,0,.52) 42%,rgba(0,0,0,.06) 76%),
  linear-gradient(0deg,rgba(0,0,0,.72) 0%,transparent 52%)}
.heroB-in{position:relative;z-index:2;width:100%;padding-top:clamp(60px,10vw,120px);
  padding-bottom:clamp(34px,5vw,68px)}
.heroB .eyebrow{color:var(--white)}
.heroB .eyebrow::before{background:var(--white)}
.heroB h1{color:var(--white)}
.heroB p.sub{color:rgba(255,255,255,.86)}
.vnote{position:absolute;right:var(--pad);top:26px;z-index:3;max-width:238px;
  border:1px dashed rgba(255,255,255,.45);border-radius:3px;padding:12px 14px;
  color:rgba(255,255,255,.92);font-size:12px;line-height:1.5;background:rgba(0,0,0,.3)}
.vnote b{display:block;letter-spacing:.14em;text-transform:uppercase;font-size:10px;margin-bottom:5px}
@media(max-width:1000px){.vnote{display:none}}

/* ---------- credibility strip ---------- */
.creds{background:var(--paper);border-bottom:1px solid var(--rule)}
.creds-g{display:grid;grid-template-columns:1fr 1fr;gap:0}
@media(min-width:900px){.creds-g{grid-template-columns:repeat(3,1fr)}}
/* 3 chips on a 2-col mobile grid: let the odd one out span the full width */
@media(max-width:899px){.creds-g>.cred:last-child:nth-child(odd){grid-column:1/-1;border-right:0;padding-right:0}}
.cred{padding:22px clamp(12px,2vw,26px) 22px 0;display:flex;gap:12px;align-items:flex-start;
  border-right:1px solid var(--rule)}
.cred:nth-child(2n){border-right:0;padding-right:0}
@media(min-width:900px){
  .cred{padding:28px clamp(14px,2vw,28px);border-right:1px solid var(--rule)}
  .cred:nth-child(2n){border-right:1px solid var(--rule);padding-right:clamp(14px,2vw,28px)}
  .cred:first-child{padding-left:0}
  .cred:last-child{border-right:0;padding-right:0}
}
.cred svg{width:24px;height:24px;flex:none;stroke:var(--blue);fill:none;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round;margin-top:2px}
.cred p{margin:0;font-size:14.8px;line-height:1.45;font-weight:600}

/* ---------- split feature ---------- */
.split{display:grid;grid-template-columns:1fr;gap:34px;align-items:center}
/* Phase 2: asymmetric by default (5:7). The eye should not find a centre line.
   .split--7-5 flips the weight, .split--4-8 is the harder ratio, .split--even
   is the opt-out for the rare case that genuinely needs 50:50. */
@media(min-width:960px){
  .split{grid-template-columns:5fr 7fr;gap:clamp(44px,6vw,84px)}
  .split--7-5{grid-template-columns:7fr 5fr}
  .split--4-8{grid-template-columns:4fr 8fr}
  .split--8-4{grid-template-columns:8fr 4fr}
  .split--even{grid-template-columns:1fr 1fr}
}
.split--stretch{align-items:stretch}
.split--wide{grid-template-columns:1fr}
@media(min-width:960px){.split--wide{grid-template-columns:1.05fr .95fr}}
/* photography inside a split */
.shot{position:relative;overflow:hidden;background:var(--paper)}
.shot img{width:100%;height:100%;object-fit:cover;display:block}
.shot picture{display:block;width:100%;height:100%}
.shot--tall{aspect-ratio:4/5}
.shot--wide{aspect-ratio:16/10}
.shot--square{aspect-ratio:1/1}

/* ---------- SalamAir panel on home ---------- */
/* The card sits on brand blue, so it darkens rather than tints: white type on the
   card measures 5.1:1, comfortably past 4.5:1. */
.sa-card{border:1px solid rgba(255,255,255,.34);padding:clamp(20px,3vw,32px);
  background:rgba(0,0,0,.18)}
.sa-pair{display:flex;justify-content:space-between;align-items:flex-end;gap:16px}
.sa-city{font-family:var(--display);font-size:clamp(22px,3vw,32px);line-height:1.08}
.sa-code{font-size:11px;letter-spacing:.2em;color:rgba(255,255,255,.9);margin-top:5px}
.sa-line{position:relative;height:1px;background:var(--rule-light);margin:22px 0}
.sa-line::before,.sa-line::after{content:"";position:absolute;top:50%;width:6px;height:6px;
  border-radius:50%;background:var(--blue);transform:translateY(-50%)}
.sa-line::before{left:0}.sa-line::after{right:0}
/* Mogadishu is the origin for this audience, so the aircraft flies out to
   Muscat, turns, and comes back. Round trip, then loop. */
/* Punch-list 4.0 section 4: at 16px this did not register as an aircraft at
   all, it read as a speck on the rule. The glyph is sized explicitly rather
   than left to the SVG's intrinsic default, so the span and the artwork agree.
   Shared with the identical route bar on salamair.html, which had the same
   problem — scope this to `#salamair .sa-plane` if the two should differ. */
.sa-plane{position:absolute;top:50%;left:0;width:30px;height:30px;color:var(--white);
  transform:translate(-50%,-50%) rotate(90deg);animation:saRound 11s ease-in-out infinite}
.sa-plane svg{display:block;width:100%;height:100%}
@keyframes saRound{
  0%  {left:0;   opacity:0; transform:translate(-50%,-50%) rotate(90deg)}
  5%  {opacity:1}
  42% {left:100%;opacity:1; transform:translate(-50%,-50%) rotate(90deg)}
  47% {left:100%;opacity:0; transform:translate(-50%,-50%) rotate(90deg)}
  53% {left:100%;opacity:0; transform:translate(-50%,-50%) rotate(-90deg)}
  58% {opacity:1}
  95% {left:0;   opacity:1; transform:translate(-50%,-50%) rotate(-90deg)}
  100%{left:0;   opacity:0; transform:translate(-50%,-50%) rotate(-90deg)}
}
@media(prefers-reduced-motion:reduce){
  .sa-plane{animation:none;left:50%;opacity:1}
}
.sa-facts{list-style:none;margin:0;padding:0}
.sa-facts li{display:flex;justify-content:space-between;gap:18px;padding:15px 0;
  border-bottom:1px solid var(--rule-light);font-size:15.5px}
.sa-facts li:first-child{border-top:1px solid var(--rule-light)}
.sa-facts .k{color:var(--white);letter-spacing:.06em;font-size:14px}
.sa-facts .v{font-weight:600;text-align:right}

/* ---------- services ---------- */
.svc-g{display:grid;grid-template-columns:1fr;gap:clamp(12px,1.6vw,20px);margin-top:clamp(26px,3vw,40px)}
@media(min-width:680px){.svc-g{grid-template-columns:1fr 1fr}}
@media(min-width:1040px){
  .svc-g{grid-template-columns:repeat(3,1fr)}
  /* One column dropped half a step. Enough to break the grid's flatness without
     turning into a motif. */
  .svc-g>.svc:nth-child(3n+2){transform:translateY(20px)}
  .svc-g>.svc:nth-child(3n+2):hover{transform:translateY(14px)}
}
.svc{position:relative;display:block;color:inherit;background:var(--white);
  border:1px solid var(--rule);padding:clamp(24px,2.8vw,34px);overflow:hidden;
  transition:transform .28s ease,box-shadow .28s ease,border-color .28s ease}
/* The blue edge draws in on hover: the card acknowledges the pointer instead of
   just tinting. */
.svc::before{content:"";position:absolute;left:0;top:0;height:3px;width:0;
  background:var(--blue);transition:width .32s ease}
.svc:hover{transform:translateY(-6px);border-color:var(--blue-28);
  box-shadow:0 16px 40px rgba(30,76,134,.13)}
.svc:hover::before{width:100%}
.svc:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
/* Phase 2: icons sit inline at text scale with no container. No chips. */
.svc-ico{display:block;margin-bottom:18px}
.svc-ico svg{width:34px;height:34px;stroke:var(--blue);fill:none;stroke-width:1.4;
  stroke-linecap:round;stroke-linejoin:round}
.svc h3{margin-bottom:10px;font-size:clamp(22px,2.1vw,26px);font-weight:600;line-height:1.15}
.svc p{margin:0;font-size:15.6px;color:var(--grey)}
/* Services page: the same card, sized for a page that is about these six things
   rather than a page that mentions them. Bigger icon, bigger title, more air,
   and the cards reveal one after another instead of the grid arriving in one
   block — the --i on each card staggers it. */
.svc-g--feature{margin-top:clamp(20px,2.4vw,32px)}
.svc-g--feature .svc{padding:clamp(28px,3.2vw,42px)}
.svc-g--feature .svc-ico{margin-bottom:22px}
.svc-g--feature .svc-ico svg{width:46px;height:46px;stroke-width:1.3}
.svc-g--feature .svc h2{margin:0 0 12px;font-family:var(--display);font-weight:500;
  font-size:clamp(25px,2.5vw,31px);line-height:1.12;letter-spacing:-.016em}
.svc-g--feature .svc p{font-size:16px;line-height:1.6}
.svc-g--feature .svc.rv{transition-delay:calc(var(--i,0) * 70ms)}
@media(min-width:1040px){
  /* the home page drops the middle column half a step; keep the motif */
  .svc-g--feature>.svc:nth-child(3n+2){transform:translateY(20px)}
  .svc-g--feature>.svc:nth-child(3n+2):hover{transform:translateY(14px)}
  .svc-g--feature>.svc.rv:nth-child(3n+2){transform:translateY(36px)}
  .svc-g--feature>.svc.rv.in:nth-child(3n+2){transform:translateY(20px)}
}

/* ---------- cargo ---------- */
.cargo{background:var(--paper);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.cargo-panel{background:var(--blue);color:var(--white);padding:clamp(26px,4vw,44px);border-radius:3px}
.cargo-panel h3{font-size:clamp(21px,2.5vw,28px);margin-bottom:12px}
.cargo-panel p{color:rgba(255,255,255,.88);font-size:15.6px;margin:0 0 24px}

/* ---------- contact ---------- */
.contact{background:var(--white)}
.offices{display:grid;grid-template-columns:1fr;gap:0;margin-top:52px;border-top:1px solid var(--rule)}
@media(min-width:820px){.offices{grid-template-columns:repeat(3,1fr);column-gap:40px}}
.office{padding:22px 0;border-bottom:1px solid var(--rule)}
@media(min-width:820px){.office{border-bottom:0}}
.office h4{font-size:19px;margin-bottom:6px}
.office p{margin:0;font-size:14.6px;color:var(--grey);line-height:1.55}
.office p+p{margin-top:9px}
/* The four numbers are equals; this note explains why, so it sits under
   them at a smaller size rather than beside one of them. */
.office-note{font-size:13.4px!important;color:var(--grey-soft)!important}
.office .todo{color:var(--blue);font-style:italic}

/* ---------- footer ---------- */
.ftr{background:var(--black);color:rgba(255,255,255,.62);font-size:14.5px}
.ftr-g{display:grid;grid-template-columns:1fr;gap:30px;padding-top:clamp(40px,5vw,64px)}
@media(min-width:820px){.ftr-g{grid-template-columns:1.6fr 1fr 1fr}}
.ftr h5{font-family:var(--display);font-weight:500;font-size:17px;color:var(--white);margin:0 0 14px}
.ftr a:hover{color:var(--white)}
.ftr ul{list-style:none;margin:0;padding:0}
.ftr li{margin-bottom:9px}
.ftr-btm{border-top:1px solid var(--rule-light);margin-top:34px;padding:20px 0 34px;
  display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between;font-size:13px}

/* ---------- reveal ---------- */
.rv{opacity:0;transform:translateY(16px);transition:opacity .7s ease,transform .7s ease}
.rv.in{opacity:1;transform:none}

@media(prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  .rv{opacity:1;transform:none}
  .map .arc-main,.map .arc-onward,.map .arc-region{stroke-dashoffset:0}
  .map .fade{opacity:1}
}

/* SalamAir page only: the airline's colours lead, Ibra keeps the frame.
   Hex values are the confirmed ones from SalamAir Brand Guidelines p.23
   (assets/salamir-brand-guidelines.pdf), replacing the mockup placeholders. */
:root{
  --sa-green:#81B43F;   /* Mountainside Green, Pantone 377C */
  --sa-teal:#00ACCA;    /* Sea Shallows Blue, Pantone 3125C */
  --sa-lime:#D6E028;    /* Leaf Green Bright, Pantone 382C */
  --sa-deep:#00506B;    /* Deep Sea Blue, Pantone 2955C */
  --sa-slate:#B7E4E9;   /* Mountain Slate Blue, Pantone 552C */
  --sa-sand:#E5E2DA;    /* Masonry Grey */
}
.sap-hero{position:relative;overflow:hidden;background:var(--sa-sand);
  border-bottom:1px solid var(--rule)}
.sap-hero .eyebrow{color:var(--sa-deep)}
.sap-hero .eyebrow::before{background:var(--sa-green)}
.sap-in{display:grid;grid-template-columns:1fr;gap:34px;align-items:center;
  padding-top:clamp(38px,5vw,70px);padding-bottom:clamp(38px,5vw,70px)}
@media(min-width:1000px){.sap-in{grid-template-columns:1.02fr .98fr;gap:56px}}
.sap-band{height:5px;background:linear-gradient(90deg,var(--sa-green) 0 34%,var(--sa-lime) 34% 62%,var(--sa-teal) 62% 100%)}
.co-brand{display:flex;align-items:center;gap:16px;margin-bottom:26px;flex-wrap:wrap}
.co-brand .lock{display:flex;align-items:center;gap:14px;padding:10px 16px;border:1px solid var(--rule);border-radius:3px;background:var(--white)}
.co-brand svg.mark,.co-brand img.mark{width:32px;height:32px;object-fit:contain}
.co-brand .x{color:var(--grey-soft);font-size:13px}
.sa-word{font-family:var(--display);font-size:22px;color:var(--sa-green);letter-spacing:.01em}
.sa-word span{color:var(--sa-teal)}
.sap-note{font-size:12px;color:var(--grey-soft)}
.btn--sa{background:var(--sa-deep);color:#fff}
.btn--sa:hover{background:#063f54}
.btn--sa-out{border-color:rgba(0,80,107,.35);color:var(--sa-deep)}
.btn--sa-out:hover{background:rgba(0,80,107,.06);border-color:var(--sa-deep)}
.btn--sa:focus-visible,.btn--sa-out:focus-visible{outline-color:var(--sa-deep)}
.sap-card{border:1px solid var(--rule);border-radius:4px;overflow:hidden;background:var(--white)}
.sap-card-top{background:var(--sa-deep);color:#fff;padding:clamp(22px,3vw,30px)}
.sap-card-top .sa-city{font-family:var(--display);font-size:clamp(22px,3vw,31px)}
.sap-card-top .sa-code{color:rgba(255,255,255,.6)}
.sap-card-top .sa-line{background:rgba(255,255,255,.24)}
.sap-card-top .sa-line::before,.sap-card-top .sa-line::after{background:var(--sa-lime)}
.sap-card-body{padding:clamp(20px,3vw,28px)}
.sap-card-body ul{list-style:none;margin:0;padding:0}
.sap-card-body li{display:flex;justify-content:space-between;gap:16px;padding:13px 0;
  border-bottom:1px solid var(--rule);font-size:15.4px}
.sap-card-body li:last-child{border-bottom:0}
.sap-card-body .k{color:var(--grey)}
.sap-card-body .v{font-weight:600;text-align:right}
.sap-steps{display:grid;grid-template-columns:1fr;gap:1px;background:var(--rule);
  border:1px solid var(--rule);margin-top:42px}
@media(min-width:760px){.sap-steps{grid-template-columns:repeat(3,1fr)}}
.step{background:var(--white);padding:clamp(22px,3vw,30px)}
.step-n{font-family:var(--display);font-size:13px;letter-spacing:.16em;color:var(--sa-deep);
  display:block;margin-bottom:12px}
.step h3{margin-bottom:7px}
.step p{margin:0;color:var(--grey);font-size:15.2px}
.sap-onward{background:var(--sa-deep);color:#fff}
.sap-onward .eyebrow{color:var(--sa-lime)}
.sap-onward .eyebrow::before{background:var(--sa-lime)}
.sap-onward h2{color:#fff}
.sap-onward .lede{color:rgba(255,255,255,.74)}
.reg-g{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:rgba(255,255,255,.16);
  border:1px solid rgba(255,255,255,.16);margin-top:40px}
@media(min-width:760px){.reg-g{grid-template-columns:repeat(4,1fr)}}
.reg{background:var(--sa-deep);padding:24px 20px}
.reg b{font-family:var(--display);font-size:19px;font-weight:500;display:block;margin-bottom:5px}
.reg span{font-size:13.6px;color:rgba(255,255,255,.62)}
.sap-cargo{background:var(--paper);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.sap-cargo .cargo-panel{background:var(--sa-deep)}
.sap-cargo .btn--light{color:var(--sa-deep)}

/* =====================================================================
   SalamAir page — Phase 4 additions
   ===================================================================== */

/* ---------- hero: the home page's own service card, on a light ground ----------
   Punch-list 4 section 2.1 asks for the same component as the home page rather
   than a second design. .sa-card is that component; everything here is the one
   modifier that lets it sit on sand instead of brand blue. Nothing is
   re-laid-out, so the two stay in step if either changes. */
/* Stretched to match the copy column, so the contents centre rather than
   sitting at the top with a hole under them. */
.sa-card--light{border-color:rgba(0,80,107,.20);background:var(--white);color:var(--black);
  display:flex;flex-direction:column;justify-content:center}
.sa-card--light .sa-city{color:var(--sa-deep)}
.sa-card--light .sa-code{color:var(--grey-soft)}
.sa-card--light .sa-line{background:var(--rule)}
.sa-card--light .sa-line::before,.sa-card--light .sa-line::after{background:var(--sa-green)}
.sa-card--light .sa-plane{color:var(--sa-deep)}
.sa-card--light .sa-facts li{border-bottom-color:var(--rule)}
.sa-card--light .sa-facts li:first-child{border-top-color:var(--rule)}
.sa-card--light .sa-facts .k{color:var(--grey)}
.sa-card--light .sa-facts .v{color:var(--black)}
/* The two hero columns now finish level. The headline was long enough that the
   copy column used to overrun the card and centre-alignment left a gap under
   it; stretched, with the copy spread, they square up top and bottom. */
.sap-in{align-items:stretch}
.sap-copy{display:flex;flex-direction:column;justify-content:space-between;gap:clamp(20px,2.6vw,32px)}
/* One step down from the home page's display scale: this headline is a
   statement of fact rather than the site's opening line, and at the full
   size it ran to three lines and dragged the column past the card. */
.sap-hero h1{font-size:clamp(34px,5vw,68px)}
.sap-copy .hero-cta{margin-top:0}

/* ---------- appointment: office photograph ---------- */
.ap-copy{display:flex;flex-direction:column;justify-content:center}
.ap-shot{margin:0;position:relative;overflow:hidden;border-radius:3px;background:var(--paper);
  min-height:clamp(240px,30vw,420px)}
.ap-shot picture{display:block;width:100%;height:100%}
.ap-shot img{width:100%;height:100%;object-fit:cover;display:block}

/* ---------- full-bleed aircraft band ---------- */
.sky-band{position:relative;overflow:hidden;background:var(--sa-slate);
  height:clamp(170px,25vw,330px)}
.sky-band picture{position:absolute;inset:0;display:block}
.sky-band img{width:100%;height:100%;object-fit:cover;display:block}

/* ---------- page hero: shared full-bleed interior hero ----------
   The one hero for Services, Cargo and Contact (phase-4 section 5.1). Built
   here on the Services page, which is the first of the three; the other two
   copy that block and swap the picture, the h1, the subtext and the buttons.

   Contract:
     .page-hero           the section; height and the fallback colour
     .page-hero-media     the <picture>, full-bleed behind everything
     .page-hero-scrim     the gradient that keeps the copy legible
     .page-hero-in        the copy column, above the scrim

   Deliberately NOT .cta-band with different padding: that one closes a page
   with an h2 and an optional film, this one opens a page with an h1 and a
   priority image. They share the technique, not the component, so changing the
   feel of a closing CTA cannot silently restyle three page headers.

   The image is fetchpriority="high" and not lazy: it is the LCP element. */
.page-hero{position:relative;overflow:hidden;background:var(--blue-ink);color:var(--white);
  display:flex;align-items:flex-end;min-height:clamp(360px,44vw,540px)}
.page-hero-media{position:absolute;inset:0}
.page-hero-media picture{position:absolute;inset:0;display:block}
.page-hero-media img{width:100%;height:100%;object-fit:cover;display:block}
/* Measured against the hero image, not guessed — see the note on .cta-band-scrim.
   Weighted to the bottom-left, where the copy sits, and thin over the aircraft. */
.page-hero-scrim{position:absolute;inset:0;background:
  linear-gradient(92deg,rgba(6,20,34,.80) 0%,rgba(6,20,34,.66) 38%,rgba(6,20,34,.24) 70%,rgba(6,20,34,.05) 100%),
  linear-gradient(0deg,rgba(6,20,34,.74) 0%,rgba(6,20,34,.22) 46%,rgba(6,20,34,0) 78%)}
@media(max-width:820px){
  .page-hero-scrim{background:linear-gradient(0deg,rgba(6,20,34,.92) 0%,rgba(6,20,34,.78) 52%,rgba(6,20,34,.52) 100%)}
}
.page-hero-in{position:relative;z-index:1;width:100%;
  padding-top:clamp(48px,6vw,84px);padding-bottom:clamp(40px,5vw,64px)}
.page-hero-in .eyebrow{color:var(--white)}
.page-hero-in .eyebrow::before{background:var(--white)}
.page-hero-in h1{color:var(--white);max-width:17ch;font-size:clamp(34px,5.2vw,70px)}
.page-hero-in .sub{color:rgba(255,255,255,.92);max-width:48ch}
.page-hero-in .hero-cta{margin-top:clamp(22px,3vw,32px)}
.page-hero .btn--light{background:var(--white);color:var(--blue-ink)}
.page-hero .btn--light:hover{background:var(--paper)}
.page-hero .btn--ghost{border-color:rgba(255,255,255,.5);color:var(--white)}
.page-hero .btn--ghost:hover{background:rgba(255,255,255,.16)}

/* ---------- CTA band: reusable closing section over a film or a still ----------
   Extracted from the SalamAir booking section so it can close any page
   (salamair-3.0-revisions section 3). It is a plain block of markup, not a
   template — this site has no build step — so "reusable" means: copy the
   <section class="cta-band"> block, swap the poster, the <source data-src>,
   the heading, the copy and the two buttons. Nothing is page-specific.

   Contract:
     .cta-band            the section; sets the height and the fallback colour
     .cta-band-media      poster + optional <video data-ambient>
     .cta-band-scrim      the gradient that keeps the copy legible
     .cta-band-in         the copy column, sits above the scrim
     .cta-band--sa        modifier, SalamAir page only
   The video is optional: drop the <video> and the poster carries it.
   With one, site.js attaches it only above 900px, with motion allowed, and off
   save-data / 2g — the same discipline as the home page hero.

   The base component is Ibra's. SalamAir's colours are quarantined in the
   --sa modifier, because the rule everywhere else on this site is that the
   airline's palette leads on the SalamAir page and nowhere else — a component
   that dragged deep sea blue onto the Contact page would break that the first
   time it was reused. The scrim is deliberately shared: at these alphas it is
   effectively neutral, and keeping one means the contrast measurement behind
   it stays valid on every page that uses it. */
.cta-band{position:relative;overflow:hidden;background:var(--blue-ink);color:var(--white);
  display:flex;align-items:center;min-height:clamp(420px,50vw,600px)}
.cta-band--sa{background:var(--sa-deep)}
.cta-band-media{position:absolute;inset:0}
.cta-band-media picture{position:absolute;inset:0;display:block}
.cta-band-media img,.cta-band-media video{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}
/* Measured, not guessed: the composited background under every line here was
   sampled against the poster frame and the worst line comes out well past the
   4.5:1 floor the rest of the site holds to. The film is brighter in places
   than the poster, hence the weight on the left where the copy sits. */
.cta-band-scrim{position:absolute;inset:0;background:
  linear-gradient(96deg,rgba(0,28,40,.92) 0%,rgba(0,28,40,.86) 34%,rgba(0,28,40,.46) 62%,rgba(0,28,40,.12) 100%),
  linear-gradient(0deg,rgba(0,28,40,.40) 0%,rgba(0,28,40,.06) 55%,rgba(0,28,40,0) 100%)}
@media(max-width:820px){
  .cta-band-scrim{background:linear-gradient(0deg,rgba(0,32,44,.94) 0%,rgba(0,32,44,.86) 55%,rgba(0,32,44,.72) 100%)}
}
.cta-band-in{position:relative;z-index:1;width:100%;
  padding-top:clamp(52px,6vw,88px);padding-bottom:clamp(52px,6vw,88px)}
.cta-band-in h2{color:var(--white);max-width:16ch}
.cta-band-in .lede{color:rgba(255,255,255,.92);max-width:52ch}
.cta-band-in .hero-cta{margin-top:clamp(22px,3vw,32px)}
/* Optional supporting line under the lede — smaller, so it reads as an aside
   to the CTA rather than competing with it. */
.cta-band-note{margin:14px 0 0;font-size:15.4px;color:rgba(255,255,255,.82)}
/* The primary is white, not a dark brand colour: on a dark scrim the filled
   button was the same colour twice and vanished. */
.cta-band .btn--light{background:var(--white);color:var(--blue-ink)}
.cta-band .btn--light:hover{background:var(--paper);color:var(--blue-ink)}
.cta-band .btn--ghost{border-color:rgba(255,255,255,.5);color:var(--white)}
.cta-band .btn--ghost:hover{background:rgba(255,255,255,.16)}
.cta-band--sa .btn--light{color:var(--sa-deep)}
.cta-band--sa .btn--light:hover{background:var(--sa-lime);color:var(--sa-deep)}

/* ---------- cargo panel: the route line comes back ----------
   The site's signature device, reused here because cargo genuinely travels on
   this exact sector (punch-list 4 section 2.9). */
.sap-cargo .cargo-panel{display:flex;flex-direction:column;justify-content:center}
.cargo-panel-note{margin:22px 0 0!important;color:rgba(255,255,255,.88)}
.sap-cargo .cargo-panel .sa-line{background:rgba(255,255,255,.28)}
.sap-cargo .cargo-panel .sa-line::before,.sap-cargo .cargo-panel .sa-line::after{background:var(--sa-lime)}
.sap-cargo .cargo-panel .sa-code{color:rgba(255,255,255,.7)}

/* ---------- network map ----------
   Drawn by site.js from the destination list in the markup. The list is the
   data, the accessible version and the no-JS version all at once, so it is
   always visible rather than being a hidden fallback. */
.netmap-sec{background:var(--paper);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
/* The head and the growth panel share the row the head used to have to itself.
   Below 960px the panel drops under the heading rather than beside it, so the
   map never gets squeezed by it on a phone. */
.netmap-head{display:grid;grid-template-columns:1fr;gap:clamp(24px,3vw,40px);align-items:start}
@media(min-width:960px){
  .netmap-head{grid-template-columns:1.06fr .94fr;gap:clamp(40px,5vw,76px);align-items:center}
}
.netmap-head .section-head{margin:0}
/* .proof is the home page's callout, reused as the punch-list asks. Only the
   size is relaxed: this panel carries two sentences where the original carries
   one, and at the display size it shouted over the heading beside it. */
.netmap-growth .proof{font-size:clamp(16.4px,1.55vw,19px);line-height:1.46;letter-spacing:-.008em}
.growth-src{margin:12px 0 0;padding-left:18px;font-size:12.8px;color:var(--grey-soft)}
.growth-src a{border-bottom:1px solid rgba(0,0,0,.18);padding-bottom:1px}
.growth-src a:hover{color:var(--sa-deep);border-bottom-color:var(--sa-deep)}
.growth-src a:focus-visible{outline:2px solid var(--sa-deep);outline-offset:3px}
.netmap{margin-top:clamp(26px,3.4vw,44px)}
/* At ~44 destinations the labels need roughly 860px before they stop fighting
   each other, which is the failure the source graphic already has. Below that
   the map scrolls sideways rather than shrinking into illegibility, and the
   grouped list underneath carries the same information at any width. */
.netmap-scroll{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;
  background:var(--white);border:1px solid var(--rule);border-radius:3px}
.netmap-canvas{min-width:860px}
.netmap-canvas svg{display:block;width:100%;height:auto}
.netmap-hint{display:none;margin:10px 0 0;font-size:13.2px;color:var(--grey-soft)}
@media(max-width:900px){.netmap-hint{display:block}}

.netmap svg .nm-arc{fill:none;stroke:var(--blue);stroke-width:1.1;opacity:.42;stroke-linecap:round}
.netmap svg .nm-arc--main{stroke:var(--sa-deep);stroke-width:2.6;opacity:1}
.netmap svg .nm-arc--seasonal{stroke:var(--sa-green);stroke-dasharray:5 4;opacity:.85}
.netmap svg .nm-arc--salalah{stroke:var(--sa-teal);stroke-width:1.2;opacity:.75}
.netmap svg .nm-dot{fill:var(--white);stroke:var(--blue);stroke-width:1.6}
.netmap svg .nm-dot--seasonal{stroke:var(--sa-green)}
.netmap svg .nm-hub{fill:var(--sa-deep);stroke:var(--sa-deep)}
.netmap svg .nm-halo{fill:var(--sa-deep);opacity:.14}
.netmap svg .nm-origin{fill:var(--blue);stroke:var(--blue)}
.netmap svg .nm-origin-halo{fill:var(--blue);opacity:.16}
.netmap svg .nm-lead{stroke:var(--grey-soft);stroke-width:.7;opacity:.5}
/* paint-order puts a white casing under every label, so an arc or another
   city's dot passing behind one cannot cut through the word. This is what
   keeps the Muscat/Suhar/Sharjah cluster readable, which is exactly where
   the source graphic gives up. */
.netmap svg .nm-lbl{font-family:var(--body);font-size:12px;font-weight:600;fill:#4A525E;
  paint-order:stroke;stroke:var(--white);stroke-width:3.2px;stroke-linejoin:round}
.netmap svg .nm-lbl--end{stroke-width:4.5px}
.netmap svg .nm-lbl--seasonal{fill:var(--sa-green)}
/* The two the client asked to lead. Salalah is deliberately not among them:
   it renders bold on the source map as a second hub and the instruction was to
   take that emphasis away. */
.netmap svg .nm-lbl--end{font-size:17px;font-weight:700;fill:var(--sa-deep)}
.netmap svg .nm-lbl--origin{fill:var(--blue-ink)}
.netmap svg .nm-land{fill:rgba(65,136,220,.07)}

.netmap-legend{list-style:none;display:flex;flex-wrap:wrap;gap:8px 26px;
  margin:16px 0 0;padding:0;font-size:13.4px;color:var(--grey)}
.netmap-legend li{display:flex;align-items:center;gap:9px}
.netmap-legend .key{width:26px;height:0;flex:none;border-top:2px solid var(--blue);opacity:.55}
.netmap-legend .key--seasonal{border-top:2px dashed var(--sa-green);opacity:1}
.netmap-legend .key--salalah{border-top:2px solid var(--sa-teal);opacity:1}

/* The rule and the spacing move to the <details> so the toggle sits on the
   line whether the list is open or shut. */
.netmap-disclosure{margin-top:clamp(24px,3vw,38px);border-top:1px solid var(--rule)}
.netmap-toggle{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:9px;
  padding:clamp(15px,1.9vw,20px) 0;font-size:15px;font-weight:600;color:var(--sa-deep)}
.netmap-toggle::-webkit-details-marker{display:none}
.netmap-toggle::marker{content:""}
.netmap-toggle svg{width:15px;height:15px;transition:transform .2s ease}
.netmap-disclosure[open] .netmap-toggle svg{transform:rotate(180deg)}
.netmap-toggle:hover{color:var(--blue-ink)}
.netmap-toggle:focus-visible{outline:2px solid var(--sa-deep);outline-offset:3px}
.netmap-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:clamp(18px,2.4vw,30px);padding-bottom:clamp(10px,1.6vw,18px)}
.netgroup h4{font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--sa-deep);margin:0 0 10px;font-family:var(--body)}
.netgroup ul{list-style:none;margin:0;padding:0}
.netgroup li{font-size:15.2px;line-height:1.6;color:var(--grey)}
.netgroup li[data-role="hub"],.netgroup li[data-role="origin"]{font-weight:600;color:var(--black)}
.netgroup li[data-type="seasonal"]{color:var(--sa-green)}
.netmap-src{margin:clamp(20px,2.6vw,28px) 0 0;font-size:13px;color:var(--grey-soft);max-width:70ch}

@media(prefers-reduced-motion:reduce){
  .netmap svg .nm-arc{animation:none!important;stroke-dashoffset:0!important}
}

/* =====================================================================
   SITE ADDITIONS — built from the tokens above, same spacing rhythm.
   ===================================================================== */

/* skip link */
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--blue);color:var(--white);
  padding:12px 18px;font-size:15px;font-weight:600}
.skip:focus{left:0}

/* header: real logo asset in place of the mockup's inline SVG */
.brand img.mark{width:38px;height:38px;flex:none;object-fit:contain}

/* header: mobile navigation (the mockup hides nav under 940px; this audience
   is majority mobile, so the same links open in a panel instead) */
.nav-toggle{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  width:42px;height:42px;padding:0;border:1px solid var(--rule);border-radius:3px;
  background:var(--white);color:var(--black);cursor:pointer}
.nav-toggle svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.7;stroke-linecap:round}
.nav-toggle:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
.nav-toggle .ico-close{display:none}
.nav-toggle[aria-expanded="true"] .ico-open{display:none}
.nav-toggle[aria-expanded="true"] .ico-close{display:block}
.nav-m{display:none;border-top:1px solid var(--rule);background:var(--white)}
.nav-m.is-open{display:block}
.nav-m ul{list-style:none;margin:0;padding:6px var(--pad) 18px}
.nav-m li{border-bottom:1px solid var(--rule)}
.nav-m li:last-child{border-bottom:0}
.nav-m a{display:block;padding:14px 0;font-size:17px}
.nav-m a.is-on{color:var(--blue)}
.nav-m .nav-m-cta{padding:16px var(--pad) 22px;border-top:1px solid var(--rule);
  display:flex;flex-wrap:wrap;gap:10px}
@media(min-width:940px){.nav-toggle,.nav-m{display:none!important}}

/* page hero for the pages without a dedicated mockup — heroA minus the map */
.hero--page{background:var(--paper)}
.hero--page .hero-in{padding-top:clamp(38px,5vw,72px);padding-bottom:clamp(34px,4.4vw,60px);
  max-width:64ch}
.hero--page h1{max-width:18ch}
.hero--page .lede{max-width:56ch}

/* prose blocks (about, services, cargo bodies) */
.prose{margin:0;color:var(--grey);font-size:16.4px;max-width:62ch}
.prose+.prose{margin-top:16px}
.stack>*+*{margin-top:clamp(38px,4.6vw,64px)}
.quote{border-left:2px solid var(--blue);padding-left:clamp(18px,2.6vw,30px)}
.quote p:first-child{margin:0;font-size:clamp(17px,2vw,21px);font-family:var(--display);line-height:1.45}
.quote p+p{margin:14px 0 0;color:var(--grey);font-size:15.6px}
.todo{color:var(--blue);font-style:italic}
/* The marker is set in --blue, which IS the tone-blue background — on
   contact.html the opening-hours placeholder rendered as an invisible line that
   read "Opening hours:" and then stopped. On blue it becomes a chip instead, so
   an unresolved [FACT TO CONFIRM] still cannot ship unnoticed. */
.tone-blue .todo{color:var(--white);font-style:italic;
  background:rgba(0,0,0,.30);padding:1px 8px;border-radius:2px}
.note{font-size:13.4px;color:var(--grey-soft);margin:10px 0 0}

/* service detail rows (services.html) */
.svc-list{margin-top:46px;border-top:1px solid var(--rule)}
.svc-row{display:grid;grid-template-columns:1fr;gap:8px;padding:clamp(24px,3vw,34px) 0;
  border-bottom:1px solid var(--rule)}
@media(min-width:820px){.svc-row{grid-template-columns:46px 1fr 1.25fr;gap:clamp(20px,3vw,40px);align-items:start}}
.svc-row .svc-ico{margin-bottom:6px}
.svc-row h2{font-size:clamp(22px,2.5vw,28px)}
.svc-row p{margin:0;color:var(--grey);font-size:16px}

/* updates (v2) */
.upd-g{display:grid;grid-template-columns:1fr;gap:1px;background:var(--rule);
  border:1px solid var(--rule);margin-top:44px}
@media(min-width:760px){.upd-g{grid-template-columns:repeat(3,1fr)}}
.upd{background:var(--white);padding:clamp(22px,3vw,30px)}
.upd h3{margin-bottom:8px}
.upd p{margin:0;color:var(--grey);font-size:15.4px}

/* partners (v2) */
.partners{background:var(--paper);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}

/* watch-the-announcement module (build brief section 9) */
.watch{display:grid;grid-template-columns:1fr;gap:clamp(22px,3vw,40px);align-items:center}
@media(min-width:900px){.watch{grid-template-columns:1.05fr .95fr}}
.watch-frame{position:relative;border:1px solid var(--rule);border-radius:4px;overflow:hidden;
  background:var(--black)}
.watch-frame img{width:100%;height:auto;opacity:.82}
.watch-play{position:absolute;inset:0;display:grid;place-items:center;width:100%;height:100%;
  border:0;background:transparent;cursor:pointer;color:var(--white)}
.watch-play span{display:grid;place-items:center;width:74px;height:74px;border-radius:50%;
  background:rgba(0,0,0,.55);border:1.5px solid rgba(255,255,255,.7);transition:background .2s,transform .2s}
.watch-play svg{width:26px;height:26px;fill:currentColor;margin-left:3px}
.watch-play:hover span{background:rgba(0,0,0,.72);transform:scale(1.04)}
.watch-play:focus-visible{outline:2px solid var(--white);outline-offset:-6px}
.watch-play[disabled]{cursor:not-allowed}
.watch-play[disabled] span{opacity:.6}
.watch-badge{position:absolute;left:14px;top:14px;background:rgba(0,0,0,.62);color:var(--white);
  font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;padding:7px 11px;border-radius:3px}
.watch-cta{display:flex;flex-wrap:wrap;gap:11px;margin-top:22px}
.watch--mini{display:grid;grid-template-columns:104px 1fr;gap:16px;align-items:center;
  border:1px solid var(--rule-light);padding:14px;border-radius:3px;margin-top:34px}
.watch--mini img{border-radius:2px}
.watch--mini p{margin:0;font-size:14.6px;color:rgba(255,255,255,.72)}
.watch--mini a{color:var(--white);border-bottom:1px solid var(--rule-light)}

/* modal / lightbox for the narrated film */
.modal[hidden]{display:none}
.modal{position:fixed;inset:0;z-index:90;display:grid;place-items:center;padding:var(--pad);
  background:rgba(0,0,0,.82)}
.modal-in{position:relative;width:min(1040px,100%)}
.modal video{width:100%;height:auto;background:#000;border-radius:3px}
.modal-close{position:absolute;right:0;top:-46px;background:transparent;border:1px solid var(--rule-light);
  color:var(--white);border-radius:3px;padding:8px 14px;font-size:14px;font-weight:600;cursor:pointer;
  font-family:var(--body)}
.modal-close:hover{background:rgba(255,255,255,.14)}
.modal-close:focus-visible{outline:2px solid var(--white);outline-offset:3px}

/* figures (content photography) */
.fig{margin:0}
.fig img{width:100%;height:auto;border-radius:3px}
.fig figcaption{font-size:13.4px;color:var(--grey-soft);margin-top:10px}
.sap-onward .fig figcaption{color:rgba(255,255,255,.6)}

/* The contact form styles (.form, .field, .field--check, .hp, .form-msg) that
   sat here are removed with the form itself (Phase 4, section 5.3). They were
   only ever used by contact.html, and `grep -r 'class="form\|class="field' site/`
   now returns nothing, so they were shipping on every page for no one. The block
   is kept verbatim in retired/form.css if the form ever comes back. */

/* hero video variant switch: set data-hero on <html> to "route" or "video" */
[data-hero="route"] .heroB{display:none}
[data-hero="video"] .heroA{display:none}
.heroB video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.heroB-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* the mockup's gradient stands in for the poster; once a real poster image is
   present it becomes the hero and the gradient's highlight wash is dropped */
.heroB-media.has-poster::after{content:none}

/* =====================================================================
   PHASE 3 — homepage rebuild components
   ===================================================================== */

/* ---------- About: standfirst, proof line, video facade ---------- */
.standfirst{font-family:var(--display);font-size:clamp(18px,2vw,23px);color:var(--black);
  margin:16px 0 0;letter-spacing:-.014em}
.about-film{display:flex;flex-direction:column;gap:14px}
@media(min-width:960px){
  .about-film .yt{flex:1 1 auto;min-height:0}
  .about-film .yt-btn{aspect-ratio:auto;height:100%;min-height:clamp(280px,26vw,420px)}
}
.about-copy{display:flex;flex-direction:column;gap:clamp(24px,3vw,40px)}
.about-copy>p.proof{margin-top:auto}
/* The GSA appointment is the section's credibility anchor: it sits directly
   above the film, set larger than body copy and ruled off. */
.proof{margin:0;font-family:var(--display);font-size:clamp(18px,1.9vw,22px);line-height:1.32;
  letter-spacing:-.014em;color:var(--black);border-left:2px solid var(--blue);padding-left:18px}
.cap{margin:0;font-size:13.6px;color:var(--grey-soft)}

.yt{position:relative}
.yt-btn{display:block;width:100%;padding:0;border:0;background:var(--black);cursor:pointer;
  position:relative;aspect-ratio:16/9;overflow:hidden}
.yt-btn picture,.yt-btn img{display:block;width:100%;height:100%;object-fit:cover}
/* Bottom-weighted scrim: it darkens the label strip without flattening the
   photograph, and puts the play control on a ground it can be seen against. */
.yt-btn::after{content:"";position:absolute;inset:0;transition:background .25s;
  background:linear-gradient(0deg,rgba(0,0,0,.72) 0%,rgba(0,0,0,.34) 34%,rgba(0,0,0,.18) 100%)}
.yt-btn:hover::after{background:linear-gradient(0deg,rgba(0,0,0,.66) 0%,rgba(0,0,0,.24) 34%,rgba(0,0,0,.08) 100%)}
.yt-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:2;
  width:86px;height:86px;display:grid;place-items:center;background:var(--white);
  border-radius:50%;box-shadow:0 10px 34px rgba(0,0,0,.34);transition:transform .25s,background .25s}
.yt-btn:hover .yt-play{transform:translate(-50%,-50%) scale(1.07);background:var(--blue)}
.yt-play svg{width:34px;height:34px;color:var(--blue);margin-left:4px;transition:color .25s}
.yt-btn:hover .yt-play svg{color:var(--white)}
.yt-label{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:16px clamp(16px,2.4vw,24px);
  font-family:var(--body);font-size:14.5px;font-weight:600;letter-spacing:.02em;
  color:var(--white);text-align:left}
.yt-btn:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
.yt iframe{display:block;width:100%;aspect-ratio:16/9;border:0}
/* Shown only when the embedded player reports an error or never starts.
   It is a link, not a dead error panel, so the film is still one click away. */
.yt-fallback{display:flex;align-items:center;justify-content:center;text-align:center;
  width:100%;aspect-ratio:16/9;padding:24px;background:var(--black);color:var(--white);
  font-size:16px;font-weight:600;letter-spacing:.02em;
  border-bottom:0;text-decoration:underline;text-underline-offset:5px}
.yt-fallback:hover{color:var(--blue)}
/* The quieter cousin: added under a frame that has not spoken up, without
   taking the frame away. */
.yt-escape{display:block;margin-top:10px;font-size:14.5px;font-weight:600;color:var(--blue);
  text-decoration:underline;text-underline-offset:4px}

/* ---------- SalamAir section ---------- */
/* The copy column pins its card + CTA to the bottom so it finishes level with
   the photograph beside it. */
.sa-copy{display:flex;flex-direction:column;justify-content:space-between;gap:clamp(24px,3vw,38px)}
.offers{min-height:clamp(300px,34vw,460px)}
.sa-card{margin-top:0}
.sa-copy .hero-cta{margin-top:22px}
/* The route artwork band that used to close this section is gone: it is supplied
   on a transparent ground with almost no ink, so it rendered as an empty black
   strip under the section (punch-list 8). */

/* ---------- offers carousel ---------- */
/* Sits in the right-hand column of the SalamAir section, on brand blue. The
   card is white so the offer reads as the loudest thing in the section, which
   is what it now is. Slides are stacked in one grid cell and cross-faded, so
   the box takes the height of the tallest slide and never jumps as it rotates. */
.offers{display:flex;flex-direction:column;gap:18px;min-width:0}
.offers-vp{display:grid;list-style:none;margin:0;padding:0;flex:1 1 auto}
.offer{grid-area:1/1;opacity:0;visibility:hidden;transform:translateY(10px);
  transition:opacity .5s ease,transform .5s ease,visibility 0s linear .5s}
.offer.is-on{opacity:1;visibility:visible;transform:none;transition-delay:0s,0s,0s}
/* Only the live slide is reachable, so tabbing does not fall into a hidden
   offer. visibility:hidden already removes it from the tab order; this is the
   belt for browsers that animate visibility late. */
.offer:not(.is-on) a,.offer:not(.is-on) button{pointer-events:none}
/* The copy is grouped on the floor of the card and the photograph gets the top.
   Spreading it over the full height (which is what this did before the imagery
   landed) meant scrimming the whole picture to keep the type legible, and a
   photograph you have to bury is not worth having. Bottom-weighted, the scrim
   can be thick exactly where the words are and almost absent over the skyline —
   the type gets *more* contrast than it had, and the city is still the city. */
.offer-card{position:relative;overflow:hidden;
  height:100%;min-height:430px;
  display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-end;
  background:var(--blue-ink);color:var(--white);
  padding:clamp(26px,3.4vw,44px);border-radius:3px;
  box-shadow:0 18px 44px rgba(0,0,0,.18)}
/* Destination photography behind the offer (punch-list 4.0 section 4). Absolute,
   so it drops out of the card's flex flow and the auto margins below still
   distribute the copy. --blue-ink above is the floor if the image never loads. */
.offer-bg{position:absolute;inset:0;z-index:0;display:block}
.offer-bg img{width:100%;height:100%;object-fit:cover;display:block}
/* The scrim, weighted to the bottom where the copy sits, and held near-opaque
   all the way up to the eyebrow before it falls away.
   The stops are not guesswork: the composited background under every line of
   type was sampled per pixel against both photographs and the worst case
   measured. A gentler ramp (.60 at 62%) put the eyebrow over a sunlit patch of
   Dubai sky at 2.45:1 — the top of the copy block sits higher up the card than
   it looks, around 68%, because the block is tall. These stops put the worst
   line comfortably past the 4.5:1 floor the rest of the site holds to, and the
   top quarter still thins to .12 so the Burj and the minarets read as
   photographs rather than as texture. */
.offer-card::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(to top,
    rgba(6,14,24,.94) 0%,
    rgba(6,14,24,.90) 50%,
    rgba(6,14,24,.80) 66%,
    rgba(6,14,24,.45) 76%,
    rgba(6,14,24,.12) 88%,
    rgba(6,14,24,.04) 100%)}
.offer-card>*:not(.offer-bg){position:relative;z-index:2}
/* A light tint of the brand blue rather than the blue itself: #4188DC sits at
   about 2.6:1 here. This is the highest line of type on the card, so it is the
   one nearest the thin end of the scrim and the one that sets the floor. */
.offer-flag{margin:0;font-size:11.5px;font-weight:600;letter-spacing:.18em;
  text-transform:uppercase;color:#CFE2FA;display:flex;align-items:center;gap:10px}
.offer-flag::before{content:"";width:22px;height:1px;background:#CFE2FA;flex:none}
/* Scoped to .offer-card on purpose: the section is .tone-blue, whose
   `.tone-blue h3{color:#fff}` rule would otherwise win on specificity and set
   this heading white on a white card. */
.offer-card .offer-title{font-family:var(--display);font-weight:500;color:var(--white);
  font-size:clamp(28px,3.1vw,41px);line-height:1.04;letter-spacing:-.022em;margin:18px 0 0}
/* Route and frequency on one line. The frequency string is a single shared
   data-key across all three cards, so the wording cannot drift apart. */
.offer-meta{margin:8px 0 0;font-size:16px;color:rgba(255,255,255,.88);
  display:flex;flex-wrap:wrap;align-items:baseline}
.offer-dot{opacity:.55;padding:0 8px}
/* The Hyderabad card carries no confirmed times, so its strip is codes
   only and needs the padding the time row would otherwise have given it. */
.offer-hops--codes li{padding:19px 0}
/* The three hops are the whole itinerary at a glance. Codes lead, times follow,
   and the rule between them is the flight. */
.offer-hops{list-style:none;display:flex;align-items:stretch;gap:0;margin:clamp(18px,2.4vw,26px) 0 0;
  padding:0;width:100%;border-top:1px solid rgba(255,255,255,.28);
  border-bottom:1px solid rgba(255,255,255,.28)}
.offer-hops li{flex:1 1 0;min-width:0;padding:13px 0;text-align:center;position:relative}
.offer-hops li+li::before{content:"";position:absolute;left:0;top:50%;width:1px;height:26px;
  background:rgba(255,255,255,.28);transform:translateY(-50%)}
.hop-code{display:block;font-size:15px;font-weight:600;letter-spacing:.16em;color:var(--white)}
.hop-time{display:block;margin-top:4px;font-size:13.4px;color:rgba(255,255,255,.82)}
/* Both slides share one grid cell, so they are the same height and the two
   buttons land in the same place whichever offer is showing. */
.offer-fine{margin:14px 0 clamp(22px,2.8vw,30px);font-size:13.4px;line-height:1.5;
  color:rgba(255,255,255,.85)}
.offer-cta{margin-top:0}
/* Set by site.js only when a slide is given a data-href. Inert slides never get
   it, so nothing here needs to be undone when the landing pages arrive. */
.offer--linked .offer-card{cursor:pointer;transition:transform .25s ease,box-shadow .25s ease}
.offer--linked .offer-card:hover{transform:translateY(-3px);box-shadow:0 24px 54px rgba(0,0,0,.32)}
.offer--linked .offer-bg img{transition:transform .5s ease}
.offer--linked .offer-card:hover .offer-bg img{transform:scale(1.04)}

.offers-ui{display:flex;align-items:center;justify-content:space-between;gap:16px}
/* Tap targets (phase-4 6.1): the dot is drawn by ::before and the button itself
   is a transparent 30px square, so a thumb can actually hit it. The visible dot
   and its 18px centre-to-centre spacing are unchanged from the 9px-button
   version; gap is 0 because the padding of the target now does the spacing's
   job without the hit areas overlapping. */
.offers-dots{display:flex;align-items:center;gap:0;margin-left:-10px}
.offers-dot{position:relative;width:30px;height:30px;padding:0;border:0;border-radius:50%;cursor:pointer;
  background:transparent}
.offers-dot::before{content:"";position:absolute;left:50%;top:50%;width:9px;height:9px;margin:-4.5px 0 0 -4.5px;
  border-radius:50%;background:rgba(255,255,255,.42);transition:background .2s,transform .2s}
.offers-dot:hover::before{background:rgba(255,255,255,.72)}
.offers-dot[aria-current="true"]::before{background:var(--white);transform:scale(1.34)}
.offers-dot:focus-visible,.offers-arrow:focus-visible{outline:2px solid var(--white);outline-offset:-4px}
.offers-arrow:focus-visible{outline-offset:3px}
.offers-arrows{display:flex;gap:8px}
.offers-arrow{width:38px;height:38px;display:inline-flex;align-items:center;justify-content:center;
  padding:0;cursor:pointer;border:1px solid rgba(255,255,255,.42);border-radius:50%;
  background:transparent;color:var(--white);transition:background .2s,border-color .2s}
.offers-arrow:hover{background:rgba(255,255,255,.16);border-color:var(--white)}
.offers-arrow svg{width:18px;height:18px}
/* A single offer needs no controls; site.js hides the row rather than leaving a
   lone dot and two dead arrows under the card. */
.offers[data-single] .offers-ui{display:none}
@media(prefers-reduced-motion:reduce){
  .offer{transition:none}
}

/* ---------- Cargo full-bleed ---------- */
.cargo-bleed{min-height:clamp(340px,42vw,520px)}
.cargo-bleed::after{background:
  linear-gradient(92deg,rgba(0,0,0,.86) 0%,rgba(0,0,0,.72) 40%,rgba(0,0,0,.20) 72%,rgba(0,0,0,.06) 100%),
  linear-gradient(0deg,rgba(0,0,0,.52) 0%,rgba(0,0,0,.12) 60%,rgba(0,0,0,0) 100%)}
@media(max-width:900px){
  .cargo-bleed::after{background:linear-gradient(0deg,rgba(0,0,0,.88) 0%,rgba(0,0,0,.74) 55%,rgba(0,0,0,.5) 100%)}
}
.cargo-bleed>picture{position:absolute;inset:0;display:block}
.cargo-bleed>picture img{width:100%;height:100%;object-fit:cover;display:block}
.cargo-bleed>.wrap{position:relative;z-index:1;width:100%;color:var(--white);
  padding-top:clamp(48px,5.6vw,80px);padding-bottom:clamp(40px,4.8vw,66px)}
/* Title, one paragraph and the two CTAs read as a single block against the
   photograph rather than as two columns with a hole between them. */
.cargo-block{max-width:min(58ch,68%)}
@media(max-width:900px){.cargo-block{max-width:none}}
.cargo-block .lede{max-width:52ch}
.cargo-bleed h2,.cargo-bleed h3{color:var(--white)}
.cargo-bleed .lede{color:rgba(255,255,255,.9)}
.cargo-bleed .eyebrow{color:var(--white)}
.cargo-bleed .eyebrow::before{background:var(--white)}
.cargo-bleed .hero-cta{margin-top:26px}

/* ---------- Get in touch ---------- */
.gt-copy{display:flex;flex-direction:column}
.gt-head{max-width:none}
.gt-list{margin:clamp(26px,3vw,40px) 0 0;padding:0;
  border-top:1px solid rgba(255,255,255,.34)}
.gt-row{display:grid;grid-template-columns:1fr;gap:6px;
  padding:clamp(18px,2.2vw,26px) 0;border-bottom:1px solid rgba(255,255,255,.34)}
@media(min-width:620px){.gt-row{grid-template-columns:150px 1fr;gap:clamp(18px,2.4vw,32px);align-items:baseline}}
.gt-row dt{font-size:13px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--white);padding-top:4px}
.gt-row dd{margin:0}
/* Type on brand blue is set at full white throughout. See the contrast note in
   the hand-back: white on #4188DC measures 3.6:1, so nothing here is dimmed
   further with opacity. */
.gt-lead{margin:0;font-size:clamp(17px,1.7vw,19px);line-height:1.45;color:var(--white)}
.gt-lead a:hover,.gt-sub a:hover{text-decoration:underline}
.gt-sub{margin:7px 0 0;font-size:16px;color:var(--white)}
/* A second .gt-lead directly under the first needs the gap .gt-sub used to
   provide, without the size change that came with it. */
.gt-lead--stack{margin-top:7px}
/* Two WhatsApp routes, side by side and weighted the same, because they are two
   members of staff rather than a main number and a fallback. The badge is white
   with the green glyph inside it: WhatsApp green straight onto brand blue is
   about 2:1 and would read as mud, while on white it is the mark people
   recognise, and white on blue carries the badge itself. */
.wa-pair{list-style:none;display:grid;grid-template-columns:1fr;gap:12px;margin:0;padding:0}
@media(min-width:420px){.wa-pair{grid-template-columns:1fr 1fr;gap:clamp(12px,1.6vw,20px)}}
.wa-link{display:flex;align-items:center;gap:12px;min-width:0;
  padding:12px 14px;border:1px solid rgba(255,255,255,.34);border-radius:3px;
  background:rgba(0,0,0,.14);transition:background .2s,border-color .2s}
.wa-link:hover{background:rgba(0,0,0,.26);border-color:var(--white)}
.wa-link:focus-visible{outline:2px solid var(--white);outline-offset:3px}
.wa-badge{flex:none;width:32px;height:32px;border-radius:50%;background:var(--white);
  display:inline-flex;align-items:center;justify-content:center;color:#25D366}
.wa-badge svg{width:20px;height:20px;display:block}
/* The number is the label, so it is set at full white and allowed to shrink
   rather than wrap mid-number when the two sit side by side. */
.wa-num{color:var(--white);font-size:clamp(14.5px,1.35vw,16.5px);font-weight:600;
  letter-spacing:.005em;white-space:nowrap}
.gt-minor{margin:10px 0 0;font-size:14.4px;color:var(--white);line-height:1.6;opacity:.9}
.gt-minor a:hover{text-decoration:underline}
/* Map facade is not needed: the iframe is lazy and this is the last section on
   the page, so nothing reaches Google until the visitor is nearly on it. */
.gt-map{position:relative;display:flex;flex-direction:column;gap:14px}
.gt-map iframe{flex:1 1 auto;width:100%;min-height:clamp(260px,30vw,420px);border:0;display:block;
  border-radius:3px;background:rgba(0,0,0,.18)}
.gt-map-link{position:relative;align-self:flex-start;font-size:14.5px;font-weight:600;color:var(--white);
  border-bottom:1px solid rgba(255,255,255,.5);padding-bottom:2px}
/* Invisible hit area: the link measured 26px tall on a phone. Extends the tap
   target to ~46px without moving the underline or the map above it. */
.gt-map-link::after{content:"";position:absolute;left:-8px;right:-8px;top:-10px;bottom:-10px}
.gt-map-link:hover{border-bottom-color:var(--white)}

/* ---------- social row ---------- */
.social{list-style:none;display:flex;gap:22px;padding:0;
  margin:clamp(34px,4.6vw,60px) 0 0;flex-wrap:wrap}
.social a{display:inline-flex;color:currentColor;opacity:.82;transition:opacity .2s}
.social a:hover{opacity:1}
.social svg{width:23px;height:23px}
.social a:focus-visible{outline:2px solid currentColor;outline-offset:4px}
.social--ftr{margin-top:22px;gap:18px}

/* ---------- rebuilt footer ---------- */
.ftr-brand{display:flex;flex-direction:column;align-items:flex-start}
.ftr-logo{width:154px;height:auto;margin-bottom:20px}
.ftr-about{margin:0;max-width:42ch}
/* The bio and the social row were running into each other. */
.ftr-brand .social--ftr{margin-top:30px}
.ftr-links li{margin-bottom:9px}
.ftr-contact{list-style:none;margin:0;padding:0}
.ftr-contact li{display:flex;align-items:flex-start;gap:11px;margin-bottom:11px;line-height:1.45}
.ftr-contact svg{width:17px;height:17px;flex:none;margin-top:3px;color:var(--blue)}
.ftr-contact a:hover{color:var(--white);text-decoration:underline}
.ftr-phones{line-height:1.7}

/* =====================================================================
   Cargo page — Phase 4 section 4
   ===================================================================== */

/* ---------- route line inside the generic blue cargo panel ----------
   .sap-cargo already re-tints .sa-line for the SalamAir page's deep-sea panel.
   The Cargo page uses the base .cargo-panel on Ibra blue, so the device needs
   its own treatment here rather than borrowing the airline's. Scoped to the
   --route modifier so the plain .cargo-panel elsewhere is untouched. */
.cargo-panel--route .sa-line{background:rgba(255,255,255,.34);margin:22px 0 26px}
/* The endpoint dots default to --blue, which is this panel's own background.
   White is the only value that reads here. */
.cargo-panel--route .sa-line::before,.cargo-panel--route .sa-line::after{background:var(--white)}

/* ---------- key cargo markets ----------
   A hairline grid, not cards: five destinations are a list, and boxing each one
   would have given the page a second heavy component right after the blue
   panel. Built on the Ibra tokens — the retired .reg-g it echoes was hard-wired
   to --sa-deep, which would have dragged the airline's palette onto an Ibra
   page. Five across once there is room; two columns on a phone, where five
   items would otherwise leave a half-empty last row that reads as a broken
   tile, so China takes the full width there (see .mkt--via below). */
.mkt-g{list-style:none;margin:clamp(30px,4vw,44px) 0 0;padding:0;
  display:grid;grid-template-columns:repeat(2,1fr);gap:1px;
  background:var(--rule);border:1px solid var(--rule)}
@media(min-width:760px){.mkt-g{grid-template-columns:repeat(5,1fr)}}
.mkt{background:var(--white);padding:clamp(20px,2.6vw,28px) clamp(16px,2vw,22px);
  display:flex;flex-direction:column;gap:5px}
.mkt b{font-family:var(--display);font-size:clamp(18px,2vw,21px);font-weight:500;
  line-height:1.15;letter-spacing:-.012em}
.mkt span{font-size:13.4px;line-height:1.45;color:var(--grey)}
/* China is not a SalamAir sector. The tile is deliberately quieter than the
   four route markets and carries its qualifier on the face of it, so the
   distinction survives someone screenshotting just this grid. */
.mkt--via{background:var(--blue-05)}
/* At two columns the fifth tile would sit beside an empty cell, and the grid's
   own hairline background showed through it as a sixth, blank market. China
   spans the row instead — which is also the honest hierarchy, since it is the
   one entry on this grid that is not a route. */
@media(max-width:759px){.mkt--via{grid-column:1/-1}}
.mkt--via b{color:var(--blue-ink)}
.mkt--via span{color:var(--blue-ink);opacity:.82}
/* --grey, not --grey-soft, even though this is small print: the note carries the
   correction that China is not a SalamAir route, and that is not a line to set
   at 2.9:1. --grey measures 5.4:1 on paper. */
.mkt-note{margin:clamp(18px,2.2vw,24px) 0 0;font-size:13.6px;color:var(--grey);
  max-width:62ch}

/* ---------- cargo hero framing ----------
   A page-scoped modifier on the shared .page-hero, not a change to it: the
   Services hero is a single aircraft in open sky and centres fine, but the
   subject here — the open cargo door and the pallets on the loader — sits right
   of centre, and a centred cover crop on a phone lands on blank fuselage. The
   wide layout is untouched; only the narrow crop shifts. */
@media(max-width:820px){
  .page-hero--cargo .page-hero-media img{object-position:70% center}
}

/* ---------- contact hero framing ----------
   Same kind of page-scoped modifier, for the opposite reason. The office photo
   is backlit — the room behind the desk is already dark in the original — and
   the shared mobile scrim, tuned for bright aircraft-in-sky shots, took the
   bottom of it to near-black, which is the "renders as a plain dark box" the
   punch-list objects to elsewhere. Lightened here only. The copy is still white
   on a composited background darker than #1a2430, so nothing drops below the
   4.5:1 floor; there was contrast to spare, not contrast to trade. */
@media(max-width:820px){
  .page-hero--contact .page-hero-scrim{
    background:linear-gradient(0deg,rgba(6,20,34,.82) 0%,rgba(6,20,34,.66) 52%,rgba(6,20,34,.40) 100%)}
}

/* ---------- about page: launch photography ----------
   Captioned photographs inside a .split. The caption is --grey, not the
   --grey-soft of .cap: one of these names the Managing Director, and that is
   not a line to set below 4.5:1. .story-row spaces two splits stacked in one
   section, alternating photo side. */
.fig{margin:0}
.fig .shot{border-radius:3px;aspect-ratio:3/2}
.fig .shot--square{aspect-ratio:1/1}
.fig-cap{margin:12px 0 0;font-size:13.6px;line-height:1.5;color:var(--grey);max-width:60ch}
.story-row+.story-row{margin-top:clamp(48px,6vw,92px)}
.story-copy .proof{margin-top:clamp(22px,2.6vw,30px)}
.story-link{margin:18px 0 0;font-weight:600}
.story-link a{color:var(--blue-ink);text-decoration:underline;text-underline-offset:3px}
/* Below 960px a split stacks in source order. The second row puts its photo
   first in the markup for the desktop zigzag; on a phone the copy should still
   come before its picture, so the order is flipped back. */
@media(max-width:959px){.story-row--flip .fig{order:2}}
