/* ============================================================================
   MAVENTA DUBAI — "Desert Collage"
   Implementation of the design system documented in /design.md
   (street-poster collage: rigid skeleton + decorative mess layer on top)

   Contents
     01  Fonts
     02  Tokens
     03  Reset & base
     04  Layout primitives
     05  Typography
     06  Texture layer (grain, torn dividers, rips, tape, doodles)
     07  Buttons
     08  Header + nav overlay
     09  Sections & section patterns
     10  Cards
     10b Visa (hub cards, process, checklist, shared fact strip)
     10c Destination cards (international tour packages)
     11  Accordion
     12  Forms
     13  Testimonials
     14  Footer
     15  Chat widget
     16  Motion
============================================================================ */

/* ---------------------------------------------------------------- 01 fonts */
/* @font-face declarations live in fonts.css (base64-inlined woff2) so the
   site renders the same from file:// as it does over http.            */

/* --------------------------------------------------------------- 02 tokens */

:root {
  /* Surfaces — deep desert-night base, warm sand paper for light surfaces */
  --ink:        #12141A;
  --ink-soft:   #191C24;
  --black:      #000000;
  --paper:      #FCF4E4;
  --white:      #FFFFFF;

  /* Poster inks, pulled from the Maventa skyline mark and pushed to
     full saturation. One role each — see design.md §2.1 */
  --teal:       #00BFB2;   /* INTERACTIVE — buttons, links, controls        */
  --teal-deep:  #0A8F86;
  --gold:       #FFC61E;   /* ATTENTION  — tape, hover, highlights          */
  --red:        #E8402A;   /* EMPHASIS   — one word per headline            */
  --terra:      #C4441C;   /* colour band background                        */
  --orange:     #F5811F;   /* HUMAN      — names, attribution               */
  --blue:       #1B3FE8;
  --magenta:    #FF3DD0;   /* neon prop                                     */
  --sand:       #E8C48A;

  /* Type */
  --font-display: 'Archivo Black', 'Arial Black', sans-serif;
  --font-body:    'Outfit', 'Segoe UI', system-ui, sans-serif;

  /* Fluid between the design.md steps, not stepped onto them. A fixed 122px
     lets "Everything," fill the whole column at vw 1200 and overflow it below,
     which is what pushed the gutter decorations into the type. The cap keeps
     the spec size everywhere there is room for it. */
  --fs-display-xl: min(122px, 9.6vw);  --lh-display-xl: 0.80;
  --fs-display-l:  min(76px, 6.1vw);   --lh-display-l:  0.88;
  --fs-display-m:  48px;
  /* Sized from the longest menu label, not chosen. The page names are the
     menu now, and .nav-item__roll is a one-line overflow:hidden window — a
     label that wraps is not small, it is invisible. "WHAT'S HAPPENING IN
     DUBAI" measures 16.31x its font-size, and the clear width left of the
     nav collage is ~51% of the viewport, so 2.8vw keeps it on one line with
     room to spare from 1200px up. Was a flat 88px, which fitted "EXPLORE". */
  --fs-nav:        clamp(34px, 2.8vw, 56px);
  --fs-body-l:     24px;   --lh-body-l:     1.5;
  --fs-body-m:     18px;   --lh-body-m:     1.6;
  --fs-body-s:     16px;   --lh-body-s:     1.5;
  --fs-micro:      12px;

  /* Layout */
  --content-max: 1200px;
  --gutter:      120px;
  --page-pad:    80px;   /* header / footer / nav gutter */
  --section-y:   120px;
  --grid-gap:    24px;
  --card-w:      384px;

  /* Components */
  --btn-radius: 360px;
  --btn-pad:    18px 32px 20px;
  --btn-border: 2px;

  --ease: cubic-bezier(.2, .8, .2, 1);
}

@media (max-width: 1199.98px) {
  :root {
    --gutter: 60px;  --page-pad: 60px;  --section-y: 80px;
    /* fluid for the same reason as the phone band below — at a flat 100px
       "Everything," is 758px wide inside a 690px column at 810vw */
    --fs-display-xl: clamp(72px, 9.4vw, 100px);
    --fs-display-l:  clamp(46px, 6.6vw, 60px);
    --fs-display-m: 40px;
    --fs-nav: clamp(26px, 3vw, 36px); --fs-body-l: 20px;
  }
}
@media (max-width: 809.98px) {
  :root {
    --gutter: 24px;  --page-pad: 24px;  --section-y: 60px;
    /* fluid, not stepped: a long word like ADVENTURES must never clip */
    --fs-display-xl: clamp(32px, 10.4vw, 56px);
    --fs-display-l:  clamp(26px, 8.4vw, 42px);
    --fs-display-m:  clamp(24px, 7vw, 32px);
    --fs-nav:        clamp(15px, 5vw, 30px);
    --fs-body-l: 18px; --fs-body-m: 16px;
  }
}

/* ------------------------------------------------------------ 03 reset/base */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { scroll-behavior: smooth; overflow-x: clip; }

body {
  background: var(--ink);
  color: var(--white);
  font-family: var(--font-body);
  font-size: var(--fs-body-m);
  line-height: var(--lh-body-m);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6, p, figure { margin: 0; }
img { max-width: 100%; display: block; }
/* The UA stylesheet's `[hidden] { display: none }` is a plain author-level-beating
   rule only until a component sets its own display — `.map__key` is display:flex,
   which silently outranks it, so hiding the legend by setting `hidden` did
   nothing. Anything toggled by the `hidden` attribute needs this to hold. */
[hidden] { display: none !important; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }
button { font: inherit; color: inherit; }

:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 999;
  background: var(--gold); color: #000; padding: 10px 18px;
  border-radius: 360px; font-weight: 700; transition: top .2s;
}
.skip-link:focus { top: 12px; }

/* --------------------------------------------------------- 04 layout prims */

.wrap {
  width: 100%;
  max-width: calc(var(--content-max) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--narrow { max-width: calc(820px + var(--gutter) * 2); }

.stack        { display: flex; flex-direction: column; min-width: 0; }
.stack--40    { gap: 40px; }
.stack--24    { gap: 24px; }
.stack--16    { gap: 16px; }
.center       { text-align: center; align-items: center; }

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: center;
}
/* grid/flex items default to min-width:auto, which lets a fixed-width child
   blow the track out past the viewport — pin them to the track instead */
.split > *, .grid-3 > *, .grid-2 > * { min-width: 0; }
.split--wide-left  { grid-template-columns: 1.15fr 1fr; }
.split--wide-right { grid-template-columns: 1fr 1.15fr; }

/* Size a display heading against its COLUMN, not the viewport.
   --fs-display-l is capped on vw, so it reaches 76px while a
   .split--wide-right left column is only 417px wide at a 1200px viewport and
   528px at 1920px. "EXPERIENCE" in Archivo Black wants 7.07x its font size —
   537px at 76px — so it overflowed by 9px at 1920 and 100px at 1200. That is
   not a crowded neighbour: .display--rough masks at the border box, so the
   overflowing glyphs were amputated mid-letter.
   13.6cqw keeps the longest word inside the column at every desktop width,
   with ~4% to spare. Only the two-column desktop layout needs it; below
   1200px the split stacks and the column is the full content width. */
@media (min-width: 1200px) {
  .split > * { container-type: inline-size; }
  .split .display-l { font-size: min(var(--fs-display-l), 13.6cqw); }
}

@media (max-width: 1199.98px) {
  .split, .split--wide-left, .split--wide-right {
    grid-template-columns: 1fr;
    gap: 48px;
  }
}

/* Fill the other half of a split. Four short cards beside a heading + lede +
   button left ~230px of empty band below them; stretching the grid to the
   column and letting the rows share it evenly closes the gap. Only above
   1200px — below that the split stacks, and full-height rows on a single
   column would just be four over-tall boxes. */
@media (min-width: 1200px) {
  .grid-2--fill { height: 100%; grid-auto-rows: 1fr; }
}

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--grid-gap);
}
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: var(--grid-gap); }
@media (max-width: 1199.98px) { .grid-3 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 809.98px)  { .grid-3, .grid-2 { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------- 05 typography */

.display {
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
.display-xl { font-size: var(--fs-display-xl); line-height: var(--lh-display-xl); }
.display-l  { font-size: var(--fs-display-l);  line-height: var(--lh-display-l); }
.display-m  { font-size: var(--fs-display-m);  line-height: 0.95; }
/* Manifesto block: a paragraph-sized statement set in the display face with
   word-level colour coding (design.md §2.2.2). */
.display-statement {
  font-size: clamp(26px, 4vw, 56px);
  line-height: 1.06;
  letter-spacing: -0.005em;
}

/* Distressed poster type: a sparse speckle mask eats into the letterforms so
   the display face reads as roughly printed. A mask (not background-clip) so
   that per-word colour spans inside the heading keep their own colour and all
   get the same erosion. Degrades to clean type if masks are unsupported. */
.display--rough {
  -webkit-mask-image: var(--tex-rough); mask-image: var(--tex-rough);
  -webkit-mask-size: 420px 420px;      mask-size: 420px 420px;
  -webkit-mask-repeat: repeat;         mask-repeat: repeat;
}
@media (max-width: 809.98px) {
  /* finer grain at small sizes so the type stays legible */
  .display--rough { -webkit-mask-size: 240px 240px; mask-size: 240px 240px; }
}

.eyebrow {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.lede { font-size: var(--fs-body-l); line-height: var(--lh-body-l); }
.body-s { font-size: var(--fs-body-s); line-height: var(--lh-body-s); }

.t-red    { color: var(--red); }
.t-teal   { color: var(--teal); }
.t-gold   { color: var(--gold); }
.t-orange { color: var(--orange); }
.t-blue   { color: var(--blue); }
.t-white  { color: var(--white); }
.t-ink    { color: var(--ink); }
.t-muted  { color: rgba(255,255,255,.72); }

/* Echo stack — final word repeated at fading opacity (design.md §2.2.3).
   The ghosts sit in normal flow so they reserve their own space; they are
   tightly overlapped (line-height .56) so the word reads as a fading echo
   rather than as four separate lines. */
.echo { display: block; }
.echo__live { display: block; }
.echo__ghost { display: block; pointer-events: none; user-select: none; }
.echo__ghost > span { display: block; line-height: .56; }
.echo__ghost > span:last-child { padding-bottom: .18em; }

/* Ghost outline marquee word */
.marquee {
  overflow: hidden;
  width: 100%;
  pointer-events: none;
  user-select: none;
}
.marquee__track {
  display: flex;
  width: max-content;
  gap: 0.35em;
  animation: marquee-scroll 38s linear infinite;
}
.marquee__track > span {
  font-family: var(--font-display);
  font-size: 190px;
  line-height: 0.8;
  text-transform: uppercase;
  color: transparent;
  -webkit-text-stroke: 3px currentColor;
  white-space: nowrap;
  padding-right: .35em;
}
.marquee--sm .marquee__track > span { font-size: 110px; -webkit-text-stroke-width: 2px; }
@keyframes marquee-scroll { to { transform: translateX(-50%); } }
@media (max-width: 809.98px) {
  .marquee__track > span { font-size: 92px; -webkit-text-stroke-width: 2px; }
}

/* ------------------------------------------------------------ 06 textures */

/* Global asphalt grain over the flat page colour */
body::before {
  content: '';
  position: fixed; inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .40;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='260' height='260' filter='url(%23g)' opacity='.42'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}
#page { position: relative; z-index: 1; }

/* Mask helper */
.mask {
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
}
.mask--stretch { -webkit-mask-size: 100% 100%; mask-size: 100% 100%; }

/* Torn divider — sits on a section edge, painted in that section's colour.
   Never let a colour change happen on a straight line (design.md §3.2). */
.torn {
  position: absolute; left: 0; right: 0;
  height: 36px;
  z-index: 3;
  pointer-events: none;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
}
.torn--top    { top: -34px; -webkit-mask-image: var(--tex-torn-top-2);    mask-image: var(--tex-torn-top-2); }
.torn--top-b  { top: -34px; -webkit-mask-image: var(--tex-torn-top-1);    mask-image: var(--tex-torn-top-1); }
.torn--bottom { bottom: -34px; -webkit-mask-image: var(--tex-torn-bottom-1); mask-image: var(--tex-torn-bottom-1); }
.torn--bottom-b { bottom: -34px; -webkit-mask-image: var(--tex-torn-bottom-3); mask-image: var(--tex-torn-bottom-3); }
/* Inward variants — for a section whose background is a photo/gradient and so
   cannot paint its own torn edge. These are painted in the NEIGHBOURING
   section's colour and sit inside the band, biting into it. */
.torn--in-top {
  top: 0;
  -webkit-mask-image: var(--tex-torn-bottom-2); mask-image: var(--tex-torn-bottom-2);
}
.torn--in-bottom {
  bottom: 0;
  -webkit-mask-image: var(--tex-torn-top-3); mask-image: var(--tex-torn-top-3);
}
@media (max-width: 809.98px) {
  .torn { height: 22px; }
  .torn--top, .torn--top-b { top: -20px; }
  .torn--bottom, .torn--bottom-b { bottom: -20px; }
  .torn--in-top { top: 0; }
  .torn--in-bottom { bottom: 0; }
}

/* Ripped photo — photos are never rectangles (design.md §3.2) */
.rip {
  position: relative;
  background-position: center;
  background-size: cover;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
}
.rip--1 { -webkit-mask-image: var(--tex-rip-mask-1); mask-image: var(--tex-rip-mask-1); }
.rip--2 { -webkit-mask-image: var(--tex-rip-mask-2); mask-image: var(--tex-rip-mask-2); }
.rip--3 { -webkit-mask-image: var(--tex-rip-mask-3); mask-image: var(--tex-rip-mask-3); }
.rip--4 { -webkit-mask-image: var(--tex-rip-mask-4); mask-image: var(--tex-rip-mask-4); }
.rip--p1 { -webkit-mask-image: var(--tex-rip-portrait-1); mask-image: var(--tex-rip-portrait-1); }
.rip--p2 { -webkit-mask-image: var(--tex-rip-portrait-2); mask-image: var(--tex-rip-portrait-2); }

/* Masking tape — torn ends via clip-path, fibre grain via gradients */
.tape {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  background: var(--gold);
  color: #000;
  padding: 12px 34px 13px;
  transform: rotate(-1.2deg);
  clip-path: polygon(
    2% 6%, 14% 0%, 31% 7%, 48% 1%, 66% 8%, 84% 2%, 98% 9%,
    100% 92%, 86% 100%, 68% 93%, 50% 99%, 33% 92%, 16% 100%, 1% 93%
  );
}
.tape::after {
  content: '';
  position: absolute; inset: 0;
  background: repeating-linear-gradient(
    92deg, rgba(0,0,0,.055) 0 2px, transparent 2px 7px);
  mix-blend-mode: multiply;
  pointer-events: none;
}
.tape > * { position: relative; z-index: 1; }
.tape--heading {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 22px;
  letter-spacing: .01em;
}
.tape--chip {
  padding: 6px 16px 7px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--fs-micro);
  letter-spacing: .14em;
  text-transform: uppercase;
  transform: rotate(-3.5deg);
}
.tape--ink   { background: var(--black); color: var(--white); }
.tape--teal  { background: var(--teal);  color: #06231F; }
.tape--blue  { background: var(--blue);  color: var(--white); }
@media (max-width: 809.98px) {
  .tape--heading { font-size: 17px; padding: 10px 22px 11px; }
}

/* Doodles — masked shapes coloured by background-color */
.doodle {
  position: absolute;
  pointer-events: none;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
  z-index: 2;
}
.d-squiggle  { -webkit-mask-image: var(--tex-doodle-squiggle);  mask-image: var(--tex-doodle-squiggle); }
.d-chalk     { -webkit-mask-image: var(--tex-doodle-chalk);     mask-image: var(--tex-doodle-chalk); }
.d-triangle  { -webkit-mask-image: var(--tex-doodle-triangle);  mask-image: var(--tex-doodle-triangle); }
.d-sparkle   { -webkit-mask-image: var(--tex-doodle-sparkle);   mask-image: var(--tex-doodle-sparkle); }
.d-arrow     { -webkit-mask-image: var(--tex-doodle-arrow);     mask-image: var(--tex-doodle-arrow); }
.d-circle    { -webkit-mask-image: var(--tex-doodle-circle);    mask-image: var(--tex-doodle-circle); }
.d-highlight { -webkit-mask-image: var(--tex-doodle-highlight); mask-image: var(--tex-doodle-highlight); }
.d-plane     { -webkit-mask-image: var(--tex-doodle-plane);     mask-image: var(--tex-doodle-plane); }
.d-camel     { -webkit-mask-image: var(--tex-doodle-camel);     mask-image: var(--tex-doodle-camel); }
.d-sun       { -webkit-mask-image: var(--tex-doodle-sun);       mask-image: var(--tex-doodle-sun); }

/* inline (non-absolute) doodle, e.g. an underline under a heading */
.doodle--inline { position: relative; display: block; }

@media (max-width: 809.98px) {
  /* the mess layer is sized for desktop — shrink it rather than let it
     dominate a 390px canvas. `scale` composes with any inline rotate. */
  .doodle { scale: .58; }
  .doodle--inline { scale: 1; }
  .pin { width: 76px; height: 26px; }
  .hero .doodle { display: none; }   /* nothing decorative over the H1 */
}

/* Highlighter swipe sitting behind a word */
.swipe { position: relative; display: inline-block; }
.swipe::before {
  content: '';
  position: absolute; left: -.12em; right: -.12em; top: 8%; bottom: 6%;
  background: var(--teal);
  -webkit-mask-image: var(--tex-doodle-highlight); mask-image: var(--tex-doodle-highlight);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  z-index: -1;
}

/* Neon prop frame */
.neon-frame { position: relative; }
.neon-frame::after {
  content: '';
  position: absolute; inset: 14px -18px -18px 14px;
  border: 3px solid var(--magenta);
  box-shadow: 0 0 14px var(--magenta), inset 0 0 14px rgba(255,61,208,.5);
  z-index: -1;
}

/* Rotating circular badge (text on a path) */
.badge { position: absolute; z-index: 4; pointer-events: none; }
/* Sticker on a form card. The card is capped at 880px, so on desktop this
   corner is clear margin. On phones the card fills the column and the fine
   print runs its full width — the sticker was landing on "Unsubscribe any
   time." and on the WhatsApp link — so it drops onto the band below, into
   the card's bottom padding where no text reaches. */
.badge--card { width: 132px; right: 8%; bottom: 8%; }
@media (max-width: 809.98px) {
  .badge--card { width: 96px; right: 16px; bottom: 10px; }
}
/* CTA-band sticker. That band's content is centred and its headline is
   display-xl, so the only reliably clear space is the gutter outside the text
   column — it lives in a .deco-col and fills exactly that gutter. Below
   1200px the gutter is 60px or less, too small to hold a legible sticker. */
.badge--band { width: var(--gutter); right: 0; bottom: 12%; }
@media (max-width: 1199.98px) { .badge--band { display: none; } }
.badge svg { display: block; width: 100%; height: auto; }
.badge__spin { transform-origin: 50% 50%; animation: badge-spin 18s linear infinite; }
@keyframes badge-spin { to { transform: rotate(360deg); } }

/* Brick / mesh backdrop utilities */
.bg-brick {
  background-color: #0C0E13;
  background-image:
    repeating-linear-gradient(0deg, rgba(255,255,255,.045) 0 1px, transparent 1px 42px),
    repeating-linear-gradient(90deg, rgba(255,255,255,.045) 0 1px, transparent 1px 92px);
  background-position: 0 0, 0 0;
}
.bg-mesh {
  background-color: #0B0D12;
  background-image:
    repeating-linear-gradient(45deg,  rgba(255,255,255,.05) 0 1px, transparent 1px 18px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.05) 0 1px, transparent 1px 18px);
}
.bg-dune {
  background:
    radial-gradient(120% 80% at 50% 120%, rgba(245,129,31,.20), transparent 60%),
    var(--ink);
}

/* ------------------------------------------------------------- 07 buttons */

.btn {
  position: relative;
  display: inline-block;
  border-radius: var(--btn-radius);
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
}
/* offset "sticker shadow" pill revealed on hover */
.btn::before {
  content: '';
  position: absolute; inset: 0;
  border-radius: var(--btn-radius);
  background: var(--gold);
  transform: translate(0, 0);
  opacity: 0;
  transition: transform .28s var(--ease), opacity .18s linear;
  z-index: -1;
}
.btn__pill {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  padding: var(--btn-pad);
  border: var(--btn-border) solid var(--teal);
  border-radius: var(--btn-radius);
  background: var(--black);
  overflow: hidden;
  transition: border-color .25s var(--ease);
}
/* diagonal wipe bar parked off the left edge */
.btn__pill::before {
  content: '';
  position: absolute;
  top: -53px; bottom: -53px; left: -60px;
  width: 35px;
  background: var(--gold);
  transform: rotate(-19deg);
  transition: left .45s var(--ease);
  pointer-events: none;
}
.btn__labels {
  position: relative;
  display: block;
  height: 16px;
  overflow: hidden;
  font-family: var(--font-display);
  font-size: var(--fs-body-s);
  line-height: 16px;
  text-transform: uppercase;
  letter-spacing: .02em;
  white-space: nowrap;
}
.btn__labels > span {
  display: block;
  height: 16px;
  transition: transform .32s var(--ease);
}
.btn__labels > span:first-child { color: var(--teal); }
.btn__labels > span:last-child  { color: var(--gold); }
/* sparkle pop */
.btn__spark {
  position: absolute;
  top: -12px; right: -10px;
  width: 30px; height: 30px;
  background: var(--gold);
  -webkit-mask-image: var(--tex-doodle-sparkle); mask-image: var(--tex-doodle-sparkle);
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  transform: scale(0) rotate(-40deg);
  transition: transform .3s var(--ease);
  pointer-events: none;
  z-index: 2;
}

.btn:hover::before, .btn:focus-visible::before { transform: translate(7px, 8px); opacity: 1; }
.btn:hover .btn__pill, .btn:focus-visible .btn__pill { border-color: var(--gold); }
.btn:hover .btn__pill::before, .btn:focus-visible .btn__pill::before { left: calc(100% + 42px); }
.btn:hover .btn__labels > span, .btn:focus-visible .btn__labels > span { transform: translateY(-16px); }
.btn:hover .btn__spark, .btn:focus-visible .btn__spark { transform: scale(1) rotate(0deg); }

.btn--sm .btn__pill { padding: 12px 20px 14px; }
.btn--sm .btn__labels { font-size: 14px; }

/* Filled variant (form submit) */
.btn-solid {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 200px;
  padding: 22px 40px;
  border: 0;
  border-radius: var(--btn-radius);
  background: var(--teal);
  color: #04211E;
  font-family: var(--font-display);
  font-size: var(--fs-body-s);
  text-transform: uppercase;
  letter-spacing: .04em;
  cursor: pointer;
  transition: background .22s var(--ease), transform .22s var(--ease);
}
.btn-solid:hover, .btn-solid:focus-visible { background: var(--gold); transform: translateY(-2px); }

/* Text link */
.link-u {
  color: var(--teal);
  border-bottom: 2px solid currentColor;
  padding-bottom: 1px;
  transition: color .2s;
}
.link-u:hover { color: var(--gold); }

/* -------------------------------------------------- 08 header + nav overlay */

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  height: 176px;
  z-index: 200;
  pointer-events: none;
}
.site-header > * { pointer-events: auto; }
/* Scrim so page content scrolling under the fixed logo stays readable.
   Hidden while the nav overlay is open — the gold panel needs no scrim. */
.site-header::before {
  content: '';
  position: absolute; inset: 0 0 auto 0;
  height: 150px;
  background: linear-gradient(180deg, rgba(9,10,14,.70) 0%, rgba(9,10,14,.32) 50%, rgba(9,10,14,0) 100%);
  pointer-events: none;
  opacity: 1;
  transition: opacity .3s var(--ease);
  z-index: -1;
}
body[data-nav-open="true"] .site-header::before { opacity: 0; }

/* The brand is a single emblem that carries its own "MAVENTA / DUBAI"
   wordmark, so the header sets no type of its own — the old .brand__name /
   .brand__sub spans would have printed the words a second time. The badge
   reads on both backgrounds it has to survive (the dark scrim and the gold
   nav overlay) because its lower half is dark navy with the wordmark
   reversed out of it. */
.brand {
  position: absolute;
  left: 50%;
  top: 20px;
  transform: translateX(-50%);
  display: block;
}
/* The brand carries `.drop-in`, whose final keyframe is `transform: none`.
   Animations outrank normal declarations and `both` holds the final frame,
   so the shared animation was erasing the centring translate above and
   parking the lockup half its own width right of centre. It needs its own
   keyframes that carry the translate through. */
.brand.drop-in { animation-name: drop-in-centred; }
@keyframes drop-in-centred {
  from { opacity: 0; transform: translate(-50%, -90px); }
  to   { opacity: 1; transform: translateX(-50%); }
}
.brand__mark { width: 138px; height: auto; display: block; }

.header-cta { position: absolute; left: var(--page-pad); top: 16px; }
@media (max-width: 809.98px) { .header-cta { display: none; } }

.burger {
  position: absolute;
  right: var(--page-pad); top: 16px;
  width: 44px; height: 36px;
  padding: 0; margin: 0;
  background: none; border: 0;
  cursor: pointer;
  z-index: 2;
}
.burger span {
  position: absolute; left: 0;
  display: block; width: 44px; height: 6px;
  background: var(--white);
  transition: transform .35s var(--ease), opacity .2s linear, background-color .3s;
}
.burger span:nth-child(1) { top: 0; }
.burger span:nth-child(2) { top: 16px; }
.burger span:nth-child(3) { top: 31px; height: 5px; }
.burger[aria-expanded="true"] span { background: #101014; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(16px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-15px) rotate(-45deg); }

@media (max-width: 809.98px) {
  .site-header { height: 120px; }
  .brand { top: 12px; }
  .brand__mark { width: 92px; }
  .burger { width: 32px; height: 22px; top: 20px; }
  .burger span { width: 32px; height: 5px; }
  .burger span:nth-child(2) { top: 9px; }
  .burger span:nth-child(3) { top: 18px; height: 4px; }
  .burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(9px) rotate(45deg); }
  .burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }
}

/* Nav overlay — flat gold panel, halftone dots, huge display links */
.nav-overlay {
  position: fixed; inset: 0;
  z-index: 150;
  background: var(--gold);
  background-image: radial-gradient(rgba(0,0,0,.09) 1.4px, transparent 1.5px);
  background-size: 14px 14px;
  /* flex-start + auto margins, NOT align-items:center. Centring a flex item
     taller than its line overflows equally in BOTH directions, so on a short
     viewport the first menu item was pushed up past the 140px padding and
     landed under the Inquire Now button. Auto margins distribute free space
     but never go negative, so the padding always holds. */
  display: flex; align-items: flex-start;
  padding: 140px var(--page-pad) 60px;
  overflow-y: auto;
  overflow-x: hidden;
  clip-path: inset(0 0 100% 0);
  transition: clip-path .55s var(--ease), visibility 0s linear .55s;
  visibility: hidden;
}
.nav-overlay[data-open="true"] {
  clip-path: inset(0 0 0 0);
  visibility: visible;
  transition: clip-path .55s var(--ease), visibility 0s;
}
.nav-overlay__inner {
  position: relative; z-index: 2;
  margin-block: auto;
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
}
.nav-list { display: flex; flex-direction: column; gap: 18px; }
.nav-item { display: block; width: max-content; max-width: 100%; }
/* The roll window must be tall enough to show a full cap-height glyph of the
   display face, or the next colour copy peeks out underneath. */
.nav-item__roll {
  display: block;
  height: calc(var(--fs-nav) * 0.82);
  overflow: hidden;
}
.nav-item__roll > span {
  display: block;
  height: calc(var(--fs-nav) * 0.82);
  font-family: var(--font-display);
  font-size: var(--fs-nav);
  line-height: calc(var(--fs-nav) * 0.82);
  text-transform: uppercase;
  letter-spacing: -.015em;
  transition: transform .38s var(--ease);
}
.nav-item__roll > span:nth-child(1) { color: #101014; }
.nav-item__roll > span:nth-child(2) { color: var(--blue); }
.nav-item__roll > span:nth-child(3) { color: var(--red); }
.nav-item__roll > span:nth-child(4) { color: var(--white); }
.nav-item:hover .nav-item__roll > span,
.nav-item:focus-visible .nav-item__roll > span {
  transform: translateY(calc(var(--fs-nav) * -0.82 * 3));
}
.nav-socials { display: flex; gap: 14px; margin-top: 52px; }
.nav-socials a {
  display: grid; place-items: center;
  width: 46px; height: 46px;
  border: 2px solid #101014;
  border-radius: 50%;
  color: #101014;
  transition: background .2s, color .2s;
}
.nav-socials a:hover { background: #101014; color: var(--gold); }
.nav-socials svg { width: 20px; height: 20px; }
.nav-meta { margin-top: 34px; font-size: 15px; color: #24261c; font-weight: 500; }
.nav-meta a { border-bottom: 2px solid rgba(0,0,0,.3); }
.nav-collage {
  position: absolute; right: -4%; bottom: -6%;
  width: 46%; max-width: 620px;
  z-index: 1;
}
.nav-collage .rip { aspect-ratio: 10 / 7; }
@media (max-width: 1199.98px) { .nav-collage { width: 42%; opacity: .95; } }
@media (max-width: 809.98px)  {
  .nav-overlay { padding-top: 116px; align-items: flex-start; }
  .nav-collage { display: none; }
  .nav-list { gap: 12px; }
  .nav-socials { margin-top: 34px; }
}

/* ------------------------------------------------- 09 sections & patterns */

/* Sections must NOT clip: the torn dividers deliberately hang outside the box
   so a colour change never lands on a straight line. `overflow-x:hidden` on
   <body> is what stops decorative bleed from creating a horizontal scrollbar. */
.section {
  position: relative;
  padding-block: var(--section-y);
}
.section--clip { overflow: hidden; }
.section--flush-top    { padding-top: 0; }
.section--flush-bottom { padding-bottom: 0; }
.section--tall { padding-block: calc(var(--section-y) * 1.25); }
.section__inner { position: relative; z-index: 2; }

.section--band  { background: var(--terra); }
.section--paper { background: var(--paper); color: #17181C; }
.section--paper .lede, .section--paper p { color: #2A2C33; }

/* Page hero — full-bleed photo, torn bottom edge, logo over it */
.hero {
  position: relative;
  min-height: 640px;
  display: flex;
  align-items: flex-end;
  padding-block: 200px 96px;
  overflow: hidden;
}
.hero--tall { min-height: 780px; }
.hero__media {
  position: absolute; inset: 0;
  background-position: center;
  background-size: cover;
  z-index: 0;
}
/* Background loop. Sits inside .hero__media so the scrim below still covers
   it — ::after is painted after element children, so the gradient lands on
   top of the video without needing a z-index on either.
   It carries no src until main.js assigns one; until then (and for anyone we
   decide not to load it for) the poster set as .hero__media's background-image
   shows through, which is why the video itself has no `poster` attribute. */
.hero__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  border: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) { .hero__video { display: none; } }

.hero__media::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(10,11,15,.72) 0%, rgba(10,11,15,.35) 38%, rgba(10,11,15,.78) 100%);
}
/* A moving hero needs a heavier scrim than a still one. This gradient is at
   its thinnest (.35) exactly where the H1 sits, which is fine over one chosen
   photograph but not over 22s of montage — at ~13.7s the footage goes to
   bright haze and the white headline dropped to 2.4:1, under the 3:1 WCAG AA
   floor for large text. Taking the mid stop to .50 puts the worst frame at
   3.8:1. Scoped to .hero--video so the five photo heroes keep the lighter
   scrim they were tuned against. */
.hero--video .hero__media::after {
  background: linear-gradient(180deg,
    rgba(10,11,15,.72) 0%, rgba(10,11,15,.50) 38%, rgba(10,11,15,.78) 100%);
}
.hero__inner { position: relative; z-index: 2; width: 100%; }
/* Decoration layer anchored to the SAME column the text uses, so the two hold
   their relationship at every width. Doodles used to be positioned in
   percentages of the viewport while the headline sat in a fixed centred
   column — the two moved independently, so the decoration drifted across the
   type as the window resized.
   This box matches `.wrap`'s border box, so in here the text column spans
   [var(--gutter), 100% - var(--gutter)]. Offsetting a doodle by
   `calc(var(--gutter) - <its width>)` parks it flush against the outside of
   that column, in the gutter — clear of every letter at every width.
   Sits at z-index 1, under `.hero__inner` / `.section__inner` (both z-index 2). */
.deco-col, .hero__deco {
  position: absolute; inset: 0;
  width: 100%;
  max-width: calc(var(--content-max) + var(--gutter) * 2);
  margin-inline: auto;
  pointer-events: none;
  z-index: 1;
}
.hero__edge {
  position: absolute; left: 0; right: 0; bottom: -2px;
  height: 44px;
  background: var(--ink);
  z-index: 3;
  -webkit-mask-image: var(--tex-torn-bottom-2); mask-image: var(--tex-torn-bottom-2);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
@media (max-width: 809.98px) {
  .hero { min-height: 520px; padding-block: 150px 70px; }
  .hero--tall { min-height: 560px; }
  .hero__edge { height: 26px; }
}

/* Collage cluster — taped/ripped photos with doodle punctuation */
.collage { position: relative; }
.collage__item { position: absolute; }
.collage__item .rip { width: 100%; height: 100%; }
.collage--hero { height: 560px; }
@media (max-width: 1199.98px) { .collage--hero { height: 460px; } }
@media (max-width: 809.98px)  { .collage--hero { height: 340px; } }

/* a tape strip pinning a photo */
.pin {
  position: absolute;
  width: 118px; height: 38px;
  background: var(--sand);
  opacity: .92;
  clip-path: polygon(0 12%, 100% 0, 98% 88%, 2% 100%);
  box-shadow: 0 4px 10px rgba(0,0,0,.35);
  z-index: 3;
}
.pin::after {
  content: '';
  position: absolute; inset: 0;
  background: repeating-linear-gradient(90deg, rgba(0,0,0,.06) 0 2px, transparent 2px 6px);
}
.pin--gold { background: var(--gold); }
.pin--blue { background: var(--blue); opacity: .95; }

/* Stat row */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.stat__num {
  font-family: var(--font-display);
  font-size: 64px; line-height: 1;
  color: var(--gold);
}
.stat__label {
  font-size: 14px; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255,255,255,.75); margin-top: 10px;
}
@media (max-width: 809.98px) {
  .stats { grid-template-columns: repeat(2, 1fr); gap: 32px 16px; }
  .stat__num { font-size: 44px; }
}

/* ------------------------------------------------- 09b interactive map ---
   Hotspot map, design.md §4.10. Pins are real buttons; each hover card is a
   sibling inside the same wrapper so :hover / :focus-within stay true while
   the pointer travels from pin to card. Works without JS. */

.section--map { padding-bottom: calc(var(--section-y) * 1.1); }

.map { position: relative; width: 100%; }

.map__scroll {
  /* NB: overflow-x:auto forces overflow-y to auto as well, which clips the
     hover cards and the tape. Panning is enabled at the phone breakpoint only. */
  overflow: visible;
}
.map__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2;
  background: #EFE0C2;
  border: 3px solid #2A2C33;
  box-shadow: 10px 12px 0 rgba(42,44,51,.16);
}
.map__art { display: block; width: 100%; height: 100%; }
/* Seven sheets are inlined; all but the selected one carry `hidden`. Kept as
   plain markup rather than swapped in by JS so the page still shows Dubai —
   the default, and the only sheet with pins — when JS never runs. */
.map__sheet { position: absolute; inset: 0; }
.map__sheet[hidden] { display: none; }

/* ---- emirate picker, top-right corner of the sheet ---- */
.map__pick {
  position: absolute;
  right: 16px; top: 16px;
  z-index: 7;                 /* over the pins layer (5) and the tape (4) */
  display: flex; flex-direction: column; gap: 5px;
  padding: 10px 13px 12px;
  background: #FFFDF6;
  border: 2px solid #2A2C33;
  box-shadow: 3px 4px 0 rgba(42,44,51,.28);
}
.map__pick-label {
  font-size: 11px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(42,44,51,.62);
}
.map__select {
  appearance: none; -webkit-appearance: none;
  min-width: 172px;
  padding: 7px 34px 7px 11px;
  font-family: var(--font-body);
  font-size: 14px; font-weight: 700;
  color: #17181C;
  background-color: var(--gold);
  /* chevron drawn inline — an external SVG would be blocked over file:// */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%232A2C33' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 12px 8px;
  border: 2px solid #2A2C33;
  border-radius: 360px;
  cursor: pointer;
}
.map__select:hover { background-color: #FFD44E; }

/* The caption names what the sheet is showing. Geography, not a sales claim. */
.map__caption {
  margin-top: 16px;
  max-width: 760px;
  margin-inline: auto;
  text-align: center;
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255,255,255,.72);
}
.map__caption[hidden] { display: none; }

@media (max-width: 809.98px) {
  .map__pick { right: 10px; top: 10px; padding: 7px 9px 9px; }
  .map__pick-label { font-size: 10px; }
  .map__select { min-width: 132px; font-size: 13px; padding: 6px 30px 6px 9px; }
}

/* tape holding the map onto the page */
.map__tape { position: absolute; z-index: 4; }
.map__tape--a { left: -18px; top: -16px; transform: rotate(-24deg); }
.map__tape--b { right: -14px; bottom: -18px; transform: rotate(-14deg); }

.map__pins { position: absolute; inset: 0; z-index: 5; }

/* ---- pin ---- */
.poi { position: absolute; transform: translate(-50%, -50%); }
.poi__btn {
  position: relative;
  display: flex; align-items: center; gap: 9px;
  padding: 5px 12px 5px 6px;
  background: #FFFDF6;
  border: 2px solid #2A2C33;
  border-radius: 360px;
  color: #17181C;
  cursor: pointer;
  white-space: nowrap;
  box-shadow: 2px 3px 0 rgba(42,44,51,.35);
  transition: transform .18s var(--ease), background-color .18s, box-shadow .18s;
}
.poi__dot {
  flex: none;
  width: 14px; height: 14px;
  border: 3px solid #2A2C33;
  border-radius: 50%;
  background: var(--teal);
}
.poi--experience .poi__dot { background: var(--red); }
.poi--our .poi__dot        { background: var(--gold); }
.poi--attraction .poi__dot { background: var(--blue); }
/* pins that sit inside a sheet's exclave inset — the box is 280x200 of a
   1200x800 sheet, so a full-size pill would overflow it */
.poi--inset .poi__btn  { padding: 3px 9px 3px 4px; gap: 7px; }
.poi--inset .poi__dot  { width: 11px; height: 11px; border-width: 2px; }
.poi--inset .poi__name { font-size: 11.5px; }
.poi__name {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .02em;
}
.poi__btn:hover, .poi__btn:focus-visible {
  transform: translateY(-2px);
  background: var(--gold);
  box-shadow: 3px 5px 0 rgba(42,44,51,.5);
}
.poi[data-open="true"] .poi__btn { background: var(--gold); }

/* pulse ring so the pins read as interactive */
.poi__btn::after {
  content: '';
  position: absolute;
  left: 11px; top: 50%;
  width: 14px; height: 14px;
  margin-top: -7px;
  border: 2px solid var(--teal);
  border-radius: 50%;
  animation: poi-pulse 2.6s ease-out infinite;
  pointer-events: none;
}
.poi--experience .poi__btn::after { border-color: var(--red); }
.poi--our .poi__btn::after        { border-color: var(--gold); }
.poi--attraction .poi__btn::after { border-color: var(--blue); }
.poi--inset .poi__btn::after      { left: 8px; width: 11px; height: 11px; margin-top: -5.5px; }
@keyframes poi-pulse {
  0%        { transform: scale(1);   opacity: .75; }
  70%, 100% { transform: scale(2.6); opacity: 0; }
}

/* ---- hover card ---- */
.poi__card {
  position: absolute;
  top: 50%;
  z-index: 20;
  width: 268px;
  padding: 18px 20px 20px;
  background: var(--paper);
  color: #17181C;
  border: 2px solid #2A2C33;
  box-shadow: 6px 8px 0 rgba(42,44,51,.28);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-46%) scale(.96);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility 0s .18s;
  pointer-events: none;
}
.poi[data-side="right"] .poi__card { left: calc(100% + 14px); }
.poi[data-side="left"]  .poi__card { right: calc(100% + 14px); }

.poi:hover .poi__card,
.poi:focus-within .poi__card,
.poi[data-open="true"] .poi__card {
  opacity: 1;
  visibility: visible;
  transform: translateY(-50%) scale(1);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility 0s;
  pointer-events: auto;
}
.poi:hover, .poi:focus-within, .poi[data-open="true"] { z-index: 30; }

.poi__kicker {
  font-size: 11px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--terra);
  margin-bottom: 8px;
}
.poi__title {
  font-family: var(--font-display);
  font-size: 20px; line-height: 1.05; text-transform: uppercase;
  margin-bottom: 8px;
}
.poi__text { font-size: 14.5px; line-height: 1.5; color: #3A3C44; }
.poi__link {
  display: inline-block;
  margin-top: 14px;
  font-size: 13px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--terra);
  border-bottom: 2px solid currentColor;
}
.poi__link:hover { color: #17181C; }

/* legend, taped into the corner of the sheet */
.map__key {
  position: absolute;
  left: 16px; bottom: 16px;
  z-index: 6;
  display: flex; flex-direction: column; gap: 7px;
  padding: 13px 17px 14px;
  background: #FFFDF6;
  border: 2px solid #2A2C33;
  box-shadow: 3px 4px 0 rgba(42,44,51,.28);
  transform: rotate(-1deg);
}
.map__key li {
  display: flex; align-items: center; gap: 9px;
  font-size: 12.5px; font-weight: 600;
  color: #2A2C33;
}
.map__key-dot {
  width: 13px; height: 13px;
  border: 3px solid #2A2C33;
  border-radius: 50%;
}
.map__key-dot--district   { background: var(--teal); }
.map__key-dot--experience { background: var(--red); }
.map__key-dot--office     { background: var(--gold); }
.map__key-dot--attraction { background: var(--blue); }

/* legend + hint */
.map__hint {
  display: none;
  margin-top: 14px;
  font-size: 13px; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(23,24,28,.55);
  text-align: center;
}

/* shared detail panel — the phone-sized replacement for anchored cards.
   Desktop uses the anchored hover cards instead, so it stays hidden there. */
.map__detail {
  display: none;
  margin-top: 20px;
  padding: 22px 22px 24px;
  background: var(--paper);
  border: 2px solid #2A2C33;
  box-shadow: 5px 6px 0 rgba(42,44,51,.25);
}

@media (max-width: 1199.98px) {
  .poi__card { width: 240px; }
  .poi__name { font-size: 12px; }

  /* Hold the sheet at a usable size and let it pan, from here down — not just
     on phones. Below the two-column breakpoint the content column narrows much
     faster than a 1200x800 sheet carrying 24 labelled pins can usefully
     shrink: at an 810px viewport the wrap is 690px, which made the emirate
     picker 29% of the frame and sat it squarely on top of the Deira pin. */
  .map__frame { min-width: 860px; aspect-ratio: 16 / 11; }
  .map__scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    border-bottom: 2px dashed rgba(42,44,51,.3);
    padding-bottom: 10px;
  }
}

@media (max-width: 809.98px) {
  /* Too little room for anchored cards — the active pin fills one shared
     panel underneath instead. */
  .map__hint { display: block; }
  .poi__card { display: none; }
  .map__detail:not([hidden]) { display: block; }
  .poi__name { font-size: 12.5px; }
  .map__tape { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .poi__btn::after { animation: none; opacity: 0; }
}

/* ---------------------------------------------------------------- 10 cards */

.card {
  position: relative;
  display: flex; flex-direction: column;
  gap: 22px;
  padding: 14px 14px 26px;
  background:
    linear-gradient(rgba(255,255,255,.035), rgba(255,255,255,.015)),
    #15171E;
  transition: transform .3s var(--ease);
}
.card::before {
  content: '';
  position: absolute; inset: 0;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='c'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.6' numOctaves='4'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23c)' opacity='.5'/%3E%3C/svg%3E");
  opacity: .18;
  mix-blend-mode: overlay;
  pointer-events: none;
}
.card > * { position: relative; z-index: 1; }
.card:hover { transform: translateY(-6px) rotate(-.35deg); }
.card__media { position: relative; aspect-ratio: 10 / 7; }
.card__media .rip { width: 100%; height: 100%; }
.card__body { display: flex; flex-direction: column; gap: 12px; padding-inline: 10px; }
.card__title {
  font-family: var(--font-display);
  font-size: 24px; line-height: 1.05;
  text-transform: uppercase;
  color: var(--white);
}
.card__meta { font-size: 14px; letter-spacing: .1em; text-transform: uppercase; color: var(--gold); }
.card__text { font-size: 16px; line-height: 1.55; color: rgba(255,255,255,.76); }
.card__foot { margin-top: auto; padding: 4px 10px 0; }

/* Bare card — a tour Maventa has named but not yet described. Same frame and
   same button as a written one, so the grid keeps its rhythm; the media well
   holds the abstract wash above rather than a stock photo standing in for a
   helicopter tour, and the body is the name alone rather than an invented
   sentence. See design.md 4.13c.
   The media keeps .card's 10/7 ratio but is shortened: without an excerpt the
   card is two elements tall, and a full-height panel over one line of title
   reads as an image that failed to load. */
.card--bare .card__media { aspect-ratio: 16 / 7; }
/* Do not stretch to a photo card's height. Grid items default to `stretch`,
   and .card__foot is margin-top:auto, so a bare card sharing a row with two
   written ones grew a void between its title and its button. The section
   already staggers rows on purpose, so a shorter card reads as the rhythm
   rather than as a gap. */
.card--bare { align-self: start; }
.card--bare .card__body { gap: 0; }
.card--bare .card__title { color: rgba(255,255,255,.94); }
.card--bare:hover .card__title { color: var(--gold); }

/* --- attraction card: the tour card plus a price -------------------------- */
/* The price sits ON the photograph rather than in the body, because it is the
   thing a visitor scans a rate list for and the body is only two lines. */
.card__price {
  position: absolute; z-index: 2; right: 10px; top: 10px;
  padding: 6px 12px 7px;
  background: var(--gold); color: #12141A;
  font-family: var(--font-display); font-size: 15px; line-height: 1;
  text-transform: uppercase; letter-spacing: .02em;
  transform: rotate(-2deg);
}
/* "Closed" is a real value in this table, not a missing price, so it says so
   plainly instead of showing an empty tag or hiding the card. */
/* Not var(--red): white on #fa371e measures 4.04:1, under the 4.5 floor for
   15px text. Darkened just far enough to clear it while still reading as the
   same signal red. */
.card__price--closed { background: #D0331A; color: #fff; }
.card--att .card__body { gap: 6px; }
.card--att .card__title { font-size: 21px; }
/* Names in this set run long ("Dubai Mall Underwater Zoo & Aquarium —
   standard ticket"), so the body must not stretch its neighbours. */
.card--att { align-self: start; }

/* Attraction page: the headline price and the ticket tiers. */
.attprice {
  font-family: var(--font-display); font-size: clamp(40px, 6vw, 64px);
  line-height: 1; color: var(--gold); text-transform: uppercase;
}
.attprice--closed { color: var(--red); font-size: clamp(28px, 4.4vw, 44px); }
.attopts {
  display: grid; gap: 10px; width: 100%;
  max-width: 760px; margin-inline: auto;
}
.attopts li {
  position: relative; padding: 14px 18px 15px 40px;
  background: rgba(0,0,0,.24);
  border: 1px solid rgba(255,255,255,.22);
  font-size: 16px; line-height: 1.5; color: #fff;
}
.attopts li::before {
  content: ''; position: absolute; left: 17px; top: 1.35em;
  width: 9px; height: 5px;
  border-left: 2px solid var(--gold); border-bottom: 2px solid var(--gold);
  transform: rotate(-45deg);
}

/* deliberate row stagger — the grid must never read as machine-aligned */
.grid-3 > .card:nth-child(3n+2) { transform: translateY(26px); }
.grid-3 > .card:nth-child(3n+3) { transform: translateY(12px); }
.grid-3 > .card:nth-child(3n+2):hover { transform: translateY(20px) rotate(-.35deg); }
.grid-3 > .card:nth-child(3n+3):hover { transform: translateY(6px) rotate(.35deg); }
@media (max-width: 809.98px) {
  .grid-3 > .card:nth-child(n) { transform: none; }
  .grid-3 > .card:nth-child(n):hover { transform: translateY(-4px); }
}

/* Service card — icon-led, on the colour band or dark */
.svc {
  position: relative;
  padding: 34px 30px 36px;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.13);
  transition: background .25s, border-color .25s, transform .25s var(--ease);
}
.svc:hover { background: rgba(255,255,255,.09); border-color: var(--teal); transform: translateY(-4px); }
.svc__no {
  font-family: var(--font-display);
  font-size: 14px; letter-spacing: .18em;
  color: var(--teal);
  margin-bottom: 18px;
}
/* teal on terracotta is too low-contrast — switch the index to gold there */
.section--band .svc__no { color: var(--gold); }
.section--band .svc { border-color: rgba(255,255,255,.24); }
.section--band .svc:hover { border-color: var(--gold); }
.section--band .svc__text { color: rgba(255,255,255,.88); }
.svc__title {
  font-family: var(--font-display);
  font-size: 26px; line-height: 1.05; text-transform: uppercase;
  margin-bottom: 12px;
}
.svc__text { font-size: 16px; line-height: 1.6; color: rgba(255,255,255,.75); }
/* the four capability boxes carry a number + label only — the full .svc
   padding left them reading as empty cards */
.svc--label { padding: 22px 24px 24px; }
.svc--label .svc__no { margin-bottom: 12px; }
.svc--label .svc__title { font-size: 22px; margin-bottom: 0; }

/* Clickable capability card. The link wraps only the title, and ::after
   stretches it over the whole card — so there is one link per card for a
   screen reader (not a second empty one), the card is entirely clickable, and
   the text stays selectable. .svc is already position: relative. */
.svc--link { padding-right: 46px; }
.svc__link { color: inherit; }
.svc__link::after { content: ''; position: absolute; inset: 0; }
.svc__go {
  position: absolute; right: 20px; bottom: 20px;
  font-size: 19px; line-height: 1; color: var(--gold);
  opacity: .5; transition: opacity .25s var(--ease), transform .25s var(--ease);
  /* it sits after the link in DOM order, so without this it paints over the
     stretched ::after and the corner of the card stops being clickable —
     a dead zone exactly where the affordance says to click */
  pointer-events: none;
}
.svc--link:hover .svc__go { opacity: 1; transform: translateX(4px); }
.svc--link:hover .svc__title { color: var(--gold); }
/* the link is the focusable element, so the ring has to show on the card */
.svc__link:focus-visible { outline: none; }
.svc--link:focus-within { outline: 3px solid var(--gold); outline-offset: 3px; }

/* Anchor targets on /services: the header is fixed and its bottom edge sits at
   176px on desktop (the badge overhangs), 120px below 810px — so an un-offset
   jump parks the target card underneath it. Measured, not guessed: 120px was
   the first attempt and still landed under the header. */
.svc[id] { scroll-margin-top: 208px; }
@media (max-width: 809.98px) { .svc[id] { scroll-margin-top: 152px; } }

/* Note card — coloured torn paper, tape header (the "parking cards" pattern) */
.note {
  position: relative;
  padding: 26px 26px 32px;
  background: var(--blue);
  color: var(--white);
  text-align: center;
  clip-path: polygon(
    1% 4%, 22% 0, 44% 5%, 68% 1%, 88% 6%, 100% 2%,
    99% 96%, 78% 100%, 55% 95%, 32% 100%, 12% 95%, 0 99%
  );
}
.note--teal { background: var(--teal-deep); }
.note--terra { background: var(--terra); }
.note__head { margin: -8px 0 18px; }
.note__text { font-size: 16px; line-height: 1.6; }
.note__link { display: inline-block; margin-top: 16px; color: var(--gold); font-weight: 700; }
.note__link:hover { text-decoration: underline; }

/* Team card */
.person { text-align: center; }
.person__photo { aspect-ratio: 3 / 4; margin-bottom: 18px; }
.person__photo .rip { width: 100%; height: 100%; }
.person__name { font-family: var(--font-display); font-size: 22px; text-transform: uppercase; }
.person__role {
  font-size: 12px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--orange); margin-top: 8px;
}

/* ---------------------------------------------------------------- 10b visa */

/* Unsupplied copy, rendered so it cannot be mistaken for content. Any page
   still containing one of these is written noindex and kept out of the
   sitemap — see sitekit.page(). The dashed gold reads as "unfinished" against
   every surface the site has, which a grey lorem block does not. */
.tbd {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 13px; font-weight: 600; letter-spacing: .04em;
  text-transform: none; color: var(--gold);
  background: rgba(255,198,30,.08);
  border: 1px dashed rgba(255,198,30,.6);
  padding: 5px 11px;
}
.tbd::before {
  content: 'ADD';
  font-weight: 800; letter-spacing: .14em; opacity: .7;
  margin-right: .62em;   /* a trailing space inside content() collapses */
}
.tbd--block {
  display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 104px; padding: 24px 20px; text-align: center;
}
/* gold on terracotta is the one surface it washes out on — same rule the
   .svc__no index needed */
.section--band .tbd {
  color: #fff; background: rgba(0,0,0,.26); border-color: rgba(255,255,255,.65);
}

/* Hub cards. Typographic rather than photographic on purpose: there is no
   visa imagery in the library, and a Dubai skyline standing in for a Schengen
   visa would be decoration pretending to be information. */
.visa-card {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 14px;
  padding: 36px 30px 30px;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.13);
  transition: background .25s, border-color .25s, transform .25s var(--ease);
}
.visa-card > * { position: relative; z-index: 1; }
.visa-card:hover {
  background: rgba(255,255,255,.09); border-color: var(--teal);
  transform: translateY(-6px) rotate(-.35deg);
}
.visa-card__ghost {
  position: absolute; z-index: 0; right: -10px; bottom: -38px;
  font-family: var(--font-display); font-size: 122px; line-height: .8;
  color: rgba(255,255,255,.055); pointer-events: none;
}
.visa-card__region {
  font-size: 13px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gold);
}
.visa-card__name {
  font-family: var(--font-display); font-size: 30px; line-height: 1.02;
  text-transform: uppercase;
}
.visa-card__text { font-size: 16px; line-height: 1.6; color: rgba(255,255,255,.76); }
.visa-card__foot { margin-top: auto; padding-top: 10px; }

/* Title-only variant. With the region, blurb and button gone the card would
   collapse to one line of type in a 36px-padded box, so it holds a minimum
   height and drops its name to the floor — the ghost numeral behind it needs
   room to read as a numeral rather than as a stray shape.
   The whole card is the link (stretched ::after). .visa-card__go is the
   affordance only: pointer-events:none, or it paints over that ::after and
   kills clicks in its own corner, exactly as .svc__go once did. */
.visa-card--bare {
  justify-content: flex-end;
  min-height: 190px;
  padding: 30px;
  /* Creates a stacking context so the ghost numeral can go to z-index -1:
     see below. Without it, -1 would put the numeral behind the card's own
     background and it would vanish. */
  isolation: isolate;
}
/* `.visa-card > * { position: relative }` above made the <h3> the containing
   block for the link's ::after, so `inset: 0` stretched it over the TITLE
   rather than the card — 103 of 121 sampled points on the card were dead.
   Static here hands the job back to .visa-card, which is position:relative.
   The numeral then has to drop below the content it no longer outranks. */
.visa-card--bare .visa-card__name { position: static; }
.visa-card--bare .visa-card__ghost { z-index: -1; }
.visa-card__link { display: inline-block; }
.visa-card__link::after { content: ''; position: absolute; inset: 0; z-index: 2; }
.visa-card--bare:hover .visa-card__link,
.visa-card__link:focus-visible { color: var(--gold); }
.visa-card__go {
  position: absolute; z-index: 1; right: 26px; top: 26px;
  font-size: 22px; line-height: 1; color: var(--teal);
  pointer-events: none;
  transition: transform .25s var(--ease);
}
.visa-card--bare:hover .visa-card__go { transform: translate(4px, -4px); }
@media (max-width: 809.98px) { .visa-card--bare { min-height: 148px; } }

/* Photo-free hero, for a page whose photography has not been supplied yet.
   A flat colour under the standard scrim reads as an empty black band, so this
   paints its own backdrop: a warm dune wash up from the lower left, a teal one
   down from the upper right, and the mesh weave over both. The scrim is
   dropped — unlike a photograph this backdrop is already dark and under our
   control, and the white H1 sits over the brightest point at 9.1:1. */
/* One definition, two users: the hero and the bare tour card. Both stand in
   for a photograph that does not exist, and two copies of a five-layer
   gradient would drift the first time either was touched. */
.hero--plain .hero__media,
.card--bare .card__media {
  background-color: #0E1017;
  background-image:
    radial-gradient(88% 66% at 14% 106%, rgba(245,129,31,.40), transparent 64%),
    radial-gradient(64% 56% at 92% 2%,   rgba(0,191,178,.22), transparent 62%),
    repeating-linear-gradient(45deg,  rgba(255,255,255,.05) 0 1px, transparent 1px 18px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.05) 0 1px, transparent 1px 18px);
}
.hero--plain .hero__media::after { background: none; }

/* Fee / spec cards — one per variant. Schengen has one, Turkey two, UAE four,
   so the grid has to look deliberate at all three counts: auto-fit settles on
   two columns inside the 800px cap, and --one narrows it so a lone card is not
   an 800px banner. Almost no prices were supplied (South Korea is the only
   exception), hence the "Request price" link where a figure would sit. */
.vplans {
  display: grid; gap: 22px; width: 100%;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  max-width: 800px; margin-inline: auto;
}
.vplans--one { max-width: 420px; }
.vplan {
  display: flex; flex-direction: column; gap: 16px;
  padding: 28px 26px 24px;
  /* .28 not .16: the gold "Request price" link only reaches 4.2:1 on the
     lighter card and it is 13px, so it is not large text. Darkening the card
     takes it to 5.2:1. */
  background: rgba(0,0,0,.28);
  border: 1px solid rgba(255,255,255,.28);
}
.vplan__name {
  font-family: var(--font-display); font-size: 20px; line-height: 1.1;
  text-transform: uppercase; color: #fff;
}
.vplan__facts { margin: 0; }
.vplan__facts > div {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 9px 0; border-top: 1px solid rgba(255,255,255,.22);
}
.vplan__facts dt {
  flex: none;
  font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: rgba(255,255,255,.78);
}
.vplan__facts dd { margin: 0; font-size: 15px; color: #fff; text-align: right; }
.vplan__ask {
  margin-top: auto; align-self: flex-start;
  font-size: 13px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--gold); border-bottom: 2px solid currentColor;
}
.vplan__ask:hover { color: #fff; }

/* Titled supplementary lists (requirements, special notes, cancellation…). */
.vblock { width: 100%; }
.vblock__title {
  font-family: var(--font-display); font-size: 26px; line-height: 1.1;
  text-transform: uppercase; margin-bottom: 20px;
}
.vlist { display: flex; flex-direction: column; gap: 12px; }
.vlist li {
  position: relative; padding-left: 24px;
  font-size: 16px; line-height: 1.6; color: rgba(255,255,255,.8);
}
.vlist li::before {
  content: ''; position: absolute; left: 0; top: .62em;
  width: 9px; height: 9px; background: var(--teal);
}

/* Document checklist. */
.vdocs {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px 40px;
  width: 100%; margin-top: 4px;
}
.vdocs li {
  position: relative; padding-left: 30px;
  font-size: 17px; line-height: 1.6; color: rgba(255,255,255,.82);
}
.vdocs li::before {
  content: ''; position: absolute; left: 0; top: .46em;
  width: 14px; height: 14px; border: 2px solid var(--teal);
}

/* Fact strip — shared by the tour pages ("Before you go") and the visa pages.
   Flex, not an auto-fit grid: with 5 facts a 4-column grid left one cell
   stranded beside 750px of empty row. A centred last row balances any count. */
.facts {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 0 22px;
  max-width: 1040px; margin-inline: auto; width: 100%;
}
.fact { flex: 1 1 168px; max-width: 260px; padding: 24px 4px;
        border-top: 1px solid rgba(255,255,255,.45); }
.fact dt {
  font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: rgba(255,255,255,.8); margin-bottom: 10px;
}
.fact dd { margin: 0; font-size: 17px; line-height: 1.45; color: #fff; }

@media (max-width: 809.98px) {
  .fact { flex: 1 1 44%; max-width: none; }
  .vdocs { grid-template-columns: 1fr; }
  .visa-card__name { font-size: 26px; }
  .visa-card__ghost { font-size: 96px; }
  .vblock__title { font-size: 22px; }
}

/* ------------------------------------------------- 10c destination cards */
/* International Tour Packages: flag, country, one action. Modelled on .svc so
   the two service pages feel like the same site. */
.flagcard {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  padding: 30px 24px 28px;
  text-align: center;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.13);
  transition: background .25s, border-color .25s, transform .25s var(--ease);
}
.flagcard:hover {
  background: rgba(255,255,255,.09); border-color: var(--teal);
  transform: translateY(-4px);
}
/* Constrained by HEIGHT, never width. Seven of the nine flags are 3:2 and two
   (Malaysia, Azerbaijan) are 2:1; a fixed width would squash those two, and a
   squashed flag is a wrong flag. The width/height attributes come from each
   SVG's own viewBox, so the box is reserved correctly before it loads. */
.flagcard__flag {
  height: 70px; width: auto; display: block;
  /* Japan and Georgia are white fields, and Indonesia and Singapore are white
     across their lower half — without an edge they would bleed into the card
     and stop reading as flags. outline, not border: it does not join the box
     model, so it cannot alter the aspect ratio the attributes just set. */
  outline: 1px solid rgba(255,255,255,.3);
}
.flagcard__name {
  font-family: var(--font-display);
  font-size: 24px; line-height: 1.05; text-transform: uppercase;
}
/* .grid-3 steps 3 -> 2 -> 1, so at the 2-column stage the ninth card sits
   alone on the last row. Left alone deliberately: every card here is the same
   height, so a lone one reads as the end of a list rather than as a gap, and
   overriding the shared grid for one page would make this the only listing on
   the site that steps differently. */
@media (max-width: 809.98px) {
  .flagcard__flag { height: 58px; }
  .flagcard__name { font-size: 21px; }
}

/* ------------------------------------------------------------ 11 accordion */

.acc { display: flex; flex-direction: column; }
.acc__item { border-bottom: 1px solid rgba(255,255,255,.4); }
.acc__item[data-open="true"] { border-bottom-color: var(--gold); }
.acc__btn {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 26px 0;
  background: none; border: 0;
  text-align: left;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.3;
  color: var(--white);
  cursor: pointer;
}
.acc__icon {
  position: relative;
  flex: none;
  width: 20px; height: 20px;
}
.acc__icon::before, .acc__icon::after {
  content: '';
  position: absolute; left: 50%; top: 50%;
  background: currentColor;
  transform: translate(-50%, -50%);
  transition: transform .28s var(--ease), opacity .2s;
}
.acc__icon::before { width: 18px; height: 2.5px; }
.acc__icon::after  { width: 2.5px; height: 18px; }
.acc__item[data-open="true"] .acc__icon::after { transform: translate(-50%,-50%) rotate(90deg); opacity: 0; }
.acc__item[data-open="true"] .acc__btn { color: var(--gold); }
.acc__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s var(--ease);
}
.acc__item[data-open="true"] .acc__panel { grid-template-rows: 1fr; }
.acc__panel > div { overflow: hidden; }
.acc__panel p { padding-bottom: 26px; font-size: 17px; line-height: 1.6; color: rgba(255,255,255,.85); }

.section--band .acc__item { border-bottom-color: rgba(255,255,255,.45); }
.section--band .acc__item[data-open="true"] { border-bottom-color: var(--gold); }

/* ---------------------------------------------------------------- 12 forms */

.form-card {
  position: relative;
  max-width: 880px;
  margin-inline: auto;
  padding: 56px clamp(24px, 5vw, 72px) 64px;
  background: var(--paper);
  color: #17181C;
  clip-path: polygon(
    0.5% 2%, 18% 0, 39% 3%, 61% 0, 82% 3%, 100% 1%,
    99.5% 97%, 80% 100%, 58% 97%, 36% 100%, 16% 97%, 0 99%
  );
}
.form-card::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, transparent 32%, rgba(0,0,0,.05) 32.2%, transparent 32.5%),
    linear-gradient(90deg, transparent 68%, rgba(0,0,0,.04) 68.2%, transparent 68.5%);
  pointer-events: none;
}
.form-card > * { position: relative; z-index: 1; }
.form { display: grid; gap: 10px; margin-top: 34px; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 809.98px) { .form__row { grid-template-columns: 1fr; } }
.field { position: relative; }
.field input, .field textarea {
  width: 100%;
  padding: 20px 4px 16px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(23,24,28,.38);
  border-radius: 0;
  font-family: var(--font-body);
  font-size: 16px;
  color: #17181C;
}
.field textarea { min-height: 120px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: rgba(23,24,28,.45); }
.field input:focus, .field textarea:focus {
  outline: none;
  border-bottom-color: var(--terra);
  border-bottom-width: 2px;
  padding-bottom: 15px;
}
.field label {
  display: block;
  font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: rgba(23,24,28,.6);
}
.form__actions { margin-top: 22px; text-align: center; }
.form__note { margin-top: 16px; font-size: 13px; color: rgba(23,24,28,.6); text-align: center; }
/* Submit result. A separate element from .form__note so the note's WhatsApp
   link survives a submit instead of being overwritten by the outcome, and so
   the live region starts empty — an aria-live node that already has text in it
   announces nothing when that text is what changes. */
.form__status {
  margin-top: 16px; text-align: center;
  font-size: 14px; font-weight: 600; line-height: 1.5;
  color: rgba(23,24,28,.7);
}
.form__status:empty { display: none; }   /* no gap before anything is said */
.form__status--ok  { color: #1B6B39; }
.form__status--bad { color: #A32E0C; }

/* ------------------------------------------------------- 13 testimonials */

.quotes { position: relative; }
.quote-track {
  display: flex;
  gap: 32px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding-bottom: 8px;
  /* Bleed to the viewport edge so a partially visible card reads as
     "there is more to scroll", not as clipped text. */
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  scroll-padding-inline: var(--gutter);
}
.quote-track::-webkit-scrollbar { display: none; }
.quote {
  flex: 0 0 min(560px, 84vw);
  scroll-snap-align: center;
  position: relative;
  padding: 46px 44px 40px;
  background: #EFE7D6;
  color: #16171B;
  transform: rotate(-1.1deg);
  clip-path: polygon(
    1% 3%, 20% 0, 42% 4%, 64% 0, 86% 4%, 100% 1%,
    99% 97%, 78% 100%, 56% 96%, 34% 100%, 14% 96%, 0 99%
  );
}
.quote:nth-child(even) { transform: rotate(1.2deg); }
.quote__text { font-size: 19px; line-height: 1.55; font-weight: 500; }
.quote__by { margin-top: 22px; color: #A8541A; font-weight: 700; }
.quote__src { font-size: 13px; color: rgba(22,23,27,.55); margin-top: 4px; }
.quotes--single .quote-track { justify-content: center; }
.quotes--single .quote { flex: 0 1 min(720px, 100%); }
.quotes__ctrl { display: flex; gap: 12px; justify-content: center; margin-top: 34px; }
.quotes__ctrl button {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border: 2px solid rgba(255,255,255,.35);
  border-radius: 50%;
  background: rgba(0,0,0,.2);
  color: var(--white);
  cursor: pointer;
  transition: border-color .2s, background .2s, color .2s;
}
.quotes__ctrl button:hover { border-color: var(--gold); color: var(--gold); }

/* --------------------------------------------------------------- 14 footer */

.site-footer {
  position: relative;
  /* 88px, not 48px: the chat fab is fixed 22px off the bottom and ~42px tall,
     so it owns the bottom ~64px of the viewport. At 48px the footer's last row
     ended inside that zone and the fab sat on the "Get in touch" link — 45%
     covered at 700px even with the short label. Reserving the zone fixes it
     for any label length instead of only the current one. */
  padding: 120px 0 88px;
  background: #0C0E13;
  overflow: hidden;
}
.footer-watermark {
  position: absolute;
  left: -60px; bottom: -34px;
  font-family: var(--font-display);
  font-size: 210px;
  line-height: .8;
  text-transform: uppercase;
  color: rgba(255,255,255,.022);
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
}
.footer-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 48px; }
@media (max-width: 809.98px) { .footer-cols { grid-template-columns: 1fr; gap: 40px; } }
/* Centred: heading tape, body lines and menu items alike. The socials are a
   flex row and the sub-list links are inline-blocks, so neither inherits
   text-align — both are centred on their own axis below. */
.footer-col { text-align: center; }
.footer-col__head { margin-bottom: 24px; }
.footer-col p, .footer-col li { font-size: 16px; line-height: 1.7; color: rgba(255,255,255,.82); }
.footer-col a:hover { color: var(--gold); }

/* "Visa & Travel" reveals the visa pages on hover (capped in sitekit.footer,
   with an "all visas" tail — the full list is 15).
   grid-template-rows 0fr rather than display:none, because display:none takes
   the links out of the tab order — and then :focus-within can never fire from
   inside, so the sub-list would be unreachable by keyboard. At 0fr the links
   are still focusable, so tabbing in expands it as you arrive. */
.fsub__top { font-weight: 600; }
.fsub__top::after {
  content: ''; display: inline-block; margin-left: 8px;
  width: 5px; height: 5px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -2px);
  transition: transform .3s var(--ease);
}
.fsub__wrap {
  display: grid; grid-template-rows: 0fr; opacity: 0;
  transition: grid-template-rows .3s var(--ease), opacity .22s;
}
.fsub__list { overflow: hidden; }
.fsub__list li { font-size: 15px; }
/* Each link carried a teal dash at its left edge. That was an indent marker for
   a left-aligned list, where the dashes stacked into a clean vertical rule.
   Centred, every item centres on its own width, so the dashes landed at seven
   different x positions — a ragged edge that read as a mistake. The sub-list is
   already marked as subordinate by being smaller, dimmer, and only present
   under Visa Services, so the dash is dropped rather than re-placed. */
.fsub__list a {
  display: inline-block;
  padding: 3px 6px;
  color: rgba(255,255,255,.66);
}
.fsub:hover .fsub__wrap,
.fsub:focus-within .fsub__wrap { grid-template-rows: 1fr; opacity: 1; }
.fsub:hover .fsub__top::after,
.fsub:focus-within .fsub__top::after { transform: rotate(-135deg) translate(-2px, -1px); }

/* No hover means no way to reveal it, so on touch it simply stays open. */
@media (hover: none) {
  .fsub__wrap { grid-template-rows: 1fr; opacity: 1; }
  .fsub__top::after { transform: rotate(-135deg) translate(-2px, -1px); }
}
.footer-socials { display: flex; justify-content: center; gap: 12px; margin-top: 20px; }
.footer-socials a {
  display: grid; place-items: center;
  width: 42px; height: 42px;
  border: 1.5px solid rgba(255,255,255,.35);
  border-radius: 50%;
  transition: border-color .2s, color .2s;
}
.footer-socials a:hover { border-color: var(--gold); color: var(--gold); }
.footer-socials svg { width: 18px; height: 18px; }
.footer-nav {
  display: flex; flex-wrap: wrap; gap: 16px; justify-content: center;
  margin-top: 76px;
}
.footer-partners { margin-top: 64px; text-align: center; }
.footer-partners__rule {
  display: flex; align-items: center; gap: 22px;
  color: rgba(255,255,255,.75);
  font-size: 14px; letter-spacing: .16em; text-transform: uppercase;
}
.footer-partners__rule::before, .footer-partners__rule::after {
  content: ''; flex: 1; height: 1px; background: rgba(255,255,255,.22);
}
.footer-legal {
  display: flex; flex-wrap: wrap; gap: 12px 40px; justify-content: center;
  margin-top: 56px;
  font-size: 14px; letter-spacing: .06em; text-transform: uppercase;
  color: rgba(255,255,255,.66);
}
.footer-legal a:hover { color: var(--gold); }

/* -------------------------------------------------------- 15 chat widget */

.chat-fab {
  position: fixed;
  right: 22px; bottom: 22px;
  z-index: 300;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 10px 18px 10px 12px;
  background: var(--white);
  color: #101014;
  border-radius: 360px;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: .08em;
  text-transform: uppercase;
  box-shadow: 0 8px 26px rgba(0,0,0,.45);
  transition: transform .2s var(--ease);
}
.chat-fab:hover { transform: translateY(-3px); }
.chat-fab svg { width: 22px; height: 22px; color: #25D366; }
/* "Chat with us!" makes the pill 178px. That is fine down to 480px, where it
   is 37% of the screen and overlaps nothing — but below that it starts sitting
   on the hero's Book Now button (2% at 390px, rising to 20% at 320px) while
   taking up to 56% of the width. One fixed button on top of another is a
   tap-target conflict, so phone portrait drops back to "Chat" (103px). The
   accessible name degrades with it, and "Chat" is still an accurate one. */
@media (max-width: 479.98px) { .chat-fab__more { display: none; } }

/* --------------------------------------------------------------- 16 motion */

.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.reveal[data-in="true"] { opacity: 1; transform: none; }
.reveal--left  { transform: translateX(-46px); }
.reveal--right { transform: translateX(46px); }
.reveal--left[data-in="true"], .reveal--right[data-in="true"] { transform: none; }
@media (max-width: 1199.98px) {
  /* a sideways start offset overflows narrow viewports before it animates in */
  .reveal--left, .reveal--right { transform: translateY(26px); }
}
.reveal[data-delay="1"] { transition-delay: .10s; }
.reveal[data-delay="2"] { transition-delay: .20s; }
.reveal[data-delay="3"] { transition-delay: .30s; }
.reveal[data-delay="4"] { transition-delay: .40s; }

.drop-in { animation: drop-in .8s var(--ease) both; animation-delay: .25s; }
@keyframes drop-in { from { opacity: 0; transform: translateY(-90px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; }
  .marquee__track { animation: none; }
  .badge__spin { animation: none; }
}

/* Print — strip the mess layer */
@media print {
  body::before, .doodle, .torn, .badge, .chat-fab, .nav-overlay { display: none !important; }
  body { background: #fff; color: #000; }
}

/* ============================================================
   10c · Dubai Experiences, tour packages, events calendar
   ============================================================ */

/* Highlights of Dubai — eight numbered tiles. Six of the eight have no page
   and no photograph, only a name, so the tile is typographic by necessity and
   the numeral does the decorating. Whole tile is the link (stretched ::after);
   .hl__cta is pointer-events:none or it paints over that ::after and kills
   clicks in its own corner. */
.hl-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(4, 1fr);
  width: 100%;
}
.hl {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 10px;
  min-height: 172px; padding: 22px 20px 18px;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.13);
  transition: background .25s, border-color .25s, transform .25s var(--ease);
}
.hl:hover { background: rgba(255,255,255,.09); border-color: var(--gold);
            transform: translateY(-5px) rotate(-.3deg); }
.hl__no {
  font-family: var(--font-display); font-size: 15px; letter-spacing: .12em;
  color: var(--teal);
}
.hl__name {
  font-family: var(--font-display); font-size: 22px; line-height: 1.05;
  text-transform: uppercase; margin-top: auto;
}
.hl__link::after { content: ''; position: absolute; inset: 0; z-index: 2; }
.hl:hover .hl__name { color: var(--gold); }
.hl__cta {
  font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: rgba(255,255,255,.6); pointer-events: none;
}
.hl:hover .hl__cta { color: var(--gold); }
@media (max-width: 1099.98px) { .hl-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 809.98px)  { .hl-grid { grid-template-columns: repeat(2, 1fr); }
                                .hl { min-height: 142px; }
                                .hl__name { font-size: 18px; } }
@media (max-width: 419.98px)  { .hl-grid { grid-template-columns: 1fr; }
                                .hl { min-height: 0; } }

/* Events calendar. Drawn by main.js from the [data-events] JSON so it is never
   a stale hard-coded month; with an empty list it is a working empty calendar
   rather than a broken one. Weeks start Monday, which is how the UAE working
   week is written even though its weekend is Sat/Sun. */
.cal {
  width: 100%; max-width: 860px; margin-inline: auto;
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.13);
  padding: 22px;
}
.cal__head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.cal__month {
  font-family: var(--font-display); font-size: 24px; text-transform: uppercase;
  letter-spacing: .01em;
}
.cal__nav {
  flex: none; width: 40px; height: 40px;
  display: grid; place-items: center;
  border: 1.5px solid rgba(255,255,255,.35); border-radius: 50%;
  background: none; color: inherit; font-size: 17px; cursor: pointer;
  transition: border-color .2s, color .2s;
}
.cal__nav:hover { border-color: var(--gold); color: var(--gold); }
.cal__dow, .cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px;
  /* both are <ol>: the global reset only clears markers on ul, so without
     this the week header rendered as "1. MON  2. TUE  3. WED". */
  list-style: none; }
.cal__dow {
  margin-top: 20px;
  font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: rgba(255,255,255,.5); text-align: center;
}
.cal__grid { margin-top: 6px; position: relative; }
/* Every grid child is a cell wrapper, event or not, so the 7 columns stay
   square and nth-child() can still count columns. */
.cal__cell { aspect-ratio: 1; display: grid; }
.cal__day {
  /* Relative because .cal__day--has::after (the event dot) is absolute and has
     to anchor to the DATE. It used to inherit this from the cell, but the cell
     is only positioned at >=810px now — below that the dots all resolved
     against .cal__grid instead and stacked in one spot at the foot of the
     grid. The dot belongs to the day, so the day carries the containing block.
     Safe for the card: .cal__pop is a sibling of this, not a child. */
  position: relative;
  display: grid; place-items: center;
  font-size: 15px; color: rgba(255,255,255,.82);
  border: 1px solid transparent;
}
/* A day with something on is a real <button> — the details have to be
   reachable without a mouse. Stripped back to look like the other dates. */
button.cal__day {
  font-family: inherit; background: none; color: rgba(255,255,255,.82);
  cursor: pointer; padding: 0; width: 100%; height: 100%;
}
button.cal__day:hover, button.cal__day:focus-visible { color: var(--gold); }
/* Adjacent-month days. Recessed, but not below readable: at .22 they measured
   2.05:1, which is a number you can see is there and cannot quite read — the
   worst of both. They stay distinguishable from the current month by weight
   and by carrying neither the event dot nor the today ring. */
.cal__day--pad { color: rgba(255,255,255,.56); }
.cal__day--today { border-color: var(--teal); color: #fff; font-weight: 700; }
/* A day with something on gets a dot, not a colour fill: the grid has to stay
   readable as dates first and as a chart second. */
.cal__day--has::after {
  content: ''; position: absolute; left: 50%; bottom: 14%;
  width: 5px; height: 5px; margin-left: -2.5px;
  border-radius: 50%; background: var(--gold);
}
/* Hover / focus card.

   Two layouts, because one does not work at both ends. On a phone the grid is
   about 42px per cell and the card is ~360px: anchoring it to the date puts it
   off-screen from EVERY column, and shifting the edge columns only changes
   which side it hangs off (measured: 20 of 21 cards outside the viewport at
   390px). So the small-screen card is not a tooltip on the date at all — it is
   a panel spanning the grid, one fixed position, nothing that can be clipped.

   The anchored-to-the-date version starts at 810px, where a cell is wide
   enough for it to make sense. Written as min-width rather than the file's
   usual max-width for that reason: the anchoring is the enhancement, not the
   default. */
.cal__pop {
  position: absolute; z-index: 6;
  top: calc(100% + 10px); left: 0; right: 0;
  padding: 15px 17px;
  text-align: left;
  background: #191B22;
  border: 1px solid rgba(255,255,255,.24);
  box-shadow: 0 14px 34px rgba(0,0,0,.55);
  opacity: 0; visibility: hidden;
  transition: opacity .16s var(--ease), visibility .16s;
  pointer-events: none;   /* never eats a hover meant for the date beneath */
}
.cal__cell:hover .cal__pop,
.cal__cell:focus-within .cal__pop { opacity: 1; visibility: visible; }

@media (min-width: 810px) {
  /* Positioned cell = the card resolves against the DATE. Below this width
     .cal__cell stays static and it resolves against .cal__grid instead. */
  .cal__cell { position: relative; }
  .cal__pop {
    top: calc(100% + 8px); left: 50%; right: auto;
    width: 360px; transform: translateX(-50%);
  }
  /* Even at 810px a 360px card centred on the outer columns runs past the
     edge, so the two columns each side anchor to that edge. nth-child counts
     every cell including the padding days, so this really is "which column"
     and not "which date". */
  .cal__grid > li:nth-child(7n+1) .cal__pop,
  .cal__grid > li:nth-child(7n+2) .cal__pop { left: 0; right: auto; transform: none; }
  .cal__grid > li:nth-child(7n+6) .cal__pop,
  .cal__grid > li:nth-child(7n)   .cal__pop { left: auto; right: 0; transform: none; }
}

.cal__pop-item + .cal__pop-item {
  margin-top: 13px; padding-top: 13px; border-top: 1px solid rgba(255,255,255,.16);
}
.cal__pop-when {
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--gold);
}
.cal__pop-name {
  font-family: var(--font-display); font-size: 18px; line-height: 1.1;
  text-transform: uppercase; margin-top: 5px;
}
.cal__pop-where { font-size: 13px; color: rgba(255,255,255,.72); margin-top: 3px; }
.cal__pop-note {
  font-size: 13.5px; line-height: 1.5; color: rgba(255,255,255,.8); margin-top: 8px;
}

.cal__list { margin-top: 22px; display: grid; gap: 12px; }
.cal__event-note {
  font-size: 14px; line-height: 1.55; color: rgba(255,255,255,.72);
  margin-top: 6px; max-width: 62ch;
}
.cal__event {
  display: flex; gap: 16px; align-items: baseline;
  padding-bottom: 12px; border-bottom: 1px solid rgba(255,255,255,.14);
}
.cal__event-when {
  flex: none; min-width: 108px;
  font-size: 13px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--gold);
}
.cal__event-name { font-family: var(--font-display); font-size: 19px; text-transform: uppercase; }
.cal__event-where { font-size: 14px; color: rgba(255,255,255,.7); }
.cal__empty { margin-top: 22px; color: rgba(255,255,255,.62); text-align: center; }
@media (max-width: 809.98px) {
  .cal { padding: 16px; }
  .cal__month { font-size: 19px; }
  .cal__day { font-size: 13px; }
  .cal__event { flex-direction: column; gap: 4px; }
  .cal__event-when { min-width: 0; }
}

/* ============================================================
   10d · Package listing (/services/dubai-tour-packages)
   ============================================================ */

/* Filter rail beside the rows. The rail is sticky on desktop so the controls
   stay put down a ten-row list; below 1024 it becomes a normal block above
   the rows, because a sticky sidebar on a narrow screen is a lid. */
.pkglist {
  display: grid; gap: 28px; width: 100%;
  grid-template-columns: 260px minmax(0, 1fr);
  align-items: start;
}
@media (max-width: 1023.98px) { .pkglist { grid-template-columns: 1fr; } }

.pfil {
  position: sticky; top: 200px;
  display: flex; flex-direction: column; gap: 22px;
  padding: 24px 22px;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.13);
}
@media (max-width: 1023.98px) { .pfil { position: static; } }
.pfil__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.pfil__title {
  font-family: var(--font-display); font-size: 21px; text-transform: uppercase;
}
.pfil__clear {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-size: 13px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--teal); border-bottom: 2px solid currentColor;
}
.pfil__clear:hover { color: var(--gold); }
.pfil__group { border: 0; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.pfil__legend {
  padding: 0 0 4px;
  font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: rgba(255,255,255,.55);
}
.pfil__opt {
  display: flex; align-items: center; gap: 10px;
  font-size: 15px; color: rgba(255,255,255,.86); cursor: pointer;
}
/* A real checkbox, restyled rather than replaced: accent-color keeps the
   native control, so it stays keyboard-operable and announces itself. */
.pfil__opt input { accent-color: var(--teal); width: 16px; height: 16px; cursor: pointer; }
.pfil__opt:hover { color: #fff; }
.pfil__n {
  margin-left: auto;
  /* .45 measured 4.38:1 at 12px — just under the 4.5 floor for body text.
     The count tells you whether a box is worth ticking, so it is content. */
  font-size: 12px; color: rgba(255,255,255,.56);
  font-variant-numeric: tabular-nums;
}
.pfil__count { font-size: 13px; color: rgba(255,255,255,.6); }

/* --- one package row ------------------------------------------------------
   Three zones: media well, details, action rail. The rail is where a price
   would sit on a normal travel listing; none was supplied, so it holds what
   IS known and ends at an enquiry. */
.pkglist__rows { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.prow {
  display: grid;
  grid-template-columns: 172px minmax(0, 1fr) 200px;
  gap: 0;
  background:
    linear-gradient(rgba(255,255,255,.035), rgba(255,255,255,.015)),
    #15171E;
  border: 1px solid rgba(255,255,255,.11);
  transition: border-color .25s, transform .25s var(--ease);
}
.prow:hover { border-color: var(--teal); transform: translateY(-3px); }

.prow__media {
  position: relative;
  display: grid; place-items: center;
  /* the photo-free wash again — no package photography was supplied */
  background-color: #0E1017;
  background-image:
    radial-gradient(88% 66% at 14% 106%, rgba(245,129,31,.40), transparent 64%),
    radial-gradient(64% 56% at 92% 2%,   rgba(0,191,178,.22), transparent 62%),
    repeating-linear-gradient(45deg,  rgba(255,255,255,.05) 0 1px, transparent 1px 18px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.05) 0 1px, transparent 1px 18px);
}
.prow__no {
  font-family: var(--font-display); font-size: 46px; line-height: 1;
  color: rgba(255,255,255,.42);
}

.prow__body { padding: 24px 26px; min-width: 0; }
.prow__name {
  font-family: var(--font-display); font-size: 24px; line-height: 1.08;
  text-transform: uppercase; color: var(--white);
}
.prow__meta {
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  margin-top: 8px;
  font-size: 14px; color: rgba(255,255,255,.72);
}
.prow__meta strong { color: var(--gold); font-weight: 700; }
.prow__where {
  margin-top: 4px;
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--teal);
}
/* Inclusions. Two columns from 600px up — these lists run to twelve items and
   a single column turns the row into a page. */
/* CSS columns, not a grid. A grid aligns rows, so a two-line item opposite a
   one-line item leaves a visible blank beside it — and these lists mix
   "Jet ski ride" with "Abu Dhabi city tour with Ferrari World / Warner Bros".
   Columns flow the items continuously instead, so the list closes up. */
.prow__inc {
  columns: 2; column-gap: 26px;
  margin-top: 16px;
}
.prow__inc li { break-inside: avoid; margin-bottom: 4px; }
@media (max-width: 599.98px) { .prow__inc { columns: 1; } }
.prow__inc li {
  position: relative; padding-left: 20px;
  font-size: 15px; line-height: 1.5; color: rgba(255,255,255,.8);
  list-style: none;
}
.prow__inc li::before {
  content: ''; position: absolute; left: 0; top: .48em;
  width: 9px; height: 5px;
  border-left: 2px solid var(--teal); border-bottom: 2px solid var(--teal);
  transform: rotate(-45deg);
}

/* The rail. Dashed rule rather than a border on the whole cell, so it reads
   as a tear-off stub like a ticket. */
.prow__rail {
  display: flex; flex-direction: column; justify-content: center; gap: 10px;
  padding: 24px 22px;
  border-left: 2px dashed rgba(255,255,255,.18);
  text-align: center;
}
.prow__railtop {
  font-family: var(--font-display); font-size: 22px; color: var(--gold);
}
.prow__ask { font-size: 13px; color: rgba(255,255,255,.62); }
.prow__acts { display: flex; align-items: center; justify-content: center; gap: 10px; }
.prow__wa {
  flex: none; display: grid; place-items: center;
  width: 38px; height: 38px;
  border: 1.5px solid rgba(255,255,255,.35); border-radius: 50%;
  color: #25D366;
  transition: border-color .2s, background .2s;
}
.prow__wa:hover { border-color: #25D366; background: rgba(37,211,102,.12); }
.prow__wa svg { width: 18px; height: 18px; }

.pkglist__empty {
  padding: 40px 20px; text-align: center;
  font-size: 17px; color: rgba(255,255,255,.7);
  border: 1px dashed rgba(255,255,255,.22);
}

/* Stack the three zones once the row cannot hold them side by side. The media
   well becomes a thin band rather than disappearing — it carries the number. */
@media (max-width: 809.98px) {
  .prow { grid-template-columns: 1fr; }
  .prow__media { min-height: 68px; }
  .prow__no { font-size: 34px; }
  .prow__body { padding: 20px; }
  .prow__name { font-size: 20px; }
  .prow__rail {
    border-left: 0; border-top: 2px dashed rgba(255,255,255,.18);
    flex-direction: row; flex-wrap: wrap; justify-content: space-between;
    padding: 16px 20px; text-align: left;
  }
  .prow__acts { margin-left: auto; }
}
@media (min-width: 810px) and (max-width: 1023.98px) {
  .prow { grid-template-columns: 128px minmax(0, 1fr) 168px; }
}
