/* ==========================================================================
   ZAEREEN — Ziyarat platform design system
   Powered by Oxford Travels

   Every token is --z- prefixed on purpose. The shared Oxford navbar/footer
   declare their own :root blocks that render after ours and would otherwise
   redefine generic names like --card-bg (see includes/footer_user.php, which
   drops --card-bg to 3% white and makes "solid" cards go see-through).
   Nothing in this file may be renamed to an unprefixed token.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Palette — Raudat Tahera
   White marble, gold inlay, deep dome green. The turquoise is the tilework
   accent found across Bohra masjid interiors; it carries wayfinding and
   secondary emphasis so the gold is never asked to do two jobs at once.
   -------------------------------------------------------------------------- */

:root {
    /* --- ground & surfaces --- */
    --z-marble:       #fbf8f0;
    --z-cream:        #f4ecda;
    --z-cream-deep:   #e9dec5;
    --z-surface:      #fffdf7;
    --z-surface-2:    #f7f0e0;

    /* --- ink --- */
    --z-ink:          #17201a;
    --z-ink-2:        #4b554a;
    --z-ink-3:        #7f8a7e;

    /* --- brand: dome green --- */
    --z-green:        #0d2c22;
    --z-green-2:      #14412f;
    --z-green-3:      #1f6047;
    --z-green-soft:   #dfeae1;

    /* --- brand: gold leaf --- */
    --z-gold:         #c19a3f;
    --z-gold-deep:    #8f6f1c;
    --z-gold-light:   #e3c886;
    --z-gold-pale:    #f2e6c6;
    --z-gold-wash:    #f6efdb;
    --z-gold-leaf:    linear-gradient(135deg, #efdca7 0%, #d4b158 26%, #b08d2c 54%, #e0c67f 78%, #c19a3f 100%);

    /* --- accent: tilework turquoise --- */
    --z-teal:         #12655f;
    --z-teal-light:   #3d9a92;
    --z-teal-wash:    #e0efec;

    /* --- lines & shadow --- */
    --z-line:         #ded1b3;
    --z-line-soft:    #ebe1ca;
    /* For rules that must stay legible on the deeper cream fills — a hairline
       at --z-line disappears against --z-cream-deep at small sizes. */
    --z-line-strong:  #cbb995;
    --z-line-gold:    rgba(193, 154, 63, .42);
    --z-shadow-sm:    0 1px 2px rgba(23, 32, 26, .05);
    --z-shadow:       0 2px 6px rgba(23, 32, 26, .06), 0 14px 34px -22px rgba(13, 44, 34, .38);
    --z-shadow-lg:    0 4px 12px rgba(23, 32, 26, .07), 0 30px 62px -34px rgba(13, 44, 34, .48);

    /* --- semantic (seat status) --- */
    --z-open:         #1b6349;
    --z-open-bg:      #dfeae1;
    --z-few:          #91600f;
    --z-few-bg:       #f7ecd6;
    --z-sold:         #8a3024;
    --z-sold-bg:      #f5e3df;

    /* --- type --- */
    --z-display: "Cormorant Garamond", "Times New Roman", Georgia, serif;
    --z-body:    "Jost", "Segoe UI", system-ui, -apple-system, sans-serif;
    --z-arabic:  "Amiri", "Traditional Arabic", serif;

    /* --- metrics --- */
    --z-shell:   1400px;
    --z-radius:  14px;
    --z-radius-sm: 9px;

    /* The pointed keel arch, as a mask for imagery. Same profile as the
       #zArch clipPath that shapes the hero mihrab, so a photograph in a card
       niche and the mihrab itself are cut to one arch, not two. */
    --z-arch-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='120' viewBox='0 0 100 120' preserveAspectRatio='none'%3E%3Cpath d='M50,0 C45.5,5 29,15 20,22.2 C6.5,32.2 0,48 0,64.2 L0,120 L100,120 L100,64.2 C100,48 93.5,32.2 80,22.2 C71,15 54.5,5 50,0 Z' fill='%23fff'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   Ground textures
   -------------------------------------------------------------------------- */

:root {
    /* Arabesque — a fine ogee lattice with a small rosette in each cell.
       This is islimi, the flowing vegetal mode, rather than girih geometry:
       an ogee (pointed-oval) lattice with a four-petal rosette at the heart
       of every cell and a bud at each lattice point. The cusps meet at the
       tile edges, so the ogees run continuously in both directions.
       Deliberately small — 34px — so it reads as a fine damask on cream and
       as gold thread on the green bands, never as a graphic competing with
       the content. */
    --z-pattern: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cg fill='none' stroke='%23a8843a' stroke-width='1.05' opacity='0.15'%3E%3Cpath d=%22M0.00 -14.14 L2.26 -5.45 L10.00 -10.00 L5.45 -2.26 L14.14 0.00 L5.45 2.26 L10.00 10.00 L2.26 5.45 L0.00 14.14 L-2.26 5.45 L-10.00 10.00 L-5.45 2.26 L-14.14 0.00 L-5.45 -2.26 L-10.00 -10.00 L-2.26 -5.45 Z%22/%3E%3Cpath d=%22M40.00 -14.14 L42.26 -5.45 L50.00 -10.00 L45.45 -2.26 L54.14 0.00 L45.45 2.26 L50.00 10.00 L42.26 5.45 L40.00 14.14 L37.74 5.45 L30.00 10.00 L34.55 2.26 L25.86 0.00 L34.55 -2.26 L30.00 -10.00 L37.74 -5.45 Z%22/%3E%3Cpath d=%22M0.00 25.86 L2.26 34.55 L10.00 30.00 L5.45 37.74 L14.14 40.00 L5.45 42.26 L10.00 50.00 L2.26 45.45 L0.00 54.14 L-2.26 45.45 L-10.00 50.00 L-5.45 42.26 L-14.14 40.00 L-5.45 37.74 L-10.00 30.00 L-2.26 34.55 Z%22/%3E%3Cpath d=%22M40.00 25.86 L42.26 34.55 L50.00 30.00 L45.45 37.74 L54.14 40.00 L45.45 42.26 L50.00 50.00 L42.26 45.45 L40.00 54.14 L37.74 45.45 L30.00 50.00 L34.55 42.26 L25.86 40.00 L34.55 37.74 L30.00 30.00 L37.74 34.55 Z%22/%3E%3Cpath d=%22M20.00 5.86 L22.26 14.55 L30.00 10.00 L25.45 17.74 L34.14 20.00 L25.45 22.26 L30.00 30.00 L22.26 25.45 L20.00 34.14 L17.74 25.45 L10.00 30.00 L14.55 22.26 L5.86 20.00 L14.55 17.74 L10.00 10.00 L17.74 14.55 Z%22/%3E%3C/g%3E%3Cg fill='%23a8843a' opacity='0.13'%3E%3Cpath d=%22M20.00 -3.40 L23.40 0.00 L20.00 3.40 L16.60 0.00 Z%22/%3E%3Cpath d=%22M0.00 16.60 L3.40 20.00 L0.00 23.40 L-3.40 20.00 Z%22/%3E%3Cpath d=%22M40.00 16.60 L43.40 20.00 L40.00 23.40 L36.60 20.00 Z%22/%3E%3Cpath d=%22M20.00 36.60 L23.40 40.00 L20.00 43.40 L16.60 40.00 Z%22/%3E%3C/g%3E%3C/svg%3E");
    --z-pattern-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cg fill='none' stroke='%23e3c886' stroke-width='1.05' opacity='0.085'%3E%3Cpath d=%22M0.00 -14.14 L2.26 -5.45 L10.00 -10.00 L5.45 -2.26 L14.14 0.00 L5.45 2.26 L10.00 10.00 L2.26 5.45 L0.00 14.14 L-2.26 5.45 L-10.00 10.00 L-5.45 2.26 L-14.14 0.00 L-5.45 -2.26 L-10.00 -10.00 L-2.26 -5.45 Z%22/%3E%3Cpath d=%22M40.00 -14.14 L42.26 -5.45 L50.00 -10.00 L45.45 -2.26 L54.14 0.00 L45.45 2.26 L50.00 10.00 L42.26 5.45 L40.00 14.14 L37.74 5.45 L30.00 10.00 L34.55 2.26 L25.86 0.00 L34.55 -2.26 L30.00 -10.00 L37.74 -5.45 Z%22/%3E%3Cpath d=%22M0.00 25.86 L2.26 34.55 L10.00 30.00 L5.45 37.74 L14.14 40.00 L5.45 42.26 L10.00 50.00 L2.26 45.45 L0.00 54.14 L-2.26 45.45 L-10.00 50.00 L-5.45 42.26 L-14.14 40.00 L-5.45 37.74 L-10.00 30.00 L-2.26 34.55 Z%22/%3E%3Cpath d=%22M40.00 25.86 L42.26 34.55 L50.00 30.00 L45.45 37.74 L54.14 40.00 L45.45 42.26 L50.00 50.00 L42.26 45.45 L40.00 54.14 L37.74 45.45 L30.00 50.00 L34.55 42.26 L25.86 40.00 L34.55 37.74 L30.00 30.00 L37.74 34.55 Z%22/%3E%3Cpath d=%22M20.00 5.86 L22.26 14.55 L30.00 10.00 L25.45 17.74 L34.14 20.00 L25.45 22.26 L30.00 30.00 L22.26 25.45 L20.00 34.14 L17.74 25.45 L10.00 30.00 L14.55 22.26 L5.86 20.00 L14.55 17.74 L10.00 10.00 L17.74 14.55 Z%22/%3E%3C/g%3E%3Cg fill='%23e3c886' opacity='0.075'%3E%3Cpath d=%22M20.00 -3.40 L23.40 0.00 L20.00 3.40 L16.60 0.00 Z%22/%3E%3Cpath d=%22M0.00 16.60 L3.40 20.00 L0.00 23.40 L-3.40 20.00 Z%22/%3E%3Cpath d=%22M40.00 16.60 L43.40 20.00 L40.00 23.40 L36.60 20.00 Z%22/%3E%3Cpath d=%22M20.00 36.60 L23.40 40.00 L20.00 43.40 L16.60 40.00 Z%22/%3E%3C/g%3E%3C/svg%3E");

    /* Marble veining for the pale bands — barely-there, on the scale of
       polished stone rather than a graphic. */
    --z-marble-tex: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300' viewBox='0 0 300 300'%3E%3Cg fill='none' stroke='%230d2c22' stroke-width='.6' opacity='.045'%3E%3Cpath d='M-20 60Q60 40 120 78T290 52'/%3E%3Cpath d='M-20 140Q70 118 140 158T310 132'/%3E%3Cpath d='M-20 224Q80 202 150 240T310 214'/%3E%3Cpath d='M40 -20Q58 70 26 140T60 320'/%3E%3Cpath d='M226 -20Q244 80 212 150T246 320'/%3E%3C/g%3E%3C/svg%3E");
}

/* ==========================================================================
   Base
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

/* LIGHT ONLY, DECLARED. Zaereen has one theme — marble, cream and green —
   and without this a mobile browser assumes the page can be inverted: Android
   Chrome's auto dark theme and Samsung Internet's dark mode repaint white
   surfaces and form controls on their own, which is how the white "Continue
   with Google" button turned black on phones. It also keeps the UA out of the
   text inputs and selects on the sign-in gate. */
html { color-scheme: light; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

body.zaereen {
    margin: 0;
    background-color: var(--z-cream);
    background-image: var(--z-marble-tex), var(--z-pattern);
    background-size: 300px 300px, 26px 26px;
    color: var(--z-ink);
    font-family: var(--z-body);
    font-size: 16px;
    line-height: 1.62;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

.zaereen h1, .zaereen h2, .zaereen h3, .zaereen h4 {
    font-family: var(--z-display);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: .005em;
    text-wrap: balance;
    margin: 0;
    color: var(--z-ink);
}

/* Buttons are excluded from the link colour on purpose.
   `.zaereen a` is (0,1,1); `.z-btn-green` is only (0,1,0), so on an <a> the
   link colour won and painted --z-green-2 (#14412f) text on the --z-green
   (#0d2c22) fill — 1.29:1, invisible. That hit every anchor styled as a
   button: "Reserve Seat" on the tour listing, "Apply for Visa" on the visa
   listing, and the card CTAs generally. A <button> is not an <a>, which is
   why the filter panel's Apply always looked right and the cards did not.
   Excluding .z-btn here lets each variant's own colour apply (#f2e9d5 on
   green, 12.3:1) instead of raising specificity variant by variant.

   :where() is what keeps this safe. A plain :not(.z-btn) would add the class's
   own weight, making this (0,2,1) — which then outranks `.z-crumb a` and
   `.z-footer a` (both (0,1,1), and both relying on source order to win), so
   the breadcrumb and every footer link turned dark green. :where() contributes
   zero specificity, so this stays exactly (0,1,1) as before and only the
   match changes, never the ranking. */
.zaereen a:not(:where(.z-btn)) { color: var(--z-green-2); text-decoration: none; }
.zaereen a:not(:where(.z-btn)):hover { color: var(--z-gold-deep); }
.zaereen img { max-width: 100%; display: block; }
.zaereen p { margin: 0 0 1em; }
.zaereen ul { margin: 0; padding: 0; list-style: none; }

.zaereen :focus-visible {
    outline: 2px solid var(--z-gold);
    outline-offset: 3px;
    border-radius: 4px;
}

.z-shell {
    width: 100%;
    max-width: var(--z-shell);
    margin: 0 auto;
    padding: 0 24px;
}

.z-sr {
    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 — keyboard users land here first. */
.z-skip {
    position: absolute; left: 12px; top: -60px; z-index: 999;
    background: var(--z-green); color: #fff; padding: 10px 18px;
    border-radius: 0 0 8px 8px; font-size: 14px; transition: top .18s ease;
}
.z-skip:focus { top: 0; color: #fff; }

/* ==========================================================================
   Fatemi motifs
   ========================================================================== */

/* --- Al-Aqmar medallion between two gold rules --- */
.z-orn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 18px;
    width: 100%;
}
.z-orn::before, .z-orn::after {
    content: "";
    height: 1px;
    flex: 1 1 auto;
    max-width: 190px;
    background: linear-gradient(90deg, transparent, var(--z-gold-light) 55%, var(--z-gold));
}
.z-orn::after { background: linear-gradient(270deg, transparent, var(--z-gold-light) 55%, var(--z-gold)); }

.z-orn-medallion {
    flex: none;
    display: block;
    width: 34px; height: 34px;
    color: var(--z-gold);
}
.z-orn-medallion svg { width: 100%; height: 100%; display: block; }

/* A smaller lozenge for tight spots (the hero arch rule). */
.z-orn-mark {
    flex: none;
    width: 9px; height: 9px;
    transform: rotate(45deg);
    border: 1px solid var(--z-gold);
    background: var(--z-gold-wash);
}

/* --- stepped merlon cresting (shurfa) ---
   Tiles across the top edge of a green band so the band reads as a wall.
   `width` is left to the repeat; height fixes the merlon scale. */
.z-cresting {
    position: absolute;
    left: 0; right: 0;
    height: 15px;
    width: 100%;
    display: block;
    pointer-events: none;
}
.z-cresting.is-flip { transform: scaleY(-1); }

/* The tiled version: a repeating background rather than one stretched glyph,
   so merlons keep their proportion at any viewport width. */
.z-crest-band {
    position: absolute;
    left: 0; right: 0;
    height: 16px;
    pointer-events: none;
    background-repeat: repeat-x;
    background-size: auto 16px;
    background-position: center bottom;
}
.z-crest-band.is-top {
    top: -15px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='16' viewBox='0 0 24 18'%3E%3Cpath d='M0,18 L0,13 L4,13 L4,8 L8,8 L8,3 L12,0 L16,3 L16,8 L20,8 L20,13 L24,13 L24,18 Z' fill='%230d2c22'/%3E%3C/svg%3E");
}
.z-crest-band.is-bottom {
    bottom: -15px;
    transform: scaleY(-1);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='16' viewBox='0 0 24 18'%3E%3Cpath d='M0,18 L0,13 L4,13 L4,8 L8,8 L8,3 L12,0 L16,3 L16,8 L20,8 L20,13 L24,13 L24,18 Z' fill='%230d2c22'/%3E%3C/svg%3E");
}

/* --- squared-Kufic frieze, used as a divider --- */
.z-kufic-rule {
    height: 15px;
    color: var(--z-gold);
    opacity: .5;
    background-repeat: repeat-x;
    background-size: auto 15px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='16' viewBox='0 0 48 16'%3E%3Cpath d='M2,14 V4 H6 V10 H10 V2 H14 V14 H18 V6 H22 V14 M26,14 V2 H30 V8 H34 V4 H38 V14 H42 V6 H46 V14' fill='none' stroke='%23c19a3f' stroke-width='1.6' stroke-linecap='square'/%3E%3C/svg%3E");
}

/* --- arcade panel, for decorative rails --- */
.z-arcade { width: 100%; height: 100%; display: block; color: var(--z-gold); opacity: .3; }

/* --- gold manuscript frame: a hairline inside a hairline --- */
.z-framed { position: relative; }
.z-framed::after {
    content: "";
    position: absolute;
    inset: 5px;
    border: 1px solid var(--z-line-gold);
    border-radius: calc(var(--z-radius) - 5px);
    pointer-events: none;
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.z-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    font-family: var(--z-body);
    font-size: 14.5px;
    font-weight: 500;
    letter-spacing: .02em;
    padding: 13px 26px;
    border-radius: 8px;
    border: 1px solid transparent;
    cursor: pointer;
    text-align: center;
    /* Set here rather than inherited from the link rule, which no longer
       matches buttons (see .zaereen a:not(.z-btn) above). */
    text-decoration: none;
    transition: background-color .2s ease, color .2s ease, border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.z-btn:hover { transform: translateY(-1px); }
.z-btn:active { transform: translateY(0); }

/* Gold leaf, not a flat fill: the multi-stop gradient gives the edge-catch of
   beaten leaf, which is how gold reads on Bohra masjid inlay. */
.z-btn-gold {
    background: var(--z-gold-leaf);
    color: #2a1f00;
    box-shadow: inset 0 1px 0 rgba(255, 250, 232, .5), var(--z-shadow-sm);
}
.z-btn-gold:hover {
    background: linear-gradient(135deg, #d4b158 0%, #b08d2c 40%, #8f6f1c 100%);
    color: #fffaf0;
    box-shadow: inset 0 1px 0 rgba(255, 250, 232, .28), var(--z-shadow);
}

.z-btn-green {
    background: var(--z-green);
    color: #f2e9d5;
    box-shadow: inset 0 0 0 1px rgba(227, 200, 134, .18);
}
.z-btn-green:hover { background: var(--z-green-2); color: #fffaf0; box-shadow: inset 0 0 0 1px var(--z-line-gold); }

.z-btn-outline {
    background: transparent;
    color: var(--z-green);
    border-color: var(--z-line-gold);
}
.z-btn-outline:hover {
    border-color: var(--z-gold);
    background: var(--z-gold-wash);
    color: var(--z-green);
}

.z-btn-block { width: 100%; }
.z-btn-sm { padding: 9px 18px; font-size: 13.5px; }

.z-btn .z-arrow { transition: transform .2s ease; }
.z-btn:hover .z-arrow { transform: translateX(3px); }

/* ==========================================================================
   Header
   ========================================================================== */

.z-header {
    position: absolute;
    inset: 0 0 auto 0;
    z-index: 40;
    padding: 14px 0;
}
.z-header.is-solid {
    position: sticky;
    top: 0;
    background: rgba(247, 240, 226, .94);
    backdrop-filter: blur(12px);
    /* No border-bottom. The rule under the nav was asked to go; the dark
       .z-pagehead directly below supplies the edge on every inner page. */
    padding: 10px 0;
}

.z-header-in {
    display: flex;
    align-items: center;
    gap: 28px;
}
/* The nav is centred in the BAR, not in the space left over. `margin:0 auto`
   alone centres it between its neighbours, and the brand (78px) and the
   actions (163px) are not the same width — so it landed some 40px left of
   true centre. Giving both sides an equal flex share fixes the midpoint. */
.z-header-in > .z-brand,
.z-header-in > .z-header-actions { flex: 1 1 0; min-width: 0; }
.z-header-in > .z-header-actions { justify-content: flex-end; }

/* --- wordmark ---
   The supplied artwork is a vertical lockup: a calligraphic teardrop above a
   blackletter "Zaereen.com". In a horizontal bar the two are set side by
   side instead, so both stay legible at header height. Sizes are driven off
   `height` with `width:auto` — the mark is 300x523 and the wordmark 760x118,
   so fixing both dimensions would squash them. */
/* The logo sits on its own dark plate so it reads as the brand rather than
   as one more icon in the row beside it — the nav marks are all dark-on-
   cream, and this is the one element that should not look like them. The
   green measures 12:1 against the bar, which is what does the separating;
   the gold hairline and the jali texture are the same treatment every
   other green surface on the site carries. */
.z-brand {
    /* Stacked: lockup, then "Mumineen Travel Portal" centred under it. The
       same arrangement as the footer, so the brand reads the same at the top
       and the bottom of the page.

       Column rather than a row with the tagline alongside — beside a nearly
       square logo the line pushed the brand slot wide enough to shove the
       nav off centre, which is what the note below is about. */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    /* The link is the layout slot the nav is centred against, so it must
       stay free to take its flex share. The plate therefore lives on the
       image inside it — putting it here stretched the green across the
       whole slot (357px) instead of hugging the logo. */
    justify-content: center;
}

/* In the bar the tagline is a caption under a 50px logo, so it is set small
   and light on the cream ground; the footer version inherits its own colour
   from the block below. */
.z-header .z-brand-tag {
    color: var(--z-gold-deep);
    font-size: 9px;
    letter-spacing: .1em;
    line-height: 1;
    white-space: nowrap;
}

/* The lockup is 765x742 — all but square, because the artwork stacks the
   calligraphic mark over the wordmark. In a bar this deep that caps its
   height at about 64px, and the wordmark inside it is then small; the
   tagline beside it carries the reading weight, which is why that line is
   set the size it is rather than shrunk to match the logo. */
/* 50px, giving a 66px plate with its 8px padding. At 60px the plate stood
   76px tall against nav items of 63 and My Journey of 68 — it overhung the
   row by 7px top and bottom, which is what read as the logo sitting out of
   line. Keep this in step with the nav item height if either changes. */
/* Phone and tablet only — the rule that reveals it lives in the max-width:
   1080px block near the foot of this file, beside the dark-header treatment
   it is coloured for. Hidden by default so the desktop bar is untouched: up
   there the brand slot is what the nav centres against, and a third child in
   that row would pull the whole thing off centre. */
.z-header-tagline { display: none; }

.z-brand-lockup {
    height: 50px;
    width: auto;
    display: block;
    flex: none;
    /* The plate: it is what stops the logo reading as one more of the
       dark-on-cream nav icons beside it. Green measures 12:1 against the
       bar, and the gold hairline plus jali texture are the treatment every
       other green surface on the site carries. */
    padding: 8px 14px;
    box-sizing: content-box;
    border-radius: var(--z-radius-sm, 10px);
    background: var(--z-green);
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
    box-shadow: inset 0 0 0 1px var(--z-line-gold);
}

/* Beside the logo now, not beneath a wordmark, so it no longer has a width
   to match and is free to be set for legibility. Deeper than
   --z-gold-deep, which measures only 4.15:1 on the header cream — under
   the 4.5:1 small text needs; this reads at 5.88:1. */
.z-brand-tag {
    font-size: 10px;
    letter-spacing: .08em;
    font-weight: 600;
    text-transform: uppercase;
    color: #7a5c12;
    /* One line. A max-width here wrapped it onto three, which beside a
       square logo read as a paragraph rather than a tagline. */
    white-space: nowrap;
}

/* --- primary nav --- */
.z-nav {
    display: flex;
    align-items: center;
    /* Air between the icon plates. Each item already has its own 10px of
       side padding, so this is the gap between plate edges rather than
       between labels. */
    gap: 12px;
    margin: 0 auto;
}
.z-nav > li { position: relative; }
.z-nav a.z-nav-link {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 7px 12px;
    font-size: 12.5px;
    /* Bold. At 12.5px on a cream bar the regular weight went thin next to the
       tinted marks above it, and the row read as captions under icons rather
       than as the navigation. */
    font-weight: 600;
    letter-spacing: .01em;
    color: var(--z-ink);
    border-radius: 7px;
    white-space: nowrap;
    transition: color .18s ease, background-color .18s ease;
}
.z-nav a.z-nav-link svg { flex: none; color: var(--z-navc, var(--z-gold-deep)); }
.z-nav-label { display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; line-height: 1.2; }
.z-nav a.z-nav-link .z-nav-caret { opacity: .55; }
.z-nav a.z-nav-link:hover { color: var(--z-gold-deep); background: rgba(193, 154, 63, .1); }
/* On hover the whole item takes the product's colour, so the bar tells you
   what you are pointing at rather than only that you are pointing. */
.z-nav a.z-nav-link:hover { color: var(--z-navc, var(--z-gold-deep)); background: color-mix(in srgb, var(--z-navc, #c19a3f) 10%, transparent); }
.z-nav a.z-nav-link[aria-current="page"] { color: var(--z-navc, var(--z-gold-deep)); }
.z-nav a.z-nav-link[aria-current="page"]::after { background: var(--z-navc, var(--z-gold)); }
.z-nav a.z-nav-link[aria-current="page"] { color: var(--z-gold-deep); }
.z-nav a.z-nav-link[aria-current="page"]::after {
    content: "";
    position: absolute;
    left: 12px; right: 12px; bottom: 0;
    height: 1.5px;
    background: var(--z-gold);
}

/* --- header right --- */
.z-header-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.z-header-link {
    display: inline-flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 5px;
    font-size: 12.5px;
    color: var(--z-ink);
    padding: 7px 12px;
    border-radius: 7px;
    white-space: nowrap;
}
.z-header-link svg { flex: none; color: var(--z-navc, var(--z-gold-deep)); }
.z-header-link:hover { color: var(--z-navc, var(--z-gold-deep)); background: color-mix(in srgb, var(--z-navc, #c19a3f) 10%, transparent); }

.z-burger {
    display: none;
    width: 44px; height: 44px;
    align-items: center; justify-content: center;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 50%;
    cursor: pointer;
    color: var(--z-green);
}

/* --- mobile drawer --- */
.z-drawer {
    position: fixed;
    inset: 0 0 0 auto;
    width: min(340px, 86vw);
    background: var(--z-surface);
    border-left: 1px solid var(--z-line);
    box-shadow: var(--z-shadow-lg);
    z-index: 120;
    padding: 22px;
    transform: translateX(100%);
    transition: transform .28s cubic-bezier(.4, 0, .2, 1);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.z-drawer.is-open { transform: translateX(0); }
.z-drawer a {
    display: flex; align-items: center; gap: 12px;
    padding: 13px 12px;
    font-size: 16px;
    color: var(--z-ink);
    border-bottom: 1px solid var(--z-line-soft);
}
.z-drawer a svg {
    flex: none;
    box-sizing: content-box;
    width: 18px; height: 18px; padding: 8px;
    border-radius: 10px;
    color: var(--z-navc, var(--z-gold-deep));
    background: color-mix(in srgb, var(--z-navc, #c19a3f) 12%, transparent);
}
.z-drawer a:last-of-type { border-bottom: 0; }
.z-drawer-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.z-drawer-close {
    width: 38px; height: 38px; border-radius: 50%;
    background: var(--z-surface-2); border: 1px solid var(--z-line);
    cursor: pointer; color: var(--z-ink); font-size: 20px; line-height: 1;
}
.z-scrim {
    position: fixed; inset: 0; z-index: 110;
    background: rgba(18, 51, 42, .45);
    backdrop-filter: blur(2px);
    opacity: 0; visibility: hidden;
    transition: opacity .28s ease, visibility .28s;
}
.z-scrim.is-open { opacity: 1; visibility: visible; }

/* ==========================================================================
   Hero
   ========================================================================== */

.z-hero {
    position: relative;
    min-height: 600px;
    display: flex;
    align-items: center;
    justify-content: center;
    /* 56px, not 150px. The 150 was clearance for the header overlaying this
       section; the homepage now carries the same sticky cream bar as every
       other page, and a sticky header takes up its own space — so that
       clearance became a gap of dead ground above the arch. */
    padding: 56px 0 110px;
    isolation: isolate;
    /* No overflow:hidden — the merlon crest hangs below the box. The bg layer
       is inset:0 and never spills, so nothing needs clipping here. */
}
.z-hero-bg {
    position: absolute;
    inset: 0;
    z-index: -2;
    background-size: cover;
    background-position: center;
}
.z-hero-bg::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
        linear-gradient(180deg, rgba(247, 240, 226, .92) 0%, rgba(247, 240, 226, .35) 26%, rgba(18, 51, 42, .30) 72%, rgba(18, 51, 42, .55) 100%);
}

/* The mihrab — a pointed keel arch, not a dome.
   border-radius can only ever round a corner, so it gives a half-round top;
   the apex has to be a real cusp. The shape therefore comes from the shared
   #zArch clipPath (see zaereen/includes/ui/header.php), and the gold outline
   is produced by stacking clipped layers rather than by a border, since a
   border would be clipped away with everything else.

   Layers, outermost first:
     .z-arch-frame   gold, 2px of padding  -> reads as the outer rule
     .z-arch         green field
     .z-arch::before gold, inset 10px      -> the inner rule
     .z-arch::after  green, inset 11px     -> leaves ::before showing as 1px
*/
.z-arch-frame {
    position: relative;
    z-index: 1;
    width: min(468px, 100%);
    padding: 2px;
    background: linear-gradient(160deg, var(--z-gold-light) 0%, var(--z-gold) 42%, var(--z-gold-deep) 100%);
    clip-path: url(#zArch);
    filter: drop-shadow(0 34px 60px rgba(4, 18, 13, .72));
}
.z-arch {
    position: relative;
    background: linear-gradient(170deg, #12392c 0%, #0b241c 62%, #081c16 100%);
    clip-path: url(#zArch);
    padding: 76px 46px 46px;
    text-align: center;
    color: #f5edda;
}
.z-arch::before,
.z-arch::after {
    content: "";
    position: absolute;
    clip-path: url(#zArch);
    pointer-events: none;
}
.z-arch::before { inset: 9px;  background: var(--z-gold); opacity: .5; }
.z-arch::after  { inset: 10px; background: linear-gradient(170deg, #12392c 0%, #0b241c 62%, #081c16 100%); }
/* Content sits above both rule layers. */
.z-arch > * { position: relative; z-index: 1; }
/* The full supplied lockup, in white, sitting inside the arch. */
.z-arch-lockup {
    height: clamp(132px, 19vw, 168px);
    width: auto;
    margin: 0 auto;
    display: block;
}
.z-arch-rule { margin: 18px auto; max-width: 210px; }
.z-arch-rule::before, .z-arch-rule::after { max-width: 80px; }

.z-arch h1 {
    font-family: var(--z-display);
    font-size: clamp(21px, 2.6vw, 26px);
    font-weight: 500;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #ece2cc;
    margin: 0;
}
.z-arch h1 .z-accent {
    display: block;
    font-size: clamp(27px, 3.6vw, 35px);
    font-weight: 600;
    letter-spacing: .05em;
    color: var(--z-gold-light);
    margin-top: 5px;
}
.z-arch-lede {
    font-size: 15.5px;
    line-height: 1.66;
    color: rgba(240, 232, 214, .84);
    max-width: 40ch;
    margin: 18px auto 26px;
}

/* ==========================================================================
   Hero search
   ========================================================================== */

/* .z-search, the single-product bar this replaced, is gone — .z-tabsearch
   is its successor. .z-search-grid below stays: departures.php still uses
   it, standalone, for its own month/city filter row. */
.z-search-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr) auto;
    gap: 14px;
    align-items: end;
}
.z-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.z-field label {
    font-size: 11px;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--z-ink-3);
    font-weight: 500;
}
.z-field select,
.z-field input {
    font-family: var(--z-body);
    font-size: 15px;
    color: var(--z-ink);
    background: var(--z-surface-2);
    border: 1px solid var(--z-line);
    border-radius: 8px;
    padding: 12px 13px;
    width: 100%;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%238a9186' stroke-width='1.6' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 13px center;
    padding-right: 34px;
}
.z-field input { background-image: none; padding-right: 13px; }
.z-field select:hover, .z-field input:hover { border-color: var(--z-gold-light); }

.z-quick {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    margin-top: 15px;
    padding-top: 15px;
    border-top: 1px solid var(--z-line-soft);
}
.z-quick-label {
    font-size: 11px;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--z-ink-3);
    margin-right: 2px;
}
.z-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 15px;
    font-size: 13.5px;
    color: var(--z-green);
    background: var(--z-gold-wash);
    border: 1px solid transparent;
    border-radius: 100px;
    transition: border-color .18s ease, background-color .18s ease;
}
.z-chip:hover { border-color: var(--z-gold); background: var(--z-surface); color: var(--z-green); }

/* ==========================================================================
   Section scaffolding
   ========================================================================== */

.z-section { padding: 68px 0; position: relative; }

/* Marble band: paler and cooler than the page ground, with the jali dropped
   out, so alternating sections read as polished stone panels set into a
   patterned wall. */
.z-section.is-tint {
    background-color: var(--z-marble);
    background-image: var(--z-marble-tex);
    background-size: 300px 300px;
    border-top: 1px solid var(--z-line-gold);
    border-bottom: 1px solid var(--z-line-gold);
}

/* A green band, crested top and bottom like a parapet. */
.z-section.is-green {
    background-color: var(--z-green);
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
    color: rgba(240, 233, 215, .84);
    margin: 30px 0;
}
.z-section.is-green h2, .z-section.is-green h3 { color: #fbf5e6; }

.z-section-head { text-align: center; margin-bottom: 38px; }
.z-section-head h2 {
    font-size: clamp(24px, 3.4vw, 31px);
    font-weight: 600;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--z-ink);
}
.z-section-head .z-orn { margin: 16px auto 0; max-width: 560px; }
.z-section-head p {
    margin: 14px auto 0;
    max-width: 58ch;
    font-size: 15.5px;
    color: var(--z-ink-2);
}

.z-section-foot { display: flex; justify-content: center; margin-top: 34px; }

/* ==========================================================================
   Tour cards
   ========================================================================== */

.z-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px; }
.z-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }

.z-card {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    display: flex;
    flex-direction: column;
    box-shadow: var(--z-shadow-sm);
    transition: transform .24s ease, box-shadow .24s ease, border-color .24s ease;
}
.z-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--z-shadow-lg);
    border-color: var(--z-gold);
}

/* The image sits in a keyhole-arch niche rather than a rectangle — the
   single change that makes a grid of shrine photographs read as Fatemi.
   Padding around the mask leaves a margin of card ground visible, the way a
   niche is set into a wall. */
.z-card-media {
    position: relative;
    padding: 12px 12px 0;
    background: transparent;
}
.z-card-arch {
    position: relative;
    z-index: 1;
    display: block;
    aspect-ratio: 4 / 4.4;
    overflow: hidden;
    background: var(--z-cream-deep);
    -webkit-mask-image: var(--z-arch-mask);
            mask-image: var(--z-arch-mask);
    -webkit-mask-size: 100% 100%;
            mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
}
.z-card-arch img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform .6s cubic-bezier(.2, .7, .3, 1);
}
.z-card:hover .z-card-arch img { transform: scale(1.06); }

/* A gold hairline traced just outside the arch, like the painted outline
   round a real niche. Drawn as a second masked layer so it follows the
   curve exactly instead of approximating it with border-radius. */
.z-card-media::before {
    content: "";
    position: absolute;
    inset: 6px 6px 0;
    z-index: 0;
    background: var(--z-gold);
    opacity: .38;
    -webkit-mask-image: var(--z-arch-mask);
            mask-image: var(--z-arch-mask);
    -webkit-mask-size: 100% 100%;
            mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    pointer-events: none;
    transition: opacity .24s ease;
}
.z-card:hover .z-card-media::before { opacity: .75; }

/* The pill itself carries no positioning — it is used inline in departure
   rows as well as over card imagery, and a transform here would shift every
   inline one sideways. */
.z-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .07em;
    text-transform: uppercase;
    white-space: nowrap;
    border-radius: 100px;
}

/* Over an arched niche the badge centres on the base, not a corner: the
   corners are outside the masked curve, and the crown is too narrow to hold
   a label like "8 Departures" without overhanging the arch. */
.z-card-media .z-badge {
    position: absolute;
    bottom: 14px; left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    max-width: calc(100% - 40px);
    backdrop-filter: blur(6px);
    box-shadow: 0 2px 10px rgba(13, 44, 34, .28);
}
.z-badge-open { background: rgba(226, 239, 231, .93); color: var(--z-open); }
.z-badge-few  { background: rgba(247, 236, 214, .93); color: var(--z-few); }
.z-badge-sold { background: rgba(246, 228, 224, .93); color: var(--z-sold); }

.z-card-body { padding: 20px; display: flex; flex-direction: column; flex: 1 1 auto; }
.z-card-title {
    font-family: var(--z-display);
    font-size: 21px;
    font-weight: 600;
    letter-spacing: .045em;
    text-transform: uppercase;
    color: var(--z-ink);
    margin: 0 0 8px;
}
.z-card-route {
    font-size: 13px;
    color: var(--z-gold-deep);
    letter-spacing: .04em;
    margin: 0 0 10px;
}
.z-card-text {
    font-size: 14.5px;
    color: var(--z-ink-2);
    line-height: 1.6;
    margin: 0 0 16px;
}

.z-meta { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 0 0 16px; }
.z-meta li {
    display: flex; align-items: center; gap: 7px;
    font-size: 13.5px; color: var(--z-ink-2);
}
.z-meta svg { color: var(--z-gold-deep); flex: none; }

.z-price { margin-top: auto; padding-top: 4px; }
.z-price small {
    display: block;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--z-ink-3);
    margin-bottom: 2px;
}
.z-price b {
    font-family: var(--z-display);
    font-size: 27px;
    font-weight: 600;
    color: var(--z-gold-deep);
    font-variant-numeric: tabular-nums;
}
.z-price span { font-size: 13px; color: var(--z-ink-3); margin-left: 3px; }

.z-card-actions { display: flex; gap: 9px; margin-top: 16px; }
.z-card-actions .z-btn { flex: 1 1 auto; }

/* ==========================================================================
   Departure cards
   ========================================================================== */

.z-dep {
    display: grid;
    grid-template-columns: 92px 1fr auto;
    gap: 20px;
    align-items: center;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    padding: 18px 20px;
    box-shadow: var(--z-shadow-sm);
    transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.z-dep:hover { border-color: var(--z-gold-light); box-shadow: var(--z-shadow); transform: translateY(-2px); }

/* The date plaque is itself a little arched tablet. */
.z-dep-date {
    text-align: center;
    background: var(--z-green);
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
    color: #f2e9d5;
    border-radius: 44% 44% var(--z-radius-sm) var(--z-radius-sm) / 26% 26% var(--z-radius-sm) var(--z-radius-sm);
    padding: 16px 8px 12px;
    box-shadow: inset 0 0 0 1px var(--z-line-gold);
}
.z-dep-date .d {
    display: block;
    font-family: var(--z-display);
    font-size: 32px;
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.z-dep-date .m {
    display: block;
    font-size: 11px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--z-gold-light);
    margin-top: 5px;
}
.z-dep-date .y { display: block; font-size: 11px; color: rgba(242, 233, 213, .6); margin-top: 2px; }

.z-dep-main h3 {
    font-family: var(--z-display);
    font-size: 20px;
    font-weight: 600;
    letter-spacing: .03em;
    margin: 0 0 6px;
}
.z-dep-side { text-align: right; display: flex; flex-direction: column; gap: 10px; align-items: flex-end; }

/* ==========================================================================
   Departure date strip

   The horizontal rail of date tiles from b2b/quotes/ (.dep-strip / .dep-chip
   in assets/css/departure_calendar.css), in Zaereen's colours. Same division
   of labour as the original: the strip is the default view and the pinned
   "ALL" tile opens the two-month calendar beneath it.
   ========================================================================== */

/* The rail sits inside a panel rather than floating on the page ground.
   Naked on cream the whole control read as washed-out: pale tiles on a pale
   field, with nothing holding them together. The panel gives it an edge, a
   shadow and a gold rule, so it reads as one deliberate instrument. */
.z-strip-panel {
    position: relative;
    background: var(--z-marble);
    background-image: var(--z-marble-tex);
    background-size: 300px 300px;
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    box-shadow: var(--z-shadow);
    padding: 16px 18px;
    margin-bottom: 22px;
}
.z-strip-panel::after {
    content: "";
    position: absolute;
    inset: 5px;
    border: 1px solid var(--z-line-gold);
    border-radius: calc(var(--z-radius) - 5px);
    pointer-events: none;
}

.z-strip-wrap {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Scrollbar hidden — the arrows, the wheel and dragging all move the rail. */
.z-strip {
    display: flex;
    min-width: 0;
    gap: 8px;
    overflow-x: auto;
    scroll-behavior: smooth;
    padding: 3px 2px;
    flex: 1 1 auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.z-strip::-webkit-scrollbar { display: none; }

.z-strip-nav {
    flex: none;
    width: 30px; height: 78px;
    display: grid; place-items: center;
    border-radius: 8px;
    border: 1px solid var(--z-line-gold);
    background: var(--z-surface);
    color: var(--z-green);
    cursor: pointer;
    transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.z-strip-nav:hover { background: var(--z-green); color: var(--z-gold-light); border-color: var(--z-green); }
.z-strip-nav[data-strip-scroll="-1"] svg { transform: rotate(90deg); }
.z-strip-nav[data-strip-scroll="1"]  svg { transform: rotate(-90deg); }

/* "All dates" is pinned beside the rail rather than being its first tile: it
   is the way OUT of a date filter, and a control that has scrolled out of
   sight is no use when you are twenty departures along. */
.z-dchip-fixed {
    flex: 0 0 auto;
    margin-right: 4px;
    padding-right: 10px;
    border-right: 1px dashed var(--z-line);
}

/* A tile is a torn calendar page: gold band across the head, deep green
   numeral, price beneath. The gradient and the inner highlight are what stop
   it reading as a flat rectangle at this size. */
.z-dchip {
    flex: 0 0 auto;
    width: 76px;
    height: 82px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: 0;
    border-radius: 10px;
    overflow: hidden;
    text-decoration: none;
    background: linear-gradient(170deg, #fffdf7 0%, #f6efdf 100%);
    border: 1px solid var(--z-line-gold);
    box-shadow: 0 1px 2px rgba(23, 32, 26, .06), inset 0 1px 0 rgba(255, 255, 255, .8);
    cursor: pointer;
    position: relative;
    transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.z-dchip:hover {
    border-color: var(--z-gold);
    transform: translateY(-3px);
    box-shadow: 0 12px 24px -12px rgba(13, 44, 34, .55), inset 0 1px 0 rgba(255, 255, 255, .9);
}

/* The band across the top is what makes a tile read as a torn calendar page
   rather than a button. */
/* Deep green band, gold lettering — the same relationship the page head and
   the footer use, so a tile belongs to the same building as everything else. */
.z-dchip-mon {
    flex: 0 0 auto;
    padding: 5px 0 4px;
    text-align: center;
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: .13em;
    line-height: 1.2;
    color: var(--z-gold-light);
    background: var(--z-green);
    border-bottom: 1px solid var(--z-gold);
}
.z-dchip-day {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--z-display);
    font-size: 30px;
    font-weight: 600;
    line-height: 1;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
}
.z-dchip-meta {
    flex: 0 0 auto;
    padding: 0 3px 6px;
    text-align: center;
    font-size: 9.5px;
    letter-spacing: .02em;
    color: var(--z-ink-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.z-dchip.is-active {
    background: var(--z-green);
    border-color: var(--z-green);
    box-shadow: var(--z-shadow);
}
.z-dchip.is-active .z-dchip-mon  { color: var(--z-gold-light); background: rgba(227, 200, 134, .14); border-bottom-color: rgba(227, 200, 134, .3); }
.z-dchip.is-active .z-dchip-day  { color: #fdf8ec; }
.z-dchip.is-active .z-dchip-meta { color: rgba(240, 233, 215, .72); }

.z-dchip.is-past { opacity: .45; }
.z-dchip.is-today .z-dchip-day::after {
    content: "";
    position: absolute;
    left: 50%; bottom: 20px;
    transform: translateX(-50%);
    width: 14px; height: 1.5px;
    background: var(--z-gold);
}

/* Availability, as the same three-colour key the calendar uses. */
.z-dchip-dot {
    position: absolute;
    top: 5px; right: 5px;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--z-open);
    z-index: 1;
}
.z-dchip.is-few  .z-dchip-dot { background: var(--z-few); }
.z-dchip.is-sold .z-dchip-dot { background: var(--z-sold); }
.z-dchip.is-sold { opacity: .62; }

/* The pinned tile carries an icon where the others carry a date. */
/* THE ALL TILE CAN BE OPEN AND ACTIVE AT THE SAME TIME, and the two states
   were painting over each other into something unreadable.

   .is-active fills a chip dark green and sets its band to a 14% gold wash with
   gold-light lettering — right on green. .z-dchip-all.is-open then replaced the
   green with --z-gold-wash, and it is written later at the same specificity, so
   it won: pale gold text on a pale gold ground, on a cream tile. That is the
   ghost tile in the strip.

   The open state is scoped to when the tile is NOT active, and the active state
   is stated explicitly so it cannot be reached by source order again. */
.z-dchip-all .z-dchip-day { color: var(--z-gold-deep); }

.z-dchip-all.is-open:not(.is-active) {
    background: var(--z-gold-wash);
    border-color: var(--z-gold);
}

.z-dchip-all.is-active {
    background: var(--z-green);
    border-color: var(--z-green);
}
/* The rule above sets the glyph gold-deep for every ALL tile, and it is later
   than .z-dchip.is-active's #fdf8ec — so on the filled tile the calendar came
   out dark gold on dark green. Named again here for the active case. */
.z-dchip-all.is-active .z-dchip-day  { color: var(--z-gold-light); }
.z-dchip-all.is-active .z-dchip-meta { color: rgba(240, 233, 215, .8); }

/* And it is never one of the dimmed ones. is-muted is for a date with nothing
   left on it; ALL is the control that clears the filter, so it must stay lit
   and clickable whatever the filters have done to the dates beside it. */
.z-dchip-all.is-muted { opacity: 1; pointer-events: auto; }

/* Both selectors stacked at the right-hand end of the rail, one above the
   other, so the dates keep the full width between the arrows.

   They used to bracket the rail and were each a tile tall (82px). Stacked,
   two of those would make the strip twice its height, so the pair shares one
   tile's height between them and the label sits tighter to its select. */
.z-strip-filters {
    flex: 0 0 auto;
    height: 82px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 6px;
    padding-left: 12px;
    margin-left: 4px;
    border-left: 1px dashed var(--z-line);
}
.z-strip-dest,
.z-strip-city {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.z-strip-dest label,
.z-strip-city label {
    font-size: 9.5px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-strip-dest select,
.z-strip-city select {
    font-family: var(--z-body);
    /* Trimmed from 14px/9px padding: two of these stacked have to share the
       82px a single one used to have to itself. */
    font-size: 13px;
    color: var(--z-ink);
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: 8px;
    padding: 5px 28px 5px 10px;
    min-width: 152px;
    appearance: none;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%238f6f1c' stroke-width='1.6' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 11px center;
}
.z-strip-dest select:hover,
.z-strip-city select:hover { border-color: var(--z-gold); }

/* A date with nothing left once the city filter is on. Dimmed rather than
   removed: the rail keeps its shape, so the dates do not jump around
   underneath the pointer when a city is picked. */
.z-dchip.is-muted { opacity: .28; pointer-events: none; }

/* A calendar day whose departures the current filters rule out. Same treatment
   as the rail tile above, so the two read as one control: dimmed and dead to
   the pointer, but still occupying its square — a month grid cannot lose a
   day without the weeks below it shifting. */
.z-cal-cell.is-muted { opacity: .26; pointer-events: none; }

/* Note bar shown while a single date is selected. */
.z-active-note {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 11px 16px;
    margin-bottom: 20px;
    border-radius: var(--z-radius-sm);
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    font-size: 14px;
    color: var(--z-ink-2);
}
.z-active-note svg { color: var(--z-gold-deep); flex: none; }
.z-active-note strong { color: var(--z-ink); font-weight: 500; }
.z-active-note button {
    margin-left: auto;
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--z-green-3);
    text-decoration: underline;
    cursor: pointer;
}
.z-active-note button:hover { color: var(--z-gold-deep); }

.z-dep-hidden { display: none !important; }

@media (max-width: 780px) {
    /* Arrows go: on a phone the rail is swiped, and two 30px buttons only
       steal width from the tiles. */
    .z-strip-nav { display: none; }
    .z-strip-wrap { gap: 6px; }

    /* THE SEARCH BAR AND THE DATES ARE ONE MOVE. .z-section gives every band
       48px top and bottom on a phone, which is right between two unrelated
       sections and wrong here: the visitor searches, then picks a date, and the
       gap between the two read as the page having ended. The panel keeps its
       own padding, so this only closes the space above it. */
    #departures.z-section { padding-top: 0; }
}

/* ==========================================================================
   Departure calendar

   Two months side by side with a centred stepper, following the control in
   b2b/quotes/ (assets/css/departure_calendar.css) — same anatomy, same URL
   contract — but redrawn in Zaereen's own palette and motifs rather than the
   portal's slate and blue. Below 900px the second month is dropped instead of
   being squeezed: seven columns of legible tiles will not fit twice on a
   phone, and this is a control people will open from a WhatsApp link.
   ========================================================================== */

/* Warm marble rather than near-white: the panel is a stone ground the day
   tiles sit on, and white made the whole calendar read as a spreadsheet. */
.z-cal {
    position: relative;
    background: var(--z-marble);
    background-image: var(--z-marble-tex);
    background-size: 300px 300px;
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    box-shadow: var(--z-shadow);
    margin-bottom: 26px;
    overflow: hidden;
}
.z-cal::after {
    content: "";
    position: absolute;
    inset: 5px;
    border: 1px solid var(--z-line-gold);
    border-radius: calc(var(--z-radius) - 5px);
    pointer-events: none;
}

/* --- head --- */
/* Green header bar. On a cream body a cream header gave the panel no crown —
   the whole control read as one undifferentiated pale block. */
.z-cal-head {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 16px;
    align-items: center;
    padding: 16px 20px;
    background: var(--z-green);
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
    border-bottom: 1px solid var(--z-gold);
    color: rgba(240, 233, 215, .82);
}
.z-cal-title { display: flex; align-items: center; gap: 12px; min-width: 0; }
.z-cal-title-icon {
    flex: none;
    width: 38px; height: 45px;
    display: grid; place-items: center;
    color: var(--z-gold-light);
    background: rgba(227, 200, 134, .12);
    border: 1px solid rgba(227, 200, 134, .38);
    border-radius: 50% 50% 6px 6px / 58% 58% 6px 6px;
}
.z-cal-title strong {
    display: block;
    font-family: var(--z-display);
    font-size: 19px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #fbf5e6;
    line-height: 1.2;
}
.z-cal-summary { font-size: 12.5px; color: rgba(240, 233, 215, .62); }
.z-cal-summary b { color: var(--z-gold-light); font-weight: 500; }

/* The middle names what is on sale in the months on screen — the panel says
   WHAT as well as WHEN — and the month stepper moves to the right, beside the
   control that resets it. */
.z-cal-tour {
    justify-self: center;
    text-align: center;
    min-width: 0;
}
/* The headline of the panel, so it is sized like one: near-white for maximum
   separation from the green, with the gold kept for the caption under it.
   Gold-on-green at this size read as decoration rather than as a title. */
.z-cal-tour-name {
    display: block;
    font-family: var(--z-display);
    font-size: clamp(22px, 2.6vw, 31px);
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: #fdf8ec;
    line-height: 1.12;
    text-shadow: 0 2px 10px rgba(4, 18, 13, .45);
}
/* Hairline between the name and the city, so the two read as one lockup. */
.z-cal-tour-from {
    display: block;
    margin-top: 7px;
    padding-top: 7px;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--z-gold-light);
    position: relative;
}
.z-cal-tour-from:not(:empty)::before {
    content: "";
    position: absolute;
    top: 0; left: 50%;
    transform: translateX(-50%);
    width: 46px; height: 1px;
    background: linear-gradient(90deg, transparent, var(--z-gold), transparent);
}

.z-cal-right {
    display: flex;
    align-items: center;
    gap: 12px;
    justify-self: end;
}
.z-cal-stepper { display: flex; align-items: center; gap: 10px; }
.z-cal-nav {
    width: 34px; height: 34px;
    flex: none;
    display: grid; place-items: center;
    border-radius: 50%;
    border: 1px solid rgba(227, 200, 134, .4);
    background: rgba(227, 200, 134, .1);
    color: var(--z-gold-light);
    cursor: pointer;
    transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.z-cal-nav:hover:not(:disabled) { background: var(--z-gold); color: var(--z-green); border-color: var(--z-gold); }
.z-cal-nav:disabled { opacity: .35; cursor: not-allowed; }
/* The markup ships one chevron glyph; CSS points it. Doing this in CSS rather
   than JS means the arrows are correct on first paint, before any script. */
.z-cal-nav[data-step="-1"] svg { transform: rotate(90deg); }
.z-cal-nav[data-step="1"]  svg { transform: rotate(-90deg); }
.z-cal-range {
    font-family: var(--z-display);
    font-size: 19px;
    font-weight: 600;
    letter-spacing: .03em;
    color: #fbf5e6;
    white-space: nowrap;
    min-width: 13ch;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* --- months --- */
.z-cal-months {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
}
.z-cal-month { padding: 18px 20px 20px; }
/* Keyed to the class the script sets rather than to `+ .z-cal-month`. The two
   are equivalent for the two panels drawn today, but the class says which
   panel is being divided instead of inferring it from sibling position. */
.z-cal-month.is-second { border-left: 1px solid var(--z-line); }
/* The month is set, not filled: no background band. Size, the display face
   and a gold rule beneath carry the emphasis, which keeps the plaque from
   competing with the green month band on each departure tile — two filled
   green blocks a few pixels apart was the crowding this replaces. */
.z-cal-month-name {
    position: relative;
    text-align: center;
    font-family: var(--z-display);
    font-size: 20px;
    /* 700 is loaded for Cormorant Garamond in the header's font link, so this
       is a real bold cut rather than a synthesised one. */
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--z-green);
    padding: 2px 0 12px;
    margin-bottom: 12px;
}
.z-cal-month-name::after {
    content: "";
    position: absolute;
    left: 50%; bottom: 0;
    transform: translateX(-50%);
    width: 92px; height: 2px;
    background: linear-gradient(90deg, transparent, var(--z-gold), transparent);
}

.z-cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 5px; }
/* Weekday header as tinted chips rather than grey lettering.

   Three colours, not seven: the working week in green, Saturday in gold and
   Sunday in rose. The colour carries the distinction the eye actually wants —
   where the weekend falls — instead of decorating each column differently.

   nth-child, not first/last-child. The seven headers are children 1-7 of the
   grid, but the LAST child of .z-cal-grid is a date cell, so the previous
   `:last-child` rule for Saturday never matched anything. */
.z-cal-dow {
    text-align: center;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    padding: 5px 0;
    margin-bottom: 6px;
    border-radius: 6px;
    background: var(--z-green-soft);
    color: var(--z-green);
    border: 1px solid transparent;
}
.z-cal-dow:nth-child(7) {          /* Saturday */
    background: var(--z-gold-wash);
    color: var(--z-gold-deep);
    border-color: var(--z-line-gold);
}
.z-cal-dow:nth-child(1) {          /* Sunday */
    background: var(--z-sold-bg);
    color: var(--z-sold);
    border-color: color-mix(in srgb, var(--z-sold) 26%, transparent);
}

/* --- cells --- */
/* Every day is a ruled box, not just the ones with departures. Without the
   rule the grid read as loose numbers floating in space and the eye had
   nothing to track along a week. */
.z-cal-cell {
    position: relative;
    min-height: 78px;
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    overflow: hidden;
    text-decoration: none;
    border: 1px solid var(--z-line);
    /* Warm cream, not white. The grid is a wall of small tiles, and every one
       of them white turned the panel into a spreadsheet. */
    background: var(--z-cream);
    font-variant-numeric: tabular-nums;
}
.z-cal-cell.is-blank { border: 0; background: none; }
.z-cal-num {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    color: var(--z-ink-2);
    line-height: 1;
}
/* A day with nothing on it sits back into the wall; a bookable day comes
   forward, lighter and gold-edged. The two therefore differ in depth as well
   as in colour, which is what makes the departures findable at a glance.

   The border stays fully drawn on empty days. It was on --z-line-soft, which
   at this size vanished against the cream ground and left those dates looking
   like loose numbers while only the departures were boxed. Definition comes
   from the rule; emphasis comes from the fill. */
.z-cal-cell.is-empty {
    background: var(--z-cream-deep);
    border-color: var(--z-line-strong);
}
.z-cal-cell.is-past  { opacity: .45; }
.z-cal-cell.is-past .z-cal-num { color: var(--z-ink-3); }

/* Month band on the days that carry a departure — the same device the b2b
   calendar puts on its tiles, so a date lifted out of the grid still says
   which month it belongs to. */
.z-cal-mon {
    flex: 0 0 auto;
    padding: 3px 0 2px;
    text-align: center;
    font-size: 8.5px;
    font-weight: 600;
    letter-spacing: .12em;
    line-height: 1.2;
    color: var(--z-gold-light);
    background: var(--z-green);
    border-bottom: 1px solid var(--z-gold);
}

/* A day that actually has a departure. Gold wash, gold rule, the price under
   the date — the two facts someone scanning for a date is looking for. */
.z-cal-cell.has-dep {
    background: linear-gradient(170deg, #fffdf7 0%, #f6efdb 100%);
    border-color: var(--z-gold);
    cursor: pointer;
    transition: transform .16s ease, box-shadow .16s ease, background-color .16s ease, border-color .16s ease;
}
.z-cal-cell.has-dep .z-cal-num { color: var(--z-green); font-weight: 500; font-size: 17px; }
.z-cal-cell.has-dep:hover {
    transform: translateY(-2px);
    background: var(--z-surface);
    border-color: var(--z-gold);
    box-shadow: var(--z-shadow);
}
.z-cal-price {
    flex: 0 0 auto;
    padding: 0 2px 5px;
    text-align: center;
    font-size: 9.5px;
    letter-spacing: .01em;
    color: var(--z-gold-deep);
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.z-cal-dot {
    position: absolute;
    top: 6px; right: 6px;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--z-open);
}
.z-cal-cell.is-few  .z-cal-dot { background: var(--z-few); }
.z-cal-cell.is-sold .z-cal-dot { background: var(--z-sold); }
.z-cal-cell.is-sold { opacity: .6; }

/* Today reads as a ring, not a fill — a fill would compete with the
   departure days, which are the point of the panel. */
.z-cal-cell.is-today { box-shadow: inset 0 0 0 1.5px var(--z-green); }

.z-cal-cell.is-selected {
    background: var(--z-green);
    border-color: var(--z-green);
}
.z-cal-cell.is-selected .z-cal-num   { color: var(--z-gold-light); }
.z-cal-cell.is-selected .z-cal-price { color: rgba(240, 233, 215, .75); }

/* --- footer strip --- */
.z-cal-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 12px 20px;
    border-top: 1px solid var(--z-line);
    background: var(--z-surface-2);
    font-size: 12.5px;
    color: var(--z-ink-2);
}
.z-cal-legend { display: flex; gap: 16px; flex-wrap: wrap; }
.z-cal-legend span { display: inline-flex; align-items: center; gap: 6px; }
.z-cal-key { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.z-cal-key.is-open { background: var(--z-open); }
.z-cal-key.is-few  { background: var(--z-few); }
.z-cal-key.is-sold { background: var(--z-sold); }

.z-cal-none {
    padding: 26px 20px;
    text-align: center;
    color: var(--z-ink-2);
    font-size: 14.5px;
}

/* --- the cell below desktop: the same tile, without the price --------------
   Month band, date, day name — the desktop composition exactly — and the
   price line dropped. That line is the one part a phone cannot carry: at a
   seventh of the panel the cell is 41px wide on a 390px screen, and
   "₹1,00,000" does not read at that width whatever is done to it. The other
   three lines all do.

   NOT a square. A square cell here is 41px and these three lines need 61, so
   squaring it would mean shrinking the type to the point where the month and
   the day name are decoration rather than words. Height follows the content
   instead: 62px, which is the desktop 78 less the price row it no longer has.

   A departure still reads as one — .has-dep keeps its green wash and
   .z-cal-dot its corner dot — and the price is one tap away on the departure
   the cell opens.
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
    .z-cal-cell { min-height: 62px; }
    .z-cal-cell .z-cal-price { display: none; }

    /* The footnote goes with the prices it describes. "Prices shown are the
       lowest for that date" is not true of a grid that shows no prices. The
       seats legend stays — those dots are still on the cells. */
    .z-cal-pricenote { display: none; }
}

@media (max-width: 900px) {
    /* Seven legible tiles will not fit twice across a phone, so the second
       month is dropped rather than crushed. The stepper still walks forward
       one month at a time. */
    .z-cal-months { grid-template-columns: 1fr; }
    .z-cal-month.is-second { display: none; }
    .z-cal-head { grid-template-columns: 1fr; gap: 12px; text-align: center; }
    .z-cal-title { justify-content: center; }
    .z-cal-right { justify-self: center; flex-wrap: wrap; justify-content: center; }
    .z-cal-tour-name { font-size: 20px; }
    .z-cal-range { font-size: 17px; min-width: 0; }
}

/* ==========================================================================
   Pay in parts
   ========================================================================== */

.z-parts {
    display: grid;
    grid-template-columns: 1.05fr .95fr;
    gap: 48px;
    align-items: center;
}
.z-parts-copy h2 {
    font-size: clamp(26px, 3.6vw, 36px);
    letter-spacing: .04em;
    text-transform: uppercase;
    margin-bottom: 14px;
}
.z-parts-copy p { font-size: 16px; color: rgba(240, 233, 215, .84); max-width: 52ch; }

/* Small gold label above a heading. */
.z-eyebrow {
    font-size: 11px;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--z-gold-light);
    margin: 0 0 10px;
}
.z-section:not(.is-green) .z-eyebrow { color: var(--z-gold-deep); }

/* A marble tablet set against the green band, framed in gold. */
.z-plan {
    position: relative;
    background: var(--z-marble);
    background-image: var(--z-marble-tex);
    background-size: 300px 300px;
    border: 1px solid var(--z-gold);
    border-radius: var(--z-radius);
    box-shadow: 0 30px 70px -34px rgba(4, 18, 13, .8);
    padding: 26px;
}
.z-plan::after {
    content: "";
    position: absolute;
    inset: 5px;
    border: 1px solid var(--z-line-gold);
    border-radius: calc(var(--z-radius) - 5px);
    pointer-events: none;
}
.z-plan-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; padding-bottom: 14px; margin-bottom: 6px;
    border-bottom: 1px solid var(--z-line-soft);
}
.z-plan-head span { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--z-ink-3); }
.z-plan-head b {
    font-family: var(--z-display); font-size: 27px; font-weight: 600;
    color: var(--z-green); font-variant-numeric: tabular-nums;
}
.z-plan-row {
    display: grid;
    grid-template-columns: 26px 1fr auto;
    gap: 13px;
    align-items: center;
    padding: 12px 0;
    border-bottom: 1px dashed var(--z-line-soft);
}
.z-plan-row:last-child { border-bottom: 0; }
.z-plan-seq {
    width: 26px; height: 26px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--z-gold-wash); color: var(--z-gold-deep);
    font-size: 12px; font-weight: 500;
    font-variant-numeric: tabular-nums;
}
.z-plan-row.is-first .z-plan-seq { background: var(--z-green); color: var(--z-gold-light); }
.z-plan-label { font-size: 14.5px; color: var(--z-ink); }
.z-plan-label small { display: block; font-size: 12.5px; color: var(--z-ink-3); }
.z-plan-amt { font-size: 15px; font-weight: 500; color: var(--z-ink); font-variant-numeric: tabular-nums; }
.z-plan-note {
    margin: 16px 0 0; font-size: 12.5px; color: var(--z-ink-3);
    padding-top: 13px; border-top: 1px solid var(--z-line-soft);
}

/* ==========================================================================
   Why Zaereen
   ========================================================================== */

.z-why { display: grid; grid-template-columns: repeat(4, 1fr); gap: 30px; }
.z-why-item { display: flex; gap: 16px; align-items: flex-start; }
/* Arched niche rather than a circle — same device as the trust strip, one
   size up, so the two rows read as the same wall. */
.z-why-icon {
    flex: none;
    width: 56px; height: 66px;
    border-radius: 50% 50% 7px 7px / 56% 56% 7px 7px;
    border: 1px solid var(--z-gold);
    background: var(--z-surface);
    display: grid; place-items: center;
    color: var(--z-gold-deep);
    box-shadow: inset 0 0 0 3px var(--z-gold-wash);
}
.z-why-item h3 {
    font-family: var(--z-body);
    font-size: 15px;
    font-weight: 500;
    color: var(--z-gold-deep);
    margin: 0 0 5px;
}
.z-why-item p { font-size: 14px; color: var(--z-ink-2); margin: 0; line-height: 1.58; }

/* ==========================================================================
   Destinations
   ========================================================================== */

/* Destination tiles are full keyhole arches — a row of niches. */
.z-dest {
    position: relative;
    display: block;
    aspect-ratio: 3 / 4;
    overflow: hidden;
    background: var(--z-cream-deep);
    -webkit-mask-image: var(--z-arch-mask);
            mask-image: var(--z-arch-mask);
    -webkit-mask-size: 100% 100%;
            mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    transition: transform .28s ease;
}
.z-dest:hover { transform: translateY(-4px); }
.z-dest img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s cubic-bezier(.2,.7,.3,1); }
.z-dest:hover img { transform: scale(1.06); }
.z-dest::after {
    content: "";
    position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(13,44,34,0) 38%, rgba(9,32,25,.9) 100%);
}
/* Gold outline following the arch, drawn as a masked backing plate. */
.z-dest-frame {
    position: relative;
    padding: 5px;
    background: var(--z-gold);
    opacity: 1;
    -webkit-mask-image: var(--z-arch-mask);
            mask-image: var(--z-arch-mask);
    -webkit-mask-size: 100% 100%;
            mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    transition: filter .24s ease;
}
.z-dest-frame:hover { filter: brightness(1.1); }
.z-dest-cap {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 1;
    padding: 20px;
    color: #f6efdd;
}
.z-dest-cap b {
    display: block;
    font-family: var(--z-display);
    font-size: 22px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
}
.z-dest-cap span { font-size: 13px; color: var(--z-gold-light); }

/* ==========================================================================
   Reviews
   ========================================================================== */

.z-reviews { display: grid; grid-template-columns: repeat(5, 1fr); gap: 18px; }
.z-review {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    padding: 20px 18px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    box-shadow: var(--z-shadow-sm);
}
.z-review-top { display: flex; align-items: center; gap: 12px; }
.z-review-avatar {
    width: 46px; height: 46px; border-radius: 50%;
    object-fit: cover; flex: none;
    border: 2px solid var(--z-gold-wash);
    background: var(--z-cream-deep);
}
.z-review-who { min-width: 0; }
/* THE NAME CARRIES LIKE A CARD TITLE. At 13px, weight 500, in the muted ink
   used for body copy, the traveller's name was lighter than the words of their
   own review — the one thing on the card that says whose opinion this is read
   as its smallest print. The hotel and holiday cards set their titles in the
   display serif at 700, so this joins them.

   NOT UPPERCASED, though, which .z-story-body h3 also does. That treatment
   turns a heading into a label; applied to a person it shouts their name.
   Green rather than the cards' gold, for the same reason the price uses it —
   at this size gold is a decoration and the name is information. */
.z-review-who b {
    display: block;
    font-family: var(--z-display);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--z-green);
}
.z-stars { display: flex; gap: 2px; color: var(--z-gold); margin-top: 3px; }
.z-review q {
    font-size: 14px;
    line-height: 1.6;
    color: var(--z-ink-2);
    font-style: italic;
    quotes: "\201C" "\201D";
}
.z-review cite { font-size: 13px; font-style: normal; color: var(--z-ink); margin-top: auto; }

/* ==========================================================================
   Secondary products
   ========================================================================== */

.z-products { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.z-product {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 20px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.z-product:hover { border-color: var(--z-gold); transform: translateY(-2px); box-shadow: var(--z-shadow); }
.z-product-icon {
    flex: none; width: 46px; height: 46px; border-radius: var(--z-radius-sm);
    background: var(--z-gold-wash); color: var(--z-gold-deep);
    display: grid; place-items: center;
}
.z-product b { display: block; font-size: 15px; font-weight: 500; color: var(--z-ink); }
.z-product span { font-size: 13px; color: var(--z-ink-3); }

/* ==========================================================================
   Footer
   ========================================================================== */

/* The footer is a wall: crested along its top edge with stepped merlons, the
   way a Fatimid parapet meets the sky. margin-top leaves room for the crest,
   which sits above the block. */
.z-footer {
    position: relative;
    background: var(--z-green);
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
    color: rgba(238, 230, 213, .82);
    margin-top: 25px;
    padding: 56px 0 0;
    font-size: 14.5px;
}
.z-footer::before {
    content: "";
    position: absolute; inset: 0 0 auto 0; height: 2px;
    background: linear-gradient(90deg, transparent, var(--z-gold), transparent);
    z-index: 2;
}
.z-footer a { color: rgba(238, 230, 213, .82); }
.z-footer a:hover { color: var(--z-gold-light); }

.z-footer-grid {
    display: grid;
    /* Six explicit tracks: brand, Ziyarat, Travel, Support, Tour Organizer,
       Associated.

       NOT repeat(auto-fit, ...). auto-fit cannot share a track list with an
       fr track — the whole declaration is invalid and the browser drops it,
       which left the grid at one column and stacked the entire footer down
       the left edge.

       The last track is `auto` rather than a fraction so it collapses to
       nothing when no crests are installed and the Associated column is not
       rendered at all; a fraction would hold a column of empty space open.

       Widths follow the content: the brand and the authorisation paragraph
       need prose measure, the three link columns need only their longest
       label, and the crest plate sizes itself. */
    grid-template-columns: 1.5fr .95fr .95fr .95fr 1.8fr auto;
    gap: 36px 30px;
    padding-bottom: 40px;
    align-items: start;
}
/* IN THE FOOTER THE LOCKUP STACKS. The header sets .z-brand as a flex row —
   the link is the layout slot the nav centres against there, so the tagline
   sits beside the mark. Down here there is no nav to balance and the column
   is narrow, so the two read better stacked, with "Mumineen Travel Portal"
   centred on the logo above it. */
.z-footer-brand .z-brand {
    /* .z-brand already stacks and centres; the footer only wants more air
       between the two and a wider measure for the line. */
    gap: 8px;
    text-align: center;
}
.z-footer-brand .z-brand-tag {
    /* nowrap is right beside a square logo in the header; under it, the line
       is free to break rather than push the column wider than its track. */
    white-space: normal;
    color: var(--z-gold-light);
}

.z-footer-brand p { margin: 14px 0 18px; line-height: 1.65; max-width: 30ch; font-size: 14px; }
/* The footer sets its body at 82% parchment, so weight alone barely reads on
   the dark ground; the emphasis comes from taking the phrase to full strength
   as well. */
.z-footer-brand p b { font-weight: 600; color: #f6eeda; }

.z-social { display: flex; gap: 9px; }
.z-social a {
    width: 36px; height: 36px; border-radius: 50%;
    border: 1px solid rgba(221, 193, 124, .35);
    display: grid; place-items: center;
    transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}
.z-social a:hover { background: var(--z-gold); border-color: var(--z-gold); color: var(--z-green); }

.z-footer h4 {
    font-family: var(--z-body);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .15em;
    text-transform: uppercase;
    color: #fbf5e6;
    margin: 0 0 16px;
}
.z-footer-col li { margin-bottom: 9px; }
.z-footer-contact li { display: flex; gap: 11px; margin-bottom: 13px; align-items: flex-start; }
.z-footer-contact svg { color: var(--z-gold-light); flex: none; margin-top: 3px; }

/* --------------------------------------- the two centred footer columns ---
   Ziyarat Tour Organizer and Associated. Everything else down here is a list
   of links, which has to stay flush left or the ragged right edge of the
   labels turns into a ragged edge on both sides. These two are not lists:
   one is a statement about who authorises the tours, the other a pair of
   plates carrying crests and payment marks, and both are already symmetrical
   objects. Centred, they read as the pair of endorsements they are.

   A modifier class rather than :nth-child — the Associated column is only
   rendered when there is at least one crest or payment mark installed, so a
   positional selector would centre the wrong column on a site that has
   neither. */
.z-footer-col.is-centred { text-align: center; }

/* The plates are width: fit-content, so centring the text alone leaves them
   parked at the left edge of the track. margin-inline only: the vertical
   rhythm between the statement, the crests and the payment marks is set
   further down and has to survive. */
.z-footer-col.is-centred .z-contact-assoc { margin-inline: auto; }

/* The crest row and the payment row already centre their own contents; this
   is for the prose inside the authorisation panel, whose line breaks are set
   by the measure rather than by the markup. */
.z-footer-col.is-centred .z-authorised-by,
.z-footer-col.is-centred .z-authorised-text { text-align: center; }

/* ------------------------------------ authorised by Dawat-E-Hadiyah ---
   The endorsement that replaced the Contact Us list. It is a statement, not a
   list of links, so it is set as running text rather than inheriting the
   footer's link column rhythm.

   The two names are gold, not the red of the printed sheet: red on this dark
   green fails contrast and reads as an error state, which is the opposite of
   what an endorsement should say. */
.z-authorised {
    margin-top: 2px;
    padding: 13px 14px 14px;
    border-radius: 11px;
    border: 1px solid rgba(193, 154, 63, .30);
    background: rgba(255, 255, 255, .04);
}
.z-authorised-by {
    margin: 0 0 8px;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(193, 154, 63, .24);
    font-family: var(--z-display);
    font-size: 15px;
    line-height: 1.3;
    color: var(--z-cream);
}
.z-authorised-by span {
    font-weight: 700;
    color: var(--z-gold-light);
}
.z-authorised-text {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.7;
    color: rgba(244, 238, 224, .80);
}
.z-authorised-text b {
    font-weight: 700;
    color: var(--z-cream);
}
.z-authorised-text span {
    font-weight: 700;
    color: var(--z-gold-light);
}
/* The Sigat plate follows the statement directly, so it needs less air above
   it than it did under a list of contact rows. margin-top only — the auto
   side margins that centre it under that panel have to survive. */
.z-authorised + .z-contact-assoc { margin-top: 12px; }

/* ------------------------------ authorized by Sigat, in Contact Us ---
   A credit, not a banner: the plate hugs the four crests instead of ruling
   a line across the column, which is what made it look like an empty panel
   with logos parked in it. fit-content does the hugging; max-width keeps it
   inside the column if the plate ever outgrows the column on a phone.

   The crests are supplied on WHITE grounds, so they cannot sit on the dark
   green footer — each would carry its own pale box and read as four
   mistakes. One plate holds them all, as the printed lockup does, and the
   crest area is pure white rather than the cream used elsewhere down here:
   any tint at all and the four white JPEG grounds reappear as rectangles on
   top of it. The colour therefore lives in the title band and the gold
   edge, never in the fill behind the crests. */
.z-contact-assoc {
    width: fit-content;
    max-width: 100%;
    /* The plate had auto side margins to centre it under the Dawat-E-Hadiyah
       panel it used to sit beneath. It has a column of its own now, so it
       aligns with that column's heading like every other footer block. */
    margin: 16px 0 0;
    /* Same radius as .z-authorised, so the two stack as one pair. */
    border-radius: 11px;
    background: #fff;
    border: 1px solid rgba(193, 154, 63, .42);
    /* Lifts the plate off the dark green instead of looking cut out of it. */
    box-shadow: 0 3px 10px rgba(0, 0, 0, .18);
    /* The title band runs edge to edge, so its square corners have to be
       clipped back to the plate's radius — hence no padding on the box
       itself; the band and the crest grid carry their own. */
    overflow: hidden;
}

/* h5, not h4, so .z-footer h4 (which sets cream, uppercase and the body
   face for every heading down here) never applies — cream on this light
   plate would be invisible. Nothing else in the footer styles h5.

   Its own pale green band, as on the printed sheet: it separates the label
   from the crests without a rule, and green rather than gold because the
   band should echo the footer's ground, not compete with the gold edge. */
.z-contact-assoc-title {
    margin: 0 0 8px;
    padding: 6px 12px 5px;
    background: linear-gradient(180deg, #e8f1e6 0%, #d7e7d5 100%);
    border-bottom: 1px solid rgba(193, 154, 63, .30);
    font-family: var(--z-body);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .13em;
    text-transform: uppercase;
    text-align: center;
    white-space: nowrap;
    color: var(--z-green);
}

/* One row of four, as on the sanad. A grid rather than flex-wrap so the four
   stay on one line instead of dropping a crest onto a second row the moment
   the column narrows; minmax(0, auto) lets the cells give way in a tight
   column, and object-fit keeps a squeezed crest in proportion rather than
   letting it overflow the plate. The crests are a size down from the
   two-row version so all four fit the column comfortably. */
.z-contact-assoc-row {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, auto));
    justify-content: center;
    align-items: center;
    /* gap, not margins: nothing doubles up on the seam. */
    gap: 0 9px;
    padding: 0 11px 9px;
}
.z-contact-assoc-row img {
    /* Height-led so crests of different proportions sit on one optical
       baseline; contain so none is ever stretched. Small on purpose — this
       is a credit inside a column, not a banner. */
    height: 32px;
    width: auto;
    max-width: 60px;
    /* The cap is the smaller of the two: 60px so one wide crest cannot
       dominate the row, 100% so it still fits a cell that had to give way. */
    max-width: min(60px, 100%);
    object-fit: contain;
    display: block;
    margin: 0 auto;
    transition: transform .25s ease;
}
/* They are not links, so the lift is the only affordance available — it
   says "these are four separate seals" on a plate where they otherwise
   blend into one block. */
.z-contact-assoc-row img:hover { transform: translateY(-2px) scale(1.05); }

@media (prefers-reduced-motion: reduce) {
    .z-contact-assoc-row img { transition: none; }
    .z-contact-assoc-row img:hover { transform: none; }
}

@media (max-width: 560px) {
    .z-contact-assoc-title { padding: 5px 10px 4px; }
    .z-contact-assoc-row { gap: 0 7px; padding: 0 9px 8px; }
    .z-contact-assoc-row img { height: 29px; max-width: min(54px, 100%); }
}

.z-footer-bar {
    border-top: 1px solid rgba(221, 193, 124, .2);
    padding: 18px 0 22px;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 20px;
    align-items: center;
    font-size: 13px;
}
/* The grid is 1fr auto 1fr and was written for three children. It ran with two
   after the salawat line was removed — copyright forced into the centre column,
   credit hard right — and now runs with three again: copyright left, the credit
   centred, and the policy links closing the line on the right. */
/* Placed by class, not by position: :first-child pointed at whichever span
   happened to be written first, so swapping the two in the markup would have
   silently moved the wrong one. */
.z-footer-bar > .z-powered {
    grid-column: 1;
    text-align: left;
}
.z-footer-bar > .z-footer-copy {
    grid-column: 2;
    text-align: center;
}

/* The four policy pages, pipe-separated the way a closing line reads. The rule
   is drawn by the separator rather than a border, so the last link has nothing
   trailing it. */
.z-footer-legal {
    grid-column: 3;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: 4px 0;
}
.z-footer-legal a {
    padding: 0 11px;
    font-size: 12.5px;
    color: rgba(238, 230, 213, .78);
    white-space: nowrap;
}
.z-footer-legal a:hover { color: var(--z-gold-light); }
.z-footer-legal a + a {
    border-left: 1px solid rgba(221, 193, 124, .28);
}
.z-footer-legal a:last-child { padding-right: 0; }

/* Stacked and centred once there is no room for a three-column line. */
@media (max-width: 860px) {
    .z-footer-bar {
        grid-template-columns: 1fr;
        gap: 12px;
        text-align: center;
    }
    .z-footer-bar > .z-footer-copy,
    .z-footer-bar > .z-powered,
    .z-footer-legal { grid-column: 1; text-align: center; }
    .z-footer-legal { justify-content: center; }
    /* Wrapped onto two rows, a left border on every link but the first leaves a
       stray rule at the start of the second row. */
    .z-footer-legal a { padding: 0 10px; }
    .z-footer-legal a + a { border-left: 0; }
}

/* Small "Powered by Oxford Travels" line — required beside the mark. */
.z-powered {
    font-size: 11px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-footer .z-powered { color: rgba(238, 230, 213, .55); }

/* ==========================================================================
   Page head (inner pages)
   ========================================================================== */

.z-pagehead {
    position: relative;
    /* Ordinary padding, NOT header clearance. Every page carrying this band
       sets $z_header_solid, and .z-header.is-solid is sticky — it takes up its
       own space in flow, so the band already starts below it. The old 134px
       was clearance for the absolute, overlaying header, and under a sticky
       one it was 134px of empty green. */
    padding: 46px 0 56px;
    background: var(--z-green);
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
    color: #f3ead6;
    margin-bottom: 15px;
}
.z-pagehead::after {
    content: "";
    position: absolute; inset: auto 0 0 0; height: 2px;
    background: linear-gradient(90deg, transparent, var(--z-gold), transparent);
    z-index: 2;
}
.z-pagehead h1 {
    font-size: clamp(28px, 4vw, 40px);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: #fbf5e6;
}
.z-pagehead p { margin: 12px 0 0; color: rgba(240, 232, 214, .78); max-width: 56ch; }

/* --------------------------------------------------------- desktop only --- */
/* THE INTRO BAND IS A DESKTOP THING. Below desktop it goes, on every page.

   On a phone or tablet the green block spent the whole fold on a crumb trail,
   a title and a blurb, pushing the filter toggle — or the first result, or the
   booking form — under the scroll. The header above it already says which site
   this is, and the content below says what the page is.

   A BLANKET RULE, NOT A CLASS PER PAGE. This started as an opt-in and grew to
   twenty-one sections, at which point the exceptions were the thing worth
   naming rather than the rule. Everything wearing .z-pagehead is covered,
   including the two shared partials — ui/tour_hero.php behind every holiday,
   tour and visa detail page, and ui/booking_facts.php behind the three
   checkout steps — and including any page added later, which is the part an
   opt-in could not promise.

   THE ONE EXCEPTION is .is-home. That is not an intro band at all: it is the
   home page's hero, carrying the search, and it has its own mobile treatment a
   few thousand lines down.

   WHAT THIS COSTS, SAID PLAINLY: on a phone the hotel detail page no longer
   shows the hotel's name in the band, the visa page no longer shows the
   country, and the checkout steps lose their step title. Each of those is
   restated immediately below in the .z-facts strip, the gallery caption or the
   booking summary, so nothing is only said in the band — but it IS a name
   coming off the screen, and it was a deliberate call rather than an oversight.

   The per-page .z-desk-only markers left in the markup are redundant now and
   harmless: they hide the same elements at the same breakpoint. The class
   stays defined because it is the way to drop anything else below desktop
   without inventing a second mechanism. !important because it has to beat the
   display a component sets on the element it lands on. */
@media (max-width: 1080px) {
    .z-pagehead:not(.is-home),
    .z-desk-only { display: none !important; }
}

/* WHAT THE BAND LEAVES BEHIND. With the page head gone, whatever followed it
   now begins directly under the header's crenellation — and on the inner pages
   that is the facts strip, whose 16px of padding was sized to sit below a 56px
   green band rather than against a row of merlons. The strip reads as though
   it has been pushed up into the chrome.

   The selector is the hidden band itself: `display: none` removes an element
   from the page, not from the DOM, so it is still the sibling before the strip
   and still names exactly the pages where the band was taken away. A blanket
   `.z-facts { padding-top }` would also move the strip on pages that never had
   a band above it. */
@media (max-width: 1080px) {
    .z-pagehead + .z-facts { padding-top: 30px; }
}

.z-crumb {
    display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
    font-size: 12.5px; letter-spacing: .06em; text-transform: uppercase;
    color: rgba(240, 232, 214, .6); margin-bottom: 14px;
}
.z-crumb a { color: var(--z-gold-light); }
.z-crumb span { opacity: .5; }
/* The trail off the dark band. Every other use sits inside .z-pagehead;
   on cream those colours are all but invisible, so the light ground gets
   the ink/gold pair instead of the parchment/gold-light one. */
.z-crumb.is-onlight { color: var(--z-ink-3); }
.z-crumb.is-onlight a { color: var(--z-gold-deep); }
.z-crumb.is-onlight a:hover { color: var(--z-green); }

/* ==========================================================================
   Listing layout — filter rail + results
   ========================================================================== */

/* minmax(0, 1fr), not 1fr: a plain 1fr track refuses to shrink below the
   widest thing inside it, so one long line in one result card pushes the
   whole results column past the right-hand edge of the page. */
.z-listing { display: grid; grid-template-columns: 268px minmax(0, 1fr); gap: 30px; align-items: start; }

.z-filters {
    position: sticky;
    top: 84px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    padding: 20px;
    box-shadow: var(--z-shadow-sm);
}
.z-filters h2 {
    font-family: var(--z-body);
    font-size: 12px; font-weight: 600; letter-spacing: .14em;
    text-transform: uppercase; color: var(--z-ink-3);
    margin: 0 0 16px; padding-bottom: 12px;
    border-bottom: 1px solid var(--z-line-soft);
}
.z-filters .z-field { margin-bottom: 15px; }
.z-filters-actions { display: flex; gap: 8px; margin-top: 4px; }
.z-filters-actions .z-btn { flex: 1 1 auto; }

.z-results-bar {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 16px; flex-wrap: wrap; margin-bottom: 20px;
}
.z-results-bar b { font-family: var(--z-display); font-size: 22px; font-weight: 600; }
.z-results-bar span { font-size: 14px; color: var(--z-ink-3); }

.z-filters-toggle { display: none; }

/* ==========================================================================
   Tour detail
   ========================================================================== */


.z-tourbody { display: grid; grid-template-columns: 1fr 400px; gap: 44px; align-items: start; }

/* --- booking card --- */
.z-book {
    position: sticky;
    top: 84px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    box-shadow: var(--z-shadow);
    overflow: hidden;
}
.z-book-head {
    background: var(--z-green);
    color: #f2e9d5;
    padding: 18px 20px;
}
.z-book-head small {
    display: block; font-size: 11px; letter-spacing: .13em;
    text-transform: uppercase; color: rgba(240,232,214,.6);
}
.z-book-head b {
    font-family: var(--z-display); font-size: 32px; font-weight: 600;
    color: var(--z-gold-light); font-variant-numeric: tabular-nums;
}
.z-book-head span { font-size: 13px; color: rgba(240,232,214,.7); }
.z-book-body { padding: 18px 20px 20px; }
.z-book-row {
    display: flex; justify-content: space-between; gap: 12px;
    padding: 9px 0; border-bottom: 1px dashed var(--z-line-soft);
    font-size: 14px;
}
.z-book-row:last-of-type { border-bottom: 0; }
.z-book-row dt { color: var(--z-ink-3); margin: 0; }
.z-book-row dd { margin: 0; color: var(--z-ink); text-align: right; font-weight: 500; }
.z-book-cta { margin-top: 16px; display: grid; gap: 9px; }
.z-book-note {
    margin: 14px 0 0; font-size: 12.5px; color: var(--z-ink-3); text-align: center;
}

/* --- section blocks --- */
.z-block { margin-bottom: 40px; scroll-margin-top: 128px; }
.z-block > h2 {
    font-size: 23px;
    letter-spacing: .07em;
    text-transform: uppercase;
    padding-bottom: 12px;
    margin-bottom: 20px;
    border-bottom: 1px solid var(--z-line);
    position: relative;
}
.z-block > h2::after {
    content: "";
    position: absolute; left: 0; bottom: -1px; width: 56px; height: 2px;
    background: var(--z-gold);
}
.z-prose { color: var(--z-ink-2); font-size: 15.5px; line-height: 1.7; }
.z-prose p { margin: 0 0 .9em; }
.z-prose ul { list-style: disc; padding-left: 20px; margin: 0 0 .9em; }
.z-prose li { margin-bottom: .35em; }
.z-prose table { width: 100%; border-collapse: collapse; }
.z-prose td, .z-prose th { border: 1px solid var(--z-line); padding: 8px 10px; }

/* --- in-page section nav --- */
.z-jump {
    display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    padding: 6px;
    margin-bottom: 32px;
    position: sticky; top: 74px; z-index: 20;
}
.z-jump::-webkit-scrollbar { display: none; }
.z-jump a {
    flex: none; padding: 8px 14px; font-size: 13.5px;
    color: var(--z-ink-2); border-radius: 6px; white-space: nowrap;
}
.z-jump a:hover { background: var(--z-gold-wash); color: var(--z-green); }

/* --- departure selector --- */
.z-depsel { display: grid; gap: 10px; }
.z-depopt {
    display: grid;
    grid-template-columns: 64px 1fr auto auto;
    gap: 16px;
    align-items: center;
    width: 100%;
    text-align: left;
    background: var(--z-surface);
    border: 1.5px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    padding: 13px 16px;
    cursor: pointer;
    font-family: inherit;
    transition: border-color .18s ease, background-color .18s ease, box-shadow .18s ease;
}
.z-depopt:hover { border-color: var(--z-gold-light); }
.z-depopt[aria-pressed="true"] {
    border-color: var(--z-gold);
    background: var(--z-gold-wash);
    box-shadow: 0 0 0 3px rgba(193,154,63,.14);
}
.z-depopt[disabled] { opacity: .55; cursor: not-allowed; }
.z-depopt-date { text-align: center; }
.z-depopt-date .d {
    display: block; font-family: var(--z-display); font-size: 25px;
    font-weight: 600; line-height: 1; color: var(--z-green);
    font-variant-numeric: tabular-nums;
}
.z-depopt-date .m {
    display: block; font-size: 10.5px; letter-spacing: .14em;
    text-transform: uppercase; color: var(--z-gold-deep); margin-top: 3px;
}
.z-depopt-info { font-size: 14px; color: var(--z-ink-2); min-width: 0; }
.z-depopt-info b { display: block; font-size: 14.5px; font-weight: 500; color: var(--z-ink); }
.z-depopt-price {
    font-family: var(--z-display); font-size: 21px; font-weight: 600;
    color: var(--z-gold-deep); font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* --- occupancy / hotel grade picker --- */
.z-grades { display: grid; gap: 9px; margin-top: 16px; }
.z-grade {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 11px 14px;
    border: 1.5px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    background: var(--z-surface);
    cursor: pointer; font-size: 14px;
    transition: border-color .18s ease, background-color .18s ease;
}
.z-grade:hover { border-color: var(--z-gold-light); }
.z-grade input { accent-color: var(--z-green); margin: 0; }
.z-grade b { font-weight: 500; }
.z-grade .amt { font-weight: 500; color: var(--z-gold-deep); font-variant-numeric: tabular-nums; }
.z-grade:has(input:checked) { border-color: var(--z-gold); background: var(--z-gold-wash); }

/* --- itinerary day cards -------------------------------------------------
   Same anatomy as the holidays package page (header band + day pill + boxed
   body), rendered in Zaereen's marble/gold. Cards stay open: a pilgrim reads
   the whole route, they do not hunt one day. */
.z-daywise { display: grid; gap: 16px; }
.z-day-card {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    overflow: hidden;
    box-shadow: 0 10px 24px rgba(13, 44, 34, .07);
}
.z-day-head {
    position: relative;
    display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
    padding: 13px 16px 13px 22px;
    background: linear-gradient(180deg, var(--z-cream), var(--z-cream-deep));
    border-bottom: 1px solid var(--z-line);
}
/* Gold rail, the counterpart of the holidays card's green one. */
.z-day-head::before {
    content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px;
    background: linear-gradient(180deg, var(--z-gold-light), var(--z-gold-deep));
}
.z-day-icon {
    flex: none; width: 30px; height: 30px; border-radius: 10px;
    display: inline-flex; align-items: center; justify-content: center;
    background: rgba(18, 101, 95, .12);
    border: 1px solid rgba(18, 101, 95, .22);
    color: var(--z-teal);
}
.z-day-pill {
    flex: none;
    display: inline-flex; align-items: center;
    padding: 5px 11px; border-radius: 100px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    /* Green, not gold, on the gold wash: --z-gold-deep measures 4.10:1 there,
       and 11px uppercase is not large text. --z-green measures 12.9:1. */
    color: var(--z-green);
    font-size: 11px; font-weight: 600;
    letter-spacing: .1em; text-transform: uppercase;
    white-space: nowrap;
}
.z-day-headline {
    min-width: 0; flex: 1 1 auto;
    font-family: var(--z-display); font-size: 18px; font-weight: 600;
    letter-spacing: .02em; color: var(--z-green); line-height: 1.25;
}
.z-day-city {
    flex: none;
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 12.5px; color: var(--z-ink-2);
}
.z-day-city svg { color: var(--z-gold-deep); }

.z-day-body { padding: 14px 16px 16px; }
.z-day-desc {
    background: var(--z-marble);
    border: 1px solid var(--z-line);
    border-radius: 12px;
    padding: 12px 14px;
}
/* Descriptions are pasted from editors; strip any background they carry in so
   a stray inline style can never repaint this panel. */
.z-day-desc *,
.z-day-desc *::before, .z-day-desc *::after {
    background: transparent;
}
/* ~125 characters a line at the wider shell; cap the measure so the text
   stays readable while the panel itself still fills the card. */
.z-day-desc > p, .z-day-sight-list li { max-width: 88ch; }
.z-day-desc > *:first-child { margin-top: 0; }
.z-day-desc > *:last-child  { margin-bottom: 0; }

/* A day with no description opens straight on the ziyarat list; drop the
   gap so the panel does not float away from the header band. */
.z-day-body > .z-day-sight:first-child,
.z-day-body > .z-day-meals:first-child { margin-top: 0; }
.z-day-sight {
    margin-top: 14px;
    padding: 12px 14px;
    border-radius: 12px;
    background: linear-gradient(180deg, rgba(18, 101, 95, .10), rgba(18, 101, 95, .04));
    border: 1px solid rgba(18, 101, 95, .26);
}
.z-day-sight-title {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 11.5px; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-teal);
    margin-bottom: 8px;
}
.z-day-sight-list {
    margin: 0; padding: 0; list-style: none;
    display: grid; gap: 6px;
}
.z-day-sight-list li {
    position: relative;
    padding-left: 20px;
    font-size: 14px; line-height: 1.5; color: var(--z-ink);
}
.z-day-sight-list li::before {
    content: ""; position: absolute; left: 4px; top: .62em;
    width: 6px; height: 6px; border-radius: 2px;
    background: var(--z-gold);
    transform: translateY(-50%) rotate(45deg);
}
/* --- day card footer: date | meals | overnight city ---------------------
   A ruled strip across the bottom of each card, so the three facts a
   pilgrim scans for sit in the same place on every day. */
.z-day-foot {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 10px 18px;
    padding: 11px 16px;
    border-top: 1px solid var(--z-line);
    background: var(--z-cream);
}
.z-day-when, .z-day-where {
    display: inline-flex; align-items: center; gap: 7px;
    font-size: 13.5px; color: var(--z-ink-2);
}
.z-day-when svg, .z-day-where svg { color: var(--z-gold-deep); flex: none; }
.z-day-when b, .z-day-where b { font-weight: 600; color: var(--z-green); }
.z-day-fmeals { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px 14px; }
.z-day-meal {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 13px; font-weight: 500; color: var(--z-teal);
}
.z-day-meal svg { color: var(--z-teal); flex: none; }
.z-day-meal.is-none { color: var(--z-ink-3); font-weight: 400; }
.z-day-body { padding-bottom: 14px; }


/* --- account menu ----------------------------------------------------------
   The name in the bar opens this. Sign out has to live somewhere, and a bar
   with no way out of an account is worse than one extra click.
   -------------------------------------------------------------------------- */
.z-acct { position: relative; }
/* Layout only. The look is .z-btn-gold's, shared with every primary button on
   the site, so the header button and the page CTAs stay one design. */
.z-acct-btn { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; }
/* The name is a label, not something to select and copy by accident when
   somebody double-clicks to open the menu. */
.z-acct-btn span { user-select: none; }
.z-acct-btn .z-acct-caret { transition: transform .2s ease; }
.z-acct-btn.is-open .z-acct-caret { transform: rotate(180deg); }
.z-acct-menu {
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 50;
    min-width: 244px;
    padding: 7px;
    background: var(--z-surface);
    border: 1px solid var(--z-line-strong);
    border-radius: 12px;
    box-shadow: 0 24px 54px -18px rgba(4, 18, 13, .45);
}
.z-acct-menu[hidden] { display: none; }
/* Who you are signed in as, so the menu answers that before it acts. */
.z-acct-who {
    padding: 9px 12px 11px; margin-bottom: 5px;
    border-bottom: 1px solid var(--z-line-soft);
}
.z-acct-who b { display: block; font-size: 14.5px; color: var(--z-green); }
.z-acct-who span { font-size: 11.5px; color: var(--z-ink-3); word-break: break-word; }
.z-acct-menu a {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 12px; border-radius: 8px;
    font-size: 14px; color: var(--z-ink);
}
.z-acct-menu a svg { flex: none; color: var(--z-gold-deep); }
.z-acct-menu a:hover { background: var(--z-gold-wash); color: var(--z-green); }
/* Leaving is not the same kind of action as the rest, and reads as its own. */
.z-acct-menu a.is-out {
    margin-top: 5px; padding-top: 12px;
    border-top: 1px solid var(--z-line-soft);
    border-radius: 0 0 8px 8px;
    color: var(--z-sold);
}
.z-acct-menu a.is-out svg { color: var(--z-sold); }
.z-acct-menu a.is-out:hover { background: var(--z-sold-bg); color: var(--z-sold); }

/* --- sign in ---------------------------------------------------------------
   Zaereen's own door onto the same Oxford customer record.

   ONE CARD, TWO HALVES, rather than prose sitting beside a floating box. The
   left half is a wall — dome green, blind arcading, a merlon crest and the
   Al-Aqmar roundel — and the right half is the panel you actually type into.
   A signed-in pilgrim is handing over an identity, and the page should look
   like somewhere that is safe to do that; a bare form on cream did not.

   Everything here is scoped under .z-login. The gate is shared with the
   reservation, visa and hotel pages, so any override of .z-gate-* has to stay
   inside this block or those three change too.
   -------------------------------------------------------------------------- */
.z-login {
    display: grid;
    grid-template-columns: 1.05fr 1fr;
    align-items: stretch;               /* both halves the same height */
    margin: 8px 0 48px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 18px;
    box-shadow: var(--z-shadow-lg);
    overflow: hidden;                   /* keeps the wall inside the radius */
}
.z-login > * { min-width: 0; }

/* --- the wall ------------------------------------------------------------- */
.z-login-brand {
    position: relative;
    display: flex; flex-direction: column; justify-content: center;
    padding: 52px 46px;
    background:
        radial-gradient(120% 90% at 12% 0%, rgba(31, 96, 71, .55) 0%, rgba(13, 44, 34, 0) 60%),
        linear-gradient(158deg, var(--z-green-2) 0%, var(--z-green) 62%);
    color: var(--z-cream);
    isolation: isolate;
}
/* Blind arcading as the ground texture — the same keyhole niche the rest of
   the site is built from, at the weight of a watermark. */
.z-login-brand::before {
    content: "";
    position: absolute; inset: 0;
    background-repeat: repeat;
    background-size: 62px 62px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='62' height='62' viewBox='0 0 62 62'%3E%3Cpath d='M31 8c-7 0-12 5-12 12v18c0 5 5 9 12 9s12-4 12-9V20c0-7-5-12-12-12z' fill='none' stroke='%23c19a3f' stroke-width='1.1'/%3E%3C/svg%3E");
    opacity: .13;
    z-index: -1;
    pointer-events: none;
}
/* Merlons along the very top, so the panel reads as a wall not a rectangle. */
.z-login-brand::after {
    content: "";
    position: absolute; top: 0; left: 0; right: 0; height: 14px;
    background-repeat: repeat-x;
    background-size: auto 14px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='14' viewBox='0 0 24 18'%3E%3Cpath d='M0,18 L0,13 L4,13 L4,8 L8,8 L8,3 L12,0 L16,3 L16,8 L20,8 L20,13 L24,13 L24,18 Z' fill='%23c19a3f'/%3E%3C/svg%3E");
    opacity: .5;
    transform: scaleY(-1);
    pointer-events: none;
}
.z-login-medallion {
    width: 46px; height: 46px;
    color: var(--z-gold-light);
    opacity: .95;
    margin-bottom: 20px;
}
.z-login-brand h1 {
    margin: 0 0 14px;
    font-family: var(--z-display);
    font-size: clamp(30px, 3.2vw, 43px);
    font-weight: 600; letter-spacing: .035em; line-height: 1.12;
    color: #fdf8ec;
    text-wrap: balance;
}
.z-login-brand > p {
    margin: 0 0 26px;
    font-size: 15px; line-height: 1.65;
    color: rgba(242, 233, 213, .82);
    max-width: 44ch;
}
.z-login-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.z-login-list li {
    display: flex; align-items: flex-start; gap: 13px;
    font-size: 14.5px; line-height: 1.45;
    color: rgba(242, 233, 213, .95);
}
/* A gold disc behind each mark, so the row has an anchor rather than a
   floating glyph. */
.z-login-list svg {
    flex: none;
    width: 30px; height: 30px; padding: 7px;
    box-sizing: border-box;
    border-radius: 50%;
    background: rgba(227, 200, 134, .13);
    border: 1px solid rgba(227, 200, 134, .3);
    color: var(--z-gold-light);
}
/* The closing reassurance, set apart by a hairline. */
.z-login-trust {
    display: flex; align-items: center; gap: 9px;
    margin: 28px 0 0; padding-top: 20px;
    border-top: 1px solid rgba(227, 200, 134, .22);
    font-size: 12.5px; letter-spacing: .02em;
    color: rgba(242, 233, 213, .62);
}
.z-login-trust svg { flex: none; color: var(--z-gold-light); opacity: .8; }

/* --- the panel ------------------------------------------------------------ */
.z-login-gate {
    display: flex; flex-direction: column; justify-content: center;
    padding: 52px 46px;
    background: var(--z-surface);
}
/* The card already carries the elevation and the border, so the gate inside it
   must not draw its own — two nested boxes read as a mistake. */
.z-login-gate .z-gate.is-inline .z-gate-panel,
.z-login-gate .z-gate-panel {
    max-width: none;
    width: 100%;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    text-align: left;
}
/* Left-aligned inside the card, so the heading, the button and the fields all
   share one edge. The mark stays where it was, above the title. */
.z-login-gate .z-gate-mark { margin-bottom: 16px; }
.z-login-gate .z-gate-panel h2 { font-size: 27px; }
.z-login-gate .z-gate-note { font-size: 14px; line-height: 1.6; margin-bottom: 24px; }
.z-login-gate .z-otp-boxes { justify-content: flex-start; }
.z-login-gate .z-gate-foot {
    margin-top: 22px; padding-top: 18px;
    border-top: 1px solid var(--z-line-soft);
    line-height: 1.6;
}

@media (max-width: 980px) {
    .z-login {
        grid-template-columns: 1fr;
        margin: 4px 0 34px;
        border-radius: 14px;
    }
    /* The form first on a phone: somebody who came here to sign in should not
       have to scroll past the pitch to do it. */
    .z-login-brand { order: 2; padding: 34px 26px; }
    .z-login-gate  { order: 1; padding: 34px 26px; }
    .z-login-brand h1 { font-size: 27px; }
    .z-login-medallion { width: 38px; height: 38px; margin-bottom: 14px; }
}
@media (max-width: 480px) {
    .z-login-brand, .z-login-gate { padding: 28px 20px; }
}

/* --- my journey ------------------------------------------------------------
   One card per booking: when it leaves, what it costs, what is still owed
   and what is still missing. The date block leads because that is what a
   pilgrim scans this page for.
   -------------------------------------------------------------------------- */
.z-journey-top {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 20px; flex-wrap: wrap; margin-bottom: 26px;
}
.z-journey-owed {
    flex: none; text-align: right;
    padding: 10px 16px;
    background: var(--z-gold-wash); border: 1px solid var(--z-line-gold);
    border-radius: 11px;
}
.z-journey-owed small {
    display: block; font-size: 10px; font-weight: 600;
    letter-spacing: .11em; text-transform: uppercase; color: var(--z-ink-3);
}
.z-journey-owed b {
    font-family: var(--z-display); font-size: 22px; font-weight: 600;
    color: #91600f; font-variant-numeric: tabular-nums;
}
.z-journey-sec {
    display: flex; align-items: center; gap: 8px;
    margin: 28px 0 14px;
    font-size: 11px; font-weight: 600; letter-spacing: .16em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-journey-sec:first-of-type { margin-top: 0; }

.z-trip {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    overflow: hidden; margin-bottom: 16px;
    box-shadow: 0 10px 24px rgba(13, 44, 34, .05);
}
.z-trip-head {
    display: flex; align-items: center; gap: 16px;
    padding: 14px 18px;
    background: linear-gradient(180deg, var(--z-cream), var(--z-cream-deep));
    border-bottom: 1px solid var(--z-line);
}
/* A torn-off calendar leaf: the date is the thing being scanned for. */
.z-trip-when {
    flex: none; width: 62px; text-align: center;
    padding: 6px 0 5px;
    background: var(--z-green); color: var(--z-gold-light);
    border-radius: 9px;
}
.z-trip-when b {
    display: block; font-family: var(--z-display); font-size: 23px;
    font-weight: 600; line-height: 1; color: #fdf8ec;
    font-variant-numeric: tabular-nums;
}
.z-trip-when span { display: block; font-size: 10px; letter-spacing: .13em; }
.z-trip-when small { display: block; font-size: 9.5px; opacity: .7; }
.z-trip-what { min-width: 0; flex: 1 1 auto; }
.z-trip-what h3 {
    margin: 0 0 2px;
    font-family: var(--z-display); font-size: 19px; font-weight: 600;
    letter-spacing: .02em; color: var(--z-green);
}
.z-trip-what p { margin: 0; font-size: 13px; color: var(--z-ink-2); }
.z-trip-ref { flex: none; text-align: right; }
.z-trip-ref small {
    display: block; font-size: 9.5px; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase; color: var(--z-ink-3);
}
.z-trip-ref b {
    font-family: var(--z-display); font-size: 18px; font-weight: 600;
    letter-spacing: .04em; color: var(--z-gold-deep);
    font-variant-numeric: tabular-nums;
}

.z-trip-body {
    display: grid; grid-template-columns: repeat(5, 1fr); gap: 1px;
    background: var(--z-line);
    border-bottom: 1px solid var(--z-line);
}
.z-trip-stat { padding: 11px 14px; background: var(--z-surface); }
.z-trip-stat small {
    display: block; font-size: 9.5px; font-weight: 600;
    letter-spacing: .11em; text-transform: uppercase; color: var(--z-ink-3);
}
.z-trip-stat b { font-size: 14px; font-weight: 600; color: var(--z-green); font-variant-numeric: tabular-nums; }
.z-trip-stat b.is-owed  { color: #91600f; }
.z-trip-stat b.is-clear { color: var(--z-open); }

.z-trip-pax { display: flex; flex-wrap: wrap; gap: 6px; padding: 12px 18px 0; }
.z-trip-name {
    padding: 4px 11px; border-radius: 100px;
    background: var(--z-marble); border: 1px solid var(--z-line);
    font-size: 12.5px; color: var(--z-ink-2);
}
/* A traveller with no passport on file is the one thing holding the visa up. */
.z-trip-name.is-gap {
    background: var(--z-few-bg); border-color: rgba(145, 96, 15, .35); color: #91600f;
}

.z-trip-foot {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 10px 16px; padding: 12px 18px;
}
.z-trip-todo {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12.5px; color: #91600f;
}
.z-trip-todo.is-done { color: var(--z-open); }
.z-trip-links { display: inline-flex; gap: 16px; margin-left: auto; }
.z-trip-links a {
    font-size: 13px; color: var(--z-teal);
    text-decoration: underline; text-underline-offset: 3px;
}
.z-trip-links a:hover { color: var(--z-green); }

@media (max-width: 900px) {
    .z-trip-body { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 640px) {
    .z-trip-head { flex-wrap: wrap; }
    .z-trip-ref { margin-left: auto; }
    .z-trip-body { grid-template-columns: repeat(2, 1fr); }
    .z-trip-links { margin-left: 0; }
}

/* --- identity gate ---------------------------------------------------------
   Covers the reservation form until the mobile is verified. The form stays
   rendered behind it: the traveller blocks are what the visitor came for,
   and an empty page while a code arrives reads as a dead end.
   -------------------------------------------------------------------------- */
.z-gate {
    position: fixed; inset: 0; z-index: 60;
    display: grid; place-items: center;
    padding: 20px;
    background: rgba(11, 34, 28, .55);
    backdrop-filter: blur(3px);
    overflow-y: auto;
}
/* Inline: the login page is the gate, so there is nothing to cover. */
.z-gate.is-inline {
    position: static; inset: auto; z-index: auto;
    display: block; padding: 0;
    background: none; backdrop-filter: none; overflow: visible;
}
.z-gate.is-inline .z-gate-panel { margin: 0 auto; box-shadow: var(--z-shadow); }
.z-gate-panel {
    width: 100%; max-width: 460px;
    padding: 28px 26px 22px;
    background: var(--z-surface);
    border: 1px solid var(--z-line-strong);
    border-radius: 16px;
    box-shadow: 0 30px 70px -20px rgba(4, 18, 13, .6);
    text-align: center;
}
.z-gate-mark {
    display: inline-grid; place-items: center;
    width: 52px; height: 52px; border-radius: 50%;
    background: var(--z-gold-wash); border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep); margin-bottom: 12px;
}
.z-gate-panel h2 {
    margin: 0 0 6px;
    font-family: var(--z-display); font-size: 23px; font-weight: 600;
    letter-spacing: .02em; color: var(--z-green);
}
.z-gate-note { margin: 0 0 20px; font-size: 13.5px; color: var(--z-ink-2); }
.z-gate-grid { display: grid; gap: 12px; text-align: left; }
.z-gate .z-field { display: flex; flex-direction: column; }
.z-gate .z-field > label {
    display: flex; align-items: center; gap: 5px; margin-bottom: 5px;
    font-size: 11px; font-weight: 600; letter-spacing: .1em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-gate .z-field > label small { letter-spacing: .04em; text-transform: none; font-weight: 400; color: var(--z-ink-3); }
.z-gate .z-field input {
    width: 100%; padding: 10px 12px;
    border: 1px solid var(--z-line); border-radius: 9px;
    background: var(--z-marble); color: var(--z-ink);
    font-family: var(--z-body); font-size: 14.5px;
}
.z-gate .iti { width: 100%; display: block; }
.z-gate .z-field input:focus {
    outline: none; border-color: var(--z-gold);
    box-shadow: 0 0 0 3px rgba(193, 154, 63, .18);
}
/* One box per figure: six targets rather than one, so a mistyped digit is
   corrected where it sits instead of re-keying the code. */
.z-otp-boxes { display: flex; gap: 8px; justify-content: center; }
.z-otp-box {
    width: 48px !important; height: 56px;
    padding: 0 !important;
    text-align: center;
    font-family: var(--z-display) !important;
    font-size: 25px !important; font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--z-green);
    caret-color: var(--z-gold-deep);
}
.z-otp-box:focus { border-color: var(--z-gold); background: var(--z-surface); }
/* A filled box reads as done at a glance. */
.z-otp-box:not(:placeholder-shown),
.z-otp-box:valid:not(:focus) { border-color: var(--z-line-gold); }
@media (max-width: 420px) {
    .z-otp-boxes { gap: 6px; }
    .z-otp-box { width: 40px !important; height: 50px; font-size: 21px !important; }
}
.z-gate .z-btn-block { margin-top: 16px; }
.z-gate-back {
    display: block; width: 100%; margin-top: 10px;
    background: none; border: 0; cursor: pointer;
    font-family: var(--z-body); font-size: 13px; color: var(--z-teal);
    text-decoration: underline; text-underline-offset: 3px;
}
.z-gate-foot { margin: 18px 0 0; font-size: 12px; color: var(--z-ink-3); }
.z-gate .z-hint { display: block; margin-top: 8px; font-size: 12.5px; color: var(--z-ink-3); text-align: left; }
.z-gate .z-hint.is-bad { color: var(--z-sold); }

/* --- Continue with Google --------------------------------------------------
   NOT a Zaereen button, and deliberately so. Google's Sign-In branding rules
   fix the mark, the wording, the colours and the minimum sizes, and a button
   dressed in Zaereen's gold would break all four. It is also the point of the
   thing: a customer recognises this control from every other site they use,
   and that recognition is what makes them trust handing over an identity.
   So the palette below is Google's, verbatim — #FFFFFF ground, #747775 stroke,
   #1F1F1F text, Roboto Medium 14px, an 18px unmodified mark — and only the
   corner radius follows Zaereen (8px, inside Google's 4px-to-pill allowance)
   so it does not sit on the panel like a foreign object.

   "Continue with Google", never "Login using Gmail": a Google account is not
   a Gmail address, and half the pilgrims signing in here have a Yahoo or a
   work address on theirs.
   -------------------------------------------------------------------------- */
.z-gate-google {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    width: 100%; min-height: 44px;
    padding: 11px 18px;
    box-sizing: border-box;
    background: #fff;
    border: 1px solid #747775;
    border-radius: 8px;
    cursor: pointer;
    text-decoration: none;
    font-family: "Roboto", var(--z-body);
    font-size: 14px; font-weight: 500; letter-spacing: .01em;
    color: #1f1f1f;
    transition: background-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.z-gate-google:hover {
    /* Google's own hover: a 8% tint of the text colour over white, not a
       different colour. */
    background: #f7f8f8;
    box-shadow: 0 1px 3px rgba(31, 31, 31, .14);
    transform: translateY(-1px);
}
.z-gate-google:active { transform: translateY(0); }
.z-gate-google:focus-visible {
    outline: 2px solid var(--z-gold-deep);
    outline-offset: 2px;
}
/* The mark is never recoloured, rotated or resized below 18px. */
.z-gate-google svg { flex: none; width: 18px; height: 18px; }

/* NO DARK VARIANT. Google publishes one and this block used to carry it, on
   the reasoning that a viewer in dark mode would otherwise read white text on
   a white ground — which was never true: the rule above sets #fff AND #1f1f1f
   together, so the light button renders correctly whatever the device is set
   to. What the dark variant actually did was drop a black rectangle into the
   middle of a cream panel on every phone with dark mode on, which is what the
   site was reported to look like online while localhost (light) looked right.
   Zaereen is one theme, on cream, in every condition; the button follows it. */

/* "OR" — a rule with the word sitting in it, rather than a heading. The two
   ways in are equals, and a labelled divider says that without either one
   looking like the fallback. */
.z-gate-or {
    display: flex; align-items: center; gap: 12px;
    margin: 16px 0;
    font-size: 11px; font-weight: 600; letter-spacing: .16em;
    text-transform: uppercase; color: var(--z-ink-3);
}
.z-gate-or::before,
.z-gate-or::after {
    content: ""; flex: 1 1 auto; height: 1px;
    background: var(--z-line);
}

/* The verified customer, stated rather than asked for again. */
.z-known {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 14px;
    background: var(--z-green-soft);
    border: 1px solid rgba(27, 99, 73, .3);
    border-radius: 11px;
}
.z-known-tick {
    flex: none; width: 26px; height: 26px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--z-open); color: #fdf8ec;
}
.z-known b { display: block; font-size: 15px; color: var(--z-green); }
.z-known span { font-size: 13px; color: var(--z-ink-2); }
.z-known-tag {
    margin-left: auto; flex: none;
    padding: 4px 10px; border-radius: 100px;
    background: var(--z-surface); border: 1px solid rgba(27, 99, 73, .3);
    font-size: 10px; font-weight: 600; letter-spacing: .11em;
    text-transform: uppercase; color: var(--z-open);
}

/* --- reservation confirmed -------------------------------------------------
   The step after the booking is written: what was held, and what happens
   next. Reuses the reservation page's two-column shell.
   -------------------------------------------------------------------------- */
.z-done {
    display: flex; align-items: center; gap: 18px;
    padding: 22px 24px;
    margin-bottom: 26px;
    background: linear-gradient(180deg, var(--z-green-soft), var(--z-surface));
    border: 1px solid rgba(27, 99, 73, .3);
    border-radius: var(--z-radius-sm);
}
.z-done-tick {
    flex: none; width: 52px; height: 52px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--z-open); color: #fdf8ec;
}
.z-done h1 {
    margin: 0 0 4px;
    font-family: var(--z-display); font-size: 26px; font-weight: 600;
    letter-spacing: .02em; color: var(--z-green);
}
.z-done p { margin: 0; font-size: 14.5px; color: var(--z-ink-2); max-width: 62ch; }
.z-done-ref {
    margin-left: auto; flex: none; text-align: right;
    padding-left: 20px; border-left: 1px solid var(--z-line);
}
.z-done-ref small {
    display: block; font-size: 10px; font-weight: 600;
    letter-spacing: .14em; text-transform: uppercase; color: var(--z-ink-3);
}
.z-done-ref b {
    font-family: var(--z-display); font-size: 27px; font-weight: 600;
    letter-spacing: .04em; color: var(--z-gold-deep);
    font-variant-numeric: tabular-nums;
}

/* Numbered because these really are a sequence: we call, then the plan, then
   the documents. */
.z-steps { margin: 0; padding: 0; list-style: none; counter-reset: zstep; }
.z-steps li {
    position: relative; counter-increment: zstep;
    padding: 0 0 16px 40px;
    border-left: 1px dashed var(--z-line);
    margin-left: 13px;
}
.z-steps li:last-child { padding-bottom: 0; border-left-color: transparent; }
.z-steps li::before {
    content: counter(zstep);
    position: absolute; left: -13px; top: 0;
    width: 26px; height: 26px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--z-gold-wash); border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
    font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.z-steps b { display: block; font-size: 15px; color: var(--z-green); margin-bottom: 2px; }
.z-steps span { font-size: 13.5px; color: var(--z-ink-2); }

@media (max-width: 780px) {
    .z-done { flex-wrap: wrap; gap: 14px; padding: 18px; }
    .z-done-ref { margin-left: 0; padding-left: 0; border-left: 0; text-align: left; }
}

/* --- reservation page ------------------------------------------------------
   Two columns: the traveller forms on the left, the reservation summary held
   beside them on the right. The summary reuses .z-journey wholesale so it is
   the same card the tour page shows — one set of styles, no second version to
   keep in step.
   -------------------------------------------------------------------------- */
.z-res-title {
    font-family: var(--z-display);
    font-size: clamp(26px, 3vw, 34px);
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--z-green);
    margin: 0;
}
.z-res-sub { margin: 4px 0 26px; font-size: 15px; color: var(--z-ink-2); }

.z-res {
    display: grid;
    grid-template-columns: 1fr 400px;
    gap: 44px;
    align-items: start;
}
.z-res > * { min-width: 0; }

.z-res-block {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    padding: 20px 22px;
    margin-bottom: 18px;
    box-shadow: 0 10px 24px rgba(13, 44, 34, .05);
}
.z-res-block:last-child { margin-bottom: 0; }
.z-res-h {
    display: flex; align-items: center; gap: 9px;
    margin: 0 0 16px;
    padding-bottom: 11px;
    border-bottom: 1px solid var(--z-line);
    font-family: var(--z-display);
    font-size: 19px; font-weight: 600; letter-spacing: .02em;
    color: var(--z-green);
}
.z-res-h svg { color: var(--z-gold-deep); flex: none; }
.z-res-note { margin: -6px 0 16px; font-size: 13px; color: var(--z-ink-3); }

/* Twelve columns, so a field can be sized to what it holds rather than every
   field getting an equal share it does not need. */
.z-res-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 12px 10px; }
.z-res-grid > .z-field { grid-column: span 12; }
.z-c1 { grid-column: span 1 !important; }
.z-c2 { grid-column: span 2 !important; }
.z-c3 { grid-column: span 3 !important; }
.z-c4 { grid-column: span 4 !important; }
.z-c6 { grid-column: span 6 !important; }
/* The prefix holds "Shaikh" at its longest. A 1fr track takes its own
   content as a floor, so one column sizes itself to the widest option
   plus the arrow rather than sitting at a fixed twelfth. */
.z-cp { grid-column: span 1 !important; }
/* A select's min-content is smaller than its widest option, so the track
   would otherwise shrink under "Shaikh" plus the arrow. 82px is that text
   (39px) with the arrow and padding around it. */
.z-cp select { padding-left: 9px; padding-right: 6px; }

.z-res .z-field { display: flex; flex-direction: column; min-width: 0; }
.z-res .z-field > label {
    display: flex; align-items: center; gap: 5px;
    margin-bottom: 5px;
    font-size: 11px; font-weight: 600;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-res .z-field > label small {
    margin-left: 5px; letter-spacing: .04em; text-transform: none;
    font-weight: 400; color: var(--z-ink-3);
}
.z-res .z-field input,
.z-res .z-field select,
.z-res .z-field textarea {
    width: 100%;
    min-width: 0;
    padding: 9px 11px;
    border: 1px solid var(--z-line);
    border-radius: 9px;
    background: var(--z-marble);
    color: var(--z-ink);
    font-family: var(--z-body);
    font-size: 14px;
}
.z-res .z-field textarea { resize: vertical; }
.z-res .z-field input:focus,
.z-res .z-field select:focus,
.z-res .z-field textarea:focus {
    outline: none;
    border-color: var(--z-gold);
    box-shadow: 0 0 0 3px rgba(193, 154, 63, .18);
}
.z-res .z-field input.is-bad { border-color: var(--z-sold); }
/* Below the .z-res .z-field rules on purpose: both selectors are (0,2,0),
   so source order decides and min-width: 0 was winning, letting the track
   shrink under "Shaikh" plus its arrow. */
.z-res .z-cp { min-width: 82px; }
/* intl-tel-input wraps the input in .iti, which defaults to inline-block
   and shrinks to its content; left to itself it sat narrower than its grid
   column and opened a gap before the next field. */
.z-res .iti { width: 100%; display: block; }

/* --- one card per traveller --- */
.z-pax {
    border: 1px solid var(--z-line);
    border-radius: 12px;
    overflow: hidden;
    margin-bottom: 14px;
    background: var(--z-marble);
}
.z-pax:last-child { margin-bottom: 0; }
.z-pax-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px;
    padding: 9px 14px;
    background: linear-gradient(180deg, var(--z-cream), var(--z-cream-deep));
    border-bottom: 1px solid var(--z-line);
}
.z-pax-tag {
    display: inline-flex; align-items: center;
    padding: 4px 11px; border-radius: 100px;
    font-size: 10.5px; font-weight: 600;
    letter-spacing: .11em; text-transform: uppercase;
}
/* The three fare bands, coloured as the estimate table names them. */
.z-pax-tag.is-adult  { background: var(--z-gold-wash);        border: 1px solid var(--z-line-gold);        color: var(--z-green); }
.z-pax-tag.is-child  { background: rgba(18, 101, 95, .12);    border: 1px solid rgba(18, 101, 95, .3);     color: var(--z-teal); }
.z-pax-tag.is-infant { background: rgba(107, 59, 110, .12);   border: 1px solid rgba(107, 59, 110, .3);    color: #6b3b6e; }
.z-pax-age { font-size: 12px; color: var(--z-ink-3); }
/* The ITS sits at the far end of the header band, labelled inline so the
   row still reads as one line rather than a stray box. */
.z-pax-its { margin-left: auto; display: flex; align-items: center; gap: 8px; min-width: 0; }
.z-pax-its label {
    font-size: 10.5px; font-weight: 600;
    letter-spacing: .11em; text-transform: uppercase;
    color: var(--z-gold-deep); white-space: nowrap;
}
.z-pax-its input {
    width: 108px; min-width: 0;
    padding: 6px 9px;
    border: 1px solid var(--z-line);
    border-radius: 8px;
    background: var(--z-surface);
    font-family: var(--z-body); font-size: 13px;
    font-variant-numeric: tabular-nums;
    color: var(--z-ink);
}
.z-pax-its input:focus {
    outline: none; border-color: var(--z-gold);
    box-shadow: 0 0 0 3px rgba(193, 154, 63, .18);
}
/* ONE LINE: "Adult 01" and its ITS number, at every width.

   The header used to wrap on a phone and give the ITS a line of its own, which
   is a whole extra band of chrome per traveller — four travellers, four extra
   rows before a single name is typed. It fits: the badge is about 92px and the
   field about 194px against the 322px a 412px phone has inside the card.

   What it costs is fixed widths. The input drops from 108px to 84px, which
   still holds eight tabular digits and their padding, and the label's tracking
   comes in from .11em — at ten characters that spacing alone was 15px. */
@media (max-width: 640px) {
    .z-pax-head { flex-wrap: nowrap; gap: 8px; }
    /* THE BADGE IS WHAT YIELDS, not the field. "Infant 01" is wider than
       "Adult 01" and a child row carries an age chip an adult row does not, so
       the widest case has the least room — and if anything ever runs long it
       must not be the ITS input that gets squeezed out of the line. The badge
       shortens with an ellipsis instead; its number stays readable either
       way. */
    .z-pax-tag {
        flex: 0 1 auto;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .z-pax-age { flex: none; white-space: nowrap; }
    .z-pax-its { margin-left: auto; flex: none; gap: 6px; }
    .z-pax-its label { letter-spacing: .04em; }
    .z-pax-its input { width: 84px; }
}

/* Below 400px a CHILD row is the tight one: it carries an age beside the badge
   that an adult row does not, and three items plus a field will not fit 270px
   at full size. Everything steps down together, and the label gives up its
   second word — "ITS" is what this number is called on a Mumineen portal, and
   the input beside it removes any doubt. */
@media (max-width: 400px) {
    .z-pax-head { padding: 8px 10px; gap: 6px; }
    .z-pax-tag { font-size: 9.5px; padding: 3px 8px; letter-spacing: .06em; }
    .z-pax-age { font-size: 10.5px; }
    .z-pax-its { gap: 5px; }
    .z-pax-its label { font-size: 9.5px; letter-spacing: .03em; }
    .z-pax-its .z-its-word { display: none; }
    .z-pax-its input { width: 76px; padding: 5px 7px; font-size: 12.5px; }
}
.z-pax > .z-res-grid { padding: 14px; }
/* Inside a traveller card the fields sit as a table, so their headings
   centre over the boxes rather than hugging the left edge. */
.z-pax .z-field > label { text-align: center; justify-content: center; }
/* One hue per heading, set on the field in the markup and taken from the
   same set as the header nav and the quick-facts bar. The values below
   stay ink — ten coloured labels over ten coloured values would be a
   rainbow rather than a table. */
.z-pax .z-field > label { color: var(--z-fldc, var(--z-gold-deep)); }
/* The mark takes the heading's own colour, a shade lighter so the words
   still lead. */
.z-res .z-field > label svg { flex: none; opacity: .85; }
/* The mark costs about 18px. In the middle widths a two-twelfths column
   cannot hold "Date of Birth" plus a mark at full tracking, and a wrapped
   heading pushes its input out of line with the rest of the row. Tighten
   the heading rather than let it wrap: keeps the heading and its mark on
   one line and the inputs on one baseline. */
@media (max-width: 1240px) {
    .z-pax .z-field > label { font-size: 10px; letter-spacing: .03em; gap: 4px; }
    .z-pax .z-field > label svg { width: 12px; height: 12px; }
}

/* A ruled caption inside a traveller card, so Name and Passport read as two
   groups rather than one run of fourteen boxes. */
.z-pax-sub {
    grid-column: span 12;
    margin: 4px 0 -2px;
    padding-top: 10px;
    border-top: 1px dashed var(--z-line);
    font-size: 10.5px; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-teal);
}
.z-pax-sub:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

/* --- the summary column --- */
.z-res-side { position: sticky; top: 128px; }
.z-res-facts {
    display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
    margin-top: 14px;
}
.z-res-facts > div {
    padding: 8px 11px;
    background: var(--z-marble);
    border: 1px solid var(--z-line);
    border-radius: 9px;
}
.z-res-facts small {
    display: block;
    font-size: 9.5px; font-weight: 600;
    letter-spacing: .11em; text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-res-facts b { font-size: 13.5px; font-weight: 600; color: var(--z-green); }

.z-res-back { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.z-res-change {
    display: inline-block; margin-top: 14px;
    font-size: 13px; color: var(--z-teal);
    text-decoration: underline; text-underline-offset: 3px;
}
.z-res-change:hover { color: var(--z-green); }

/* A refusal that has to be read before anything else on the page. */
.z-note {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 16px 18px;
    border-radius: 12px;
    background: var(--z-sold-bg);
    border: 1px solid rgba(138, 48, 36, .3);
}
.z-note svg { flex: none; color: var(--z-sold); margin-top: 2px; }
.z-note b { display: block; font-size: 15px; color: var(--z-sold); margin-bottom: 3px; }
.z-note p { margin: 0; font-size: 14px; color: var(--z-ink-2); }

@media (max-width: 1240px) {
    .z-res { grid-template-columns: 1fr 340px; gap: 30px; }
}
@media (max-width: 1080px) {
    .z-res { grid-template-columns: 1fr 300px; gap: 24px; }
    /* Pairs from here down — see the note in the 900px block. This is the
       width at which a span-2 date field stops being wide enough to draw a
       date, so it is the width at which the twelve-track arrangement stops
       being usable. */
    .z-pax > .z-res-grid > .z-field { grid-column: span 6 !important; }
}
/* Below this the summary would be narrower than the phone layout it is about
   to become, so the two columns fold and the summary leads. */
@media (max-width: 900px) {
    .z-res { grid-template-columns: 1fr; gap: 24px; }
    .z-res-side { position: static; order: -1; }
    .z-res-main { order: 1; }

    /* --- YOUR RESERVATION, and the traveller cards under it ----------------

       THE PANEL. Above 900px it is a 300-340px rail beside the form; here it
       is the full width of the page, and its facts kept the two narrow columns
       they were given for the rail. Nothing needed to change — they simply had
       more room than they were using — but the pair rule below is what stops
       them stacking into a tall single file on a phone.

       THE TRAVELLER CARDS are the part that was actually broken, and it began
       higher up than this. .z-res-grid is twelve tracks and the passport fields
       claim one, three and two of them; that arithmetic was written for a form
       roughly 810px wide. By 1080px the main column is about 700px and a span-2
       Date of Birth is 108px — narrower than a native date control can draw
       mm/dd/yyyy plus its picker glyph, so it overflowed its own cell — while
       span-1 Prefix fell under the 82px min-width it carries and pushed the
       whole row past the card edge.

       So from 1080px down the fields pair off instead: every one of them takes
       half the row, which lands ten fields as five full rows with no hole in
       any of them. Scoped to .z-pax so the Lead Person block above keeps its
       own arrangement. */
    .z-pax > .z-res-grid > .z-field { grid-column: span 6 !important; }
}
@media (max-width: 640px) {
    .z-res-block { padding: 16px 14px; }
    .z-pax > .z-res-grid { padding: 12px; }
    /* Keep the twelve tracks and pair the fields two to a row. Halving the
       track count instead made every span-6 item spill past column six into
       implicit columns, which collapsed Prefix and Issue Date to 20px. */
    .z-c2, .z-c3 { grid-column: span 6 !important; }
    /* SIX, NOT FOUR. Prefix at span 4 beside a span 6 Surname is ten of twelve
       — Given Name could not fit the remaining two and dropped to the next
       row, leaving a hole and starting the ragged edge that ran down the rest
       of the card. Six pairs it with Surname and every row after it lands. */
    .z-cp { grid-column: span 6 !important; }
    .z-c4, .z-c6 { grid-column: span 12 !important; }
}

/* --- the reservation form at its narrowest ---------------------------------
   Two fields to a row holds down to about 400px: the card's inner width there
   is roughly 250px, so each half is 120px, which is the least a native date
   input can draw mm/dd/yyyy plus its picker glyph in. Below that they stop
   pairing and stack — a long form is a nuisance, a form whose dates cannot be
   read is not usable at all.

   The reservation facts follow the same reasoning one step later: a label over
   a short value ("12 Sep 2026", "DELUXE") fits a 120px column comfortably, and
   stacking them at 640px as this used to was giving a panel twice the height
   for no gain. They stack only when the halves stop being wide enough. */
@media (max-width: 400px) {
    .z-pax > .z-res-grid > .z-field,
    .z-res-grid > .z-field.z-cp { grid-column: span 12 !important; }
    .z-res-facts { grid-template-columns: 1fr; }
}

/* --- plan your journey -----------------------------------------------------
   The booking card from holidays/package.php: port, date, pax, category tiles
   and a live Person / Rate / No-Pax / Total estimate. Same anatomy, Zaereen's
   marble and gold rather than the dark slate.
   -------------------------------------------------------------------------- */
.z-journey {
    position: sticky;
    top: 128px;
    background: var(--z-surface);
    border: 1px solid var(--z-line-strong);
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 16px 38px rgba(13, 44, 34, .10);
}
.z-journey-head {
    display: flex; align-items: center; justify-content: center; gap: 9px;
    padding: 15px 18px;
    background: var(--z-green);
    color: var(--z-gold-light);
    font-family: var(--z-display);
    font-size: 16px; font-weight: 600;
    letter-spacing: .09em; text-transform: uppercase;
}
.z-journey-head svg { color: var(--z-gold); }
.z-journey-body { padding: 18px 16px 20px; }

.z-jfield { margin-bottom: 15px; }
.z-jfield > label {
    display: flex; align-items: center; gap: 6px;
    height: 18px; line-height: 18px;
    font-size: 11px; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
    margin-bottom: 7px;
}
.z-jfield > label svg { color: var(--z-gold-deep); }
.z-jfield > label.is-adults  { color: var(--z-green-3); }
.z-jfield > label.is-adults svg  { color: var(--z-green-3); }
.z-jfield > label.is-children { color: var(--z-gold-deep); }

/* Departure port — one sector per departure, so this states rather than asks. */
.z-jport {
    display: flex; align-items: center; gap: 9px;
    padding: 10px 12px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-radius: 10px;
}
.z-jtick {
    flex: none; width: 19px; height: 19px; border-radius: 5px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--z-green); color: var(--z-gold-light);
}
.z-jport b { font-size: 15px; font-weight: 600; color: var(--z-green); }

/* Travel Date | Adults | Children, one line. The date takes a slightly wider
   share because "05 Sep 2026" is longer than a two-digit stepper. */
.z-jrow {
    display: grid;
    grid-template-columns: 1.18fr 1fr 1fr;
    gap: 10px 8px;
    align-items: start;
    margin-bottom: 15px;
}
.z-jrow .z-jfield { margin-bottom: 0; }

/* TWO FIELDS, NOT THREE.

   .z-jrow is sized for the tour card's Travel Date | Adults | Children: one
   wide-ish column and two narrow steppers. The hotel card's dates are two of
   the WIDE kind, and fitting a third field beside them left each native date
   input about 107px inside the 400px card — under what a browser needs to draw
   dd/mm/yyyy with its picker, so the value clipped. Even halves give each date
   more room than the tour's Travel Date has, which is the field they are
   meant to match. */
.z-jrow.is-two { grid-template-columns: 1fr 1fr; }

/* One row per room, so each reads as its own party rather than as a second set
   of steppers for the same one. The rule is on the row above rather than a
   margin below, so the last room does not add a gap before the estimate. */
.z-jroom { padding-top: 12px; border-top: 1px dashed var(--z-line-gold); }
.z-jroom.is-first { padding-top: 0; border-top: 0; }
/* Grid children default to min-width:auto, so the date select and the
   steppers push the 1fr columns past the card instead of shrinking. */
.z-jrow > .z-jfield { min-width: 0; }
.z-jselect { min-width: 0; max-width: 100%; }
.z-jqty .z-qty { min-width: 0; }
.z-jqty .z-qty { width: 100%; justify-content: center; gap: 5px; padding: 4px; }
/* Two digits is the entire range here (02-40), so the field is sized to two
   digits instead of stretched across the column - the steppers then sit
   either side of the figure rather than at the far edges of the card. The
   count is a plain bold numeral, not the display serif: at this size the
   serif digits read as decoration next to the figure they state. */
.z-jqty .z-qty-input {
    flex: 0 0 auto;
    width: 2.1em;
    min-width: 0;
    font-family: system-ui, -apple-system, "Segoe UI", Arial, sans-serif !important;
    font-size: 17px !important;
    font-weight: 700;
    color: #000;
}
.z-jqty .z-qty-btn { width: 30px; height: 30px; }
/* The numeral's box is pinned, so it has to grow with the control or the
   digits sit high in the taller field. */
.z-jqty .z-qty-input { height: 30px; line-height: 30px; }
.z-jfield > label { white-space: nowrap; }
/* Travel Date | Adults | Children are one banded row, so each heading centres
   over its own control rather than sitting hard left of a centred stepper. */
.z-jrow > .z-jfield > label { justify-content: center; }

.z-jselect {
    width: 100%;
    /* 40px, matching the steppers beside it: 30px button + 4px padding a side
       + the border. The three fields sit on one line, so a change to one of
       them has to be a change to all three or the row stops lining up. */
    height: 40px;
    padding: 0 11px;
    border: 1px solid var(--z-line);
    border-radius: 10px;
    background: var(--z-cream);
    color: var(--z-ink);
    font-family: var(--z-body);
    font-size: 14px;
    cursor: pointer;
}
.z-jselect:focus-visible { outline: 2px solid var(--z-gold-deep); outline-offset: 1px; }

/* One age row per child; without an age the fare band cannot be decided. */
/* The card reuses the modal's chip row, but twelve chips will not sit
   beside a label in a 368px card: the label goes above and the chips take
   the full width, one row of twelve. */
.z-journey .z-age-row {
    display: block;
    margin: 0 0 12px;
}
.z-journey .z-age-row:last-child { margin-bottom: 0; }
.z-journey .z-age-label {
    flex: none;
    margin-bottom: 6px;
    font-size: 12px; font-weight: 600;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-journey .z-age-selector {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 3px;
}
.z-journey .z-age-option { flex: none; height: 28px; font-size: 11px; padding: 0; }
/* TWELVE ON A LINE, AT EVERY WIDTH.

   0 to 11 is one range and it reads as one: broken into 0-5 over 6-11 it looks
   like two sets of something, and with two children on the card that is four
   rows of chips between the traveller count and the package grade. The wrap
   was there because a 300px rail cannot hold twelve chips at 30px — so the
   chips give way instead of the row. Twelve columns in 300px is 22px a chip,
   and the widest label is "11". */
@media (max-width: 1240px) {
    .z-journey .z-age-selector { grid-template-columns: repeat(12, 1fr); gap: 3px; }
    .z-journey .z-age-option { height: 28px; font-size: 11px; }
}
@media (max-width: 900px) {
    /* Full width again here, so the chips can have their size back. */
    .z-journey .z-age-selector { grid-template-columns: repeat(12, 1fr); gap: 4px; }
    .z-journey .z-age-option { height: 30px; font-size: 12px; }
}
@media (max-width: 400px) {
    /* The narrowest phones still in service: the gap closes before the row
       does. Two digits at 10.5px want about 12px and there are 18 to give. */
    .z-journey .z-age-selector { gap: 2px; }
    .z-journey .z-age-option { height: 28px; font-size: 10.5px; }
}

/* --- package category tiles --- */
.z-cats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.z-cat {
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 5px;
    min-width: 0;
    padding: 10px 4px;
    border: 1px solid var(--z-line);
    border-radius: 12px;
    background: var(--z-cream);
    color: var(--z-ink-2);
    font-family: var(--z-body);
    font-size: 10px; font-weight: 600;
    letter-spacing: .03em; text-align: center; line-height: 1.25;
    cursor: pointer;
    transition: background-color .2s ease, border-color .2s ease,
                color .2s ease, box-shadow .2s ease;
}
.z-cat svg { color: var(--z-gold-deep); }
.z-cat:hover { border-color: var(--z-line-gold); background: var(--z-gold-wash); color: var(--z-green); }
.z-cat.is-active {
    background: linear-gradient(135deg, var(--z-gold-light), var(--z-gold));
    border-color: var(--z-gold);
    color: var(--z-green);
    box-shadow: 0 8px 18px rgba(193, 154, 63, .28);
}
.z-cat.is-active svg { color: var(--z-green); }
.z-cat:focus-visible { outline: 2px solid var(--z-gold-deep); outline-offset: 2px; }

/* --- the estimate table --- */
.z-paytable {
    margin: 16px 0 0;
    border: 1px solid var(--z-line-strong);
    border-radius: 12px;
    overflow: hidden auto;
}
/* Money strings do not wrap, so four natural columns set a min-content
   wider than a 300px card. Fixed layout makes the columns obey. */
.z-paytable table {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}
.z-paytable thead th {
    padding: 9px 6px;
    background: var(--z-green);
    color: var(--z-gold-light);
    font-size: 10px; font-weight: 600;
    letter-spacing: .11em; text-transform: uppercase;
    text-align: center;
}
.z-paytable tbody td {
    padding: 10px 6px;
    border-bottom: 1px solid var(--z-line);
    text-align: right;
    color: var(--z-ink);
}
.z-paytable thead th.th-person { width: 26%; }
.z-paytable thead th.th-rate   { width: 28%; }
.z-paytable thead th.th-qty    { width: 18%; }
.z-paytable thead th.th-total  { width: 28%; }

/* --- the bed marker on a Child row -----------------------------------------
   Sits BESIDE the word, not under it: the note used to be a display:block
   second line, which made every child row two lines deep and "Without bed"
   wrap to three in a 300px rail. As a glyph it costs 15px on the line that is
   already there. It rides .item-mark, which td.item's flex row was built for
   and which already carries `flex: none`.

   COLOURED APART, because `bed` and `nobed` are the same drawing and the
   diagonal through the second is all that separates them at 15px. Muted ink
   was not enough — it read as a faint smudge rather than a mark. Green for the
   bed a child has, the sold red for the one they do not: the same pair this
   palette uses for yes and no everywhere else, so the strike is read as an
   absence rather than a scuff on the icon.

   KEYED ON A CLASS, not on the title text. The first version selected
   [title="Without bed"], which ties a colour to a sentence — retype the note
   in tour_repository.php and the styling silently stops matching. */
.z-paytable .item-mark svg { display: block; }
.z-paytable .item-mark.is-bed   { color: var(--z-open); }
.z-paytable .item-mark.is-nobed { color: var(--z-sold); }

/* Anything that is not a bed — "As adult" — keeps its words, on its own line
   as before. It is a fare band, not a yes/no, and there is no glyph for it. */
.z-pt-note {
    display: block;
    font-weight: 400;
    font-size: 10.5px;
    color: var(--z-ink-3);
}
/* The count is centred in the body too, under its centred heading. */
.z-paytable tbody td.qty { text-align: center; }
.z-paytable tbody td { overflow-wrap: anywhere; }
.z-paytable tbody td.item {
    text-align: left;
    font-weight: 600;
    color: var(--z-green);
}
/* The bed band is an icon, not words, so the column stays short. */
.z-paytable td.item {
    display: flex; align-items: center; gap: 6px;
}
.z-paytable .item-mark {
    flex: none;
    display: inline-flex; align-items: center;
    color: var(--z-teal);
}

/* Column rules as well as row rules, so Person / Rate / No-Pax / Total read
   as a ruled grid rather than four drifting numbers. Adjacent-sibling
   selectors, so no rule hangs off the last column against the border. */
.z-paytable th + th,
.z-paytable td + td { border-left: 1px solid var(--z-line); }
.z-paytable tfoot td + td { border-left-color: var(--z-line-gold); }
.z-paytable thead th + th { border-left-color: rgba(227, 200, 134, .30); }
.z-paytable tbody tr:last-child td { border-bottom: 0; }
/* The total is the table's last row, so it takes the same cells, the same
   padding and the same right edge as the figures above it. The gold band
   carries the emphasis the pill used to. */
.z-paytable tfoot td {
    padding: 12px 6px;
    background: var(--z-gold-wash);
    border-top: 2px solid var(--z-gold);
}
.z-paytable tfoot td.foot-label {
    text-align: right;
    font-size: 11px; font-weight: 600;
    letter-spacing: .11em; text-transform: uppercase;
    /* A quiet caption beside the figure, not a second heading. 6.8:1. */
    color: var(--z-ink-2);
}
.z-paytable tfoot td.foot-total {
    text-align: right;
    font-family: var(--z-display);
    font-size: 17px; font-weight: 600;
    color: var(--z-few);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* The card narrows to 340px then 300px between these widths, and "No/Pax"
   is 47px of heading: at a 264px table an 18% column leaves 35px for it.
   Shift width off the name column and tighten the tracking there. */
@media (max-width: 1240px) {
    /* "No/Pax" is 47px of heading; at a 264px table 18% leaves 35px for it.
       Shift width from the name column and tighten the tracking. */
    .z-paytable thead th.th-person { width: 25%; }
    .z-paytable thead th.th-rate   { width: 28%; }
    .z-paytable thead th.th-qty    { width: 19%; }
    .z-paytable thead th.th-total  { width: 28%; }
    .z-paytable thead th { letter-spacing: .04em; padding: 9px 3px; }
    .z-paytable tbody td { padding: 10px 3px; }
    .z-paytable tfoot td { padding: 11px 3px; }
    .z-paytable tfoot td.foot-total { font-size: 14px; }
}
/* Below 900px the card is full width again, so the table goes back. */
@media (max-width: 900px) {
    /* Card is full width again here, so the table returns to its own widths. */
    .z-paytable thead th.th-person { width: 26%; }
    .z-paytable thead th.th-rate   { width: 28%; }
    .z-paytable thead th.th-qty    { width: 18%; }
    .z-paytable thead th.th-total  { width: 28%; }
    .z-paytable thead th { letter-spacing: .11em; padding: 9px 6px; }
    .z-paytable tbody td { padding: 10px 6px; }
    .z-paytable tfoot td { padding: 12px 6px; }
    .z-paytable tfoot td.foot-total { font-size: 17px; }
}
@media (max-width: 440px) {
    /* "No/Pax" is 47px of heading; at a 264px table 18% leaves 35px for it.
       Shift width from the name column and tighten the tracking. */
    .z-paytable thead th.th-person { width: 25%; }
    .z-paytable thead th.th-rate   { width: 28%; }
    .z-paytable thead th.th-qty    { width: 19%; }
    .z-paytable thead th.th-total  { width: 28%; }
    .z-paytable thead th { letter-spacing: .04em; padding: 9px 3px; }
    .z-paytable tbody td { padding: 10px 3px; }
    .z-paytable tfoot td { padding: 11px 3px; }
    .z-paytable tfoot td.foot-total { font-size: 14px; }
}

/* Stands in for the estimate table on a tour with no published fare. Built
   to the same weight as the total row it replaces, so the card keeps its
   shape instead of collapsing where the price belongs. */
.z-jonreq {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px;
    margin-top: 14px;
    padding: 13px 14px;
    border-radius: 10px;
    background: var(--z-cream, #f7f2e6);
    border: 1px solid var(--z-line-gold, rgba(193, 154, 63, .34));
}
.z-jonreq span {
    font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-ink-3, #6b6558);
}
.z-jonreq b {
    font-family: var(--z-display); font-size: 19px; font-weight: 600;
    color: var(--z-gold-deep, #7d6015);
}

.z-jmeal {
    display: flex; align-items: center; gap: 9px;
    margin-top: 12px;
    padding: 10px 12px;
    border-radius: 10px;
    background: linear-gradient(180deg, rgba(18, 101, 95, .10), rgba(18, 101, 95, .04));
    border: 1px solid rgba(18, 101, 95, .26);
}
.z-jmeal[hidden] { display: none; }
.z-jmeal-ico {
    flex: none; width: 22px; height: 22px; border-radius: 7px;
    display: inline-flex; align-items: center; justify-content: center;
    background: rgba(18, 101, 95, .14); color: var(--z-teal);
}
.z-jmeal-label {
    font-size: 10.5px; font-weight: 600;
    letter-spacing: .11em; text-transform: uppercase;
    color: var(--z-teal);
}
.z-jmeal b { font-size: 13px; color: var(--z-ink); font-weight: 500; }

/* The vehicle row on a domestic holiday. Same plate as the meal plan it sits
   above — they are one pair of inclusions, so they are drawn as one pair —
   with the gap between them closed up: 12px twice reads as two unrelated
   panels rather than a list of what the price covers. */
.z-jveh + .z-jmeal { margin-top: 8px; }
.z-jveh b { white-space: normal; }

/* Enquiry and Booking share the row; the PDF sits beside them as a compact
   third action rather than competing with the two that convert. */
.z-jcta { display: grid; grid-template-columns: auto 1fr 1fr; gap: 8px; margin-top: 16px; }
.z-jcta .z-jpdf { padding-left: 11px; padding-right: 11px; gap: 5px; }
.z-jcta .z-jpdf span { font-size: 12px; font-weight: 600; letter-spacing: .06em; }
.z-jcta .z-btn { width: 100%; justify-content: center; }
.z-jcta .z-btn-block { grid-column: 1 / -1; }
.z-jcta > * { min-width: 0; }
/* TWO BUTTONS, NOT THREE. The row above is sized for the tour card's PDF +
   Enquiry + Booking: an auto column and two fractions. The visa card has no
   PDF, so Enquiry took the auto track, Book Now was left a narrow fraction
   and its label broke across two lines with an empty third column beside it.
   Even halves, and a label that is not allowed to wrap. */
.z-jcta.is-two { grid-template-columns: 1fr 1fr; }
.z-jcta.is-two .z-btn { white-space: nowrap; padding-left: 10px; padding-right: 10px; }

/* The card drops to 340px then 300px below these widths; three fields and
   four tiles stop fitting, so both rows fold. */
@media (max-width: 1240px) {
    /* THREE ACROSS, EVERY PANEL. All three journey cards — tour, visa, hotel —
       hold one row of three: Travel Date | Adults | Children on the first two,
       Check-in | Nights | Check-out and Rooms | Adults | Children on the
       hotel. None of them folds any more; the row keeps its shape and the
       controls shrink to pay for it.

       This band is the 1024 tablet, where the card is back to being a narrow
       sidebar: three columns of about 81px, the tightest they ever get. The
       controls come down further here than on a phone, where the card is full
       width. */
    .z-jrow {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 10px 5px;
    }
    .z-jdate,
    .z-jrow.is-qty3 > .z-jfield:last-child { grid-column: auto; }

    /* PDF, ENQUIRY AND BOOKING STAY ON ONE LINE. Booking used to be given the
       full width on a row of its own below the other two, which put the page's
       primary action a scroll further down on exactly the screens with the
       least room to spare. An auto track for the narrow PDF button and two
       fractions for the rest, with labels that are not allowed to wrap. */
    .z-jcta { grid-template-columns: auto 1fr 1fr; gap: 6px; }
    .z-jcta > *:last-child { grid-column: auto; }
    .z-jcta .z-btn { white-space: nowrap; padding-left: 9px; padding-right: 9px; }
    .z-jcta .z-jpdf { padding-left: 9px; padding-right: 9px; }

    /* TALLER, NOT WIDER. The stepper shares a banded row with Travel Date and
       sat noticeably shorter than it, which read as the row having been
       assembled from two different controls. Height is free — the row takes
       the tallest field either way — where width is not: three columns in a
       300px rail leave about 95px each, and widening the two buttons is what
       would push the figure between them out of its column. So the buttons
       grow downward only and stay 23px across. */
    .z-journey .z-jqty .z-qty { gap: 1px; padding: 3px; }
    .z-journey .z-jqty .z-qty-btn { width: 23px; height: 28px; }
    .z-journey .z-jqty .z-qty-input {
        width: 1.7em;
        font-size: 14px !important;    /* the base rule is !important too */
        height: 28px;
        line-height: 28px;
    }
    .z-journey .z-jselect { font-size: 11px; padding-left: 5px; }
    .z-journey .z-jfield > label { font-size: 8.5px; letter-spacing: .02em; gap: 3px; }
    .z-journey .z-jfield > label svg { width: 10px; height: 10px; }
    /* FOUR ACROSS, NOT TWO BY TWO. The grades are a single choice from four
       and read that way in a row; stacked two-by-two they read as two pairs,
       and the block costs twice the height directly above the price table. */
    .z-cats { grid-template-columns: repeat(4, 1fr); gap: 5px; }
    .z-cat { padding: 10px 3px; font-size: 9.5px; letter-spacing: .02em; }
    .z-jqty .z-qty { gap: 6px; padding: 4px; }
    .z-jqty .z-qty-btn { width: 30px; height: 30px; }
}
/* Stacked below 900px, where the card is full width again — both rows have
   room for the wide arrangement once more. */
@media (max-width: 900px) {
    .z-jrow { grid-template-columns: 1.18fr 1fr 1fr; gap: 10px 8px; }
    .z-jcta { grid-template-columns: auto 1fr 1fr; }
    .z-jcta > *:last-child { grid-column: auto; }

    /* THE CONTROLS GO BACK TO FULL SIZE. Between 561 and 900 the card is full
       width — three columns of about 229px — so the squeeze the 1240 band
       needs for an 81px sidebar column is just small type here. The 560 block
       below shrinks them again, less hard, for the phone. */
    .z-journey .z-jqty .z-qty { gap: 5px; padding: 4px; }
    .z-journey .z-jqty .z-qty-btn { width: 30px; height: 30px; }
    .z-journey .z-jqty .z-qty-input {
        width: 2.1em;
        font-size: 17px !important;
        height: 30px;
        line-height: 30px;
    }
    /* Padding deliberately untouched: .z-fp-input reserves 42px on the right
       for its calendar glyph, and any padding-right written here would take
       that reserve away and leave the date running under the icon. */
    .z-journey .z-jselect { font-size: inherit; }
    .z-journey .z-jfield > label { font-size: 10.5px; letter-spacing: .1em; gap: 6px; }
    .z-journey .z-jfield > label svg { width: 13px; height: 13px; }
    .z-cats { grid-template-columns: repeat(4, 1fr); gap: 6px; }
    .z-cat { padding: 10px 4px; font-size: 10px; letter-spacing: .03em; }
}
@media (max-width: 560px) {
    /* --- three across on a phone too -------------------------------------
       Travel Date | Adults | Children on the tour and visa cards, and
       Check-in | Nights | Check-out over Rooms | Adults | Children on the
       hotel. The row never folds.

       Everything in the controls comes down to pay for it: a phone column is
       about 100px and a stepper at the desktop sizing wants 114 (two 30px
       buttons, a 2.1em numeral at 17px, 5px gaps and 4px of padding). */
    .z-jrow {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 10px 6px;
    }
    .z-jdate,
    .z-jrow.is-qty3 > .z-jfield:last-child { grid-column: auto; }

    /* One line here too — see the 1240 block. */
    .z-jcta { grid-template-columns: auto 1fr 1fr; gap: 6px; }
    .z-jcta > *:last-child { grid-column: auto; }
    .z-jcta .z-btn { white-space: nowrap; padding-left: 8px; padding-right: 8px; font-size: 12.5px; }
    .z-jcta .z-jpdf { padding-left: 8px; padding-right: 8px; }
    .z-jcta .z-jpdf span { font-size: 11px; letter-spacing: .03em; }

    /* Same again on a phone, with a little more of it: the card is full width
       here, so the control can afford 30px of height and a 15px numeral while
       the buttons stay 25px across and inside their column. */
    .z-journey .z-jqty .z-qty { gap: 2px; padding: 4px; }
    .z-journey .z-jqty .z-qty-btn { width: 25px; height: 30px; }
    .z-journey .z-jqty .z-qty-input {
        width: 1.8em;
        /* The base rule carries !important for the font stack, so this has to
           as well or the 17px stays and the numeral will not fit. */
        font-size: 15px !important;
        height: 30px;
        line-height: 30px;
    }
    /* The native date control draws mm/dd/yyyy plus its picker glyph; at the
       default size that needs more than the column has. */
    .z-journey .z-jselect { font-size: 11.5px; padding-left: 7px; }
    .z-journey .z-jfield > label { font-size: 9px; letter-spacing: .03em; gap: 3px; }
    .z-journey .z-jfield > label svg { width: 11px; height: 11px; }
    /* Still one row. The card is full width on a phone, so the four have more
       room here than they do in the tablet rail above. */
    .z-cats { grid-template-columns: repeat(4, 1fr); gap: 5px; }
    .z-cat { padding: 11px 3px; font-size: 10px; letter-spacing: .02em; }
}

/* --- the tour card at its narrowest ----------------------------------------
   The three actions are held on one line down to about 360px on the strength
   of an auto track and two fractions. Below that the arithmetic runs out: a
   245px card less the PDF button leaves 86px a side, and "Booking" with its
   arrow wants nearer 90 — and these labels are `nowrap`, so the overflow would
   go outside the card rather than folding.

   The PDF button gives up its word and keeps its icon. It is the least of the
   three actions and the only one whose meaning survives as a glyph; "Booking"
   is the one thing on this card that must not shrink.

   PLACED AFTER THE 560px BLOCK DELIBERATELY: identical specificity, so only
   source order decides which of the two applies. */
@media (max-width: 380px) {
    .z-jcta .z-jpdf span { display: none; }
    .z-jcta .z-jpdf { padding-left: 11px; padding-right: 11px; }
    .z-jcta .z-btn { font-size: 12px; }
    .z-cat { font-size: 9px; padding: 10px 2px; }

    /* The stepper keeps the extra height it was given and gives back width
       instead: 21px buttons, still 27px tall against the 25px square they
       were before. Height was the ask; width is what the row cannot spare. */
    .z-journey .z-jqty .z-qty { gap: 1px; padding: 3px; }
    .z-journey .z-jqty .z-qty-btn { width: 21px; height: 27px; }
    .z-journey .z-jqty .z-qty-input {
        width: 1.7em;
        font-size: 13px !important;
        height: 27px;
        line-height: 27px;
    }
}

/* --- policies rail ---------------------------------------------------------
   The Important Information block on activities/activity_detail.php: a column
   of topics on the left, the chosen one on the right. Same anatomy, Zaereen's
   marble and gold instead of the dark glass.
   -------------------------------------------------------------------------- */
.z-polbox { display: flex; align-items: flex-start; gap: 22px; }

.z-polnav {
    flex: 0 0 220px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.z-polnav-item {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    width: 100%;
    padding: 14px 15px;
    border: 1px solid var(--z-line);
    border-radius: 12px;
    background: var(--z-cream);
    color: var(--z-ink);
    font-family: var(--z-body);
    font-size: 14.5px;
    font-weight: 500;
    text-align: left;
    line-height: 1.35;
    cursor: pointer;
    transition: background-color .25s ease, border-color .25s ease,
                color .25s ease, transform .25s ease, box-shadow .25s ease;
}
/* The library's chevron points down; a quarter turn makes it point into the
   pane it opens, as the reference's fa-chevron-right does.

   DIRECT CHILD ONLY. Written as `.z-polnav-item svg` it also caught the topic
   mark added inside .z-polnav-ico, and turned every wallet and passport in the
   rail on its side. */
.z-polnav-item > svg { flex: none; transform: rotate(-90deg); color: var(--z-gold-deep); opacity: .55; }

/* The topic's own mark, in a tile at the head of the row. The rail is six
   near-identical lines of text otherwise, and someone looking for the
   cancellation charges has to read all six to find them. */
.z-polnav-ico {
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px;
    border-radius: 9px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
    transition: background-color .25s ease, border-color .25s ease, color .25s ease;
}
/* The label takes what is left, so the chevron stays pinned to the right
   edge however short the topic's name is. */
.z-polnav-ico + span { flex: 1 1 auto; min-width: 0; }
.z-polnav-item:hover {
    background: var(--z-gold-wash);
    border-color: var(--z-line-gold);
    color: var(--z-green);
    transform: translateX(4px);
}
.z-polnav-item.is-active {
    background: linear-gradient(135deg, var(--z-gold-light), var(--z-gold));
    border-color: var(--z-gold);
    color: var(--z-green);
    font-weight: 600;
    box-shadow: 0 10px 20px rgba(193, 154, 63, .26);
    transform: none;
}
.z-polnav-item.is-active > svg { color: var(--z-green); opacity: .85; }
/* On the gold row the wash tile disappears into its own background, so the
   active mark inverts to the green instead. */
.z-polnav-item.is-active .z-polnav-ico {
    background: var(--z-green);
    border-color: var(--z-green);
    color: var(--z-gold-light);
}
.z-polnav-item:hover .z-polnav-ico { border-color: var(--z-gold); color: var(--z-green); }
.z-polnav-item:focus-visible { outline: 2px solid var(--z-gold-deep); outline-offset: 2px; }

.z-polpanes {
    flex: 1 1 auto;
    min-width: 0;
    padding: 20px 22px;
    background: var(--z-marble);
    border: 1px solid var(--z-line);
    border-radius: 14px;
}
.z-polpanes .z-polpane-title svg { flex: none; color: var(--z-gold-deep); }

.z-polpane { animation: zPolIn .38s ease-out; }
.z-polpane[hidden] { display: none; }
/* Two classes deep on purpose: the base ".zaereen h3" rule is (0,1,1) and
   would otherwise win and paint this --z-ink instead of the brand green. */
.z-polpanes .z-polpane-title {
    display: flex;
    align-items: center;
    gap: 9px;
    font-family: var(--z-display);
    font-size: 19px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--z-green);
    margin: 0 0 14px;
}
.z-polpane > *:last-child { margin-bottom: 0; }
.z-polpane .z-prose p, .z-polpane .z-prose li { max-width: 88ch; }
@keyframes zPolIn {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .z-polpane { animation: none; }
    .z-polnav-item:hover { transform: none; }
}

/* The rail eats a column the inclusions grid also wants; below this the two
   lists stack rather than each getting half of a half. */
@media (max-width: 1040px) {
    .z-polnav { flex-basis: 190px; }
    .z-polnav-item { padding: 12px 13px; font-size: 14px; }
}
/* Phones: the rail lies down above the pane and swipes. */
@media (max-width: 780px) {
    .z-polbox { flex-direction: column; gap: 14px; }
    .z-polnav {
        flex: 1 1 auto; width: 100%;
        flex-direction: row;
        gap: 8px;
        overflow-x: auto;
        scrollbar-width: none;
        padding-bottom: 2px;
    }
    .z-polnav::-webkit-scrollbar { display: none; }
    .z-polnav-item { width: auto; white-space: nowrap; }
    .z-polnav-item:hover { transform: none; }
    .z-polnav-item svg { display: none; }
    .z-polpanes { width: 100%; padding: 16px; }
}

/* --- disclosure accordion (policies, FAQs) --- */
.z-acc {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    margin-bottom: 10px;
    overflow: hidden;
}
.z-acc > summary {
    display: flex; align-items: center; gap: 16px;
    padding: 15px 18px; cursor: pointer; list-style: none;
}
.z-acc > summary::-webkit-details-marker { display: none; }
.z-acc > summary::after {
    content: ""; margin-left: auto; flex: none;
    width: 9px; height: 9px;
    border-right: 1.6px solid var(--z-ink-3);
    border-bottom: 1.6px solid var(--z-ink-3);
    transform: rotate(45deg); transition: transform .22s ease;
}
.z-acc[open] > summary::after { transform: rotate(-135deg); }
.z-acc[open] > summary { background: var(--z-gold-wash); }
.z-acc-title { min-width: 0; }
.z-acc-title b {
    display: block; font-family: var(--z-display); font-size: 18px;
    font-weight: 600; letter-spacing: .03em; color: var(--z-ink);
}
.z-acc-title span { font-size: 13px; color: var(--z-ink-3); }
.z-acc-body { padding: 4px 18px 18px; }

.z-tag {
    font-size: 11.5px; letter-spacing: .05em;
    padding: 3px 10px; border-radius: 100px;
    background: var(--z-green-soft, var(--z-surface-2));
    border: 1px solid var(--z-line);
    color: var(--z-ink-2);
}

/* --- inclusion / exclusion lists --- */
.z-incex { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; }
.z-list li {
    display: flex; gap: 11px; align-items: flex-start;
    padding: 8px 0; font-size: 14.5px; color: var(--z-ink-2);
    border-bottom: 1px solid var(--z-line-soft);
}
.z-list li:last-child { border-bottom: 0; }
.z-list svg { flex: none; margin-top: 3px; }
.z-list.is-in svg { color: var(--z-open); }
.z-list.is-out svg { color: var(--z-sold); }

/* --- stays --- */
.z-stays { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; }
.z-stay {
    background: var(--z-surface); border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm); padding: 16px;
}
.z-stay b {
    display: block; font-family: var(--z-display); font-size: 20px;
    font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--z-ink);
}
.z-stay span { font-size: 13.5px; color: var(--z-gold-deep); }

/* --- flight legs --- */
.z-leg {
    display: grid; grid-template-columns: 1fr auto 1fr; gap: 18px; align-items: center;
    background: var(--z-surface); border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm); padding: 16px 18px; margin-bottom: 10px;
}
.z-leg-end b {
    display: block; font-family: var(--z-display); font-size: 22px;
    font-weight: 600; color: var(--z-ink); letter-spacing: .04em;
}
.z-leg-end span { font-size: 13px; color: var(--z-ink-3); }
.z-leg-mid { text-align: center; color: var(--z-gold-deep); font-size: 12px; }
.z-leg-mid svg { display: block; margin: 0 auto 3px; }
.z-leg:last-child { margin-bottom: 0; }
.z-leg-end:last-child { text-align: right; }

/* ==========================================================================
   Mobile sticky reserve bar
   ========================================================================== */

.z-sticky {
    display: none;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 90;
    background: var(--z-surface);
    border-top: 1px solid var(--z-line);
    box-shadow: 0 -6px 24px -12px rgba(18, 51, 42, .5);
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
    gap: 14px;
    align-items: center;
}

/* ==========================================================================
   Empty state
   ========================================================================== */

.z-empty {
    text-align: center;
    padding: 48px 24px;
    background: var(--z-surface);
    border: 1px dashed var(--z-line);
    border-radius: var(--z-radius);
    color: var(--z-ink-2);
}
.z-empty b { display: block; font-family: var(--z-display); font-size: 21px; color: var(--z-ink); margin-bottom: 6px; }

/* ==========================================================================
   Responsive
   ========================================================================== */

/* Between the full-width card and the narrow one, so the reading column
   does not pinch just above the 1080px breakpoint. */
@media (max-width: 1240px) {
    .z-tourbody { grid-template-columns: 1fr 340px; gap: 32px; }
}

@media (max-width: 1080px) {
    .z-nav { display: none; }
    /* NO BURGER ON PHONE OR TABLET.
       It used to appear here, and it was the third way to reach the same
       places. Below this width the .z-quicktop strip already carries every
       product — For You, Flights, Hotels, Holidays, Visas, Mazaarat — as
       labelled icons under the bar, and the .z-acct chip beside the logo
       still opens My Trips, Enquiries, Profile, Account and Sign out (it is
       neither .z-desk-only nor .z-header-link, so nothing below hides it).
       A hamburger next to both is a menu whose contents are already on
       screen.

       WHAT IS ACTUALLY LOST: only the drawer's indented sub-destinations —
       the regions listed beneath each product. Those are one tap away on the
       product's own listing page, which is where somebody browsing
       destinations is going anyway.

       The base rule at the top of this file is `display: none`, so deleting
       this line is all it takes. The drawer, scrim and their script stay in
       the markup: inert while nothing can open them, and putting the button
       back is a one-line change rather than a rebuild. */
    .z-header-actions .z-header-link { display: none; }
    /* .z-grid-3 belongs here too. Without it that grid went straight from
       three columns to one, so across the whole tablet band it stayed at
       three — 174px cards on an 857px viewport, with the listing sidebar
       taking its share first. Two is what fits. */
    .z-grid-4, .z-grid-3 { grid-template-columns: repeat(2, 1fr); }
    .z-why { grid-template-columns: repeat(2, 1fr); }
    /* Five is a desktop count. Three here, two once a third of the row stops
       holding a quotation, one when even a half does. */
    .z-reviews { grid-template-columns: repeat(3, 1fr); }
    .z-products { grid-template-columns: repeat(2, 1fr); }
    /* Six columns need roughly 1240px to breathe; below that the footer
       reads better as three. */
    .z-footer-grid { grid-template-columns: 1fr 1fr 1fr; }
    /* THE FOOTER GOES ENTIRELY below desktop. The bottom bar carries the
       account and contact routes and the strip under the header carries the
       products, so the block underneath was repeating what the chrome already
       says — and it is the longest thing on a phone.

       WHAT GOES WITH IT: the Terms, Privacy and Cancellation links live in
       .z-footer-bar and the drawer does not carry them, so those three pages
       have no route on a phone while this rule stands. Moving them into the
       drawer is the fix if that matters.

       The footer's own mobile rules below are left in place rather than
       deleted — none of them applies while this is display:none, and they are
       what the block needs the moment it is switched back on. */
    .z-footer { display: none; }

    /* THE THREE LINK COLUMNS GO on everything below desktop. This is the
       same breakpoint that swaps the nav for the burger and raises the
       bottom quick bar, and between them those two already carry every one
       of these links: Ziyarat and Travel are the drawer's own lists and the
       quick bar's five buttons, and Support is reached from the account
       menu. Repeating all thirteen as a stack of headed lists made the
       footer the longest thing on a phone.

       Only the linked columns go. .is-centred holds the Tour Organizer
       authorisation and the association crests, which appear nowhere else
       and are the reason the footer is worth scrolling to. */
    .z-footer-col:not(.is-centred) { display: none; }

    /* THE TWO PLATES GO SIDE BY SIDE — Authorized by Sigat on the left, We
       Accept on the right. Stacked they were two full-width slabs one under
       the other, which is most of a phone screen for two rows of logos; the
       footer is a single column at this width, so there is a whole second
       half going spare beside each of them.

       The heading spans both. Each plate drops `width: fit-content` and the
       auto side margins that centred it in its own column, so the pair
       divides the row evenly instead of floating in the middle of it. */
    .z-footer-col.is-assoc {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 12px;
        align-items: start;
    }
    .z-footer-col.is-assoc > h4 { grid-column: 1 / -1; }
    .z-footer-col.is-assoc .z-contact-assoc {
        width: auto;
        margin: 0;
    }
    .z-footer-col.is-assoc .z-contact-pay { margin-top: 0; }

    /* The tagline goes from the footer too, both copies of it: the line under
       the lockup and the "powered by" line on the closing bar render the same
       three words, and on a phone they landed within a screen of each other
       with the header's copy already above them. */
    .z-footer-brand .z-brand-tag,
    .z-footer-bar > .z-powered { display: none; }
    .z-parts { grid-template-columns: 1fr; gap: 32px; }
    .z-listing { grid-template-columns: 220px 1fr; gap: 22px; }
    /* Two cards beside a 220px rail is 270px each — workable. Three was not. */
    .z-listing .z-grid-3 { grid-template-columns: repeat(2, 1fr); gap: 18px; }
    .z-tourbody { grid-template-columns: 1fr 300px; gap: 26px; }
}

/* Below this the two page columns leave the reading side narrower than
   the single-column phone layout it is about to become. */
@media (max-width: 900px) {
    .z-tourbody { grid-template-columns: 1fr; gap: 26px; }
    .z-journey { position: static; }

    /* THE MISSING RUNG IN THE REVIEW GRID. It went three across at 1080 and
       straight to one at 780, so a tablet showed three cards about 210px wide
       and then, twenty pixels of viewport later, a single card 700px wide.
       Two is what that band is for. */
    .z-reviews { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 780px) {
    body.zaereen { font-size: 15.5px; }
    .z-shell { padding: 0 16px; }
    .z-section { padding: 48px 0; }

    .z-hero { min-height: 0; padding: 120px 0 90px; }
    /* The clipPath scales itself; only the interior padding needs to come in. */
    .z-arch { padding: 56px 26px 34px; }
    .z-arch::before { inset: 7px; }
    .z-arch::after  { inset: 8px; }

    .z-search { margin-top: -28px; padding: 15px; }
    .z-search-grid { grid-template-columns: 1fr; gap: 11px; }
    .z-search-grid .z-btn { width: 100%; }


    /* `.z-listing .z-grid-3` from the tablet block is more specific than this
       one, so it has to be reset by name or the listing keeps two columns all
       the way down to a phone. */
    .z-grid-4, .z-grid-3,
    .z-listing .z-grid-3 { grid-template-columns: 1fr; }
    .z-why { grid-template-columns: 1fr; gap: 22px; }
    .z-reviews { grid-template-columns: 1fr; }
    /* A single full-width card is a big block for four lines of quotation, so
       it gives back the padding it was using at a third of the row. */
    .z-review { padding: 16px 15px; gap: 10px; }
    .z-review-avatar { width: 40px; height: 40px; }
    .z-review q { font-size: 13.5px; }
    .z-products { grid-template-columns: 1fr; }

    .z-dep { grid-template-columns: 72px 1fr; gap: 14px; }
    .z-dep-side { grid-column: 1 / -1; text-align: left; align-items: stretch; flex-direction: row; justify-content: space-between; }

    .z-footer-grid { grid-template-columns: 1fr; gap: 28px; }
    .z-footer-bar { grid-template-columns: 1fr; text-align: center; }
    .z-footer-bar > :last-child { text-align: center; }

    .z-sticky { display: flex; }
    body.zaereen.has-sticky { padding-bottom: 76px; }

    .z-pagehead { padding: 96px 0 32px; }

    /* Filters collapse behind a toggle rather than pushing results off-screen. */
    .z-listing { grid-template-columns: 1fr; gap: 18px; }
    .z-filters { position: static; }
    .z-filters-toggle {
        display: flex;
        width: 100%;
        justify-content: space-between;
        margin-bottom: 12px;
    }
    .z-filters[hidden] { display: none; }

    /* Detail page: the booking card stops being a rail and becomes a block
       above the content, with the sticky bar carrying the primary action. */
    .z-tourbody { grid-template-columns: 1fr; gap: 24px; }
    .z-book { position: static; }
    .z-jump { top: 0; }

    .z-depopt { grid-template-columns: 52px 1fr; gap: 12px; }
    .z-depopt-price { grid-column: 2; text-align: left; }
    .z-incex { grid-template-columns: 1fr; gap: 20px; }
    .z-day-head { padding: 12px 12px 12px 18px; gap: 8px; }
    .z-day-headline { font-size: 16px; }
    .z-day-body { padding: 12px 12px 12px; }
    .z-day-foot { padding: 10px 12px; gap: 8px 12px; }
    .z-day-when, .z-day-where, .z-day-meal { font-size: 12.5px; }
    .z-leg { grid-template-columns: 1fr auto 1fr; gap: 10px; padding: 14px; }
    .z-leg-end b { font-size: 18px; }
}

/* Horizontal scroll rails on phones — cards keep their width and swipe. */
@media (max-width: 780px) {
    .z-rail-mobile {
        display: flex;
        gap: 14px;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 6px;
        margin: 0 -16px;
        padding-left: 16px;
        padding-right: 16px;
        scrollbar-width: none;
    }
    .z-rail-mobile::-webkit-scrollbar { display: none; }
    .z-rail-mobile > * { flex: 0 0 78%; scroll-snap-align: start; }
}

/* The head sits on green, so its outline button inverts too. */
.z-cal-head .z-btn-outline {
    color: var(--z-gold-light);
    border-color: rgba(227, 200, 134, .4);
    background: rgba(227, 200, 134, .1);
}
.z-cal-head .z-btn-outline:hover { background: var(--z-gold); color: var(--z-green); border-color: var(--z-gold); }

/* Below 780px the bracketing selectors stack above and below the rail rather
   than squeezing it — two dropdowns plus seven-day tiles will not share a
   phone's width. */
@media (max-width: 780px) {
    /* --- THE STRIP, STACKED ----------------------------------------------

           [ ALL ] | DESTINATION
                   | ------------
                   | DEPARTURE CITY
           [ dates rail, full width ]

       The two selectors live inside .z-strip-filters, which on a wide screen is
       a fixed 82px column pinned to the RIGHT of the rail. The rules that used
       to sit here tried to rearrange things by ordering .z-strip-dest and
       .z-strip-city — children of that box, not siblings of the rail — so the
       ordering moved nothing and the column stayed pinned where the desktop
       layout left it.

       The wrapper is what moves. The ALL tile keeps the first place and the two
       selectors stack beside it, which puts the calendar toggle and the two
       things that filter it on one line, and gives the dates the full width of
       the row below rather than sharing it with a control. */
    .z-strip-wrap { flex-wrap: wrap; align-items: flex-start; }

    /* First, at its own width. Its dashed right border is the rule between it
       and the selectors — the filters do not draw a second one. */
    .z-dchip-fixed { order: 0; }

    .z-strip-filters {
        order: 1;
        flex: 1 1 0;
        min-width: 0;
        width: auto;
        height: auto;
        flex-direction: column;
        justify-content: flex-start;
        gap: 8px;
        padding-left: 12px;
        margin-left: 0;
        margin-bottom: 10px;
        border-left: 0;
    }
    .z-strip-dest,
    .z-strip-city {
        width: 100%;
        min-width: 0;
        height: auto;
        padding: 0;
        margin: 0;
        border: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 3px;
    }
    /* The line between the two, as a divider rather than a border on the box:
       it separates Destination from Departure City and stops where the second
       one starts. */
    .z-strip-dest {
        padding-bottom: 8px;
        border-bottom: 1px dashed var(--z-line);
    }
    .z-strip-dest select,
    .z-strip-city select { width: 100%; min-width: 0; }

    /* The dates take the whole of the next line. */
    .z-strip { order: 2; flex: 1 1 100%; min-width: 0; }
}

/* The tile is a fixed 76px, so everything a narrower screen takes away comes
   out of the selectors beside it: 149px at 320px against the ~159px
   "All Destinations" wants at full size. The type steps down rather than the
   layout breaking, and the tile gives back a little of its own padding. */
@media (max-width: 360px) {
    .z-dchip-fixed { padding-right: 7px; margin-right: 2px; }
    .z-strip-filters { padding-left: 8px; gap: 6px; }
    .z-strip-dest select,
    .z-strip-city select {
        font-size: 12.5px;
        padding-left: 9px;
        padding-right: 24px;
    }
    .z-strip-dest label,
    .z-strip-city label { font-size: 8.5px; letter-spacing: .08em; }
}

/* ==========================================================================
   Enquiry modal — opens when a date is clicked
   ========================================================================== */

.z-modal {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.z-modal[hidden] { display: none; }

.z-modal-scrim {
    position: absolute;
    inset: 0;
    background: rgba(8, 28, 22, .62);
    backdrop-filter: blur(3px);
}

.z-modal-panel {
    position: relative;
    width: min(620px, 100%);
    max-height: calc(100vh - 40px);
    overflow-y: auto;
    background: var(--z-marble);
    background-image: var(--z-marble-tex);
    background-size: 300px 300px;
    border: 1px solid var(--z-gold);
    border-radius: var(--z-radius);
    box-shadow: 0 40px 90px -30px rgba(4, 18, 13, .8);
}

.z-modal-close {
    position: absolute;
    top: 12px; right: 14px;
    width: 34px; height: 34px;
    border-radius: 50%;
    border: 1px solid rgba(227, 200, 134, .4);
    background: rgba(227, 200, 134, .12);
    color: var(--z-gold-light);
    font-size: 21px;
    line-height: 1;
    cursor: pointer;
    z-index: 1;
}
.z-modal-close:hover { background: var(--z-gold); color: var(--z-green); border-color: var(--z-gold); }

/* Green head, matching the calendar panel it opens from. */
.z-modal-head {
    padding: 16px 22px 15px;
    background: var(--z-green);
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
    border-bottom: 1px solid var(--z-gold);
    text-align: center;
}
.z-modal-head h2 {
    font-family: var(--z-display);
    font-size: clamp(21px, 3vw, 27px);
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #fdf8ec;
    margin: 4px 0 0;
}
.z-modal-facts {
    display: flex;
    justify-content: center;
    gap: 8px 20px;
    flex-wrap: wrap;
    margin-top: 12px;
    font-size: 13px;
    color: rgba(240, 233, 215, .72);
}
.z-modal-facts span { display: inline-flex; align-items: center; gap: 6px; }
.z-modal-facts svg { color: var(--z-gold-light); }
.z-modal-facts b { color: var(--z-gold-light); font-weight: 500; }

.z-modal-body { padding: 14px 18px 16px; }
/* Layout lives in the flex block further down — a six-column grid reserved a
   full column per field, which left dead space beside the narrow ones. These
   declarations are gone rather than overridden so there is one place to look. */
.z-modal-grid .z-field input,
.z-modal-grid .z-field select,
.z-modal-grid .z-field textarea {
    font-family: var(--z-body);
    font-size: 15px;
    color: var(--z-ink);
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 8px;
    padding: 9px 11px;
    width: 100%;
    resize: vertical;
}
.z-modal-grid .z-field input:focus,
.z-modal-grid .z-field select:focus,
.z-modal-grid .z-field textarea:focus { border-color: var(--z-gold); outline: none; }
.z-req { color: var(--z-sold); }

.z-modal-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--z-line-soft);
}
.z-modal-note { margin: 0; font-size: 12.5px; color: var(--z-ink-3); max-width: 34ch; }

@media (max-width: 620px) {
    .z-modal { padding: 0; align-items: flex-end; }
    .z-modal-panel { max-height: 92vh; border-radius: var(--z-radius) var(--z-radius) 0 0; }
    .z-modal-grid { grid-template-columns: repeat(2, 1fr); }
    .z-modal-grid .z-col-2, .z-modal-grid .z-col-3 { grid-column: 1 / -1; }
    .z-modal-foot { flex-direction: column; align-items: stretch; }
    .z-modal-foot .z-btn { width: 100%; }
}

/* Outcome banner after a departure enquiry. */
.z-flash {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px 18px;
    margin: 20px 0 -6px;
    border-radius: var(--z-radius-sm);
    font-size: 15px;
    line-height: 1.5;
}
.z-flash svg { flex: none; margin-top: 2px; }
.z-flash b { display: block; margin-top: 3px; font-weight: 500; letter-spacing: .04em; }
.z-flash.is-ok  { background: var(--z-open-bg); border: 1px solid var(--z-open); color: var(--z-open); }
.z-flash.is-bad { background: var(--z-sold-bg); border: 1px solid var(--z-sold); color: var(--z-sold); }

/* ==========================================================================
   Enquiry form: pax steppers, child ages, phone

   Follows the Itinerary PDF card in b2b/holidays/ (.pdf-qty / .age-option):
   minus / zero-padded count / plus, colour-coded per pax type, with a row of
   age buttons per child. Redrawn in Zaereen's palette.
   ========================================================================== */

.z-title-field { min-width: 0; }
.z-pax-field label { display: flex; align-items: baseline; gap: 6px; }
.z-pax-field label small {
    font-size: 10px;
    letter-spacing: .04em;
    text-transform: none;
    color: var(--z-ink-3);
}
.z-pax-field label.is-adults   { color: var(--z-green-3); }
.z-pax-field label.is-children { color: var(--z-gold-deep); }
.z-pax-field label.is-infants  { color: var(--z-teal); }

.z-qty {
    display: flex;
    align-items: center;
    gap: 6px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 8px;
    padding: 4px;
}
/* The glyphs are drawn, not typed: a text "+" sits off-centre at this size
   and shifts with the font stack. */
.z-qty-btn {
    position: relative;
    flex: none;
    width: 30px; height: 30px;
    border: 0;
    border-radius: 6px;
    cursor: pointer;
    background: var(--z-green-3);
    transition: filter .15s ease;
}
.z-qty-btn::before {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 11px; height: 2px;
    background: #fff;
    border-radius: 1px;
}
.z-qty-plus::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 2px; height: 11px;
    background: #fff;
    border-radius: 1px;
}
.z-qty-btn:hover  { filter: brightness(1.12); }
.z-qty-btn:active { filter: brightness(.9); }

.z-qty[data-target="zeAdults"]  .z-qty-btn { background: var(--z-green-3); }
.z-qty[data-target="zeChildren"] .z-qty-btn { background: var(--z-gold-deep); }
.z-qty[data-target="zeInfants"]  .z-qty-btn { background: var(--z-teal); }
/* Booking card steppers, coded the same way as the enquiry form. */
.z-qty[data-target="zPlanAdults"]   .z-qty-btn { background: var(--z-green-3); }
.z-qty[data-target="zPlanChildren"] .z-qty-btn { background: var(--z-gold-deep); }

.z-qty-input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0 !important;
    background: transparent !important;
    text-align: center;
    /* The display face sits high in a default line box, so the digits
       drifted above centre in the stepper. Pin the box. */
    height: 26px;
    line-height: 26px;
    font-family: var(--z-display) !important;
    font-size: 21px !important;
    font-weight: 600;
    color: var(--z-ink);
    font-variant-numeric: tabular-nums;
    padding: 0 !important;
    cursor: default;
}
.z-qty-input:focus { outline: none; }

/* --- child ages --- */
.z-ages[hidden] { display: none; }
.z-age-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 8px;
}
.z-age-label {
    flex: 0 0 66px;
    font-size: 12.5px;
    color: var(--z-ink-2);
}
.z-age-selector {
    display: flex;
    gap: 5px;
    flex: 1 1 auto;
    min-width: 0;
}
.z-age-option {
    flex: 1 1 0;
    min-width: 0;
    height: 32px;
    border: 1px solid var(--z-line);
    border-radius: 7px;
    background: var(--z-surface);
    color: var(--z-ink-2);
    font-family: var(--z-body);
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.z-age-option:hover { border-color: var(--z-gold); color: var(--z-green); }
.z-age-option.is-active {
    background: var(--z-gold-deep);
    border-color: var(--z-gold-deep);
    color: #fffaf0;
}

/* --- ITS validation --- */
.z-hint { display: block; margin-top: 5px; font-size: 12px; color: var(--z-ink-3); }
.z-hint.is-bad { color: var(--z-sold); }
.z-modal-grid .z-field input.is-bad { border-color: var(--z-sold); }

/* --- intl-tel-input, fitted to the Zaereen field --- */
.z-modal-grid .iti { width: 100%; display: block; }
.z-modal-grid .iti__flag-container { z-index: 2; }
.z-modal-grid .iti--separate-dial-code .iti__selected-flag {
    background: var(--z-surface-2);
    border-radius: 8px 0 0 8px;
    border-right: 1px solid var(--z-line);
}
.z-modal-grid .iti--separate-dial-code .iti__selected-dial-code {
    font-size: 14px;
    color: var(--z-ink-2);
}
.z-modal-grid .iti__country-list {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 8px;
    box-shadow: var(--z-shadow-lg);
    color: var(--z-ink);
}
.z-modal-grid .iti__country.iti__highlight { background: var(--z-gold-wash); }
.z-modal-grid .iti__dial-code { color: var(--z-ink-3); }

/* Every date now carries its month and weekday, not only the bookable ones.
   The band therefore has to stop being a departure marker: it is green with
   gold lettering on a day that has a departure, and a quiet cream strip on a
   day that does not, so the hierarchy survives being applied to all 61 cells. */
.z-cal-cell.is-empty .z-cal-mon {
    background: var(--z-surface-2);
    color: var(--z-ink-3);
    border-bottom-color: var(--z-line-strong);
    font-weight: 500;
}

/* Weekday under the number. Redundant with the column header on a desktop,
   but the column is what gets lost when a single date is quoted in a
   screenshot or read out over the phone. */
.z-cal-dow-mini {
    flex: 0 0 auto;
    padding: 0 2px 4px;
    text-align: center;
    font-size: 8.5px;
    font-weight: 500;
    letter-spacing: .1em;
    color: var(--z-ink-3);
    line-height: 1;
}
.z-cal-cell.has-dep .z-cal-dow-mini { color: var(--z-green-3); }
.z-cal-cell.is-selected .z-cal-dow-mini { color: rgba(240, 233, 215, .7); }

/* The number takes the space left between the month band and the labels under
   it, and centres in that space. An earlier `flex: 0 0 auto` here pinned it
   directly beneath the band instead, which left every date sitting high in
   its box with the slack collecting at the bottom. */
.z-cal-num {
    flex: 1 1 auto;
    padding: 3px 0 1px;
    min-height: 0;
}
.z-cal-cell.has-dep .z-cal-price { padding-top: 1px; }

/* Compact enquiry form: labels and field chrome tightened so the whole thing
   fits a laptop viewport without scrolling. */
.z-modal-grid .z-field label {
    font-size: 10px;
    letter-spacing: .1em;
    margin-bottom: 3px;
}
.z-modal-grid .z-field { gap: 3px; }
.z-modal-grid .z-pax-field .z-qty { padding: 3px; }
.z-modal-grid .z-pax-field .z-qty-btn { width: 26px; height: 26px; }
.z-modal-head h2 { font-size: clamp(19px, 2.6vw, 24px); }
.z-modal-facts { margin-top: 9px; font-size: 12.5px; }
.z-age-row { margin-top: 6px; }
.z-age-option { height: 28px; font-size: 11.5px; }
.z-modal-note { font-size: 12px; }

/* --------------------------------------------------------------------------
   Enquiry form: inputs sized to what they hold

   A field stretched to its grid column tells the visitor nothing about what
   goes in it. An 8-digit ITS and a 10-digit Indian mobile now get boxes that
   are visibly that long, and the pax steppers stop spanning a third of the
   form for a two-character number.
   -------------------------------------------------------------------------- */

.z-modal-grid .z-field label {
    display: flex;
    align-items: center;
    gap: 5px;
}
.z-modal-grid .z-field label svg { color: var(--z-gold-deep); flex: none; }
.z-pax-field label.is-adults  svg { color: var(--z-green-3); }
.z-pax-field label.is-children svg { color: var(--z-gold-deep); }
.z-pax-field label.is-infants svg { color: var(--z-teal); }

/* ch units: the box is as wide as the digits it accepts, plus padding. */
#zeIts { max-width: 13ch; font-variant-numeric: tabular-nums; letter-spacing: .06em; }
#zeTitle { max-width: 11ch; }
#zeMobile { font-variant-numeric: tabular-nums; letter-spacing: .04em; }

/* Compact steppers: a fixed, narrow control rather than one that fills the
   column. Three of these across a row now read as a set of counters. */
.z-modal-grid .z-pax-field .z-qty {
    max-width: 112px;
    gap: 4px;
    padding: 3px;
}
.z-modal-grid .z-pax-field .z-qty-btn { width: 25px; height: 25px; border-radius: 5px; }
.z-modal-grid .z-pax-field .z-qty-btn::before { width: 9px; }
.z-modal-grid .z-pax-field .z-qty-plus::after { height: 9px; }

@media (max-width: 620px) {
    /* On a phone the columns collapse, so let the boxes use the width. */
    #zeIts, #zeTitle { max-width: none; }
    .z-modal-grid .z-pax-field .z-qty { max-width: none; }
}

/* --------------------------------------------------------------------------
   Enquiry form: rows sized to content, not to a fixed column grid

   Capping the input widths left the grid still reserving a full column for
   each narrow field, so an 8-digit ITS box sat in a third of the row with the
   rest of that third empty. Flex rows let each field take only what it needs
   and hand the slack to the one field on the line that should grow.
   -------------------------------------------------------------------------- */

.z-modal-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 10px;
}
/* Fixed-width fields: the box IS the field, so no column is reserved. */
.z-modal-grid .z-c2 { flex: 0 0 auto; width: 128px; }   /* ITS, 8 digits   */
.z-modal-grid .z-c1 { flex: 0 0 auto; width: 92px;  }   /* prefix          */
.z-modal-grid .z-c3 { flex: 1 1 210px; min-width: 0; }  /* name/mobile/email */
.z-modal-grid .z-c6 { flex: 1 1 100%; }
.z-modal-grid .z-pax-field { flex: 0 0 auto; width: 124px; }

/* The caps above now do the sizing; these would fight them. */
#zeIts, #zeTitle { max-width: none; }
.z-modal-grid .z-pax-field .z-qty { max-width: none; }

@media (max-width: 620px) {
    .z-modal-grid .z-c2,
    .z-modal-grid .z-c1,
    .z-modal-grid .z-pax-field { flex: 1 1 100px; width: auto; }
    .z-modal-grid .z-c3 { flex: 1 1 100%; }
}

/* Adults / Children / Infant occupy a line of their own. As loose siblings in
   the wrapping flex row they rode up beside Email whenever the panel was wide
   enough, which left a ragged, unbalanced line. */
.z-pax-row {
    flex: 1 1 100%;
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}
/* Pax steppers: centred heading, and a counter box only as wide as the two
   digits it ever holds. The input was flex-growing to fill the field, which
   left a two-character number floating in a box sized for a name.

   One width declaration, not two. An earlier pair here set 124px and then
   98px on the same selector, with a mobile override sitting between them —
   media queries add no specificity, so the later desktop rule was winning on
   phones until a second mobile block was added to undo it. */
.z-pax-row .z-pax-field { flex: 0 0 auto; width: 98px; }
.z-pax-row .z-pax-field label {
    justify-content: center;
    text-align: center;
    white-space: nowrap;
}
/* Minus | number | plus, evenly distributed and on one optical line.

   space-between rather than center: the buttons pin to the two ends of the
   control and the number holds the middle, so all three steppers align with
   each other regardless of whether the count is one digit or two.

   The number needs an explicit height and line-height. Without them its
   content box is sized by the display face's own metrics — which are much
   taller than the 24px buttons — and `align-items: center` then centres a
   box whose glyph does not sit in the middle of it, so the digit rode high
   against the buttons. */
.z-pax-row .z-qty {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
    padding: 3px;
    max-width: none;
}
.z-pax-row .z-qty-input {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    height: 24px;
    line-height: 24px;
    text-align: center;
    font-size: 16px !important;
    font-variant-numeric: tabular-nums;
}
.z-pax-row .z-qty-btn { flex: 0 0 auto; width: 24px; height: 24px; }

@media (max-width: 620px) {
    .z-pax-row .z-pax-field { flex: 1 1 90px; width: auto; }
}

/* Mobile and Email sit side by side with no dead air between them.

   The phone field used to grow like any other, while the control inside it
   was capped to the selected country's digit count — so the field kept the
   leftover width as blank space and pushed Email away. The field now hugs
   the control (which the country JS sizes), and Email takes the remainder. */
.z-modal-grid .z-phone-field { flex: 0 0 auto; }
.z-modal-grid .z-phone-field .iti { width: 24ch; max-width: none; }

@media (max-width: 620px) {
    .z-modal-grid .z-phone-field { flex: 1 1 100%; }
    .z-modal-grid .z-phone-field .iti { width: 100%; }
}

/* --------------------------------------------------------------------------
   Availability carried by the whole date tile, not just its dot

   Seats available / Few seats left / Sold out now colour the cell background,
   its border and its month band, so a month can be read for availability at a
   glance instead of hunting for six-pixel dots. The dot stays as the key that
   ties a tile back to the legend.

   The status classes are already applied by both renderers (`is-open`,
   `is-few`, `is-sold`), so this is presentation only.
   -------------------------------------------------------------------------- */

.z-cal-cell.has-dep.is-open {
    background: linear-gradient(170deg, #f2f8f4 0%, var(--z-open-bg) 100%);
    border-color: color-mix(in srgb, var(--z-open) 42%, transparent);
}
.z-cal-cell.has-dep.is-open .z-cal-num,
.z-cal-cell.has-dep.is-open .z-cal-dow-mini { color: var(--z-open); }
.z-cal-cell.has-dep.is-open .z-cal-price { color: var(--z-open); }
.z-cal-cell.has-dep.is-open .z-cal-mon {
    background: var(--z-open);
    color: #f2f8f4;
    border-bottom-color: color-mix(in srgb, var(--z-open) 60%, #000);
}

.z-cal-cell.has-dep.is-few {
    background: linear-gradient(170deg, #fdf6e8 0%, var(--z-few-bg) 100%);
    border-color: color-mix(in srgb, var(--z-few) 45%, transparent);
}
.z-cal-cell.has-dep.is-few .z-cal-num,
.z-cal-cell.has-dep.is-few .z-cal-dow-mini { color: var(--z-few); }
.z-cal-cell.has-dep.is-few .z-cal-price { color: var(--z-few); }
.z-cal-cell.has-dep.is-few .z-cal-mon {
    background: var(--z-few);
    color: #fdf6e8;
    border-bottom-color: color-mix(in srgb, var(--z-few) 60%, #000);
}

.z-cal-cell.has-dep.is-sold {
    background: linear-gradient(170deg, #fbf0ed 0%, var(--z-sold-bg) 100%);
    border-color: color-mix(in srgb, var(--z-sold) 40%, transparent);
    opacity: .78;                      /* still legible, clearly not for sale */
}
.z-cal-cell.has-dep.is-sold .z-cal-num,
.z-cal-cell.has-dep.is-sold .z-cal-dow-mini { color: var(--z-sold); }
.z-cal-cell.has-dep.is-sold .z-cal-price { color: var(--z-sold); text-decoration: line-through; }
.z-cal-cell.has-dep.is-sold .z-cal-mon {
    background: var(--z-sold);
    color: #fbf0ed;
    border-bottom-color: color-mix(in srgb, var(--z-sold) 60%, #000);
}

/* Hover keeps the status hue rather than washing back to gold. */
.z-cal-cell.has-dep.is-open:hover { border-color: var(--z-open); background: #eaf4ee; }
.z-cal-cell.has-dep.is-few:hover  { border-color: var(--z-few);  background: #faf0dd; }
.z-cal-cell.has-dep.is-sold:hover { border-color: var(--z-sold); background: var(--z-sold-bg); }

/* The selected day still overrides everything — it is the strongest state. */
.z-cal-cell.is-selected,
.z-cal-cell.is-selected:hover { background: var(--z-green); border-color: var(--z-green); }

/* --------------------------------------------------------------------------
   Tour detail: gallery, and sub-blocks under a merged heading
   -------------------------------------------------------------------------- */


/* Sections folded under a shared heading: they keep their own titles but drop
   to a subordinate level, so the page has one h2 per nav entry rather than
   nine competing ones. */
.z-subhead {
    font-family: var(--z-display);
    font-size: 19px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--z-green);
    margin: 0 0 14px;
}
.z-block-sub {
    margin-bottom: 28px;
    padding-left: 16px;
    border-left: 2px solid var(--z-line-gold);
}
.z-block-sub > .z-subhead { margin-top: 0; }
.z-block > .z-subhead:not(:first-of-type) { margin-top: 26px; }

/* --------------------------------------------------------------------------
   Tour detail tabs

   The file-folder bar from holidays/package.php (.content-tabs-nav / .tab-btn),
   in Zaereen's palette: tabs sit on the content, the active one joins it.
   -------------------------------------------------------------------------- */

.z-tabs {
    display: flex;
    justify-content: flex-start;
    gap: 6px;
    padding: 0 14px;
    margin: 0;
    /* Visible, not a scroll container: the active tab overhangs the bar by 1px
       to paint out the panel's top border, and overflow-x:auto would clip
       exactly that pixel. The six tabs fit every desktop width; only the phone
       breakpoint below turns the bar back into a scroller. */
    overflow: visible;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    position: sticky;
    top: 75px;
    z-index: 20;
    background: var(--z-cream);
}
.z-tabs::-webkit-scrollbar { display: none; }

.z-tab {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 11px 18px 12px;
    border: 1px solid var(--z-line-strong);
    border-bottom: 0;
    border-radius: 12px 12px 0 0;
    /* One step darker than the bar behind them, so an unselected tab reads as
       recessed against the near-white panel it opens. */
    background: var(--z-cream-deep);
    color: var(--z-ink-2);
    font-family: var(--z-body);
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    position: relative;
    transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}
.z-tab svg { color: var(--z-gold-deep); flex: none; }
.z-tab:hover { background: var(--z-gold-wash); color: var(--z-green); border-color: var(--z-line-gold); }

/* The active tab is the same green as the page heads and reaches 1px into the
   panel below, covering its top border — that overlap is what makes the tab
   and its content read as one box rather than two stacked things. */
.z-tab.is-active {
    background: var(--z-green);
    border-color: var(--z-green);
    color: #fdf8ec;
    z-index: 2;
    margin-bottom: -1px;
    padding-bottom: 13px;
}
.z-tab.is-active svg { color: var(--z-gold-light); }

/* Narrower desktops: tighten the tabs so the row still fits on one line
   and the overlap survives. Below 780px the bar becomes a scroller. */
@media (max-width: 1040px) {
    .z-tab { padding: 10px 12px 11px; font-size: 13px; gap: 6px; }
    .z-tab.is-active { padding-bottom: 12px; }
}

/* --- the panel the tabs open ------------------------------------------- */
.z-tabpanel {
    position: relative;
    background: var(--z-surface);
    border: 1px solid var(--z-line-strong);
    border-radius: 16px;
    box-shadow: 0 16px 38px rgba(13, 44, 34, .07);
    padding: 26px 26px 28px;
}

/* The blocks a tab owns; hidden ones use [hidden], which the reset honours. */
.z-block[hidden] { display: none; }

/* The tab is the section's heading now — the h2 inside would say it twice.
   Sub-headings (.z-subhead) stay: those name parts, not the whole tab. */
.z-tabpanel .z-block.z-block-first > h2:not(.z-subhead) { display: none; }
.z-tabpanel .z-block.z-block-last { margin-bottom: 0; }

@media (max-width: 780px) {
    .z-tabs { top: 0; padding: 0 10px; overflow-x: auto; overflow-y: hidden; }
    .z-tab { padding: 9px 13px 10px; font-size: 13px; }
    .z-tab.is-active { padding-bottom: 10px; margin-bottom: 0; }
    .z-tab svg { display: none; }
    .z-tabpanel { padding: 18px 14px 20px; border-radius: 12px; }
}

/* --------------------------------------------------------------------------
   Gallery — main image with a thumbnail strip

   Follows .gallery-container-v2 / .main-image-wrapper / .thumb-item in
   holidays/package.php: one large frame, thumbnails under it that swap what
   is shown, active thumb marked.
   -------------------------------------------------------------------------- */

.z-gal {
    background: var(--z-marble);
    background-image: var(--z-marble-tex);
    background-size: 300px 300px;
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    box-shadow: var(--z-shadow);
    padding: 10px;
    position: relative;
}
.z-gal::after {
    content: "";
    position: absolute;
    inset: 4px;
    border: 1px solid var(--z-line-gold);
    border-radius: calc(var(--z-radius) - 4px);
    pointer-events: none;
}

.z-gal-main {
    position: relative;
    display: block;
    border-radius: var(--z-radius-sm);
    overflow: hidden;
    cursor: zoom-in;
    margin-bottom: 10px;
    background: var(--z-cream-deep);
    /* Sized to the viewport, not to a fixed ratio: a tall image used to push
       the thumbnail strip below the fold, so the gallery never showed as one
       piece. clamp keeps it readable on a laptop and on a large monitor. */
    height: clamp(240px, 46vh, 520px);
}
.z-gal-main img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform .6s cubic-bezier(.165, .84, .44, 1);
}
.z-gal-main:hover img { transform: scale(1.04); }

.z-gal-zoom {
    position: absolute;
    right: 14px; bottom: 14px;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px;
    border-radius: 100px;
    background: rgba(9, 32, 25, .68);
    backdrop-filter: blur(5px);
    color: var(--z-gold-light);
    font-size: 12.5px;
    opacity: 0;
    transition: opacity .3s ease;
    pointer-events: none;
}
.z-gal-main:hover .z-gal-zoom { opacity: 1; }

.z-gal-strip {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 2px;
}
.z-gal-strip::-webkit-scrollbar { display: none; }

.z-gal-thumb {
    flex: 0 0 auto;
    width: 92px;
    aspect-ratio: 4 / 3;
    padding: 0;
    border: 2px solid transparent;
    border-radius: 8px;
    overflow: hidden;
    background: var(--z-cream-deep);
    cursor: pointer;
    opacity: .68;
    transition: opacity .2s ease, border-color .2s ease, transform .2s ease;
}
.z-gal-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.z-gal-thumb:hover { opacity: 1; transform: translateY(-2px); }
.z-gal-thumb.is-active { opacity: 1; border-color: var(--z-gold); }

@media (max-width: 780px) {
    .z-gal-main { height: clamp(200px, 34vh, 320px); }
    .z-gal-thumb { width: 74px; }
}

/* The gallery pane has no heading, so it should not carry the heading's
   bottom rule or the block's top padding — the frame is the section. */
#gallery.z-block > h2 { display: none; }
#gallery.z-block { margin-bottom: 30px; }

/* Thumbnails: show as many as fit rather than a fixed count, and keep the
   strip on one line so the main image and the strip read as one unit. */
.z-gal-strip { scroll-snap-type: x proximity; }
.z-gal-thumb { scroll-snap-align: start; }



/* --------------------------------------------------------------------------
   Gallery alignment — measured fixes

   1. The left column was resolving 1214px inside a 1192px body, so the gallery
      overhung the tab bar by 22px. Grid and flex children default to
      `min-width: auto`, which refuses to shrink below their content: the
      12-thumb strip was setting that floor. min-width:0 lets the column
      match its container.

   2. `object-fit: contain` was pillarboxing. The photographs are ~16:9
      (800x463) and the frame was 1192x414 — a 2.88 box holding a 1.73 image,
      so it rendered 715px wide with green bars either side. The frame now
      carries the images' own ratio and fills it.
   -------------------------------------------------------------------------- */

.z-tourbody > div,
.z-tourbody > aside { min-width: 0; }

.z-gal-main {
    height: auto;
    aspect-ratio: 16 / 9;
    max-height: 56vh;
    background: var(--z-cream-deep);
}
.z-gal-main img { object-fit: cover; }

@media (max-width: 780px) {
    .z-gal-main { aspect-ratio: 4 / 3; max-height: 42vh; }
}

/* The frame spans the full width; the height is chosen, not derived.

   With `aspect-ratio: 16/9` AND a max-height, the height cap won and the
   WIDTH shrank to preserve the ratio — the image rendered 896px inside a
   1170px frame, leaving 274px of dead space on the right. A fixed ratio and
   a height cap cannot both hold, so the ratio goes: width is 100%, height is
   clamped to the viewport, and `cover` trims top and bottom evenly. */
.z-gal-main {
    aspect-ratio: auto;
    width: 100%;
    height: clamp(260px, 44vh, 460px);
    max-height: none;
}
.z-gal-main img { object-fit: cover; object-position: center; }

@media (max-width: 780px) {
    .z-gal-main { aspect-ratio: auto; height: clamp(200px, 32vh, 300px); }
    /* THE EMPTY BAND UNDER THE THUMBNAILS. .z-gal keeps 10px of padding all
       round and .z-block adds 40px below it — sized for a desktop page where
       blocks need separating, and read on a phone as a stretch of blank card
       after the last thumbnail. Both come in; the gallery ends where its
       pictures do. */
    .z-gal { padding: 8px; }
    .z-gal-strip { padding-bottom: 0; }
    #gallery.z-block { margin-bottom: 22px; }
}

/* Tour detail only. Scoped to .z-tourbody because the hotel pages share
   .z-gal and want their own frame.

   WIDTH IS THE COLUMN'S, NOT THE PICTURE'S. Two earlier attempts at making
   the photograph smaller shrank something horizontal: capping .z-gal-main
   left the marble panel at full width with the image floating inside it, and
   capping .z-gal then centred the whole card, so it sat inset from the
   Departure Calendar directly below it and the two cards no longer shared an
   edge. Every card in this column — calendar, itinerary, policies — is one
   column wide, so this one is too.

   The size comes off the HEIGHT instead: same frame as everything else, a
   photograph sized inside it. At 380px the 804px frame was cropping a
   landscape shot to a letterbox band, so it is taller than the 460px the
   card started at rather than shorter — the frame is what got adjusted, and
   the picture gets room to be one. */
.z-tourbody .z-gal-main { height: clamp(320px, 46vh, 500px); }

/* Not a link any more, so nothing should offer to enlarge it: no zoom
   cursor, and no hover push on the image. */
.z-tourbody .z-gal-main { cursor: default; }
.z-tourbody .z-gal-main:hover img { transform: none; }

@media (max-width: 780px) {
    .z-tourbody .z-gal-main { height: clamp(230px, 36vh, 340px); }
}

/* The calendar carries its own 26px below it, from the homepage where it
   stands alone. Inside a .z-block that already spaces the sections, that
   stacked with the block's 40px and left a gap half again as deep as the one
   above the card. The block owns the rhythm here. */
.z-tourbody .z-block > .z-cal:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Compact calendar — for the 804px column on the tour detail page

   Two months share 802px there, so a day cell is 47px wide against the ~85px
   it gets on the homepage. At that width the cells were 47x78 — far taller
   than wide — and the price line ("₹1,00,000") could not fit at all. The
   compact variant drops the price, tightens the height and shrinks the type
   so a cell reads square-ish again.
   -------------------------------------------------------------------------- */

.z-cal.is-compact .z-cal-cell { min-height: 54px; }
.z-cal.is-compact .z-cal-price { display: none; }
.z-cal.is-compact .z-cal-mon { font-size: 7.5px; letter-spacing: .08em; padding: 2px 0 1px; }
.z-cal.is-compact .z-cal-num { font-size: 13px; padding: 2px 0 0; }
.z-cal.is-compact .z-cal-cell.has-dep .z-cal-num { font-size: 15px; }
.z-cal.is-compact .z-cal-dow-mini { font-size: 7.5px; letter-spacing: .06em; padding-bottom: 3px; }
.z-cal.is-compact .z-cal-grid { gap: 4px; }
.z-cal.is-compact .z-cal-month { padding: 14px 14px 16px; }
.z-cal.is-compact .z-cal-month-name { font-size: 16px; padding-bottom: 9px; margin-bottom: 9px; }
.z-cal.is-compact .z-cal-dow { font-size: 9px; padding: 4px 0; letter-spacing: .04em; }
.z-cal.is-compact .z-cal-dot { width: 5px; height: 5px; top: 4px; right: 4px; }

/* Head: title left, month stepper right, on one line.

   Stacking all three parts made it 190px tall — nearly a third of the panel
   before a single date showed. The tour name goes entirely: on a tour page it
   repeats the hero heading and the Ex-city already in the meta line, so it was
   costing a row to say what the page had said twice. */
.z-cal.is-compact .z-cal-head {
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    text-align: left;
}
.z-cal.is-compact .z-cal-tour { display: none; }
.z-cal.is-compact .z-cal-title { justify-content: flex-start; }
.z-cal.is-compact .z-cal-title strong { font-size: 16px; }
.z-cal.is-compact .z-cal-title-icon { width: 32px; height: 38px; }
.z-cal.is-compact .z-cal-right { justify-self: end; }
.z-cal.is-compact .z-cal-range { font-size: 15px; min-width: 0; }
.z-cal.is-compact .z-cal-nav { width: 30px; height: 30px; }

/* Below 900px the second month is already hidden, so the cells get the full
   width back and the compact squeeze is no longer needed. */
@media (max-width: 900px) {
    .z-cal.is-compact .z-cal-cell { min-height: 62px; }
    .z-cal.is-compact .z-cal-price { display: block; }
}

/* The plain head stacks at 900px. The compact one holds its row further down
   — it carries no tour name, so two parts share the bar instead of three —
   but not this far. Its template is `1fr auto`, and the stepper's auto track
   takes the ~214px it needs before the title track gets anything: by 480px
   the title is down to 114px of text width, and "DEPARTURE CALENDAR" at 16px
   needs 185px. The heading then overflowed its own track and ran across the
   month arrows, which are drawn over it. Stack it here instead, the same way
   and for the same reason as the plain head. */
@media (max-width: 620px) {
    .z-cal.is-compact .z-cal-head {
        grid-template-columns: 1fr;
        gap: 10px;
        text-align: center;
    }
    .z-cal.is-compact .z-cal-title { justify-content: center; }
    .z-cal.is-compact .z-cal-right { justify-self: center; }
}

/* --------------------------------------------------------------------------
   Quick facts bar — under the hero, above the tabs

   The .pkg-fact-item strip from holidays/package.php: icon, small label,
   value. Wraps rather than scrolls, so nothing is hidden off the right edge
   on a narrow window.
   -------------------------------------------------------------------------- */

.z-facts {
    position: relative;
    background: var(--z-marble);
    background-image: var(--z-marble-tex);
    background-size: 300px 300px;
    border-bottom: 1px solid var(--z-line-gold);
    padding: 16px 0;
}
.z-facts-row {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 10px 26px;
}
.z-fact {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    flex: 0 1 auto;
    min-width: 0;
    padding-right: 26px;
    border-right: 1px solid var(--z-line);
}
.z-fact:last-child { border-right: 0; padding-right: 0; }
.z-fact-icon {
    flex: none;
    width: 34px; height: 40px;
    display: grid; place-items: center;
    color: var(--z-factc, var(--z-green));
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-radius: 50% 50% 5px 5px / 58% 58% 5px 5px;
}
/* Each fact takes its own hue from --z-factc, set per item in the markup and
   matching the header nav so the page reads as one set. Green remains the
   fallback: the muted --z-ink-3 this replaced sat near 2.6:1 at 10px
   uppercase, legible only if you already knew what it said. */
.z-fact h6 {
    color: var(--z-factc, var(--z-green));
    margin: 0 0 3px;
    font-family: var(--z-body);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .13em;
    text-transform: uppercase;
}
.z-fact p {
    margin: 0;
    font-size: 14.5px;
    font-weight: 500;
    color: var(--z-ink);
    line-height: 1.25;
    white-space: nowrap;
}


/* Inclusions as icon chips, one per included item. */
.z-fact-inc-row { display: flex; flex-wrap: wrap; gap: 5px; }
.z-fact-inc-chip {
    width: 27px; height: 27px;
    display: grid; place-items: center;
    border-radius: 6px;
    background: var(--z-green-soft);
    border: 1px solid color-mix(in srgb, var(--z-open) 26%, transparent);
    color: var(--z-open);
}

@media (max-width: 900px) {
    .z-fact { border-right: 0; padding-right: 0; }
    .z-facts-row { gap: 14px 22px; }
    .z-fact p { white-space: normal; }
}

/* A GRID ONCE THE ROW WRAPS, not a wrapping flex.

   .z-facts-row is a flex-wrap row and every .z-fact is content-width, so the
   moment it takes more than one line the columns stop lining up: on the tour
   page at 768 the six facts landed at left edges 16, 166, 347 and 499 on the
   first line and 16, 204 on the second, and on the hotel page the second
   column started at 300, 280, 300 and 235 down four lines. Nothing was wrong
   with any one item — they simply packed.

   Two equal columns fix every row at once, and both pages divide evenly into
   them: six facts on a tour, eight on a hotel. Desktop keeps the flex row,
   where all of them fit on one line with the dividers between and there is
   nothing to align.

   minmax(0, 1fr), not 1fr: a grid item's default min-width is auto, so a long
   hotel name would push its column wider than its share and put the
   raggedness straight back.

   NOT .is-about. That variant — about, terms, privacy and cancellation — is a
   different set of facts ending in a Destinations cell whose chip row will not
   shrink below its own content. Given a fixed half-width track it overflowed
   the page by 44px at 390 rather than wrapping, which is exactly what a
   wrapping flex row is for. Those four pages keep it. */
@media (max-width: 1080px) {
    .z-facts:not(.is-about) .z-facts-row {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: start;
    }
}


/* Traveller Details: two columns, labels on the first row and counts beneath,
   with the child ages beside the count. A rule between the columns stands in
   for the pipe, so the two read as a pair rather than a list. */
.z-fact-pax-grid {
    display: grid;
    grid-template-columns: auto auto;
    align-items: baseline;
    gap: 2px 0;
}
.z-fact-pax-grid .k {
    font-size: 11px;
    color: var(--z-ink-3);
    padding: 0 12px;
}
.z-fact-pax-grid .v {
    font-size: 15px;
    font-weight: 500;
    color: var(--z-ink);
    font-variant-numeric: tabular-nums;
    padding: 0 12px;
    white-space: nowrap;
}
.z-fact-pax-grid .k:first-child,
.z-fact-pax-grid .v:nth-of-type(1) { padding-left: 0; }
/* The divider sits on the second column so it runs between the two. */
.z-fact-pax-grid .k:nth-child(2),
.z-fact-pax-grid .v:nth-of-type(2) { border-left: 1px solid var(--z-line); }
.z-fact-pax-grid .v small {
    font-size: 11.5px;
    font-weight: 400;
    color: var(--z-gold-deep);
}

/* Traveller sub-labels follow the section heading, one step lighter so the
   hierarchy still reads: heading > label > value. */
.z-fact-pax-grid .k { color: var(--z-green-3); font-weight: 500; }

/* --------------------------------------------------------------------------
   VISA CARDS  (zaereen/visas.php)

   The card itself is the shared .z-card from the tour listing — same arch,
   same body, same actions — so the two listings stay one design. Only the
   country flag is new: it sits opposite the type badge, which already owns
   the top-left corner.
   -------------------------------------------------------------------------- */
.z-visa-flag {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 2;
    display: block;
    width: 38px;
    height: 27px;
    border-radius: 4px;
    overflow: hidden;
    /* Flags carry their own colours, several of them near-white. The ring and
       shadow keep a white flag from dissolving into a pale photograph. */
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .75), 0 2px 8px rgba(0, 0, 0, .32);
}
.z-visa-flag img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ==========================================================================
   DEPARTURE LIST — card view and line view
   ==========================================================================
   Both views render from ONE markup (zaereen/includes/ui/departure_card.php).
   Card view is the base, so zaereen/departures.php — which has no view switch
   and therefore no data-view attribute — gets the cards without opting in.
   Line view is the [data-view="line"] override.

   The trick that makes line view a real table: .z-dep-main and .z-dep-side
   become display:contents there, which promotes their children to grid items
   of .z-dep. The row then has nine cells that line up under the headings in
   departure_head.php. Both must carry the SAME grid template.
   -------------------------------------------------------------------------- */
.z-deplist { display: grid; gap: 14px; counter-reset: zdep; }
.z-dep { counter-increment: zdep; }

/* Row number, drawn from the counter so filtered-out rows leave no gaps:
   a display:none element does not increment a CSS counter. */
.z-dep-sn { display: none; }
.z-dep-sn::before { content: counter(zdep) "."; }

.z-dep-acts { display: flex; gap: 8px; align-items: center; }

/* WhatsApp enquiry, in that brand's own green rather than Zaereen's. */
.z-dep-wa {
    flex: none;
    width: 32px;
    height: 32px;
    display: inline-grid;
    place-items: center;
    border-radius: 8px;
    color: #fff;
    background: #25d366;
    border: 1px solid #1fb855;
    transition: filter .18s ease;
}
.z-dep-wa:hover { filter: brightness(.92); }

/* --- card view (base) ---------------------------------------------------
   Title on its own line, the facts wrapping beneath it. The facts are
   siblings of the title rather than a list, because line view needs each one
   promotable to its own column. */
.z-dep-main { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; min-width: 0; }
.z-dep-tour { flex: 0 0 100%; margin: 0; }
.z-dep-main > span {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 13.5px;
    color: var(--z-ink-2);
    min-width: 0;
}
.z-dep-main > span svg { color: var(--z-gold-deep); flex: none; }

/* The figure follows the side column: right against the card edge while the
   column is a right-aligned stack on desktop, left once the 780px block lays
   the column out as a full-width row. It used to carry `text-align:right` as
   an inline style in departure_card.php, which no breakpoint could reach —
   so on a phone the price sat right while its own "Starting from" and
   "/ person" lines sat left of it. */
.z-dep-side .z-price { text-align: inherit; }

/* --- card view on a phone -----------------------------------------------
   From 780px down .z-dep-side is a full-width row: price at one end, the
   three buttons at the other. The buttons need 267px between them and the
   figure another ~150px, so from about 470px the row cannot hold both and
   "Enquiry" runs off the right of the card. Nothing on that path clips, so
   it ran off the page as well — the document ended up 417px wide whatever
   the phone, and the browser shrank the whole layout to fit it.

   The row wraps instead. The price keeps the first line and the buttons take
   the second, sharing it in equal thirds so the three read as one control
   rather than a row that happens to fit.

   Scoped away from line view, which flattens .z-dep-acts with
   display:contents and makes each button a column of the table. The view
   switch in departure_strip.php only turns line view on from 1180px up, so
   this cannot collide with it today; the guard keeps that true if the
   threshold ever moves. */
@media (max-width: 560px) {
    .z-deplist:not([data-view="line"]) .z-dep-side { flex-wrap: wrap; row-gap: 12px; }
    .z-deplist:not([data-view="line"]) .z-dep-acts { flex: 1 0 100%; }
    .z-deplist:not([data-view="line"]) .z-dep-act  { flex: 1 1 0; min-width: 0; }
    .z-deplist:not([data-view="line"]) .z-dep-act .z-btn { width: 100%; padding: 13px 10px; }
}

/* --- line view ----------------------------------------------------------
   One bordered slab of hairline-separated rows, so a long list scans as a
   table rather than a stack of floating cards. */
.z-dep-head { display: none; }

.z-deplist[data-view="line"] {
    gap: 0;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    overflow: hidden;
    box-shadow: var(--z-shadow-sm);
}

/* The one template both the headings and every row are laid out on. */
.z-deplist[data-view="line"] .z-dep-head,
.z-deplist[data-view="line"] .z-dep {
    display: grid;
    grid-template-columns:
        36px                  /*  1 S/N           */
        minmax(120px, 1.3fr)  /*  2 Destination   */
        minmax(88px, 1fr)     /*  3 Airline       */
        minmax(88px, 1fr)     /*  4 Sector        */
        104px                 /*  5 Departure     */
        72px                  /*  6 Duration      */
        100px                 /*  7 Seat Status   */
        /* Sized for "₹1,00,000/-" at 15px bold plus the cell's padding. At
           98px the figure was clipping — the column people actually read. */
        118px                 /*  8 Starting From */
        /* One column per action. Each is the button plus the cell's own
           10px padding either side; too narrow and a button wraps, which
           doubles the height of every row in the table. */
        84px                  /*  9 PDF           */
        124px                 /* 10 Book Now      */
        108px;                /* 11 Enquiry       */
    /* No gap: the column rules ARE the separation, and a gap would leave the
       vertical lines floating away from the cells they divide. Cells stretch
       so each rule runs the full height of the row. */
    gap: 0;
    align-items: stretch;
}
/* The Book track is a fixed width, NOT auto. An auto track sizes to its own
   content, and the header's short "BOOK" is far narrower than a row's three
   buttons — so the two grids resolved different free space and every fr
   column drifted out of line with its heading. */

.z-deplist[data-view="line"] .z-dep-head {
    padding: 0;
    /* A shallow gradient rather than the flat cream: it gives the band a top
       edge without a second border line, and seats the headings on it. */
    background: linear-gradient(180deg, var(--z-cream) 0%, var(--z-cream-deep) 100%);
    /* 2px, and the gold at full strength. This is the one rule in the table
       that separates chrome from data, and at 1px it was the same weight as
       the rules between the rows. */
    border-bottom: 2px solid var(--z-gold);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--z-green);
    /* Two-word headings wrap to a second line while their neighbours do not,
       which left the band's height decided by whichever heading happened to be
       longest and the single-line ones floating in it. A floor plus centring
       gives every heading the same box to sit in the middle of. */
    min-height: 46px;
}

.z-deplist[data-view="line"] .z-dep {
    padding: 0;
    border: 0;
    border-bottom: 1px solid var(--z-line);
    border-radius: 0;
    box-shadow: none;
}

/* --- the gridlines ------------------------------------------------------
   Every cell, in the heading band and in each row, carries its own padding
   and a rule down its right edge. Listed explicitly rather than with `> *`
   because .z-dep-main and .z-dep-side are display:contents here — the real
   cells are their children, which no child selector on .z-dep can reach. */
.z-deplist[data-view="line"] .z-dep-head > span,
.z-deplist[data-view="line"] .z-dep-sn,
.z-deplist[data-view="line"] .z-dep-date,
.z-deplist[data-view="line"] .z-dep-dest,
.z-deplist[data-view="line"] .z-dep-air,
.z-deplist[data-view="line"] .z-dep-from,
.z-deplist[data-view="line"] .z-dep-days,
.z-deplist[data-view="line"] .z-dep-seats,
.z-deplist[data-view="line"] .z-dep-side .z-price,
.z-deplist[data-view="line"] .z-dep-act {
    display: flex;
    align-items: center;
    /* Every column centred, headings included — the table is read down its
       columns, and a centred column keeps its heading over its values whatever
       the values happen to be. */
    justify-content: center;
    text-align: center;
    min-width: 0;
    padding: 9px 10px;
    border-right: 1px solid var(--z-line);
}
/* The row's last cell closes on the table's own border. */
.z-deplist[data-view="line"] .z-dep-head > span:last-child,
.z-deplist[data-view="line"] .z-dep-act { border-right: 0; }

/* The buttons stay on one line. Wrapping them is what made every row twice
   the height it needed. */
.z-deplist[data-view="line"] .z-dep-act { flex-wrap: nowrap; }

/* The tour title is an h3, and `.zaereen h3` (0,1,1) outranks `.z-dep-tour`
   (0,1,0), so the margin reset in the card rule never reached it — leaving a
   6px gap that stopped its column rule short of the row border. Scoping to
   the list wins the cascade without an !important. */
.z-deplist .z-dep-tour { margin: 0; }

/* The heading band's rules are the stronger gold, matching its bottom edge. */
.z-deplist[data-view="line"] .z-dep-head > span { border-right-color: var(--z-line-gold); }

/* The price used to hang right; every column is centred now, so the rule that
   pushed it (and its heading, by column index) to the edge is gone. */
.z-deplist[data-view="line"] .z-dep:last-child { border-bottom: 0; }
/* No lift: rows that rise off a joined slab tear it apart. A wash and a gold
   edge down the leading side instead — the edge is what tells you WHICH row
   you are on when the pointer is out at the Enquiry button, eleven columns
   away from the destination you were reading.

   box-shadow rather than a border or an ::after: a border would move every
   cell in the row by a pixel on hover, and an inset shadow paints inside the
   row's own box without touching the grid. */
.z-deplist[data-view="line"] .z-dep {
    transition: background .16s ease, box-shadow .16s ease;
}
.z-deplist[data-view="line"] .z-dep:hover {
    transform: none;
    background: var(--z-gold-wash);
    box-shadow: inset 3px 0 0 var(--z-gold);
}

/* Promote the two wrappers' children to cells of the row. */
.z-deplist[data-view="line"] .z-dep-main,
.z-deplist[data-view="line"] .z-dep-side { display: contents; }

/* display is set by the cell rule above; repeating it here as `block` would
   undo the flex box the column rule needs. */
.z-deplist[data-view="line"] .z-dep-sn {
    font-family: var(--z-display);
    font-size: 14px;
    font-weight: 600;
    color: var(--z-gold-deep);
    font-variant-numeric: tabular-nums;
}

/* --- column order -------------------------------------------------------
   The markup is in the order card view needs (date plaque first, then the
   title and its facts, then price and buttons). The table wants a different
   sequence, so line view reorders the grid items rather than the HTML — that
   way one markup keeps serving both views.

   These MUST match the heading order in departure_head.php. */
.z-deplist[data-view="line"] .z-dep-sn     { order: 1; }
.z-deplist[data-view="line"] .z-dep-dest   { order: 2; }
.z-deplist[data-view="line"] .z-dep-air    { order: 3; }
.z-deplist[data-view="line"] .z-dep-from   { order: 4; }
.z-deplist[data-view="line"] .z-dep-date   { order: 5; }
.z-deplist[data-view="line"] .z-dep-days   { order: 6; }
.z-deplist[data-view="line"] .z-dep-seats  { order: 7; }
.z-deplist[data-view="line"] .z-dep-side .z-price { order: 8; }
.z-deplist[data-view="line"] .z-dep-act-pdf  { order: 9; }
.z-deplist[data-view="line"] .z-dep-act-book { order: 10; }
.z-deplist[data-view="line"] .z-dep-act-enq  { order: 11; }

/* The table is headed by Destination, so the tour title steps aside — and it
   MUST be hidden, not merely unstyled: an extra visible child is a tenth grid
   item in a nine-track row, which pushes every cell out from under its
   heading. Its name is not lost; it is the tooltip on the destination cell,
   and the Book column still links to that specific tour. */
.z-deplist[data-view="line"] .z-dep-tour { display: none; }

/* --- long form vs short form --------------------------------------------
   Card view takes the roomy wording, the table the compact one. */
.z-dep-from .s,
.z-dep-days .s,
.z-dep-seats .s { display: none; }

.z-deplist[data-view="line"] .z-dep-from .t,
.z-deplist[data-view="line"] .z-dep-days .t,
.z-deplist[data-view="line"] .z-dep-seats .t { display: none; }
.z-deplist[data-view="line"] .z-dep-from .s,
.z-deplist[data-view="line"] .z-dep-days .s { display: block; }
.z-deplist[data-view="line"] .z-dep-seats .s { display: inline-block; }

/* The plaque's three lines give way to one full date with the year. */
.z-dep-date .full { display: none; }
.z-deplist[data-view="line"] .z-dep-date .d,
.z-deplist[data-view="line"] .z-dep-date .m { display: none; }
.z-deplist[data-view="line"] .z-dep-date .full {
    display: block;
    font-size: 13px;
    white-space: nowrap;
    color: var(--z-green);
}

/* The arched plaque flattens to a plain date. The inset box-shadow that draws
   its hairline frame has to go too, or the date keeps a stray box around it
   once the green ground is gone.

   Note what is NOT reset here: padding. This rule sits after the cell rule
   above, so a `padding: 0` would strip the Departure cell's padding and drop
   its column rule straight onto the text. */
.z-deplist[data-view="line"] .z-dep-date {
    color: var(--z-green);
    background: none;
    background-image: none;
    border-radius: 0;
    box-shadow: none;
}
.z-deplist[data-view="line"] .z-dep-date .y { display: none; }

/* Every cell is one line and clips rather than growing the row. The clipping
   lives on .t, not on the cell: the cell is a flex box so its column rule can
   stretch, and text-overflow has no effect on a flex container. */
.z-deplist[data-view="line"] .z-dep-dest .t,
.z-deplist[data-view="line"] .z-dep-air .t,
.z-deplist[data-view="line"] .z-dep-from .s,
.z-deplist[data-view="line"] .z-dep-days .s {
    display: block;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* --- THE HIERARCHY, now that the colour has come out of the chrome --------
   With eleven headings in one colour and no column washes, the row itself has
   to say which of its facts matter. Three levels, and only three:

     Destination and Starting From   the two things a departure is chosen on
     Departure date                  the third, and the one the strip filters
     Airline, Sector, Duration       supporting detail, read after the choice

   Before this every value in the row was the same size and nearly the same
   colour, so a reader scanning for a price had to read the whole line to find
   one. --------------------------------------------------------------------- */

/* Destination is the column the eye lands on: the row's identity, and the
   only cell set in the display face. */
.z-deplist[data-view="line"] .z-dep-dest {
    font-family: var(--z-display);
    font-size: 16px;
    font-weight: 700;
    color: var(--z-green);
    letter-spacing: .01em;
}
/* The date is a fact people match against the strip above the table, so it
   holds its weight — but a step below the destination. Tabular figures so a
   column of dates lines up digit under digit. */
.z-deplist[data-view="line"] .z-dep-date .full {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
/* The icons earn their space in a card; in a headed column they only crowd
   the value the heading already names. */
.z-deplist[data-view="line"] .z-dep-dest svg,
.z-deplist[data-view="line"] .z-dep-air svg,
.z-deplist[data-view="line"] .z-dep-from svg,
.z-deplist[data-view="line"] .z-dep-days svg { display: none; }
/* The supporting three. A step down in size AND in ink, so they read as the
   detail under the choice rather than as three more competing values. */
.z-deplist[data-view="line"] .z-dep-air,
.z-deplist[data-view="line"] .z-dep-from,
.z-deplist[data-view="line"] .z-dep-days {
    font-size: 13px;
    color: var(--z-ink-2);
}

/* Scoped to .s, not to every .z-badge in the cell. Targeting .z-badge matched
   the long-form badge too, and at equal specificity this rule sits after the
   one hiding it — so both wordings rendered, reading
   "48 SEATS AVAILABLE AVAILABLE". */
.z-deplist[data-view="line"] .z-dep-seats .z-badge.s { display: inline-block; }

/* --- WHAT REPLACED THE COLUMN TINTS AND THE SOLID STATUS SLAB ------------
   The table used to carry three background washes at once: a light green on
   Airline, a stronger one on Departure, and a full-bleed block of --z-open
   down Seat Status. Each was defensible alone. Together, on eleven columns
   already headed in eleven different colours, they read as decoration rather
   than structure — and the status block was the worst of it: consecutive rows
   share a status, so the fills merged into one unbroken bar with no row
   division in it, and the heaviest object in the table was not the price or
   the destination but a column of repeated words.

   What replaces them is quieter and does more work: no vertical washes, a
   faint zebra so the eye tracks along a row, and the status as a pill with a
   dot. See the zebra and pill rules below.
   -------------------------------------------------------------------------- */

/* --- Seat Status as a pill ----------------------------------------------
   A dot plus a word on a soft tint of its own hue. It separates one row from
   the next where the old slab welded them together, it carries the colour at
   the size the eye needs it rather than a hundred square pixels of it, and —
   the reason it had to change anyway — a tint can hold DARK text of the same
   family, so a fourth status could be added without another white-on-colour
   contrast check.
   -------------------------------------------------------------------------- */
.z-deplist[data-view="line"] .z-dep-seats .z-badge.s {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 5px 11px;
    border-radius: 100px;
    border: 1px solid transparent;
    background: var(--z-open-bg);
    color: var(--z-open);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .07em;
    white-space: nowrap;
}
.z-deplist[data-view="line"] .z-dep-seats .z-badge.s::before {
    content: "";
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

/* ON REQUEST, which is not the same claim as AVAILABLE and no longer wears
   its colour — see the note in zaereen/includes/ui/departure_card.php. The
   selector is more specific than the .z-badge-open rule above it, so it wins
   without depending on source order. */
.z-deplist[data-view="line"] .z-dep-seats .z-badge.s.is-request {
    background: var(--z-few-bg);
    color: var(--z-few);
}
.z-deplist[data-view="line"] .z-dep-seats .z-badge-few.s {
    background: var(--z-few-bg);
    color: var(--z-few);
}
.z-deplist[data-view="line"] .z-dep-seats .z-badge-sold.s {
    background: #f6e4e0;
    color: var(--z-sold);
}

/* NO ZEBRA STRIPING, though it is the obvious thing to reach for once the
   vertical washes are gone, and it was tried here first.

   :nth-child() counts every sibling, including the ones the departure strip
   sets to display:none when a date tile is picked — so the stripes survive
   the filter while the rows do not, and the table comes back striped 1, 3, 4,
   6 with no pattern in it. It is the same trap that made the S/N column a CSS
   counter instead of a PHP index (see departure_card.php), and a counter
   cannot select a row, only print into it.

   What carries the eye instead is the row rule, the hover wash below, and the
   fact that every column is centred under its heading. */

/* Price loses its caption: the column heading says "Starting From". Padding
   and alignment come from the cell rule above — setting them again here would
   strip the cell's padding and collapse its column rule onto the text.

   It is the figure people came to the table for, so it carries more weight
   than the cells around it and never wraps: the track is sized for
   "₹1,00,000/-" in full, and nowrap makes a clipped column obvious in testing
   instead of quietly breaking the amount across two lines. */
.z-deplist[data-view="line"] .z-dep-side .z-price { margin: 0; white-space: nowrap; }
.z-deplist[data-view="line"] .z-price b {
    /* THE BODY SANS, not the display serif it inherits from .z-price. At 27px
       on a card Cormorant is the right face for a figure; at 16px in a table
       row it is not, and 700 there is only its heaviest cut — so the price,
       the one value the whole table is scanned for, rendered lighter than the
       destination beside it and lighter than its own column heading. Jost 700
       is a real weight. (Same trap as the review-card name; see the note on
       .z-story-body h3.)

       Deep gold, which is what this site uses for money everywhere else, and
       a step up in size from the supporting columns. */
    font-family: var(--z-body);
    font-size: 15.5px;
    font-weight: 700;
    color: var(--z-gold-deep);
    letter-spacing: .01em;
    font-variant-numeric: tabular-nums;
}
/* "/-" is the convention, not part of the number. A step down in size and
   weight so the amount reads first. */
.z-deplist[data-view="line"] .z-price .sfx {
    font-size: 12px;
    font-weight: 600;
    opacity: .7;
}

/* --- ONE PRIMARY ACTION PER ROW -----------------------------------------
   The row carried three buttons, two of them solid — a green Book Now beside
   a gold Enquiry, with an outlined PDF before them. Two filled buttons of
   equal weight in one row is two primary actions, which is none: the eye has
   nowhere to go first, and across seven rows it is forty-two buttons all
   asking equally loudly.

   Book Now stays solid. Enquiry drops to the outline it already has a style
   for, and PDF goes quieter still — it is a download, not a decision.
   Nothing moves and nothing is removed; only the weights change.
   -------------------------------------------------------------------------- */
.z-deplist[data-view="line"] .z-dep-act-enq .z-btn {
    background: none;
    color: var(--z-gold-deep);
    border: 1px solid var(--z-gold);
    box-shadow: none;
}
.z-deplist[data-view="line"] .z-dep-act-enq .z-btn:hover {
    background: var(--z-gold-wash);
    border-color: var(--z-gold-deep);
    color: var(--z-green);
}
.z-deplist[data-view="line"] .z-dep-act-pdf .z-btn {
    border-color: var(--z-line);
    color: var(--z-ink-2);
    font-weight: 600;
}
.z-deplist[data-view="line"] .z-dep-act-pdf .z-btn:hover {
    border-color: var(--z-gold);
    color: var(--z-green);
    background: var(--z-gold-wash);
}
/* The "/-" is part of the figure in a table, hidden on a card. */
.z-price .sfx { display: none; }
.z-deplist[data-view="line"] .z-price .sfx { display: inline; }
.z-deplist[data-view="line"] .z-price small,
.z-deplist[data-view="line"] .z-price span { display: none; }
/* (the 14px rule that stood here is superseded by the weightier one above) */

/* --- narrow screens -----------------------------------------------------
   The nine columns need 1070px before the shell's padding, so the strip's
   script forces card view below 1180px and the control that picks line view
   goes with it. Keep this breakpoint and LINE_MIN in departure_strip.php in
   step, or the switch offers a view the table cannot fit into. */


/* ==========================================================================
   TRAVELLER REVIEWS — story cards
   ==========================================================================
   Follows Traveler Stories on holidays/destination_detail.php: the
   travellers' own photograph, who they are, four figures, then their words,
   with the rating and a View button on a footer rail. Same arrangement, built
   from Zaereen's tokens instead of that page's navy and orange.
   -------------------------------------------------------------------------- */
.z-storywrap { position: relative; }

.z-stories {
    display: flex;
    gap: 20px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* overflow-x:auto computes overflow-y to auto as well, so the cards' hover
       lift and their shadow would both be clipped at the rail's edges. The
       padding is the room they move into. */
    padding: 6px 2px 12px;
}
.z-stories::-webkit-scrollbar { display: none; }

/* Arrows: centred on the photograph rather than the whole card, which puts
   them where the eye already is and clear of the footer buttons. */
.z-story-nav {
    position: absolute;
    top: 112px;
    z-index: 3;
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    padding: 0;
    cursor: pointer;
    color: var(--z-green);
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: 50%;
    box-shadow: var(--z-shadow-sm);
    transition: background-color .18s ease, color .18s ease, border-color .18s ease, opacity .18s ease;
}
.z-story-nav.is-prev { left: -14px; }
.z-story-nav.is-next { right: -14px; }
.z-story-nav.is-prev svg { transform: rotate(90deg); }
.z-story-nav.is-next svg { transform: rotate(-90deg); }
.z-story-nav:hover:not(:disabled) { background: var(--z-green); color: var(--z-gold-light); border-color: var(--z-green); }
.z-story-nav:focus-visible { outline: 2px solid var(--z-gold); outline-offset: 2px; }
.z-story-nav:disabled { opacity: .3; cursor: default; box-shadow: none; }
/* Nothing to scroll: the arrows are not just disabled, they are gone. */
.z-storywrap.is-static .z-story-nav { display: none; }

.z-story {
    flex: 0 0 300px;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    overflow: hidden;
    box-shadow: var(--z-shadow-sm);
    transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.z-story:hover { border-color: var(--z-gold-light); box-shadow: var(--z-shadow); transform: translateY(-2px); }

/* --- photograph --------------------------------------------------------- */
.z-story-pic {
    position: relative;
    height: 200px;
    border-bottom: 2px solid var(--z-gold);
    background: var(--z-cream-deep);
}
.z-story-pic img { width: 100%; height: 100%; object-fit: cover; display: block; }

.z-story-flag,
.z-story-rate {
    position: absolute;
    top: 10px;
    z-index: 2;
    border-radius: 6px;
    /* The photographs are group shots in daylight; a plain badge would sit on
       whatever happens to be behind it, so both carry their own dark ground. */
    background: rgba(18, 51, 42, .72);
    backdrop-filter: blur(3px);
}
.z-story-flag { left: 10px; padding: 3px; line-height: 0; }
.z-story-flag img { display: block; border-radius: 3px; width: 30px; height: 20px; object-fit: cover; }
.z-story-rate { right: 10px; padding: 5px 7px; line-height: 0; color: var(--z-gold-light); }

/* --- body --------------------------------------------------------------- */
.z-story-body { padding: 16px 16px 4px; display: flex; flex-direction: column; flex: 1 1 auto; }

.z-story-body h3 {
    /* THE BODY SANS, NOT THE DISPLAY SERIF, and the reason is the same one
       written against the product-card title below: Cormorant Garamond is
       loaded at 400-700, so 700 is merely its heaviest cut — a light-stroked
       serif that still reads thin beside anything else on the card. The
       traveller's name was set in it at 700 and came out lighter than the
       stat values underneath it, which is upside down: the name is the
       heading of the card and "Karbala" in the row below is a caption.

       Jost 700 is a real weight, so the name now reads as bold as a package
       name on the holidays cards. Everything else about the treatment stays —
       the gold, the uppercase, the centring, the rule beneath — because those
       are what tell a review card from a product card at a glance. */
    font-family: var(--z-body);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    text-align: center;
    color: var(--z-gold-deep);
    margin: 0 0 11px;
    padding-bottom: 11px;
    border-bottom: 1px solid var(--z-line);
    /* Two lines, clamped AND reserved: clamping alone stops a long name
       running away, but a one-line name still sat higher than a two-line one
       beside it and knocked every row below out of alignment across the rail. */
    line-height: 1.3;
    min-height: 2.6em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.z-story-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 6px;
    margin-bottom: 13px;
}
.z-story-stats > div { text-align: center; min-width: 0; }
.z-story-stats .v {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    color: var(--z-green);
    min-width: 0;
}
.z-story-stats .v svg { color: var(--z-gold-deep); flex: 0 0 auto; }
.z-story-stats .v b {
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}
.z-story-stats small {
    display: block;
    margin-top: 2px;
    font-size: 8.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--z-ink-3);
}

.z-story-body blockquote {
    display: flex;
    gap: 7px;
    margin: 0 0 14px;
    font-size: 13.5px;
    line-height: 1.45;
    color: var(--z-ink-2);
}
.z-story-q { flex: 0 0 auto; margin-top: 2px; color: var(--z-gold); }
.z-story-body blockquote span {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* --- footer ------------------------------------------------------------- */
.z-story-foot {
    margin-top: auto;
    padding: 12px 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border-top: 1px solid var(--z-line-gold);
    background: var(--z-cream);
}
.z-story-foot-rate small,
.z-story-foot-price small {
    display: block;
    font-size: 8.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--z-ink-3);
    margin-bottom: 3px;
}
.z-story-foot-rate .z-stars { color: var(--z-gold); }

/* Review with no photograph of its own and no tour picture behind it. */
.z-story-initials {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    font-family: var(--z-display);
    font-size: 44px;
    font-weight: 600;
    letter-spacing: .06em;
    color: var(--z-gold-light);
    background: var(--z-green);
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
}

/* ==========================================================================
   ENQUIRY POPUP — WhatsApp code step
   ==========================================================================
   Shown once a code has been sent, between the form fields and the footer.
   Reuses .z-otp-box from the sign-in gate so the two code inputs behave and
   look the same wherever a visitor meets one.
   -------------------------------------------------------------------------- */
.z-eotp {
    margin: 4px 0 0;
    padding: 14px 16px;
    border-top: 1px solid var(--z-line-gold);
    background: var(--z-cream);
}
.z-eotp-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
    color: var(--z-green);
}
.z-eotp-head b { display: block; font-size: 14px; }
.z-eotp-head span {
    display: block;
    font-size: 12.5px;
    color: var(--z-ink-3);
    font-variant-numeric: tabular-nums;
}
.z-eotp .z-otp-boxes { display: flex; gap: 8px; flex-wrap: wrap; }
.z-eotp-msg {
    margin: 9px 0 10px;
    font-size: 12.5px;
    color: var(--z-ink-2);
    min-height: 1em;
}
/* --z-sold rather than a raw red, so the one failure colour is used
   everywhere: 8.30:1 on the cream ground. */
.z-eotp-msg.is-bad { color: var(--z-sold); font-weight: 600; }


/* --- strip filter labels, in colour --------------------------------------
   Each takes the colour its own idea already carries elsewhere in the design,
   rather than three arbitrary hues: Destination the red of the Destination
   tile on the facts bar, Departure City the green of the "From" tile, and
   View the violet the account rail uses. All three measure above 7:1 on the
   marble ground, which matters at 9.5px.
   -------------------------------------------------------------------------- */
.z-strip-dest label,
.z-strip-city label { font-weight: 700; }
.z-strip-dest label { color: #8a3024; }
.z-strip-city label { color: #1f6047; }

/* Page-head spacing. The lockup that used to sit on the right of this band
   has been removed, and with it the right-hand padding that kept the
   heading clear of it — the text now has the full width again. */
.z-pagehead h1 { margin: 14px 0 10px; }
.z-pagehead p  { margin: 0; max-width: 62ch; }

/* --- three action columns ------------------------------------------------
   Card view keeps them as one button row; line view flattens the wrapper so
   each becomes its own headed column.
   -------------------------------------------------------------------------- */
.z-deplist[data-view="line"] .z-dep-acts { display: contents; }
.z-dep-act { display: inline-flex; align-items: center; }
.z-dep-act .z-btn { white-space: nowrap; }
.z-dep-act-off { color: var(--z-ink-3); }

/* Headings carry the same mark the fact does on a card. */
.z-dep-head > span { gap: 5px; }

/* --- ONE COLOUR ACROSS THE HEADING BAND ----------------------------------
   This was eleven colours, one per heading, each borrowed from wherever that
   idea appears elsewhere in the design — Destination the red of the
   Destination tile, Sector the green of the From tile, and so on. The
   reasoning was sound and the contrast was measured; the result was not. At
   9.5px, in one 30px band, eleven hues read as confetti rather than as a
   system: nothing in it is a code the reader can learn, because no two
   columns share a colour and none of them recurs in the rows below. A table
   is trusted when its chrome is quiet and its DATA carries the colour — which
   is exactly where the colour now is, in the status pills.

   So: one deep green, and the weight and tracking do the separating. The
   icons stay, because they are the same marks the cards use and a reader
   moving between the two views meets the same sign for the same thing — but
   at 55% they support the label instead of competing with it.
   -------------------------------------------------------------------------- */
.z-dep-head > span { color: var(--z-green); }
.z-dep-head > span svg { flex: none; opacity: .55; }

/* The S/N icon is `menu` — three stacked bars, which at this size reads as a
   control the reader can press rather than a label. The column is two
   characters wide and needs no mark at all. */
.z-dep-head > span:nth-child(1) svg { display: none; }

/* The mobile drawer still heads itself with the wordmark alone — it is a
   narrow panel, and the square lockup would eat the top of it. This is the
   only remaining use of .z-brand-word, kept for that one place. */
.z-brand-word {
    height: 19px;
    width: auto;
    display: block;
}

/* ==========================================================================
   PAGE HEAD — homepage variant
   ==========================================================================
   The listing pages use this band as a section label, so they keep it tight.
   The homepage uses it as the top of the site, so it gets more air above and
   below, a larger heading, and the second half of that heading in gold.

   Scoped with .is-home so tours / departures / visas are untouched.
   -------------------------------------------------------------------------- */
/* Equal air above and below the heading — measured against the SEARCH BAR,
   not the crest band, because the bar covers the band and the bar is what
   the eye reads as the bottom edge.

   The bar is centred on the band, so its top half (107px) hangs inside this
   bottom padding: the visible gap under the heading is padBottom - 115, not
   padBottom. Matched padding therefore looks lopsided — at 140/140 it was
   140 above and 25 below.

   The offset measures 100px, not the 107 half-height would suggest: the
   heading's line box sits taller than its glyphs. 100/200 gives 100 on both
   sides — checked, not derived. */
.z-pagehead.is-home { padding: 96px 0 200px; }

/* Centred, and the heading on one line. The 20ch measure and the block
   accent below were what split it across two. */
.z-pagehead.is-home .z-shell { text-align: center; }

.z-pagehead.is-home h1 {
    font-size: clamp(28px, 3.6vw, 46px);
    line-height: 1.2;
    margin: 0;   /* the 18px was spacing to a standfirst that is gone */
}

/* Three tones across one line: cream for the setup, gold for the subject,
   a warm gradient for the turn. Inline, so the heading stays on one line.
   Every tone clears AA on this ground by a wide margin — cream 13.78,
   gold-light 9.19, and the gradient runs 11.83 -> 8.04. */
.z-pagehead.is-home h1 .z-accent-2 {
    display: inline;
    color: var(--z-gold-light);
}
.z-pagehead.is-home h1 .z-accent {
    display: inline;
    /* The fallback, and the only colour anywhere background-clip:text is not
       honoured — transparent text with no clip support is invisible text. */
    color: #f5c96b;
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    .z-pagehead.is-home h1 .z-accent {
        background: linear-gradient(100deg, #f7e3b0 0%, #f0b429 55%, #e3c886 100%);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
    }
}

.z-pagehead.is-home p {
    font-size: 16.5px;
    line-height: 1.65;
    max-width: 62ch;
    margin-inline: auto;
    /* Warmer and brighter than the band's default body colour, so the lede
       reads as part of the headline rather than as small print under it. */
    color: rgba(251, 245, 230, .88);
}

/* On a phone the band should not push the search form off the first screen. */
@media (max-width: 700px) {
    .z-pagehead.is-home { padding: 56px 0 64px; }
}

/* ==========================================================================
   NAV ICONS — a tinted plate behind each mark
   ==========================================================================
   The icons were bare 1.6-weight strokes on cream: correct, but thin, and at
   20px they read as faint outlines rather than as part of the design. Each
   now sits on a soft plate of its own colour, which is what gives the row its
   weight without making the icons themselves heavier or larger.

   Applied to the svg directly — there is no wrapper element, and padding plus
   a background on an <svg> box is well supported.
   -------------------------------------------------------------------------- */
.z-nav a.z-nav-link svg,
.z-header-link > svg {
    box-sizing: content-box;
    /* 6px + a 1px border keeps the plate at the 34px it was before the border
       was added, so the bar's height does not move. */
    padding: 6px;
    border-radius: 11px;
    /* Deeper tint and a hairline of the same colour: a flat 13% wash read as
       a smudge behind the mark, where a defined edge reads as a chip. */
    background: color-mix(in srgb, var(--z-navc, #c19a3f) 20%, transparent);
    border: 1px solid color-mix(in srgb, var(--z-navc, #c19a3f) 30%, transparent);
    /* 2.0 against the 1.6 the icon set ships. The marks are read at 20px on a
       tinted ground, where the shipped weight goes faint. */
    stroke-width: 2;
    transition: background-color .18s ease, border-color .18s ease, transform .18s ease;
}

/* The plate deepens on hover and for the current page, so the row has a
   visible state rather than only a colour change in the label. */
.z-nav a.z-nav-link:hover svg,
.z-header-link:hover > svg {
    background: color-mix(in srgb, var(--z-navc, #c19a3f) 32%, transparent);
    border-color: color-mix(in srgb, var(--z-navc, #c19a3f) 48%, transparent);
    transform: translateY(-1px);
}
.z-nav a.z-nav-link[aria-current="page"] svg,
.z-header-link[aria-current="page"] > svg {
    background: color-mix(in srgb, var(--z-navc, #c19a3f) 34%, transparent);
    border-color: color-mix(in srgb, var(--z-navc, #c19a3f) 52%, transparent);
}

/* The label takes the item's own colour on hover and for the current page —
   the mark already carries it, and a bold line in the same colour is what
   makes the pair read as one control rather than an icon with a caption. */
.z-nav a.z-nav-link:hover .z-nav-label { color: var(--z-navc, var(--z-gold-deep)); }

/* The label sits closer now that the mark has a body of its own. */
.z-nav a.z-nav-link { gap: 4px; padding: 5px 10px; }

/* The plate already carries the hover; the block tint behind the whole link
   on top of it was two backgrounds doing one job. */
.z-nav a.z-nav-link:hover { background: transparent; }

/* Dates open on a group flight, shown on the card so the answer does not need
   another page load. */
.z-flight-dates {
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 2px;
}
.z-flight-dates li {
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 12px;
    color: var(--z-green);
    background: var(--z-cream-deep);
}

/* ==========================================================================
   VISA CARD — the three figures and the footer
   ==========================================================================
   Following the Oxford visa card: what the visa is, how long it lasts and
   what it costs, set out as a labelled row rather than buried in a meta list.
   Same shape as the review card's stats, so the two read as one system.
   -------------------------------------------------------------------------- */
.z-cardfacts {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px;
    margin: 2px 0 12px;
    padding: 11px 0;
    border-top: 1px solid var(--z-line);
    border-bottom: 1px solid var(--z-line);
}
.z-cardfacts > div { text-align: center; min-width: 0; }
.z-cardfacts .v {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    color: var(--z-green);
    min-width: 0;
}
.z-cardfacts .v svg { color: var(--z-gold-deep); flex: 0 0 auto; }
.z-cardfacts .v b {
    font-size: 12.5px;
    font-weight: 600;
    /* One line, clipped — a long visa type must not push the three cells out
       of step with the card beside it. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}
.z-cardfacts small {
    display: block;
    margin-top: 3px;
    font-size: 8.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--z-ink-3);
}

/* The estimated issue date, which is what most people are actually asking. */
.z-cardnote {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 12px;
    font-size: 12.5px;
    color: var(--z-ink-2);
}
.z-cardnote svg { color: var(--z-gold-deep); flex: none; }
.z-cardnote b { color: var(--z-green); font-weight: 600; }

/* Apply takes the room; WhatsApp is the square beside it. */
.z-cardacts { display: flex; align-items: center; gap: 8px; }
.z-cardacts .z-btn { flex: 1 1 auto; text-align: center; }

/* ==========================================================================
   VISA CARD — full photograph, no arch
   ==========================================================================
   The shared .z-card crops its image into the keel-arch mask, inset 12px and
   in a tall 4/4.4 portrait. The visa card follows the Oxford layout instead:
   the whole photograph, edge to edge across the top of the card.

   Three things have to go together, or the result is an arch with its corners
   showing: the mask on the image, the mask on the gold plate behind it
   (.z-card-media::before, which is arch-shaped in its own right), and the
   padding that insets both from the card edge.
   -------------------------------------------------------------------------- */
.z-card.is-flat .z-card-media {
    padding: 0;
    overflow: hidden;
    /* The card clips its own corners, so the photo meets them cleanly. */
    border-radius: var(--z-radius) var(--z-radius) 0 0;
}
.z-card.is-flat .z-card-media::before { display: none; }

.z-card.is-flat .z-card-arch {
    /* Landscape, as the reference sets it — a portrait crop of a skyline
       throws away the half of the picture that identifies the place. */
    aspect-ratio: 16 / 10;
    border-radius: 0;
    -webkit-mask-image: none;
            mask-image: none;
}

/* ==========================================================================
   PAGER
   ==========================================================================
   Shared by every Zaereen listing. Numbers, with the current one filled, and
   a chevron at each end that greys out rather than disappearing — a control
   that vanishes at the first and last page makes the row jump as you move
   through it.
   -------------------------------------------------------------------------- */
.z-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 34px;
    padding-top: 24px;
    border-top: 1px solid var(--z-line);
}

.z-pager-n,
.z-pager-step {
    min-width: 38px;
    height: 38px;
    padding: 0 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9px;
    border: 1px solid var(--z-line-gold);
    background: var(--z-surface);
    color: var(--z-ink);
    font-size: 13.5px;
    font-variant-numeric: tabular-nums;
    transition: color .18s ease, background-color .18s ease, border-color .18s ease;
}
.z-pager-n:hover,
.z-pager-step:hover { border-color: var(--z-gold); color: var(--z-green); background: var(--z-cream); }

.z-pager-n.is-current {
    color: #f7f0e2;
    background: var(--z-green);
    border-color: var(--z-green);
    font-weight: 600;
}

/* Ends of the run: present, but plainly not clickable. */
.z-pager-step.is-off { opacity: .32; }
.z-pager-step.is-off:hover { border-color: var(--z-line-gold); color: var(--z-ink); background: var(--z-surface); }

.z-pager-prev { transform: rotate(90deg); }
.z-pager-next { transform: rotate(-90deg); }

.z-pager-gap { padding: 0 2px; color: var(--z-ink-3); }

.z-pager-n:focus-visible,
.z-pager-step:focus-visible { outline: 2px solid var(--z-gold); outline-offset: 2px; }

/* --- the pager on a small screen -------------------------------------------
   The widest run this pager can draw is eleven slots — first, last, two either
   side of the current page, and the two arrows. At the desktop size that is
   about 544px, against the 507px the results column has at the narrowest
   tablet width and the 328px a 360px phone has. `flex-wrap: wrap` was doing
   what it was told with the difference: dropping buttons onto a second row,
   frequently one orphan at a time.

   The numbers stay at every width — they are how you get to page 5 without
   pressing next four times. What changes is how much room they ask for.

   TABLET keeps the full window and stops taking so much room. At 34px a side
   the eleven-slot worst case comes to about 392px, inside 507px, so it can no
   longer wrap anywhere in the band.

   PHONE shows every page up to nine of them — eleven slots at 32px is about
   320px against the 328px a 360px phone has, so the whole run fits and no
   ellipsis is drawn at all. That covers every listing on the site today
   (hotels 2 pages, visas 2, holidays 7). Past nine the partial falls back to
   the narrower window — one page either side instead of two — with its own
   ellipses, placed correctly for that window rather than inherited from the
   wide one.
   -------------------------------------------------------------------------- */

/* The phone's spare ellipses, off until the phone asks for them. */
.z-pager .is-narrow { display: none; }

@media (max-width: 1080px) {
    .z-pager { gap: 4px; margin-top: 28px; padding-top: 20px; }
    .z-pager-n,
    .z-pager-step {
        min-width: 34px;
        height: 36px;
        padding: 0 6px;
        font-size: 13px;
    }
    .z-pager-gap { padding: 0 1px; }
}

@media (max-width: 620px) {
    /* Only reached past nine pages, where the run is windowed: the outer
       numbers of the wide window stand down and the ellipses that are true
       without them come in. Below that the partial emits neither, and this
       block has nothing to act on. */
    .z-pager .is-wide { display: none; }
    .z-pager .is-narrow { display: inline-flex; }
    .z-pager-gap.is-narrow { display: inline; }

    .z-pager { flex-wrap: nowrap; justify-content: center; gap: 4px; }

    /* THE NUMBERS MAY SHRINK; THE ARROWS MAY NOT.

       `width` with `min-width: 0` rather than a min-width floor: a floor is
       what makes a row overflow instead of adapting. Nine numbers sit at their
       natural 32px on any phone, and a listing that grows past what the screen
       holds narrows them a little rather than pushing the last one off the
       edge. The arrows keep their size — they are the control you reach for
       without looking. */
    .z-pager-n {
        flex: 0 1 auto;
        width: 32px;
        min-width: 0;
        padding: 0 2px;
    }
    .z-pager-step { flex: none; min-width: 36px; }
}

/* The smallest phones still in use: 320px leaves 288 for eleven slots, so the
   cells give back a few pixels rather than the row scrolling for the sake of
   them. */
@media (max-width: 360px) {
    .z-pager { gap: 3px; }
    .z-pager-n { width: 28px; }
    .z-pager-n,
    .z-pager-step {
        height: 34px;
        font-size: 12.5px;
    }
    .z-pager-step { min-width: 32px; padding: 0 4px; }
}

/* --- visa card: centred name, lifted off the page -------------------------
   The country is the card's subject, so it sits centred over the three
   figures below it rather than hanging off the left edge.

   The ground is --z-surface (#fffdf7), NOT --z-cream: body.zaereen paints
   --z-cream, so a cream card was the same colour as the page behind it and
   the edge disappeared.

   Two light surfaces separate by LIGHTNESS, not hue — measured against the
   page, near-white steps furthest (1.16:1) while the pale sage tints that
   look more 'contrasting' actually measure worse (1.05 and 1.01), because
   they sit at almost the same luminance. The gold hairline and a deeper
   shadow do the rest of the work the colour cannot. */
.z-card.is-flat {
    background: var(--z-surface);
    border-color: var(--z-line-gold);
    box-shadow: 0 6px 18px rgba(18, 51, 42, .09);
}

.z-card.is-flat .z-card-title {
    text-align: center;
    /* The rule under the title spans the card, so centring the text without
       this leaves it looking off-centre against a full-width line. */
    width: 100%;
}

/* The facts row sits on the card ground, so its divider lines need to read
   against cream rather than against white. */
.z-card.is-flat .z-cardfacts {
    border-top-color: var(--z-line-gold);
    border-bottom-color: var(--z-line-gold);
}

/* --- visa card: the type badge opposite the flag --------------------------
   The flag sits top-right, so the badge takes the top-left corner rather than
   the bottom-centre the shared card uses. The two then bracket the top of the
   photograph instead of competing for the same edge.

   `bottom` and `transform` are reset explicitly: the shared rule centres the
   badge with translateX(-50%), and leaving that in place would pull the badge
   half its own width off the left edge of the card.
   -------------------------------------------------------------------------- */
.z-card.is-flat .z-card-media .z-badge {
    top: 12px;
    left: 12px;
    bottom: auto;
    transform: none;
    /* Smaller than the shared badge: it is a label on a photograph here, not
       the card's headline, and the country name below carries that job. */
    font-size: 9.5px;
    letter-spacing: .06em;
    padding: 4px 9px;
    max-width: calc(100% - 24px - 46px);   /* clear of the flag opposite */
    overflow: hidden;
    text-overflow: ellipsis;
    display: block;
}

/* ==========================================================================
   NAV MEGA MENU — the Holidays destinations
   ==========================================================================
   Opened by hover AND :focus-within, so it works from the keyboard with no
   script. The panel is always in the DOM; only its visibility changes, which
   is what keeps every destination reachable to a crawler and a screen reader.

   visibility is deliberately NOT transitioned. It is a discrete property, so
   Chrome flips it at the midpoint of the duration and the panel stays hidden
   for the first half of every open — the bug that made the earlier submenu
   feel unresponsive. opacity does the fade.
   -------------------------------------------------------------------------- */
/* relative, so the panel opens from its own trigger: left:0 below puts the
   panel edge on the button edge. Against .z-header-in (the old static rule)
   every panel started at the far left of the shell, 460px away from the
   Holidays button that opened it.
   A panel wider than the room left of the right edge would now hang off
   screen; that is corrected at runtime in header.php, which is the only
   place the trigger position is known. */
.z-nav > li.has-menu { position: relative; }
.z-header-in { position: relative; }

.z-mega {
    position: absolute;
    top: 100%;
    /* Sized to its content rather than stretched across the shell: 1fr
       tracks in a 1400px panel gave every column ~270px and the space
       showed. left:0 is now the TRIGGER's left edge, and the runtime shift
       below only ever pulls the panel back towards the centre, never past
       it, so the panel keeps touching the button it belongs to. */
    left: 0;
    right: auto;
    margin-left: var(--z-mega-shift, 0px);
    width: max-content;
    max-width: 100vw;
    transform: translateY(4px);
    z-index: 60;
    padding: 20px 24px 16px;
    /* A 1040px panel hung off a nav item near the right edge would run off
       screen; the clamp keeps it inside the shell either way. */
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius);
    box-shadow: 0 18px 44px rgba(18, 51, 42, .18);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .16s ease, transform .16s ease;
}
.z-nav > li.has-menu:hover > .z-mega,
.z-nav > li.has-menu:focus-within > .z-mega {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
}
/* Bridges the gap between the trigger and the panel, so the hover is not lost
   on the way down. */
.z-nav > li.has-menu > .z-mega::before {
    content: "";
    position: absolute;
    inset: -10px 0 auto 0;
    height: 10px;
}

.z-mega-cols {
    display: grid;
    /* Each column as wide as it needs and no wider. 1fr tracks split the
       panel evenly, which padded every column out to the width of the
       longest destination name in the menu. */
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    align-items: start;
    /* Columns are max-content, so this gap is the only space between them. */
    gap: 0 32px;
    /* Wide enough for five regions, capped so it cannot run past the shell on
       a laptop; the grid rewraps below that. */
}
.z-mega-col h6 {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 7px;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--z-navc, var(--z-gold-deep));
}
.z-mega-col ul { list-style: none; margin: 0 0 14px; padding: 0; }
.z-mega-col a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 5px 8px;
    border-radius: 7px;
    font-size: 13.5px;
    color: var(--z-ink);
    white-space: nowrap;
    transition: color .16s ease, background-color .16s ease;
}
/* icon, then the name taking the room, then the count pinned right. */
/* Each destination sets its own --z-navc, so the mark carries that colour
   rather than the menu's. Full strength: these are the point of the row, not
   a watermark behind it. */
.z-mega-col a svg { flex: 0 0 auto; color: var(--z-navc, var(--z-gold-deep)); }
.z-mega-col a em {
    flex: 1 1 auto;
    min-width: 0;
    font-style: normal;
    overflow: hidden;
    text-overflow: ellipsis;
}
.z-mega-col a span {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--z-ink-3);
    font-variant-numeric: tabular-nums;
}
.z-mega-col a:hover svg { opacity: 1; }

/* Drawer destinations carry the same mark. */
.z-drawer a.is-sub svg { opacity: .8; }
.z-mega-col a:hover {
    color: var(--z-navc, var(--z-gold-deep));
    background: color-mix(in srgb, var(--z-navc, #c19a3f) 10%, transparent);
}
.z-mega-col a:hover span { color: inherit; }

.z-mega-all {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    margin-top: 4px;
    padding-top: 12px;
    border-top: 1px solid var(--z-line);
    font-size: 13px;
    font-weight: 600;
    color: var(--z-green);
}
.z-mega-all:hover { color: var(--z-gold-deep); }

/* Drawer: destinations as indented plain links. */
.z-drawer a.is-sub { padding-left: 34px; font-size: 13.5px; }

@media (max-width: 1100px) {
    .z-mega { display: none; }
}

/* --- destination tiles: plain photograph -----------------------------------
   The arch mask and the gold arch plate behind it both go, and the crop turns
   from 3/4 portrait to landscape — the same treatment the cards carry, so the
   homepage and the listings read as one site.

   Both masks have to go together: removing only the tile's would leave the
   plate's arch showing behind a square photograph.
   -------------------------------------------------------------------------- */
.z-dest-frame.is-flat {
    -webkit-mask-image: none;
            mask-image: none;
    padding: 0;
    background: none;
    border-radius: var(--z-radius);
    overflow: hidden;
    border: 1px solid var(--z-line);
    box-shadow: 0 6px 18px rgba(18, 51, 42, .09);
}
.z-dest-frame.is-flat::before,
.z-dest-frame.is-flat::after { display: none; }

.z-dest.is-flat {
    aspect-ratio: 16 / 11;
    border-radius: 0;
    -webkit-mask-image: none;
            mask-image: none;
}

/* --- hotel cards: the brand green ----------------------------------------
   Neither near-white nor the chocolate sat right against the cream page.
   This is the ground the header plate, the page-head band and the footer
   already use, so every listing card reads as part of the site rather than a
   fourth surface colour — and it is a real contrast: 11.65:1 against the page,
   where white managed 1.16 and the chocolate 1.25.

   A dark ground inverts every text colour on the card, so each is restated
   here rather than inherited: title cream 12.60:1, values 11.23:1, the
   small uppercase labels in gold-light at 8.40:1. All well clear of AA.
   -------------------------------------------------------------------------- */
.z-card.is-deep {
    background: var(--z-green);
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
    border-color: var(--z-line-gold);
}
.z-card.is-deep .z-card-title { color: #fbf5e6; }
.z-card.is-deep .z-card-route { color: rgba(240, 232, 214, .78); }

.z-card.is-deep .z-cardfacts {
    border-top-color: rgba(227, 200, 134, .28);
    border-bottom-color: rgba(227, 200, 134, .28);
}
.z-card.is-deep .z-cardfacts .v { color: #f0e8d6; }
.z-card.is-deep .z-cardfacts .v svg { color: var(--z-gold-light); }
.z-card.is-deep .z-cardfacts small { color: var(--z-gold-light); }

.z-card.is-deep .z-cardnote { color: rgba(240, 232, 214, .82); }
.z-card.is-deep .z-cardnote svg { color: var(--z-gold-light); }
.z-card.is-deep .z-cardnote b { color: #fbf5e6; }

/* z-meta and z-price belong to the tours and flights cards, which the light
   ground had until now. Same inversion as the facts strip above. */
.z-card.is-deep .z-meta li { color: rgba(240, 232, 214, .86); }
.z-card.is-deep .z-meta svg { color: var(--z-gold-light); }
.z-card.is-deep .z-price small { color: var(--z-gold-light); }
.z-card.is-deep .z-price b { color: #fbf5e6; }
.z-card.is-deep .z-price span { color: rgba(240, 232, 214, .72); }

/* The outline button is drawn for a light ground; on green it needs the
   gold edge and light text or it disappears. */
.z-card.is-deep .z-btn-outline {
    color: #f0e8d6;
    border-color: rgba(227, 200, 134, .55);
}

/* --- orange button ---------------------------------------------------------
   Oxford's own #ff9800, the orange its cards already use.

   DARK text on it, not white. White on orange is the usual accessibility trap
   here: it measures 2.16:1 on this shade, and no orange dark enough to carry
   white (which needs 4.5) still reads as orange. Dark ink gives 7.75:1.
   -------------------------------------------------------------------------- */
.z-btn-orange {
    background: #ff9800;
    border: 1px solid #e0850a;
    color: #17201a;
    font-weight: 600;
}
.z-btn-orange:hover {
    background: #ffa726;
    border-color: #ff9800;
    color: #17201a;
}
.z-btn-orange svg { color: currentColor; }

/* --- .z-story as a product card --------------------------------------------
   The holiday listing uses the review card from /zaereen/ rather than a
   lookalike: same photo slot with its gold edge, same centred gold title over
   a hairline, same stats strip, same beige footer with the gold button.

   Only three things differ, and they are the three a package has that a review
   does not. `flex: 0 0 300px` on .z-story is for the horizontal rail; inside
   .z-grid-3 it is inert, because grid items are not flex items.
   -------------------------------------------------------------------------- */

/* A package has three facts, not a review's four. Padding the strip out to
   four with an invented column would be worse than a narrower one. */
.z-story-stats.is-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* Where the footer carries stars on a review, it carries the price here — on
   every listing at once: hotels, holidays, visas, mazaraat and the home page
   all build this footer from the same block.

   THE FIGURE IS THE POINT OF THE CARD and was not being drawn like it. It sat
   at 17px of Cormorant 700 in #7d6015, a gold-brown tuned to sit politely on
   the beige; polite is wrong for the one number somebody is scanning a grid of
   cards to compare. Three changes, in order of how much they do:

     COLOUR  --z-green, near-black, 13.9:1 on the footer beige against the old
             shade's 5.02. Dark reads as certain; the gold-brown read as a
             caption about a price rather than the price.

     FONT    var(--z-body), not --z-display. Cormorant is loaded at 400-700 and
             700 is as heavy as it gets — a serif at its heaviest still has thin
             strokes at 18px, so asking for "bolder" inside that family had
             nothing left to give. Jost at 700 is a different order of weight
             and is already loaded, so this costs no request.

     SIZE    18.5px, up from 17, with the tracking pulled in slightly so the
             extra weight does not spread the figure across the footer.

   The card TITLE keeps the display serif. The split is deliberate: the serif
   names the thing, the sans prices it, which is the pairing the fact strips
   and the booking cards already use. */
.z-story-foot-price b {
    display: block;
    font-family: var(--z-body);
    font-size: 18.5px;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
    line-height: 1.15;
}
/* Both were --z-ink-3, which measures 3.06 on the footer beige — under AA
   for an 8.5px label. --z-green takes them to 12.75. */
.z-story-foot-price small { color: var(--z-green); }

/* "On request" and "On dates" are NOT prices and must not be dressed as one:
   a hotel room is quoted for dates and occupancy, and a figure set in the same
   weight as a real total would read as one. Lighter, smaller, and in the muted
   ink rather than the near-black. */
.z-story-foot-price .sub {
    font-family: var(--z-body);
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: 0;
    color: var(--z-ink-2);
}

/* The duration plate, top-right, where a review shows its stars. */
.z-story-rate.is-text {
    font-family: var(--z-body, inherit);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .04em;
    line-height: 1;
    padding: 6px 9px;
    color: var(--z-gold-light);
}

/* --- the detail line on a product card --------------------------------------
   "Cities : Munnar | Thekkady" on a holiday, "Area :" on a hotel, "Next
   departure :" on a tour. The bar is a CSS separator rather than part of the
   text so it can be dimmed — the values are the content, the bar is
   punctuation, and at the same weight the line reads as a wall of pipes.
   -------------------------------------------------------------------------- */
.z-story-line {
    margin: 0 0 13px;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--z-ink-2);
    /* Two lines, reserved: a two-city tour and a six-city tour must leave
       their footers on the same line across a row. */
    min-height: calc(2 * 1.5em);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.z-story-line .lbl {
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--z-gold-deep);
}
/* :not(.lbl) on the LEFT side: the first city follows the label and must not
   be given a leading bar. Only a city that follows another city gets one. */
.z-story-line span:not(.lbl) + span::before {
    content: "| ";
    /* Not --z-line-strong: that is a border colour and lands at 1.89 on the
       card, so the bars vanished and the line read as loose words. 3.08
       keeps them legible while still subordinate to the names at 7.65. */
    color: #b08d2c;
}

/* --- visa card: the estimated date, and the documents behind it -------------
   The main site puts this date in a pulsing box on its visa cards and it is
   the right call: "when will I have it" is what somebody comparing visas is
   reading for, and here it was a run of body text between the facts and the
   price.

   THE COLOUR IS NOT COPIED. oxfordtravels.com draws it in #39FF14 on a dark
   card, which is legible there and would be neither legible nor ours on cream.
   --z-open on --z-open-bg is this palette's "yes, good news", already carried
   by .z-badge-open, and the pulse is drawn in the same green.

   BOTH SIT ON ONE ROW. A card in the three-column listing is about 280px wide,
   near 240px inside its padding, and that is what the badge and the link have
   to share — which is the whole reason the link reads "Documents" rather than
   "Documents needed". `nowrap` on the link and `min-width: 0` on the badge
   mean the date keeps its line and the pair shrink together rather than one of
   them dropping below the other.

   NOT A SHARED CLASS: .z-story-line stays exactly as it is, because the
   holiday cards and the home page use it for their bar-separated city runs and
   have no date to badge.
   -------------------------------------------------------------------------- */
.z-visa-meta {
    display: flex;
    align-items: stretch;
    gap: 8px;
    margin: 0 0 12px;
    /* Reserved on the ROW, not on the badge, so a visa with neither a date nor
       a documents list still leaves its footer on the same line as its
       neighbours. */
    min-height: 52px;
}

.z-visa-eta {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    margin: 0;
    padding: 6px 10px;
    border-radius: 10px;
    background: var(--z-open-bg);
    border: 1px solid rgba(27, 99, 73, .26);
    color: var(--z-open);
    text-align: center;
    box-sizing: border-box;
    animation: z-eta-pulse 2.4s ease-out infinite;
}
.z-visa-eta .lbl {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    opacity: .85;
    white-space: nowrap;
}
.z-visa-eta b {
    font-size: 14px;
    font-weight: 700;
    color: var(--z-green);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* A ring that grows out of the badge and fades, rather than the whole box
   changing colour: it reads at a glance without pulling the eye off the date
   while it is being read. The reduced-motion block at the top of this file
   flattens it to nothing for anyone who has asked for that. */
@keyframes z-eta-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(27, 99, 73, .30); }
    70%  { box-shadow: 0 0 0 9px rgba(27, 99, 73, 0); }
    100% { box-shadow: 0 0 0 0 rgba(27, 99, 73, 0); }
}

/* Straight into the detail page's #documents block. A companion pill rather
   than a third button: it matches the badge's height so the row reads as one
   piece, and the dashed edge keeps it plainly secondary to Enquiry and Apply
   in the footer below. */
.z-visa-docs {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 6px 11px;
    border-radius: 10px;
    border: 1px dashed var(--z-line-gold);
    background: var(--z-gold-wash);
    color: var(--z-gold-deep);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .03em;
    text-decoration: none;
    white-space: nowrap;
    box-sizing: border-box;
}
.z-visa-docs svg { flex: none; }
.z-visa-docs:hover {
    border-style: solid;
    border-color: var(--z-gold);
    color: var(--z-green);
}

/* --- product card title -----------------------------------------------------
   Bigger and dark, where a review card keeps the small gold name. Scoped to
   .is-product for exactly that reason: on /zaereen/ the traveller's name is
   meant to read as a caption, but a package name is the card's headline and
   people scan a grid of them.

   min-height stays in em, so reserving two lines follows the new size.
   -------------------------------------------------------------------------- */
.z-story.is-product .z-story-body h3 {
    /* Not the display serif: Cormorant Garamond is loaded at 400-700 and 700
       is its heaviest cut, so "bolder" there can only be a synthesised smear.
       Jost 700 is a real weight, and a package name in a scanned grid is UI
       rather than editorial. */
    font-family: var(--z-body);
    font-size: 17px;
    font-weight: 700;
    letter-spacing: .02em;
    /* Dark brown rather than the brand green: 11.5:1 on the card. */
    color: #4a3418;
}

/* A tour card carries two actions where the others carry one: the tour page
   and the departure list are different destinations, and dropping either
   would cost a route the old card had. */
.z-story-foot-acts { display: flex; align-items: center; gap: 6px; flex: none; }

/* A review's four stats are short by nature — a number, a rating, a place. A
   product's are not: "Azerbaijan Baku Tours", "International", "Tourist Visa".
   The shared rule ellipsises them, which hides the value with no sign that
   anything was cut, so on a product card they wrap instead. */
.z-story.is-product .z-story-stats .v {
    align-items: flex-start;
}
.z-story.is-product .z-story-stats .v svg { margin-top: 3px; }
.z-story.is-product .z-story-stats .v b {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.25;
}

/* ============================================================================
   MULTI-PRODUCT HERO SEARCH  (zaereen/index.php)

   NAMES: every class here is z-ts-*, not z-tab*. tour.php already owns
   .z-tab / .z-tabpanel for its itinerary tabs — 31 rules of it — and the
   first version of this bar reused those names, so the panels silently
   inherited that component's cream card, its 16px radius and its 26/28px
   padding. That inherited padding is most of why the bar looked bulky.

   Tabs are radio inputs and panels are shown with `:checked ~`, so there is
   no JavaScript: no flash of the wrong panel, nothing to break. The inputs
   are visually hidden but NOT display:none — a removed input cannot take
   focus and the tabs would stop being keyboard reachable.
   ========================================================================= */

.z-ts {
    position: relative;
    z-index: 3;
    /* ONE width for every tab. fit-content sized each tab to its own
       controls, which meant the right edge jumped between 640px and 968px
       as you switched. 980 is what the widest tab (Hotels: five controls
       plus the button) needs; the narrower tabs centre their row inside it. */
    width: min(1100px, 100%);
    /* Centred ON the crest band rather than hanging below it. The band mid
       sits at 364 and the default (Ziyarat) tab was centred at 433, so the
       bar rides up a further 69px. Tabs of other heights land near it rather
       than exactly on it — one margin cannot centre five different heights,
       and the tab a visitor lands on is the one worth getting right. */
    margin: -119px auto 30px;   /* +4: the taller controls moved the bar off the band */
}

.z-ts-input {
    position: absolute;
    width: 1px; height: 1px;
    opacity: 0;
    pointer-events: none;
}

/* --- the tabs ------------------------------------------------------------
   They sit on the dark hero, so inactive tabs are translucent green with
   cream text and the active one is the panel's own cream, overlapping the
   panel's top edge by 1px. That overlap is what makes tab and panel read as
   one folder rather than two stacked boxes — the same trick tour.php uses. */
.z-ts-strip {
    display: flex;
    flex-wrap: nowrap;   /* two rows on the narrow tabs looked broken */
    gap: 3px;
    padding: 0 12px;
}
.z-ts-tab {
    display: inline-flex;
    /* Never compress: with the bar sized to its fields, a narrow tab was
       squashing the strip and clipping the labels. */
    flex: none;
    align-items: center;
    gap: 6px;
    padding: 8px 13px 9px;
    /* A LIFT off the hero, not the hero again: rgba(13,44,34,.78) over the
       hero's own rgb(13,44,34) composites to exactly rgb(13,44,34) — 1.00:1
       — so the tab shape was invisible and only its label floated there.
       A cream veil lifts the ground and this hairline draws the edge. */
    border: 1px solid rgba(227, 200, 134, .5);
    border-bottom: none;
    border-radius: 10px 10px 0 0;
    font-size: 13px;
    font-weight: 600;
    color: #f0e8d6;
    background: rgba(247, 240, 226, .15);
    backdrop-filter: blur(6px);
    cursor: pointer;
    user-select: none;
    transition: background .18s ease, color .18s ease, border-color .18s ease;
}
.z-ts-tab svg { flex: none; color: var(--z-gold-light); }
.z-ts-tab:hover {
    background: rgba(247, 240, 226, .26);
    color: #fffdf7;
    border-color: var(--z-gold-light);
}

.z-ts-panels {
    position: relative;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 0 16px 16px 16px;
    /* Four layers, each doing one job: a gold ring so the panel reads as part
       of the brand rather than a plain white card, a highlight along the top
       edge for the lift, a tight contact shadow where it meets the band, and
       a wide soft one for the drop. A single blur reads flat at this size. */
    box-shadow:
        0 0 0 1px rgba(227, 200, 134, .38),
        inset 0 1px 0 rgba(255, 255, 255, .7),
        0 2px 6px rgba(13, 44, 34, .07),
        0 22px 48px -14px rgba(13, 44, 34, .28);
    padding: 20px;
}

/* Hidden until its tab is checked. Nothing shows if a selector is missed,
   which is the safe way round — it fails visibly rather than silently. */
.z-ts-panel { display: none; }

#z-tab-ziyarat:checked  ~ .z-ts-panels .z-ts-panel.is-ziyarat,
#z-tab-flights:checked  ~ .z-ts-panels .z-ts-panel.is-flights,
#z-tab-hotels:checked   ~ .z-ts-panels .z-ts-panel.is-hotels,
#z-tab-holidays:checked ~ .z-ts-panels .z-ts-panel.is-holidays,
#z-tab-visas:checked    ~ .z-ts-panels .z-ts-panel.is-visas { display: block; }

/* Gold, not the panel's cream. That trades the folder-tab join for a
   highlight — the active tab now reads as a lit control rather than the
   front of the panel — which is the trade a gold theme asks for. The
   1px overlap stays so the tab still sits ON the panel edge. */
#z-tab-ziyarat:checked  ~ .z-ts-strip .z-ts-tab[for="z-tab-ziyarat"],
#z-tab-flights:checked  ~ .z-ts-strip .z-ts-tab[for="z-tab-flights"],
#z-tab-hotels:checked   ~ .z-ts-strip .z-ts-tab[for="z-tab-hotels"],
#z-tab-holidays:checked ~ .z-ts-strip .z-ts-tab[for="z-tab-holidays"],
#z-tab-visas:checked    ~ .z-ts-strip .z-ts-tab[for="z-tab-visas"] {
    background: var(--z-gold-leaf);
    border-color: var(--z-line-gold);
    color: #2a1f00;
    box-shadow: inset 0 1px 0 rgba(255, 250, 232, .5);
    margin-bottom: -1px;
    padding-bottom: 11px;
    z-index: 2;
}
#z-tab-ziyarat:checked  ~ .z-ts-strip .z-ts-tab[for="z-tab-ziyarat"] svg,
#z-tab-flights:checked  ~ .z-ts-strip .z-ts-tab[for="z-tab-flights"] svg,
#z-tab-hotels:checked   ~ .z-ts-strip .z-ts-tab[for="z-tab-hotels"] svg,
#z-tab-holidays:checked ~ .z-ts-strip .z-ts-tab[for="z-tab-holidays"] svg,
#z-tab-visas:checked    ~ .z-ts-strip .z-ts-tab[for="z-tab-visas"] svg { color: #2a1f00; }

/* Focus lands on the hidden input, so the ring has to be drawn on its label. */
#z-tab-ziyarat:focus-visible  ~ .z-ts-strip .z-ts-tab[for="z-tab-ziyarat"],
#z-tab-flights:focus-visible  ~ .z-ts-strip .z-ts-tab[for="z-tab-flights"],
#z-tab-hotels:focus-visible   ~ .z-ts-strip .z-ts-tab[for="z-tab-hotels"],
#z-tab-holidays:focus-visible ~ .z-ts-strip .z-ts-tab[for="z-tab-holidays"],
#z-tab-visas:focus-visible    ~ .z-ts-strip .z-ts-tab[for="z-tab-visas"] {
    outline: 2px solid var(--z-gold);
    outline-offset: 2px;
}

/* --- the field row -------------------------------------------------------
   Separate pill controls on the cream card, the shape the single-product bar
   had — not one merged dark bar. */
.z-ts-row {
    display: flex;
    align-items: flex-end;
    justify-content: flex-start;
    gap: 12px;
}
/* Flexible fields take what is left, but only up to a point: with the dates
   and counts pinned, "remaining space" handed the Holidays destination a
   648px select to show "Kerala Tours (4)". Capped, and the row centred, so
   a tab with fewer fields sits as a tidy cluster instead of stretching to
   the edges or leaving one gap on the right. */
.z-ts-field { flex: 0 0 232px; min-width: 0; }
.z-ts-field.is-wide { flex: 0 0 400px; }
/* Hotels carries four more controls than any other tab; a 400px text box on
   top of them pushed it past a 1024 screen. */
/* Hotels is the only tab whose fixed widths do not fit: five fields plus the
   button came to 996px inside a 942px row, and with every field flex:0 0
   nothing could give, so the Search button was pushed out through the side
   of the panel. This one field absorbs the remainder instead of carrying a
   width of its own — so the row fits whatever the other four need. */
.z-ts-panel.is-hotels .z-ts-field.is-wide { flex: 1 1 0; min-width: 0; }
/* Ziyarat carries four fields, so one has to take the remainder rather than
   a width of its own or the row overflows. That job moved from Departure
   City to Destination: city names are short ("Any City", "Mumbai") and the
   leftover space made that control far wider than anything it displays,
   while Destination carries "Karbala Tours" and uses the room. */
.z-ts-panel.is-ziyarat .z-ts-field:first-of-type { flex: 1 1 0; min-width: 0; }
.z-ts-panel.is-ziyarat .z-ts-field:last-of-type  { flex: 0 0 200px; }

/* Fixed widths, sized to what the control shows rather than to whatever is
   left over: a date needs room for dd/mm/yyyy and the picker glyph, a count
   shows one or two digits, a nationality the longest country name that
   matters. Sharing the row equally made the dates cramped and the counts
   absurdly wide at the same time. */
/* 138 was the tightest it could be and still show dd/mm/yyyy plus the picker
   glyph — the value sat hard against both edges. The bar is 1100 wide now, so
   the room exists; the flexible field on each tab gives it up. */
.z-ts-field.is-date  { flex: 0 0 190px; }
.z-ts-field.is-count { flex: 0 0 84px; }
.z-ts-field.is-nat   { flex: 0 0 148px; }

.z-ts-field label {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 5px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .11em;
    text-transform: uppercase;
    /* --z-ink-3 is 3.54:1 on the cream card — under AA for a 10.5px label.
       --z-ink-2 takes it to 7.87. */
    color: var(--z-ink-2);
    cursor: pointer;
}
.z-ts-field label svg { flex: none; color: var(--z-gold-deep); }

.z-ts-field select,
.z-ts-field input {
    width: 100%;
    /* An <input> carries an intrinsic minimum from its `size` attribute —
       about 250px here — and min-width:0 on the FIELD does not reach it.
       Without this the Hotels row could not shrink below 1022px inside a
       942px panel and pushed the Search button out through the side. */
    min-width: 0;
    height: 52px;
    padding: 0 16px;
    background: var(--z-cream);
    /* --z-line-strong, not --z-line: on a cream pill sitting on a cream
       panel the lighter rule reads at ~1.1 against its own fill and the
       control loses its edge entirely. The inset gives the field a floor
       rather than leaving it flat against the card. */
    border: 1px solid var(--z-line-strong);
    box-shadow: inset 0 1px 2px rgba(13, 44, 34, .05);
    border-radius: 10px;
    font-family: inherit;
    font-size: 15px;
    font-weight: 500;
    color: var(--z-ink);
    cursor: pointer;
}
.z-ts-field input { cursor: text; }
.z-ts-field input::placeholder { color: var(--z-ink-3); }
.z-ts-field select:focus,
.z-ts-field input:focus {
    outline: none;
    border-color: var(--z-gold);
    background: var(--z-surface);
}

.z-ts-go {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 52px;
    padding: 0 28px;
    border: 1px solid var(--z-green);
    border-radius: 10px;
    background: var(--z-green);
    box-shadow: inset 0 1px 0 rgba(227, 200, 134, .22);
    color: #f7efdc;
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: .01em;
    cursor: pointer;
    transition: background .18s ease;
}
.z-ts-go:hover { background: #123a2c; }
.z-ts-go:focus-visible { outline: 2px solid var(--z-gold); outline-offset: 2px; }

/* --- Popular chips, Ziyarat tab only ------------------------------------ */
.z-ts-panel .z-quick {
    margin: 14px 0 0;
    padding-top: 13px;
    border-top: 1px solid var(--z-line-soft);
}

/* --- narrow screens ----------------------------------------------------- */
@media (max-width: 900px) {
    /* fit-content is a desktop idea: once the row stacks, the widest child is
       one field, so the bar collapsed to 246px inside a 487px phone. */
    .z-ts { margin-top: -18px; width: 100%; }
    .z-ts-tab { padding: 8px 12px 9px; font-size: 12.5px; gap: 5px; }
    .z-ts-tab span { display: none; }        /* icons only once space is tight */
    .z-ts-row { flex-direction: column; align-items: stretch; }
    .z-ts-strip { flex-wrap: wrap; }
    /* Every fixed basis has to be released here, and the ziyarat one is
       the reason: once the row is a COLUMN, flex-basis sizes the main
       axis, which is now the height. "flex: 0 0 200px" — written to
       narrow that dropdown on desktop — made the Departure City field
       200px TALL, leaving ~125px of dead space above the Search button.
       It needs the panel selector at full strength; the bare .z-ts-field
       below is too weak to override it. */
    .z-ts-field, .z-ts-field.is-wide,
    .z-ts-panel.is-hotels .z-ts-field.is-wide,
    .z-ts-panel.is-ziyarat .z-ts-field:last-of-type,
    .z-ts-field.is-date, .z-ts-field.is-count, .z-ts-field.is-nat {
        flex: 1 1 auto;
        max-width: none;
    }
    .z-ts-go { width: 100%; }
}

/* What the hero search bar carried into a listing — a date that really did
   narrow the results, a traveller count that did not. */
.z-results-note {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 16px;
    margin: 5px 0 0;
    font-size: 13px;
    color: var(--z-ink-2);
}
.z-results-note svg { color: var(--z-gold-deep); flex: none; margin-right: -3px; }
.z-results-note b { font-weight: 600; color: var(--z-green); }
.z-note-aside { color: var(--z-ink-3); font-size: 12.5px; }

/* Why a listing is in the order it is in.

   The same line, one modifier apart, because it answers the same kind of
   question as the note above it — "this is what the page did with what you
   told it". Boxed rather than bare, because that one is a restatement of the
   search still visible in the fields above, and this one is the page
   accounting for a reordering nobody asked for out loud.

   width: fit-content so the pill ends at its text: stretched across a
   three-column grid it reads as a banner, and it is a footnote.

   The link inside it is the escape hatch. It is deliberately quiet — ink-3 and
   12.5px, inherited from .z-note-aside — because most people will never want
   it, and the ones who do are looking for it. */
.z-results-note.is-recent {
    width: fit-content;
    max-width: 100%;
    margin: 8px 0 2px;
    padding: 7px 13px;
    gap: 4px 10px;
    border: 1px solid var(--z-line);
    border-radius: 999px;
    background: var(--z-cream-deep);
}
.z-results-note.is-recent a {
    color: var(--z-ink-3);
    text-decoration: underline;
    text-underline-offset: 2px;
    text-decoration-color: var(--z-line);
}
.z-results-note.is-recent a:hover,
.z-results-note.is-recent a:focus-visible {
    color: var(--z-green);
    text-decoration-color: currentColor;
}

/* --- Recent Searches -------------------------------------------------------
   Inside the panel, under a hairline, because the strip belongs to the tab
   above it — a hotel search is recalled on the Hotels tab and nowhere else.
   The script filters by the checked radio and re-renders on change.

   Shaped like the Oxford strip: a standing HEADING on the left rather than a
   field label, then the cards, each with its own titled header band over a
   body of colour-coded facts. The colours are the point — a date row and a
   traveller row that are both gold read as one paragraph at a glance, and the
   card stops being scannable. One hue per kind of fact, taken from the tints
   the booking cards' document chips already use, so the two features agree.
   -------------------------------------------------------------------------- */
.z-recent {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 14px;
    padding-top: 13px;
    border-top: 1px solid var(--z-line-soft);
    /* .z-ts is width:fit-content, so every child votes on how wide the bar is.
       Without this the CARDS won that vote and stretched it to 1211px.
       width:0 removes the row from the calculation; min-width:100% then fills
       whatever the fields decided. */
    width: 0;
    min-width: 100%;
}
.z-recent[hidden] { display: none; }

/* A heading, not a caption: it names the strip beside it the way the section
   headings elsewhere on the page name theirs, and the gold disc carries the
   clock so the mark is not a stray glyph floating next to the words. */
.z-recent-label {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    flex: none;
    font-size: 13.5px;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--z-green);
}
.z-recent-label-ico {
    flex: none;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--z-gold-pale);
    border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
}
.z-recent-label-ico svg { display: block; }

.z-recent-scroll {
    display: flex;
    gap: 10px;
    min-width: 0;          /* or the flex item refuses to shrink and never scrolls */
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    padding: 2px 0 4px;
}
.z-recent-scroll::-webkit-scrollbar { display: none; }

.z-recent-card {
    position: relative;
    flex: none;
    width: 252px;
    scroll-snap-align: start;
    /* --z-surface over the panel's own cream. The header band below is the
       shade that separates the two halves, so the body stays the lighter of
       the two rather than the card sitting flat on its ground. */
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 12px;
    box-shadow: var(--z-shadow-sm);
    overflow: hidden;      /* the header band's fill has to stop at the radius */
    transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.z-recent-card:hover {
    transform: translateY(-2px);
    border-color: var(--z-gold);
    box-shadow: var(--z-shadow);
}

.z-recent-link { display: block; text-decoration: none; }

/* The card's own heading, separated: its own fill and a hairline under it, so
   the title reads as a title and not as the first of four facts. */
.z-recent-head {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    padding: 9px 34px 9px 11px;
    background: var(--z-gold-wash);
    border-bottom: 1px solid var(--z-line-soft);
}
.z-recent-ico {
    flex: none;
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--z-gold-pale);
    border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
}
.z-recent-ico svg { display: block; }
.z-recent-head b {
    min-width: 0;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--z-gold-deep);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.z-recent-body { display: block; padding: 10px 11px 11px; }

/* One labelled row per fact, the shape the Oxford card uses: a coloured glyph
   in its own disc, the field name, then the value. */
.z-recent-row {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 11.5px;
    color: var(--z-green);
    white-space: nowrap;
    overflow: hidden;
}
.z-recent-row + .z-recent-row { margin-top: 7px; }
.z-recent-row i {
    flex: none;
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    /* The default, for a row this file has not given a hue to yet. */
    background: var(--z-gold-pale);
    color: var(--z-gold-deep);
}
.z-recent-row i svg { display: block; }
.z-recent-row em {
    flex: none;
    font-style: normal;
    font-weight: 600;
    color: var(--z-ink-3);
}
.z-recent-val {
    min-width: 0;
    font-weight: 700;
    color: var(--z-green);
    overflow: hidden;
    text-overflow: ellipsis;
}
/* One hue per kind of fact — rose for when, blue for who. */
.z-recent-row.is-date i   { background: #f7e2e9; color: #9c3358; }
.z-recent-row.is-people i { background: #dfe9f6; color: #2a4d8f; }

/* Overlays the top-right rather than sitting in the flow, so a long title
   cannot push it off the end of the card. */
.z-recent-x {
    position: absolute;
    top: 7px;
    right: 7px;
    width: 21px;
    height: 21px;
    display: grid;
    place-items: center;
    border: 1px solid var(--z-line);
    border-radius: 50%;
    background: var(--z-surface);
    color: var(--z-ink-3);
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.z-recent-x:hover {
    background: var(--z-sold-bg);
    border-color: rgba(138, 48, 36, .3);
    color: var(--z-sold);
}
.z-recent-x:focus-visible { outline: 2px solid var(--z-gold); outline-offset: 1px; }

.z-recent-nav {
    flex: none;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border: 1px solid var(--z-line);
    border-radius: 50%;
    background: var(--z-surface);
    color: var(--z-green);
    cursor: pointer;
}
.z-recent-nav[hidden] { display: none; }
.z-recent-nav:hover { background: var(--z-green); border-color: var(--z-green); color: var(--z-gold-light); }
/* The forward arrow is the one people reach for, so it carries the gold. */
.z-recent-nav.is-next {
    background: var(--z-gold-leaf);
    border-color: var(--z-gold);
    color: var(--z-green);
}
.z-recent-nav.is-next:hover { filter: brightness(1.06); color: var(--z-green); }
.z-recent-nav.is-prev svg { transform: rotate(90deg); }
.z-recent-nav.is-next svg { transform: rotate(-90deg); }

@media (max-width: 900px) {
    .z-recent { flex-wrap: wrap; gap: 9px; }
    .z-recent-nav { display: none; }
    .z-recent-card { width: 224px; }
}

/* --- Flights tab: trip type, party size, swap, popular filter ---------------
   Oxford's flight-search shape in Zaereen's palette. Every control maps to a
   real filter — see the note in the markup for what was deliberately left out.

   The trip pills are radios, like the tabs themselves, so the whole thing
   stays CSS-only apart from the swap button.
   -------------------------------------------------------------------------- */
.z-fx-top {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}

.z-fx-trip { display: inline-flex; gap: 4px; padding: 3px; background: var(--z-cream); border-radius: 999px; }
.z-fx-pill { display: inline-flex; cursor: pointer; }
.z-fx-pill input {
    position: absolute;
    width: 1px; height: 1px;
    opacity: 0;
    pointer-events: none;   /* hidden, not removed: a removed input cannot take focus */
}
.z-fx-pill span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 15px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    color: var(--z-ink-2);
    transition: background .18s ease, color .18s ease;
}
.z-fx-pill span svg { flex: none; color: var(--z-gold-deep); }
.z-fx-pill:hover span { color: var(--z-green); }
.z-fx-pill input:checked + span { background: var(--z-green); color: #f2e9d5; }
.z-fx-pill input:checked + span svg { color: var(--z-gold-light); }
.z-fx-pill input:focus-visible + span { outline: 2px solid var(--z-gold); outline-offset: 2px; }

.z-fx-pax {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 0 12px 0 13px;
    height: 40px;
    background: var(--z-cream);
    border: 1px solid var(--z-line);
    border-radius: 999px;
    cursor: pointer;
}
.z-fx-pax > svg { flex: none; color: var(--z-gold-deep); }
.z-fx-pax select {
    border: 0;
    background: transparent;
    padding: 0;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    color: var(--z-green);
    cursor: pointer;
}
.z-fx-pax select:focus { outline: none; }

/* Sits between the two sector selects, straddling the gap. align-self keeps it
   on the controls' line rather than the labels'. */
.z-fx-swap {
    flex: none;
    align-self: flex-end;
    width: 34px;
    height: 34px;
    margin-bottom: 7px;
    display: grid;
    place-items: center;
    border: 1px solid var(--z-line);
    border-radius: 50%;
    background: var(--z-surface);
    color: var(--z-gold-deep);
    cursor: pointer;
    transition: background .18s ease, color .18s ease;
}
.z-fx-swap[hidden] { display: none; }
.z-fx-swap svg { transform: rotate(90deg); }
.z-fx-swap:hover { background: var(--z-green); border-color: var(--z-green); color: var(--z-gold-light); }
.z-fx-swap:focus-visible { outline: 2px solid var(--z-gold); outline-offset: 2px; }

.z-fx-bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-top: 12px;
}
.z-fx-bottom-label {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--z-ink-2);
}
.z-fx-check { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; }
.z-fx-check input { width: 16px; height: 16px; accent-color: var(--z-green); cursor: pointer; }
.z-fx-check span { font-size: 13px; font-weight: 500; color: var(--z-green); }

@media (max-width: 900px) {
    .z-fx-swap { align-self: center; margin: 0 auto; transform: rotate(90deg); }
}

/* Visually hidden but still read aloud and still focusable. */
.z-sr-only {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* --- Guests & Rooms popover (Hotels tab) -----------------------------------
   The field is a button showing a summary; the panel drops out of it with a
   stepper pair per room. Dark ground so it reads as a layer above the cream
   panel rather than more of it.
   -------------------------------------------------------------------------- */
/* 168, not 158: "1 Room, 2 Guests" measures 113px and the button chrome
   takes ~47, so the label was clipping by 4px. */
.z-ts-field.is-guests { position: relative; flex: 0 0 168px; }
.z-ts-field.is-guests > select[hidden] { display: none; }

.z-gr-open {
    width: 100%;
    min-width: 0;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 0 12px 0 14px;
    background: var(--z-cream);
    border: 1px solid var(--z-line-strong);
    box-shadow: inset 0 1px 2px rgba(13, 44, 34, .05);
    border-radius: 10px;
    font-family: inherit;
    font-size: 15px;
    font-weight: 500;
    color: var(--z-ink);
    cursor: pointer;
    text-align: left;
}
.z-gr-open[hidden] { display: none; }
.z-gr-open svg { flex: none; color: var(--z-ink-3); transition: transform .18s ease; }
.is-guests.is-open .z-gr-open { border-color: var(--z-gold); background: var(--z-surface); }
.is-guests.is-open .z-gr-open svg { transform: rotate(180deg); }
.z-gr-open:focus-visible { outline: 2px solid var(--z-gold); outline-offset: 2px; }

.z-gr-panel {
    position: absolute;
    z-index: 20;
    top: calc(100% + 8px);
    right: 0;
    width: 380px;
    max-width: min(380px, calc(100vw - 32px));
    /* Dark, deliberately: the party picker is a panel of controls, not a
       calendar, and the brand ground sets it apart from the cream field row
       it drops out of.

       A warm charcoal rather than the brand green: the popover is a panel of
       controls, and a neutral ground lets the gold read as gold instead of
       competing with the green it sits on. Measured on this ground —
       gold-light 9.10, cream 13.65, the muted note 6.84 — every one of them
       better than the green it replaces. */
    background: #2a2724;
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
    border: 1px solid var(--z-line-gold);
    border-radius: 14px;
    box-shadow: 0 20px 44px rgba(13, 44, 34, .3);
    overflow: hidden;
}
.z-gr-panel[hidden] { display: none; }

.z-gr-rooms { padding: 14px 16px 4px; max-height: 46vh; overflow-y: auto; }
.z-gr-room + .z-gr-room { margin-top: 14px; padding-top: 14px; border-top: 1px solid rgba(227, 200, 134, .24); }

.z-gr-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.z-gr-head span {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--z-gold-light);
}
.z-gr-remove {
    border: 0;
    background: transparent;
    padding: 0;
    font-family: inherit;
    font-size: 11.5px;
    font-weight: 600;
    color: rgba(240, 232, 214, .8);
    text-decoration: underline;
    cursor: pointer;
}
.z-gr-remove:hover { color: #fbf5e6; }

.z-gr-cap {
    margin: 8px 0 12px;
    padding: 9px 11px;
    background: rgba(227, 200, 134, .12);
    border-radius: 8px;
    font-size: 12px;
    font-weight: 600;
    color: var(--z-gold-light);
}

.z-gr-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.z-gr-row + .z-gr-row { margin-top: 10px; }
.z-gr-lab { min-width: 0; }
.z-gr-lab b { font-size: 14px; font-weight: 600; color: #fbf5e6; }
.z-gr-lab em { font-style: normal; font-size: 12px; color: rgba(240, 232, 214, .72); }

.z-gr-step {
    flex: none;
    display: inline-flex;
    align-items: center;
    border: 1px solid rgba(227, 200, 134, .34);
    border-radius: 9px;
    overflow: hidden;
}
.z-gr-step button {
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    border: 0;
    background: rgba(255, 253, 247, .07);
    color: #fbf5e6;
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
}
.z-gr-step button:hover:not(:disabled) { background: rgba(255, 253, 247, .18); }
/* Disabled, not hidden: the control keeps its place so the row does not
   reflow every time a limit is reached. */
.z-gr-step button:disabled { opacity: .35; cursor: default; }
.z-gr-step button:focus-visible { outline: 2px solid var(--z-gold-light); outline-offset: -2px; }
.z-gr-step output {
    min-width: 40px;
    text-align: center;
    font-size: 14.5px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: #fbf5e6;
}

.z-gr-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px 14px;
    background: rgba(0, 0, 0, .16);
    border-top: 1px solid rgba(227, 200, 134, .2);
}
.z-gr-add {
    flex: 1 1 auto;
    padding: 10px 12px;
    border: 1px solid var(--z-gold-light);
    border-radius: 9px;
    background: transparent;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--z-gold-light);
    cursor: pointer;
}
.z-gr-add:hover:not(:disabled) { background: rgba(227, 200, 134, .14); }
.z-gr-add:disabled { opacity: .4; cursor: default; }
.z-gr-apply {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 20px;
    border: 0;
    border-radius: 9px;
    background: var(--z-gold-leaf);
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    color: #2a1f00;
    cursor: pointer;
}
.z-gr-apply:hover { filter: brightness(1.06); }
.z-gr-add:focus-visible,
.z-gr-apply:focus-visible { outline: 2px solid var(--z-gold-light); outline-offset: 2px; }

@media (max-width: 900px) {
    .z-ts-field.is-guests { flex: 1 1 auto; }
    .z-gr-panel { right: auto; left: 0; }
}

/* One age picker per child, redrawn with the count. A button grid rather than
   a <select>: eleven single digits are faster to hit than a dropdown, and the
   whole range is visible at once. */
.z-gr-age { margin-top: 12px; }
.z-gr-age-head {
    display: block;
    text-align: center;
    margin-bottom: 7px;
    font-size: 12.5px;
    font-weight: 700;
    color: #fbf5e6;
}
/* All eleven on ONE row, as the reference has it. That sets the panel's
   width rather than the other way round: 11 columns plus 10 gaps need
   ~348px of content box, so the panel is 380 wide. */
.z-gr-age-grid {
    display: grid;
    grid-template-columns: repeat(11, minmax(0, 1fr));
    gap: 4px;
}
.z-gr-age-grid button {
    height: 30px;
    padding: 0;
    border: 1px solid rgba(227, 200, 134, .3);
    border-radius: 6px;
    background-color: rgba(255, 253, 247, .07);
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: #f0e8d6;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.z-gr-age-grid button:hover { background-color: rgba(255, 253, 247, .16); border-color: var(--z-gold-light); }
.z-gr-age-grid button.is-on {
    background-image: var(--z-gold-leaf);
    border-color: var(--z-gold-light);
    color: #2a1f00;
}
.z-gr-age-grid button:focus-visible { outline: 2px solid var(--z-gold-light); outline-offset: 2px; }

/* The summary must be allowed to ellipsise, or its text is a floor the
   Guests field cannot shrink past. */
.z-gr-summary { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --- Travel date calendar (flatpickr) ---------------------------------------
   Light theme, sized down from flatpickr's 39px default.

   Scoped to .z-fp — NOT .z-cal, which the departures page already owns. That
   class sets position:relative and overflow:hidden, and inheriting it pinned
   this calendar into the page flow at the bottom of the document instead of
   floating it under the field.

   SIZING: flatpickr lays a month out as a fixed-width container whose days are
   percentage widths of it, and the weekday header uses the same percentages.
   So the ONE thing to change is the container width — the days and the header
   follow together. Setting day widths or nudging .dayContainer with margins
   (which an earlier pass did) shifts the grid without shifting its header, and
   the two months slide out of line.
   -------------------------------------------------------------------------- */
.flatpickr-calendar.z-fp {
    background: var(--z-surface);
    border: 1px solid var(--z-line-strong);
    border-radius: 14px;
    box-shadow:
        0 0 0 1px rgba(227, 200, 134, .35),
        0 18px 44px -12px rgba(13, 44, 34, .3);
    padding: 8px;
    /* flatpickr writes an inline width equal to the two month grids and knows
       nothing about this padding. With border-box sizing that padding eats
       into the content box, and .flatpickr-days (overflow:hidden) then clipped
       the last column of the second month. Overriding the inline width lets
       the box grow to fit instead. */
    width: auto !important;
}
.flatpickr-calendar.z-fp.arrowTop::before,
.flatpickr-calendar.z-fp.arrowTop::after,
.flatpickr-calendar.z-fp.arrowBottom::before,
.flatpickr-calendar.z-fp.arrowBottom::after { display: none; }

/* --- the one measurement that drives the rest --------------------------- */
.z-fp .dayContainer,
.z-fp .flatpickr-weekdaycontainer {
    width: 252px;
    min-width: 252px;
    max-width: 252px;
}
.z-fp .flatpickr-days,
.z-fp .flatpickr-rContainer { width: auto; }

/* --- month heading and arrows ------------------------------------------- */
.z-fp .flatpickr-months { padding: 2px 0 8px; }
.z-fp .flatpickr-month { background: transparent; color: var(--z-green); height: 34px; }
.z-fp .flatpickr-current-month {
    font-family: var(--z-display);
    font-size: 15.5px;
    font-weight: 700;
    letter-spacing: .03em;
    padding-top: 4px;
}
.z-fp .flatpickr-current-month .cur-month { color: var(--z-green); }
.z-fp .flatpickr-current-month input.cur-year { color: var(--z-gold-deep); font-weight: 700; }

.z-fp .flatpickr-prev-month,
.z-fp .flatpickr-next-month {
    top: 4px;
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 1px solid var(--z-line-strong);
    border-radius: 50%;
    color: var(--z-gold-deep);
    font-size: 15px;
    line-height: 1;
}
.z-fp .flatpickr-prev-month { left: 6px; }
.z-fp .flatpickr-next-month { right: 6px; }
.z-fp .flatpickr-prev-month:hover,
.z-fp .flatpickr-next-month:hover { background: var(--z-cream); color: var(--z-green); }

/* --- weekday row --------------------------------------------------------- */
.z-fp .flatpickr-weekdays { background: transparent; height: 26px; }
.z-fp span.flatpickr-weekday {
    background: transparent;
    color: var(--z-ink-2);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

/* --- days ---------------------------------------------------------------- */
.z-fp .flatpickr-day {
    height: 34px;
    line-height: 30px;
    max-width: none;
    /* The border IS the gutter. Days tile edge to edge with no margin, so a
       radius alone left the panel showing through wherever four rounded
       corners met — the four-pointed white specks. A transparent 2px border
       with padding-box clipping keeps the fill inside and puts an even gap
       all round, so the cells read as separate chips. */
    border: 2px solid transparent;
    background-clip: padding-box;
    border-radius: 8px;
    /* A filled day reads as "open" at a glance — the point of the reference —
       but a light panel needs the tint, not the saturated block.

       background-COLOR, not the shorthand: `background:` resets background-clip
       to border-box, and the fill then paints under the transparent border that
       is meant to be the gutter, so the cells touch and the corner specks come
       straight back. */
    background-color: #e2f4e8;
    color: #0d3b26;
    font-size: 12.5px;
    font-weight: 600;
}
.z-fp .flatpickr-day:hover { background-color: #c9ead6; box-shadow: inset 0 0 0 1px #7cbf9c; }

.z-fp .flatpickr-day.selected,
.z-fp .flatpickr-day.startRange,
.z-fp .flatpickr-day.endRange,
.z-fp .flatpickr-day.selected:hover {
    background-image: var(--z-gold-leaf);
    background-color: #d8b45a;
    box-shadow: inset 0 0 0 1px var(--z-gold-deep);
    color: #2a1f00;
}

/* Today keeps a mark even when another day is chosen. */
.z-fp .flatpickr-day.today:not(.selected) { box-shadow: inset 0 0 0 2px var(--z-gold); }

/* Out of range, or spilling in from the neighbouring month. */
.z-fp .flatpickr-day.flatpickr-disabled,
.z-fp .flatpickr-day.flatpickr-disabled:hover,
.z-fp .flatpickr-day.prevMonthDay,
.z-fp .flatpickr-day.nextMonthDay {
    background-color: transparent;
    background-image: none;
    box-shadow: none;
    color: var(--z-ink-3);
    cursor: default;
}

/* The rule between the months — drawn as a border on the second month's own
   box, so neither grid is displaced. */
.z-fp .flatpickr-weekdaycontainer + .flatpickr-weekdaycontainer,
.z-fp .dayContainer + .dayContainer { border-left: 1px solid var(--z-line); }

/* The visible field flatpickr swaps in for the date input.
   The icon is a background image, not an element: flatpickr builds this input
   itself, so there is no markup of ours to hang a glyph on. Selector carries
   two classes so it outranks `.z-ts-field input`, whose `background`
   shorthand would otherwise wipe the image out. */
.z-ts-field .z-fp-input,
.z-fp-input {
    cursor: pointer;
    padding-right: 42px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238f6f1c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M8 3v4M16 3v4M3 10h18'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 17px 17px;
}

/* THE GLYPH SHRINKS WHERE THE FIELD DOES. In the journey card the date takes
   a third of the row, which is 104px on a 390px phone and 85px in the 1024
   sidebar. The 42px reserve above is then most of the field, and the date is
   cut to "Mon, 0…". A smaller glyph tucked closer to the edge needs 22, and
   the script on the tour page swaps the long read format for a short one at
   these same widths, so what is left reads whole.

   The two bands are exactly where .z-jrow is narrow: the phone, and the
   sidebar between 901 and 1240. Between 561 and 900 the card is full width
   and the field keeps its full-size glyph. */
@media (max-width: 560px), (min-width: 901px) and (max-width: 1240px) {
    .z-journey .z-fp-input {
        background-size: 13px 13px;
        background-position: right 5px center;
        padding-right: 22px;
    }
}

@media (max-width: 991px) {
    .z-fp .dayContainer,
    .z-fp .flatpickr-weekdaycontainer { width: 268px; min-width: 268px; max-width: 268px; }
}

/* A search-bar validation message. Sits under the field row, inside the panel,
   so it reads as part of the control it is about. */
.z-ts-err {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 10px 0 0;
    padding: 9px 12px;
    background: #fdf0e4;
    border: 1px solid #e0b48a;
    border-radius: 9px;
    font-size: 13px;
    font-weight: 600;
    /* 5.9:1 on that ground — a warning nobody can read is not a warning. */
    color: #8a4513;
}
.z-ts-err[hidden] { display: none; }
.z-ts-err::before {
    content: "!";
    flex: none;
    display: grid;
    place-items: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #8a4513;
    color: #fdf0e4;
    font-size: 12px;
    font-weight: 700;
}

/* --- Search suggestions -----------------------------------------------------
   The dropdown under a City / Hotel, Destination or Country field. Anchored to
   the field wrapper, which is the nearest positioned ancestor — the input
   itself is static inside the row.
   -------------------------------------------------------------------------- */
.z-ts-field { position: relative; }        /* the anchor for .z-sug */

.z-sug {
    position: absolute;
    z-index: 30;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    min-width: 260px;
    max-height: 320px;
    overflow-y: auto;
    background: var(--z-surface);
    border: 1px solid var(--z-line-strong);
    border-radius: 12px;
    box-shadow:
        0 0 0 1px rgba(227, 200, 134, .35),
        0 18px 40px -12px rgba(13, 44, 34, .3);
    padding: 5px;
}
.z-sug[hidden] { display: none; }

.z-sug-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}
.z-sug-item:hover,
.z-sug-item.is-on { background: var(--z-cream); }

/* What kind of thing this is — a city, a hotel, a package. Colour-coded so the
   two groups in one list are separable at a glance. */
.z-sug-kind {
    flex: none;
    padding: 3px 7px;
    border-radius: 5px;
    font-size: 8.5px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    background: #e2f4e8;
    color: #0d3b26;
}
.z-sug-kind.is-hotel,
.z-sug-kind.is-package { background: var(--z-cream-deep); color: #7d6015; }

.z-sug-text { min-width: 0; }
.z-sug-text b {
    display: block;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--z-green);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.z-sug-text small {
    display: block;
    font-size: 11.5px;
    color: var(--z-ink-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* --- card grids: the middle of the ladder ----------------------------------
   The base rules step 3 columns -> 1 at the small breakpoint, which left a
   band (roughly 640-780px: a landscape phone, a small tablet) showing ONE card
   stretched to 725px. Two columns is the right answer across that band, so it
   is stated explicitly rather than left to whichever rule happened to win.

   Placed last so it beats both the tablet block above and the single-column
   block, without editing either — those govern several other grids that are
   correct as they stand.
   -------------------------------------------------------------------------- */
@media (min-width: 620px) and (max-width: 1080px) {
    .z-grid-3,
    .z-listing .z-grid-3 { grid-template-columns: repeat(2, 1fr); }
}

/* --- mobile / tablet quick bars ---------------------------------------------
   Below 1080px the desktop nav collapses to a burger, which buries the things
   people actually came for. Two bars put them back: the products in a strip
   under the header, and the account and contact buttons fixed along the
   bottom where a thumb reaches. Both are hidden on desktop, where the full
   nav and the footer columns already carry all of it.

   BOTH BARS ARE WALLS. Same ground as the footer — green, the jali pattern at
   26px, a gold hairline along the edge that faces the page — and each takes a
   run of merlon cresting on that edge, pointing down from the top strip and up
   from the bottom bar, so the page reads as the courtyard between two walls.

   The cresting is a CHILD of each bar, not a sibling. .z-crest-band is
   absolutely positioned and hangs 15px outside its containing block, so it
   needs the bar itself to be that block: the fixed bottom bar already is, and
   the top strip is given position:relative for it. A sibling would have had to
   be positioned against whatever came next up the tree, which on the home page
   is the transparent header over the hero.

   Neither bar tints its icons per item the way the desktop nav does. Those
   tints (#1d4ed8, #7b2f9e, #b91c1c …) were picked to carry on the cream bar
   and go muddy on dark green; gold on green is the treatment every other green
   surface here uses, and the icon shape still says which product it is.
   -------------------------------------------------------------------------- */
.z-quicktop { display: none; }
.z-quickbot { display: none; }

@media (max-width: 1080px) {

    /* --- top: the products ---------------------------------------------- */
    .z-quicktop {
        display: grid;
        /* Six equal columns. At 360px that is 60px each. "Mazaarat" is the
           longest label of the six and measures about 50px at 11px in Jost
           600, so it clears the 8px of item padding — but only just, which
           is why the step-down below moved up to 420px. */
        grid-template-columns: repeat(6, 1fr);
        position: relative;
        /* Full-bleed: the strip is a wall, and a wall runs to both edges. The
           header's shell padding stops at .z-header-in above it. */
        margin-top: 12px;
        background: var(--z-green);
        background-image: var(--z-pattern-dark);
        background-size: 26px 26px;
        /* The hairline here divides the brand row from the icon row. It is
           NOT an edge treatment — the strip's bottom edge carries no rule at
           all, because the cresting stands on that line and anything drawn
           there runs through the feet of the merlons. Same reasoning as the
           bottom bar, which has no rule on either edge. */
        border-top: 1px solid var(--z-line-gold);
    }
    /* THE WHOLE BAR IS THE WALL, brand row included.

       A cream logo row sitting on top of a green product strip read as two
       unrelated bars stacked, not one piece of chrome — so the header takes
       the same ground as the strip below it and the two become a single dark
       block with the cresting along its foot. Every page sets
       $z_header_solid, so there is no transparent-over-hero case to keep
       cream for.

       Translucent and blurred, as the cream version was: .96 over the same
       backdrop-filter, so what scrolls underneath still registers. `background`
       first and `background-image` second — the shorthand would wipe the
       pattern if the order were reversed.

       THE BOTTOM PADDING GOES TOO. It was 10px of painted ground below the
       strip, and the cresting hangs into the strip's own bottom 16px — so the
       merlon gaps showed a stripe of bar wedged between the wall and the page.
       The air above the strip comes back as the strip's own margin-top. */
    .z-header,
    .z-header.is-solid {
        background: rgba(13, 44, 34, .96);
        background-image: var(--z-pattern-dark);
        background-size: 26px 26px;
        padding-bottom: 0;
    }

    /* The lockup's green plate is what separated it from a row of dark icons
       on cream. On a green bar it is a green box on green — invisible, and
       still holding 14px of dead space either side. The artwork is already
       the light variant, so it reads on this ground unaided. */
    .z-brand-lockup {
        background: none;
        background-image: none;
        box-shadow: none;
        padding: 8px 0;
    }
    /* THE BRAND GOES LEFT, THE BUTTONS GO RIGHT, AND NOTHING SITS BETWEEN.

       The middle of this bar used to hold a mobile copy of the tagline, and
       the whole arrangement was built around it: equal flex shares dropped so
       it could find the middle of an off-centre gap, three font-size steps so
       it never ellipsised on a narrow phone, and a hide below 355px. It is
       gone from the bar now — the row is the logo and the way in, and the
       tagline is still said on the home page and in the footer.

       So the two sides are simply pushed apart. `justify-content` does the job
       the tagline's `flex: 1 1 auto` was doing by standing between them, which
       is why the equal shares stay dropped: with only two items, equal shares
       would split the bar down the middle and strand the Login button in the
       middle of the right half.

       The 28px gap goes to 12: it ate 84px of a 358px row at three gaps. */
    .z-header-in {
        gap: 12px;
        justify-content: space-between;
    }
    .z-header-in > .z-brand {
        flex: 0 0 auto;
        align-items: flex-start;
    }
    .z-header-in > .z-header-actions { flex: 0 0 auto; }

    /* The desktop copy, inside the brand link, stands down. */
    .z-header .z-brand-tag { display: none; }

    /* ...and the centred one takes over. The row here is
       logo | tagline | account, and `flex: 1` on the middle child is what
       makes it centre BETWEEN the other two rather than on the viewport —
       absolute centring would have laid it over the account chip on a 360px
       phone, because the logo plate and the chip are not the same width.
       min-width: 0 lets it shrink instead of forcing the row to overflow.

       Set in Cormorant, the display face, not the body Jost: this is the
       masthead line under a calligraphic logo, and the serif is what makes it
       read as part of the brand rather than as a label. Gold on the dark green
       bar — #e3c886 measures 8.9:1 there, so it stays legible at this size —
       and letterspaced, which is what stops small uppercase type looking
       cramped.

       clamp() rather than a breakpoint: it grows smoothly from a 320px phone
       to a 1080px tablet, so there is no width at which it is awkwardly large
       or too small to read. It may take two lines on the narrowest phones and
       that is fine — two lines at this leading are still shorter than the
       66px logo plate beside them, so the bar does not grow.

       THE 66px IS THE CEILING ON THIS SIZE, and it is worth stating in
       numbers because the next person to nudge it will want them. The plate
       is height:50px + 8px padding top and bottom, and the header has no
       fixed height of its own — it sizes to whichever column is tallest, so
       the tagline is free until it passes the plate.

         18px x 1.25 leading x 2 lines  = 45px, + 6px for the rule under it
                                        = 51px, clear of 66px.

       Tablets get one line at this width anyway; two is the phone case, and
       phones never reach 18px because 3.2vw holds them below it. Three lines
       at 18px WOULD overflow (73px), but that needs a column narrower than
       any viewport this rule applies to. Past about 20px the sum stops
       clearing 66px and the bar starts growing. */
    .z-header-tagline {
        display: block;
        flex: 1 1 auto;
        min-width: 0;
        padding: 0 6px;
        text-align: center;
        font-family: var(--z-display);
        font-size: clamp(12px, 3.2vw, 18px);
        /* BOLD, and 700 is a real weight here rather than a synthesised one:
           the Google Fonts link in header.php loads Cormorant Garamond at
           400;500;600;700, so the browser has the cut and does not have to
           smear the 600 to fake it. Cormorant is a high-contrast serif whose
           600 reads as light at 11-16px, which is what this line shrinks to on
           a phone — the extra weight is what makes the masthead hold its own
           against the logo plate beside it. Phone and tablet only: above
           1080px this element is display:none and .z-brand-tag inside the
           brand link carries the copy, where it is a caption under the lockup
           and deliberately lighter. */
        font-weight: 700;
        letter-spacing: .16em;
        line-height: 1.25;
        text-transform: uppercase;
        color: var(--z-gold-light);
        text-wrap: balance;
    }
    /* A hairline under it, the width of the text rather than the slot. The
       same gold rule the manuscript frames and the section ornaments use, so
       the masthead is dressed like the rest of the site instead of being a
       bare line of type. */
    .z-header-tagline::after {
        content: "";
        display: block;
        width: 34px;
        height: 1px;
        margin: 5px auto 0;
        background: linear-gradient(90deg,
            rgba(227, 200, 134, 0) 0%,
            rgba(227, 200, 134, .75) 50%,
            rgba(227, 200, 134, 0) 100%);
    }

    .z-burger {
        background: rgba(227, 200, 134, .12);
        border-color: var(--z-line-gold);
        color: var(--z-gold-light);
    }

    /* a.*, not .*: `.zaereen a:not(:where(.z-btn))` is (0,1,1) and paints
       every link dark green. A bare class selector is (0,1,0) and loses to
       it — which is invisible on a cream bar and unreadable on this one, the
       labels coming out dark green on dark green. Tying the class to the
       element matches that weight and wins on source order, the same trick
       `.z-footer a` uses a few thousand lines up. */
    a.z-quicktop-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 4px;
        /* No reservation at the foot: the cresting hangs BELOW the strip now,
           the mirror of the bottom bar's, so there is nothing here for the
           labels to collide with. */
        padding: 9px 4px;
        text-decoration: none;
        font-size: 11px;
        font-weight: 600;
        color: rgba(240, 233, 215, .92);
        min-height: 56px;
    }
    a.z-quicktop-item:hover { color: var(--z-gold-light); }
    .z-quicktop-item svg { color: var(--z-gold-light); flex: none; }
    a.z-quicktop-item.is-on {
        color: #fff;
        background: rgba(227, 200, 134, .12);
        box-shadow: inset 0 3px 0 var(--z-gold);
    }
    .z-quicktop-item.is-on svg { color: var(--z-gold); }

    /* --- bottom: account and contact ------------------------------------ */
    .z-quickbot {
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 40;
        background: var(--z-green);
        background-image: var(--z-pattern-dark);
        background-size: 26px 26px;
        /* NO RULE ALONG THE TOP EDGE. A border and a gold seam both used to
           sit here, and the cresting stands on this exact line — so the rule
           ran straight through the feet of the merlons and read as a stray
           line drawn across them. The crenellation IS this edge's treatment;
           it does not want underlining. The strip under the header keeps its
           seam because its cresting is inset, clear of the edge. */
        box-shadow: 0 -8px 22px -10px rgba(13, 44, 34, .55);
        /* Clear of the iPhone home indicator; 0 where there is no inset. */
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }
    /* a.*, for the same specificity reason as the strip above. */
    a.z-quickbot-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 4px;
        /* No reservation at the top: this bar's cresting is .is-top, which
           hangs ABOVE the bar rather than standing inside it, so there is
           nothing here for the icons to collide with. (The strip under the
           header still pads for its own, which is inset.) */
        padding: 9px 3px;
        text-decoration: none;
        font-size: 11px;
        font-weight: 600;
        color: rgba(240, 233, 215, .92);
        min-height: 58px;
        /* "My Enquiries" and "Chat With Us" are two words in a 72px column.
           They break rather than push the grid wider. */
        text-align: center;
        line-height: 1.2;
    }
    a.z-quickbot-item:hover { color: var(--z-gold-light); }
    .z-quickbot-item svg { color: var(--z-gold-light); flex: none; }

    /* z_icon strokes at 1.6, a weight chosen for dark glyphs on the cream
       bar. In gold on green that hairline greys out at this size; 2 gives the
       mark a body without closing up its interior detail. */
    .z-quicktop-item svg,
    .z-quickbot-item svg { stroke-width: 2; }
    a.z-quickbot-item.is-on {
        color: #fff;
        background: rgba(227, 200, 134, .12);
        box-shadow: inset 0 3px 0 var(--z-gold);
    }
    .z-quickbot-item.is-on svg { color: var(--z-gold); }

    /* The bar floats over the page, so the last of the content needs room to
       clear it — otherwise the footer's final line sits underneath.

       EXACTLY THE BAR, not the bar plus its cresting. Reserving 78 for a 58px
       bar left 20px of page ground below the end of the footer, which showed
       at the foot of every page as a strip of parchment between the green
       footer and the green bar, with the merlons stranded in it. Matching the
       bar's own height closes it: the footer now runs to the bar's top edge.

       The cresting is not counted because it is not content — it hangs over
       whatever is behind it by design. env() matches the inset the bar adds to
       its own padding on a notched phone, so the two grow together. */
    body.zaereen { padding-bottom: calc(58px + env(safe-area-inset-bottom, 0px)); }
}

@media (max-width: 420px) {
    /* Was 380px, for a five-column strip. The sixth column takes each one
       down to about 60px at 360px wide, so the labels reach their limit
       sooner — "Mazaarat" and "Holidays" are what run out of room first.
       The icons still read at any width; only the words step down. */
    .z-quicktop-item span { font-size: 9.5px; }
}

@media (max-width: 380px) {
    /* The bottom bar keeps its own threshold: it still has five columns. */
    .z-quickbot-item span { font-size: 9.5px; }
}

/* --- mobile / tablet: hero heading and a shorter tab set --------------------
   Below 1080px the headline goes. On a phone it costs a third of the first
   screen before anything useful appears, and the search bar underneath is the
   real reason anyone opened the page.

   With the heading gone the hero's padding has no content to frame, so it
   collapses too — otherwise the band is just an empty stripe. What remains is
   enough dark ground for the crest and the top of the search bar to sit on.
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
    .z-pagehead.is-home h1 { display: none; }
    /* 96px of bottom padding was sized to hold the top half of a search bar
       that rides up into it. On desktop it does — by 119px. Here the bar only
       rises 18px, so most of that padding was empty dark band between a
       hidden heading and the bar. Both numbers move together: less padding
       below, more rise above, so the bar sits ON the crest rather than under
       a stripe of nothing. */
    .z-pagehead.is-home { padding: 14px 0 44px; margin-bottom: 0; }
    /* -42, not -26: the tab strip is 40px and the crest band hangs from the
       hero's bottom edge. At -26 the band's battlements cut across the
       bottom 15px of the tabs, which is what made them look broken. The bar
       has to rise by at least the strip's own height so the tabs sit wholly
       on the dark ground and the panel below covers the band — the same
       arrangement desktop gets from -119. It also lifts the bar 16px more. */
    .z-ts { margin-top: -42px; margin-bottom: 20px; }

    /* Four tabs, not five: five across a phone leaves no room for a label.
       Visas is the one that steps out — it keeps its own entry in the bottom
       bar and in the header strip, so it does not become unreachable. The DOM
       order is already Ziyarat, Flights, Hotels, Holidays once it is out, so
       nothing needs reordering. */
    .z-ts-strip .z-ts-tab[for="z-tab-visas"] { display: none; }

    /* Their labels come back, since three tabs fit comfortably. */
    .z-ts-tab span { display: inline; }
}

/* --- mobile / tablet: section rhythm ---------------------------------------
   Desktop gives every section 48px of padding top AND bottom, so consecutive
   sections sit 96px apart. On a phone that is most of a screen of nothing
   between one heading and the next, and there are eight of them.

   34px halves the boundary without letting the sections run together — the
   heading block above each one still reads as belonging to what follows.
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
    .z-section { padding-top: 34px; padding-bottom: 34px; }
    .z-section.is-green { margin-top: 18px; margin-bottom: 18px; }

    /* The heading, its ornament and the gap beneath came to 116px before a
       single card appeared. */
    .z-section-head { margin-bottom: 20px; }
}

/* --- mobile / tablet: no green band behind the search bar -------------------
   With the headline hidden there is nothing left for the dark band to frame —
   it is just a green strip behind the tabs. Removed, along with the crest that
   edges it, so the bar sits straight on the page.

   The tabs have to change with it. They were built for a dark ground: a cream
   veil at 15% and cream text, which on the page's own cream reads as nothing
   at all. On a light ground they invert — a cream-deep chip with dark green
   text and a gold edge — while the active tab keeps its gold leaf, so the
   selected one still reads the same way it does on desktop.
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
    .z-pagehead.is-home {
        background: transparent;
        background-image: none;
        /* The green band used to separate the logo row from the search bar.
           With it gone the two collided, so the gap is now real padding.

           36, not 22: the header's cresting hangs 15px below the bar, which
           left 7px between the points of the merlons and the top of the tabs
           — close enough to read as a collision. This clears the teeth by
           about 20. */
        padding: 36px 0 0;
    }
    .z-pagehead.is-home .z-crest-band { display: none; }
    /* AND THE GOLD SEAM GOES WITH THE BAND. .z-pagehead::after draws a
       full-width rule along the band's bottom edge — right for a green band
       that needs closing, wrong here, where there is no band and the edge
       lands across the top of the tab strip. It was the stray line running
       behind the tabs. Scoped to .is-home: every other page still has its
       green band and still wants the seam under it. */
    .z-pagehead.is-home::after { display: none; }

    /* Nothing to rise into any more; the bar just follows the header. */
    .z-ts { margin-top: 0; margin-bottom: 20px; }

    .z-ts-tab {
        /* Light green, not the near-white --z-surface it used to be. On
           desktop these tabs are a cream veil over the dark hero, so they
           read as green there; with the hero gone the same veil went white
           and the strip lost that colour entirely. --z-green-soft is the
           palette's pale green — the badge mint — which puts the green back
           at a weight that works on a light ground.

           NOT --z-cream: the page IS --z-cream, so a cream tab measures 1.00
           against its own ground and only the border shows. */
        background: var(--z-green-soft);
        /* A green edge rather than the tan --z-line-strong, so the chip reads
           as one colour rather than a mint fill in a sand frame. */
        border-color: rgba(31, 96, 71, .34);
        color: var(--z-green);
    }
    /* The bare line under the bar was the PANEL'S TOP BORDER, not a
       leftover: hiding Flights and Visas at this width left three tabs
       covering ~400px of a ~725px strip, so the rest of that edge ran on
       with nothing sitting on it. The three stretch to fill it instead,
       and the side padding goes so they reach both corners — which reads
       as a segmented control rather than chips beside a stray rule. */
    /* Chips the office keeps on desktop but not here. 1080 is this
       design's tablet line — the same one that drops Flights and Visas —
       so the chip goes at the width the rest of the bar changes at, not
       at the 900 where the fields stack. */
    .z-quick .z-chip.is-lg-only { display: none; }

    /* No side padding, so the first tab starts on the panel's left edge —
       which is what .z-ts-tab:first-of-type squares its corner for. */
    .z-ts-strip { padding: 0; }
    .z-ts-tab {
        /* EACH TAB IS ITS OWN WIDTH, not a third of the bar. `flex: 1 1 0`
           stretched the three across the whole 358px panel edge, which made
           them read as blocks the size of the search box rather than tabs
           sitting on it. Content-width is what desktop does, and the three
           together come to about 234px of a 328px strip on a 360px phone —
           narrower than the panel, which is the point.

           `flex: none` is the base value; named rather than left to the
           cascade because it is the whole reason this rule exists. */
        flex: none;
        /* Smaller type than the desktop chip, but the height stays where it
           was: 12px over 6/7 vertical padding.

           Side padding is what sets how much of the panel edge the run of
           tabs covers, and with four of them it is tight. Measured totals for
           Ziyarat/Flights/Hotels/Holidays: 283px at 4, 315 at 8, 331 at 10,
           347 at 12. The panel is the viewport less 32, so 10 fits from
           376px up (331 into 344) and gives about 92% coverage — full enough
           to sit under the box without stretching to meet it. The two steps
           below cover the narrower phones. */
        padding: 6px 10px 7px;
        font-size: 12px;
        gap: 5px;
    }
    .z-ts-tab svg { width: 15px; height: 15px; }

    /* The active tab's bottom padding has to come down with it. It is set on
       the :checked selectors, which outrank anything shorter, so the list is
       repeated here — 2px more than its neighbours, which is the overlap that
       sits it on the panel edge. Left at 11 it would have shown 4px of gold
       over the panel instead of 2. */
    #z-tab-ziyarat:checked  ~ .z-ts-strip .z-ts-tab[for="z-tab-ziyarat"],
    #z-tab-flights:checked  ~ .z-ts-strip .z-ts-tab[for="z-tab-flights"],
    #z-tab-hotels:checked   ~ .z-ts-strip .z-ts-tab[for="z-tab-hotels"],
    #z-tab-holidays:checked ~ .z-ts-strip .z-ts-tab[for="z-tab-holidays"],
    #z-tab-visas:checked    ~ .z-ts-strip .z-ts-tab[for="z-tab-visas"] {
        padding-bottom: 9px;
    }
    .z-ts-tab:first-of-type { border-top-left-radius: 0; }
    .z-ts-tab svg { color: var(--z-gold-deep); flex: none; }
    .z-ts-tab:hover {
        /* One step down from --z-green-soft. The palette has no darker mint,
           and reaching for --z-cream-deep here would take the hover back to
           sand — the one thing the green chip was meant to stop. */
        background: #cfe1d5;
        color: var(--z-green);
        border-color: var(--z-green-3);
    }
}

/* FOUR TABS ON A NARROW PHONE.

   MUST COME AFTER the 1080 block: that one sets `padding` as a shorthand, so
   a padding-left/right written earlier loses to it whatever the media query
   says. This bit me — the 375 step silently did nothing and the run stayed at
   its 10px width.

   .z-ts-strip is flex-wrap:wrap from 900px down, so an overlong run drops to
   a second row rather than pushing the page sideways. That is the safety net,
   not the design: two rows of tabs doubles the strip to 71px. These steps
   keep the run on one line. Measured: 315px at 8 (fits 356px up, panel 324),
   283 at 4 (fits 320, panel 288). */
@media (max-width: 375px) {
    .z-ts-tab { padding-left: 8px; padding-right: 8px; }
}
@media (max-width: 355px) {
    .z-ts-tab { padding-left: 4px; padding-right: 4px; }
}

/* ============================================================ hotel detail ===
   zaereen/hotels/detail.php. Deliberately reuses the tour card's .z-journey,
   .z-qty, .z-gal and .z-paytable — only the pieces a hotel has and a tour does
   not are defined here. */

/* Facilities. Forty-four amenities in one run is a wall; the CRM already
   groups them, so the page prints the groups. */
.z-amen {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 18px 26px;
}
.z-amen-group h6 {
    margin: 0 0 8px;
    font-size: 10.5px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep, #7d6015);
}
.z-amen-group ul { margin: 0; }
.z-amen-group li { font-size: 13.5px; }

/* The CRM's "note" field: a house rule or a caution, so it is set apart rather
   than run into the description. */
.z-hnote {
    display: flex; align-items: flex-start; gap: 9px;
    margin: 16px 0 0;
    padding: 11px 13px;
    border-radius: 10px;
    font-size: 13.5px;
    background: rgba(193, 154, 63, .1);
    border: 1px solid rgba(193, 154, 63, .3);
    color: var(--z-ink-2, #40504a);
}
.z-hnote svg { flex: none; margin-top: 2px; color: var(--z-gold-deep, #7d6015); }

@media (max-width: 720px) {
}

/* --------------------------------------------------------------- the map ---
   An <iframe> with no width or height falls back to its intrinsic default —
   a small box floating in the corner of the panel, which is what this looked
   like. The frame is stretched to fill a container whose SHAPE is set here
   instead, so the map is sized by the layout rather than by the element's own
   opinion.

   aspect-ratio holds the shape at any width; min-height is the floor for a
   browser too old to support it, where the absolutely positioned iframe would
   otherwise collapse to nothing. */
.z-map {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    min-height: 320px;
    border-radius: 12px;
    overflow: hidden;                 /* clips the frame to the rounded corner */
    border: 1px solid var(--z-line-gold, rgba(193, 154, 63, .34));
    background: var(--z-cream, #f7f2e6);   /* while the frame loads */
}
.z-map iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

@media (max-width: 720px) {
    /* Taller in proportion on a phone: 16/9 of a 340px column is 190px, which
       is too little map to read. */
    .z-map { aspect-ratio: 4 / 3; min-height: 260px; }
}

/* ================================================= live hotel results (TBO) ===
   zaereen/hotels/search.php. A vertical card in a three-up grid: picture, name,
   the Location / Category / Starting From row, the address, then a footer with
   the price and the button — the shape the Oxford results use, in this palette. */
.z-hres {
    display: grid;
    /* auto-fill with a floor, so it is three across on a desktop, two on a
       tablet and one on a phone without a breakpoint for each. */
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 22px;
    align-items: stretch;
}

.z-hres-card {
    display: flex;
    flex-direction: column;
    background: var(--z-surface, #fffdf7);
    border: 1px solid var(--z-line-gold, rgba(193, 154, 63, .3));
    border-radius: 14px;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    transition: box-shadow .16s ease, transform .16s ease;
}
.z-hres-card:hover {
    box-shadow: 0 14px 34px rgba(18, 51, 42, .15);
    transform: translateY(-3px);
}
.z-hres-card.is-skeleton { pointer-events: none; }
.z-hres-card.is-skeleton:hover { box-shadow: none; transform: none; }

.z-hres-img {
    position: relative;
    aspect-ratio: 16 / 10;
    /* The patterned ground shows through where a supplier photo is missing
       or 404s, so the card reads as "no picture" rather than as a hole. */
    background-color: var(--z-cream, #f2ece0);
    background-image: var(--z-pattern, none);
    background-size: 22px 22px;
    /* The gold rule under the photo, as the reference card has. */
    border-bottom: 2px solid var(--z-gold, #c19a3f);
    overflow: hidden;
}
/* :not(.z-hres-flag) is doing real work here. `.z-hres-img img` is specificity
   (0,1,1) and `.z-hres-flag` only (0,1,0), so the flag — an <img> inside this
   very box — inherited inset:0 and width/height 100% and was drawn over the
   whole frame. The hotel photo was loading correctly the entire time, hidden
   behind a full-bleed national flag. */
.z-hres-img > img:not(.z-hres-flag) {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
}

/* Flag and stars sit ON the photo: they are facts about the hotel, not another
   row of text competing with the name. */
/* Scoped to the container so it outranks any rule targeting the images inside
   it, rather than relying on source order to win. */
.z-hres-img .z-hres-flag {
    position: absolute;
    top: 10px; left: 10px;
    right: auto; bottom: auto;
    width: 34px; height: auto;
    border-radius: 3px;
    object-fit: fill;
    box-shadow: 0 1px 5px rgba(0, 0, 0, .4);
    z-index: 2;
}
.z-hres-rate {
    position: absolute; top: 10px; right: 10px;
    z-index: 2;
    padding: 4px 9px;
    border-radius: 8px;
    background: rgba(11, 34, 28, .82);
    border: 1px solid rgba(221, 193, 124, .5);
    line-height: 1;
    white-space: nowrap;
}
.z-hres-rate .z-hres-star { color: var(--z-gold-light, #ddc17c); font-size: 12px; }

.z-hres-body {
    display: flex; flex-direction: column;
    gap: 12px;
    padding: 16px 18px;
    flex: 1 1 auto;          /* pushes the footer down on a short card */
    min-width: 0;
}
/* Set exactly as the holidays product card sets its name, so the two grids read
   as one site rather than two.

   NOT the display serif, and that is the holidays card's reasoning carried
   over: Cormorant Garamond is loaded at 400-700, so 700 is its heaviest cut and
   anything "bolder" can only be a synthesised smear. Jost 700 is a real weight,
   and a hotel name in a scanned grid is UI rather than editorial.

   Dark brown rather than gold: #4a3418 measures 11.5:1 on this card, where the
   gold was closer to 4:1 — legible, but thin for the one line every visitor
   reads first. */
.z-hres-body h3 {
    margin: 0;
    font-family: var(--z-body);
    font-size: 17px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: .02em;
    text-transform: uppercase;
    text-align: center;
    color: #4a3418;
    text-wrap: balance;
}

.z-hres-meta {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 4px 10px;
    padding: 12px 0;
    border-top: 1px solid var(--z-line-gold, rgba(193, 154, 63, .24));
    border-bottom: 1px solid var(--z-line-gold, rgba(193, 154, 63, .24));
    text-align: center;
}
.z-hres-meta h6 {
    margin: 0 0 4px;
    font-size: 9px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-gold-deep, #7d6015);
}
.z-hres-meta p {
    margin: 0;
    font-size: 13px; font-weight: 600;
    color: var(--z-ink, #1d2a24);
    /* One line each: a long city or category must not push the three columns
       out of step with the card beside it. */
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.z-hres-wait { font-weight: 500; color: var(--z-ink-3, #6b6558); font-style: italic; }
.z-hres-none { font-weight: 500; color: var(--z-ink-3, #6b6558); }

.z-hres-addr {
    display: flex; align-items: flex-start; gap: 7px;
    margin: 0;
    font-size: 12.5px; line-height: 1.5;
    color: var(--z-ink-2, #40504a);
    /* Two lines at most — TBO addresses run very long. */
    overflow: hidden;
}
.z-hres-addr::before {
    content: "\1F4CD";                /* pin */
    font-size: 12px;
    line-height: 1.4;
    flex: none;
}

.z-hres-foot {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    padding: 13px 18px;
    background: var(--z-cream, #f7f2e6);
    border-top: 1px solid var(--z-line-gold, rgba(193, 154, 63, .26));
}
.z-hres-fromwrap { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.z-hres-fromwrap small {
    font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-ink-3, #6b6558);
}
.z-hres-fromwrap b {
    font-family: var(--z-display, Georgia, serif);
    font-size: 18px; font-weight: 600;
    color: var(--z-gold-deep, #7d6015);
    white-space: nowrap;
}
.z-hres-cta {
    flex: none;
    padding: 9px 16px;
    border-radius: 9px;
    background: linear-gradient(180deg, var(--z-gold-light, #ddc17c), var(--z-gold, #c19a3f));
    color: #23180a;
    font-size: 12.5px; font-weight: 700;
    letter-spacing: .04em;
    white-space: nowrap;
}

.z-hres-more { display: flex; justify-content: center; margin-top: 26px; }

/* Skeletons. Animated only where the visitor has not asked for stillness. */
.z-sk {
    display: block;
    height: 12px;
    border-radius: 6px;
    background: linear-gradient(90deg, rgba(18,51,42,.07), rgba(18,51,42,.13), rgba(18,51,42,.07));
    background-size: 200% 100%;
    animation: z-sk-pulse 1.2s ease-in-out infinite;
}
.z-sk-title { height: 18px; width: 70%; margin: 0 auto 4px; }
.z-sk-line  { width: 90%; }
.z-sk-line.is-short { width: 55%; }
@keyframes z-sk-pulse {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
    .z-sk { animation: none; }
}

@media (max-width: 560px) {
    /* Three meta columns in a phone-width card gives each about 90px, which
       truncates every value. Two columns hold their values whole. */
    /* LOCATION | CATEGORY | COUNTRY — three cells, all the way down.

       Two columns were here because the third cell used to be a second copy of
       the price, which left an orphan on row two. That cell is Country now, so
       there is nothing to drop and no reason to halve the row: three values
       across a card is the shape the desktop card has, and keeping it means
       the phone reads the same card rather than a different one.

       The values wrap instead of truncating at this width. "United Arab
       Emirates" in a 113px column is two lines, and two lines of country is
       worth more than "United Arab E…". Grid rows take the tallest cell, so
       the three stay level whichever of them wraps. */
    .z-hres-meta { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px 6px; }
    .z-hres-meta p {
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        line-height: 1.35;
    }

    /* STARTING FROM | VIEW DETAILS, on one line. Stacking them gave the card a
       centred price above a full-width button — two more bands of height at
       the end of every result, on the screen with the least of it. They fit
       side by side: the pair want about 220px of the 344px a 412px phone
       leaves inside the footer's padding. */
    .z-hres-foot {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        text-align: left;
        padding: 12px 14px;
    }
    .z-hres-cta { padding: 9px 14px; }
}

/* ============================================ live hotel details (TBO) ===
   zaereen/hotels/stay.php. Reuses .z-pagehead, .z-facts, .z-tabs, .z-gal,
   .z-map and .z-journey wholesale — only the room list is new. */

/* The stay in one line under the dates, so the panel does not need three more
   fields to say what the strip above already shows. */
/* ======================================================== BOOK YOUR STAY (aside)
   hotels/stay.php's sidebar. Scoped to .z-stayside throughout so none of it
   reaches the tour page's booking card, which shares .z-journey.

   ONE RHYTHM, SET IN ONE PLACE. The panel was a stack of blocks each carrying
   its own bottom margin — 14px here, 12px there, 4px on the next — so nothing
   lined up with anything and the gaps read as accidents. The body is a grid
   now and the gap is the only spacing between sections; the children set none
   of their own. */
.z-stayside .z-journey-body {
    display: grid;
    gap: 18px;
    padding: 18px;
}
.z-stayside .z-journey-body > * { margin: 0; }

/* --- the party builder ----------------------------------------------------
   NAMED .z-party, NOT .z-stay.

   .z-stay already exists further up this file: it is the flights/tour route
   card, used by zaereen/holidays/detail.php, and it carries its own padding,
   surface and a `.z-stay b { font-family: var(--z-display) }`. Borrowing the
   name meant two components fighting over one selector — this panel inherited
   a 16px padding it never asked for, which pushed the room block's labels 30px
   in against the date labels' 14px and is exactly the misalignment on screen;
   "Room 1" came out in the display serif from the same collision; and, the
   other way round, this panel's gold ground and 12px radius were being applied
   to the tour route cards on the holidays page.

   ONE INSET, SET ONCE. Every row below is padded 14px from the card edge and
   nothing nests a second box inside it, so the date labels, the room labels
   and the buttons all start on the same vertical line. */
.z-party {
    border: 1px solid var(--z-line-gold);
    border-radius: 12px;
    background: var(--z-gold-wash);
    padding: 0;
    overflow: hidden;
}

/* minmax(0, 1fr) and not 1fr: a native date input reports an intrinsic width
   of about 200px, and a bare 1fr track is min-width:auto, so the two dates
   refuse to shrink and the row overflows the panel — which is what clipped the
   check-in field's calendar button while check-out kept its own. */
.z-party-dates {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 84px minmax(0, 1fr);
    align-items: end;
    gap: 8px;
    padding: 13px 14px;
}

/* CENTRED, BECAUSE THE CONTROLS ARE.
   A stepper puts its figure in the middle of the field and a date input centres
   its own text here too, so a label ranged left sat off to one side of the
   thing it names. Centring the label puts it over its own control, and the
   three fields then read as three columns rather than three left edges at
   different places. */
.z-occf { display: grid; gap: 5px; min-width: 0; text-align: center; }
.z-occf > label {
    display: flex; align-items: center; justify-content: center; gap: 4px;
    font-family: var(--z-body, inherit);
    font-size: 9px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-gold-deep);
    white-space: nowrap;
    min-width: 0;
}
/* The mark never shrinks and never wraps away from its word. */
.z-occf > label svg { flex: none; }
.z-occf input[type="date"],
.z-occf select {
    width: 100%;
    min-width: 0;
    height: 36px;
    padding: 0 8px;
    border: 1px solid var(--z-line);
    border-radius: 8px;
    background: var(--z-surface);
    font: inherit; font-size: 12.5px;
    color: var(--z-ink);
    text-align: center;
}
/* A select centres its text but keeps its arrow at the edge, so the visible
   text sits slightly left of true centre without this. */
.z-occf select { text-align-last: center; padding-right: 4px; }
.z-occf input[type="date"]:focus-visible,
.z-occf select:focus-visible { outline: 2px solid var(--z-gold); outline-offset: 1px; }
.z-occf > small {
    font-size: 9px; line-height: 1.3;
    color: var(--z-ink-3);
}

/* --- Check-in | Nights | Check-out, where three across will not fit --------
   A native date input needs about 115px to draw mm/dd/yyyy AND the calendar
   button beside it. Three columns give it that only while the panel is wide:

       rail 340px (<=1240)   106px   too narrow
       rail 300px (<=1080)    86px   too narrow
       full  768px           288px   fine
       phone 412px           112px   too narrow
       phone 360px            86px   too narrow

   Under 115 the browser keeps the button and clips the date, which is what put
   a half-shown "09/17/202" against the calendar glyph.

   TWO BANDS, NOT ONE. The panel is a narrow rail between 901 and 1240, full
   width from 900 down to the phone, and narrow again below 560 — so the middle
   of that range is the only part that was ever fine. Both tight bands get the
   same arrangement: the two dates share row one, and Nights takes row two on
   its own. It is the derived value of the three; it reads as a total under
   them rather than as a third date between them.

   Placed by grid-row rather than by DOM order, so the markup stays
   Check-in / Nights / Check-out for anyone reading it or tabbing through it. */
@media (min-width: 901px) and (max-width: 1240px) {
    .z-party-dates { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .z-party-dates .z-occf.is-date   { grid-row: 1; }
    .z-party-dates .z-occf.is-nights { grid-row: 2; grid-column: 1 / -1; }
    .z-party-dates .z-occf.is-nights .z-step { max-width: 160px; margin: 0 auto; }
}

@media (max-width: 560px) {
    .z-party-dates {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: 8px 10px;
        padding: 12px;
    }
    .z-party-dates .z-occf.is-date   { grid-row: 1; }
    .z-party-dates .z-occf.is-nights { grid-row: 2; grid-column: 1 / -1; }
    /* The stepper does not want a whole row's width — centred at its natural
       size it stays a control rather than becoming a banner. */
    .z-party-dates .z-occf.is-nights .z-step { max-width: 160px; margin: 0 auto; }
}

/* --- the stepper ---------------------------------------------------------- */
.z-step {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) 30px;
    align-items: stretch;
    height: 36px;
    border: 1px solid var(--z-line);
    border-radius: 8px;
    background: var(--z-surface);
    overflow: hidden;
}
.z-step input {
    min-width: 0;
    border: 0;
    background: none;
    text-align: center;
    font: inherit; font-size: 14px; font-weight: 700;
    color: var(--z-ink);
    font-variant-numeric: tabular-nums;
}
.z-step input:focus { outline: none; }
.z-step-b {
    border: 0;
    background: var(--z-gold-wash);
    color: var(--z-gold-deep);
    font: inherit; font-size: 16px; font-weight: 700; line-height: 1;
    cursor: pointer;
}
.z-step-b:hover:not(:disabled) { background: var(--z-gold-light); color: var(--z-green); }
/* Dimmed rather than removed: a control that disappears at its limit shifts
   everything beside it. */
.z-step-b:disabled { opacity: .3; cursor: default; }

/* --- one room per block, on the same inset as everything else -------------- */
.z-occ {
    border-top: 1px solid var(--z-line-gold);
    background: rgba(255, 253, 247, .62);
}
.z-occ-room { padding: 12px 14px; }
.z-occ-room + .z-occ-room { border-top: 1px dashed var(--z-line-gold); }

/* Room | Adults | Children across one row. The room's column is narrower
   because it holds a two-digit number rather than a stepper, so the two
   steppers keep a usable width instead of all three sharing a third each. */
.z-occ-row {
    display: grid;
    grid-template-columns: minmax(0, .62fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: 9px;
    align-items: start;
}

/* The number stands at the same height as the steppers beside it, so the three
   columns share one baseline and the room reads as a peer of the other two
   rather than as a caption above them. */
.z-occ-no {
    display: flex; align-items: center; justify-content: center;
    height: 36px;
    border: 1px solid var(--z-line-gold);
    border-radius: 8px;
    background: var(--z-gold-wash);
    font-family: var(--z-display);
    font-size: 15px; font-weight: 700;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
}
.z-occ-x {
    border: 0; background: none; padding: 0;
    font: inherit; font-size: 9.5px; font-weight: 600;
    color: var(--z-ink-3);
    cursor: pointer;
    text-align: center;
}
.z-occ-x:hover { color: #8a3024; text-decoration: underline; }
.z-occ-x[hidden] { display: none !important; }
/* Two per row: at this width one column wastes half the panel and four across
   leaves no room for a two-digit age. */
.z-occ-ages { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.z-occ-age { margin-top: 9px; }
.z-occ-age[hidden] { display: none !important; }

/* The crowded-room note. Amber, not red: nothing is wrong yet and nothing is
   blocked -- the party is still searched exactly as asked. */
.z-occ-warn {
    display: flex; align-items: flex-start; gap: 6px;
    margin: 9px 0 0;
    padding: 7px 9px;
    border-radius: 8px;
    background: rgba(163, 84, 24, .09);
    font-size: 10px; line-height: 1.45;
    color: #a35418;
}
.z-occ-warn svg { flex: none; margin-top: 1px; }
.z-occ-warn[hidden] { display: none !important; }

/* The empty-rates panel has to fit the sidebar as well as the main column. */
.z-empty.is-tight { padding: 18px 14px; }
.z-empty.is-tight b { font-size: 14px; }
.z-empty.is-tight p { font-size: 12px; line-height: 1.55; }


/* Shown only while the panel and the priced party disagree. */
.z-party-stale {
    display: flex; align-items: flex-start; gap: 7px;
    margin: 0;
    padding: 9px 14px;
    border-top: 1px solid var(--z-line-gold);
    background: rgba(163, 84, 24, .09);
    font-size: 10.5px; line-height: 1.45;
    color: #a35418;
}
.z-party-stale svg { flex: none; margin-top: 1px; }
.z-party-stale[hidden] { display: none !important; }

/* --- the actions ---------------------------------------------------------- */
.z-party-act {
    padding: 12px 14px;
    border-top: 1px solid var(--z-line-gold);
    background: rgba(255, 253, 247, .62);
}
.z-occ-add {
    width: 100%;
    display: flex; align-items: center; justify-content: center; gap: 7px;
    height: 38px;
    margin-bottom: 9px;
    border: 1px dashed var(--z-line-gold);
    border-radius: 9px;
    background: none;
    font: inherit; font-size: 12px; font-weight: 600;
    color: var(--z-green-3);
    cursor: pointer;
}
.z-occ-add:hover { background: rgba(193, 154, 63, .12); }
.z-occ-add svg { color: var(--z-gold-deep); }
.z-occ-add[hidden] { display: none !important; }
.z-party-act p {
    margin: 7px 0 0;
    text-align: center;
    font-size: 10.5px; line-height: 1.45;
    color: var(--z-ink-3);
}
/* --- the footer ----------------------------------------------------------- */
.z-party-foot { display: grid; gap: 10px; }
.z-stayside .z-book-note { margin: 0; }

/* --- the room list -------------------------------------------------------- */
.z-stayside #zRooms { display: grid; gap: 12px; }
.z-stayside #zRooms > .z-rooms-tbl { margin: 0; }

/* Waiting, and every other state where the panel has words instead of rooms. */
.z-jwait {
    margin: 0;
    padding: 16px 12px;
    text-align: center;
    font-size: 13.5px;
    color: var(--z-ink-3, #6b6558);
}

/* One room, one form: the whole row submits, so the price and the button
   cannot disagree about which room was chosen. */
/* --- the compact room list ------------------------------------------------
   One table, not three cards. Every price and every button sits on the same
   vertical line because they share one grid column, and the rows are divided
   by a hairline rather than each being boxed. */
.z-rooms-tbl {
    border: 1px solid var(--z-line-gold);
    border-radius: 11px;
    overflow: hidden;
    background: var(--z-surface);
}
.z-rooms-hd {
    display: grid;
    grid-template-columns: 1fr 104px;
    gap: 10px;
    padding: 7px 12px;
    background: var(--z-gold-wash);
    border-bottom: 1px solid var(--z-line-gold);
    font-size: 9.5px; font-weight: 700;
    letter-spacing: .13em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-rooms-hd span:last-child { text-align: right; }

/* The 96px column is what does the aligning: it is the same width whatever the
   name beside it runs to, so the figures read straight down. */
.z-room {
    display: grid;
    grid-template-columns: 1fr 104px;
    gap: 10px;
    align-items: start;
    padding: 11px 12px;
    border: 0;
    border-radius: 0;
    background: none;
}
.z-room + .z-room { margin-top: 0; border-top: 1px solid var(--z-line-soft); }

.z-room-i { min-width: 0; }
.z-room-i b {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 12.5px; font-weight: 700; line-height: 1.35;
    color: var(--z-ink);
}
.z-room-i span {
    display: block;
    margin-top: 3px;
    font-size: 10.5px; line-height: 1.45;
    color: var(--z-ink-3);
}
.z-room-i i { font-style: normal; font-weight: 600; }
.z-room-i i.is-free   { color: var(--z-green-3); }
.z-room-i i.is-nonref { color: #8a3024; }

.z-room-p { text-align: right; min-width: 0; }
/* THE RATE: PLAIN FACE, DARK INK.

   Was Cormorant Garamond in --z-gold-deep. A price is data, not a
   flourish -- the display serif made the digits harder to read at
   13.5px than the body face does, and the gold measured 4.7:1 on the
   card against 14.7:1 for the green. It is also the one number on the
   card a visitor is actually comparing between rooms, so it is set a
   little larger than the label beside it.

   Matches the "starting from" figure on the city cards, which was
   moved off gold for the same reason. */
.z-room-p b {
    display: block;
    font-family: var(--z-body);
    font-size: 15.5px; font-weight: 700; line-height: 1.25;
    letter-spacing: -.01em;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
}
/* The currency code, set down so the number is what the eye lands on. It also
   buys the figure back about 20px of a 104px column, which is what keeps a
   six-figure total on one line. */
.z-room-p b i {
    font-style: normal;
    font-size: 9px; font-weight: 700;
    letter-spacing: .06em;
    color: var(--z-ink-3);
    margin-right: 3px;
    vertical-align: 1px;
}
.z-room-p em {
    display: block;
    margin: 2px 0 7px;
    font-style: normal;
    font-size: 9.5px; line-height: 1.3;
    color: var(--z-ink-3);
}
.z-room-p .z-btn {
    width: 100%;
    padding: 5px 4px;
    font-size: 11px;
    letter-spacing: .04em;
}

/* --- the guests, read back rather than asked again ------------------------- */
.z-gdroom.is-review .z-gdroom-head + .z-gdtable { padding-bottom: 12px; }
/* A value where the form had an input: same column, same baseline, so the two
   screens line up when a customer flicks between them. */
.z-gdval {
    font-size: 13.5px; line-height: 1.4;
    color: var(--z-ink);
    overflow-wrap: anywhere;
}
.z-gdcontact.is-read {
    display: flex; flex-wrap: wrap; gap: 8px 18px;
    margin-left: auto;
}
.z-gdcontact.is-read span {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12.5px; color: var(--z-ink-2);
}
.z-gdcontact.is-read svg { color: var(--z-green-3); }
.z-gdedit {
    display: flex; align-items: flex-start; gap: 7px;
    margin: 0; padding: 11px 18px;
    border-top: 1px solid var(--z-line-soft);
    font-size: 11.5px; line-height: 1.5;
    color: var(--z-ink-3);
}
.z-gdedit svg { flex: none; margin-top: 2px; }
.z-gdedit a { color: var(--z-green-3); font-weight: 600; }

/* The stars in the facts strip sit on cream, not on the dark page head. */
.z-stars.is-onlight i { color: var(--z-line); }
.z-stars.is-onlight i.is-on { color: var(--z-gold); }
.z-stars.is-onlight i.is-on svg { filter: none; }

/* A summary line that is a statement, not a figure. */
.z-room-sum dd.is-note { font-size: 11.5px; font-weight: 600; color: var(--z-ink-3); }

/* THE READ-ONLY PANEL IS SIZED FOR WHAT IT HOLDS.
   It was borrowing .z-party-dates from the Book Your Stay panel, whose middle
   column is 84px because it holds a THREE-CELL STEPPER. Here the middle holds
   the two characters "01", so the row came out as two wide columns either
   side of a gap. Three equal columns instead, every value centred under its
   own label, so the three read as one row. */
.z-party.is-read .z-party-dates {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
    gap: 6px;
    padding: 13px 12px;
}
.z-party.is-read .z-occf { text-align: center; gap: 4px; }
.z-party.is-read .z-occf label { justify-content: center; font-size: 8.5px; letter-spacing: .1em; }
/* Plain face, not the display serif .z-gdate uses elsewhere. The colour
   was already --z-green; what made these read thin is Cormorant
   Garamond at 13px. Same treatment as the room rates and the total, so
   every fact in this panel is set in one face. */
.z-party.is-read .z-gdate {
    font-family: var(--z-body, inherit);
    font-size: 13.5px; font-weight: 700;
    color: var(--z-green);
    white-space: normal;
    font-variant-numeric: tabular-nums;
}
/* The nights column carries two characters against two dates, so it is given
   rules either side rather than left looking like a gap. */
.z-party.is-read .z-occf.is-nights {
    width: auto;
    border-left: 1px solid var(--z-line-gold);
    border-right: 1px solid var(--z-line-gold);
}

/* --- the shared booking panel ---------------------------------------------
   zaereen/includes/ui/booking_aside.php, on guest details, review and
   payment. One partial, so the three steps cannot drift. */
.z-asideparty {
    display: grid; grid-template-columns: 1fr 1fr;
    list-style: none; margin: 0;
    /* A little more room top and bottom. At 10px the row sat tight
       against the dates above and the room name below, so the three read
       as one block rather than as the separate facts they are. The
       divider between the two halves needs the height to register as a
       divider too. */
    padding: 14px;
    border-top: 1px solid var(--z-line-gold);
    background: rgba(255, 253, 247, .62);
}
.z-asideparty li { display: flex; align-items: center; gap: 7px; min-width: 0;
                   font-size: 12.5px; font-weight: 600; color: var(--z-ink); }
/* BOTH CENTRED, WITH A RULE BETWEEN THEM.
   There were two .z-asideparty blocks in this file. The earlier one
   centred both items and drew the divider; this one then set the second
   to flex-end, so "1 room" sat centred and "2 adults" was shoved to the
   right edge with a border stranded between them. The earlier block is
   gone and this is now the only definition. */
.z-asideparty li { justify-content: center; }
.z-asideparty li + li { border-left: 1px solid var(--z-line-gold); }
.z-asideparty svg { flex: none; color: var(--z-green-3); }
.z-asideparty span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Solid, like the other property-charge panels: an rgba fill here would show
   the page pattern through it. */
.z-asidesupp {
    padding: 11px 12px;
    border: 1px solid #e2c3a5;
    border-left: 3px solid #a35418;
    border-radius: 10px;
    background: #fbf1e8;
}
.z-asidesupp > b { display: flex; align-items: center; gap: 6px; margin-bottom: 7px;
                   font-size: 9.5px; font-weight: 700; letter-spacing: .1em;
                   text-transform: uppercase; color: #a35418; }
.z-asidesupp ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.z-asidesupp li { display: flex; justify-content: space-between; gap: 10px;
                  font-size: 12px; color: var(--z-ink); }
.z-asidesupp li b { white-space: nowrap; font-variant-numeric: tabular-nums; }
.z-asidesupp p { margin: 7px 0 0; font-size: 10.5px; line-height: 1.45; color: #a35418; }

.z-paylead {
    display: flex; align-items: flex-start; gap: 10px;
    margin: 0 0 16px;
    padding: 13px 15px;
    border: 1px solid rgba(31, 96, 71, .3);
    border-left: 3px solid var(--z-green-3);
    border-radius: 11px;
    background: #eef6f0;   /* solid: it sits over the page pattern */
    font-size: 13.5px; line-height: 1.6;
    color: var(--z-ink);
}
.z-paylead svg { flex: none; margin-top: 2px; color: var(--z-green-3); }
/* The head states the step; the card under it no longer repeats the title, so
   its mark sits above the body rather than beside a heading. */
.z-paycard .z-paycard-mark { margin-bottom: 16px; }

/* --- the payment step, in the reading column ------------------------------ */
.z-paystep {
    padding: 22px 24px;
    border: 1px solid var(--z-line-gold);
    border-radius: 16px;
    background: var(--z-surface);
}
.z-paystep-head { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 4px; }
.z-paystep-mark { flex: none; display: inline-flex; align-items: center;
                  justify-content: center; width: 46px; height: 46px;
                  border-radius: 50%; background: var(--z-green-3); color: #fff; }
.z-paystep-head h1 { margin: 0 0 6px; font-size: 22px; color: var(--z-green); }
.z-paystep-head p { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--z-ink-2); }
.z-payfacts { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 8px; }
.z-payfacts li { display: flex; align-items: center; gap: 9px; font-size: 13px;
                 color: var(--z-ink-2); }
.z-payfacts svg { flex: none; color: var(--z-green-3); }
.z-paystep .z-payamt { margin: 18px 0 0; max-width: none; }
.z-paystep .z-paystatus { margin: 12px 0 14px; }
/* SIDE BY SIDE, NOT STACKED FULL WIDTH.
   The three cards hold very little each — "Room Only" is one line, and the
   cancellation table three. Stacked across the whole reading column they
   read as three near-empty bands with their text stranded on the left. Laid
   out at a minimum of 300px they sit together and each is as wide as its
   content needs. */
.z-rev-body.is-single { grid-template-columns: minmax(0, 1fr); }
/* FULL WIDTH, LIKE THE GUEST TABLE ABOVE THEM.
   These three sit directly under the Room 1 table, which spans the whole
   reading column — laid out three-up they were a third of its width and the
   block read as a different page element rather than a continuation of the
   same one. One column, each card as long as the table above it.

   The alignment fix stays: headings and body both ranged left, which is what
   was actually wrong before — not the number of columns. */
.z-rev-body.is-single .z-rev-col {
    grid-template-columns: minmax(0, 1fr);
}
/* The charge column is sized; the date takes what is left. Fixing the DATE
   column at a percentage worked while these cards were a third of the page
   and gave "100%" a third of the reading column once they were not. */
.z-rev-pol { table-layout: auto; }
.z-rev-pol th:last-child, .z-rev-pol td:last-child {
    width: 1%; white-space: nowrap; padding-left: 24px;
}
.z-rev-pol td:last-child { font-weight: 600; }

/* ================================================= PAYMENT SCREENS (ZAEREEN)
   zaereen/hotels/views/* — the screens the shared controller renders on the way
   to a booking. Solid grounds throughout: these sit over the page's pattern. */

.z-paycard {
    max-width: 620px;
    margin: 0 auto;
    padding: 32px 26px 26px;
    text-align: center;
    border: 1px solid var(--z-line-gold);
    border-radius: 16px;
    background: var(--z-surface);
}
.z-paycard-mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 58px; height: 58px;
    margin-bottom: 14px;
    border-radius: 50%;
    color: #fff;
}
.z-paycard.is-pay  .z-paycard-mark { background: var(--z-green-3); }
.z-paycard.is-wait .z-paycard-mark { background: #a35418; }
.z-paycard.is-stop .z-paycard-mark { background: #8a3024; }
.z-paycard h1 { margin: 0 0 12px; font-size: 24px; color: var(--z-green); }
.z-paycard-body p {
    margin: 0 auto 10px;
    max-width: 58ch;
    font-size: 14px; line-height: 1.65;
    color: var(--z-ink-2);
}
.z-paycard-acts {
    display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
    margin-top: 20px;
}

.z-payamt {
    display: flex; align-items: baseline; justify-content: center; gap: 12px;
    margin: 18px auto 12px;
    padding: 14px 20px;
    max-width: 380px;
    border: 1px solid var(--z-line-gold);
    border-radius: 12px;
    background: var(--z-gold-wash);
}
.z-payamt span {
    font-size: 10px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-payamt b {
    font-family: var(--z-display);
    font-size: 26px; font-weight: 700;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
}
.z-payfor {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    font-size: 13px; color: var(--z-ink-2);
}
.z-paystatus { font-size: 12.5px; color: var(--z-ink-3); min-height: 1.4em; }
.z-paynote {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    margin: 18px 0 0;
    font-size: 11.5px;
    color: var(--z-ink-3);
}

/* The block that goes up after payment has been taken. It has to cover the page:
   the request behind it can run for minutes and this is exactly when somebody
   presses back. */
.z-payblock {
    position: fixed; inset: 0; z-index: 9999;
    display: flex; align-items: center; justify-content: center;
    padding: 24px;
    background: rgba(13, 44, 34, .93);
    text-align: center;
    color: #fff;
}
.z-payblock[hidden] { display: none !important; }
.z-payblock h2 { margin: 16px 0 10px; font-size: 22px; color: var(--z-gold-light); }
.z-payblock p { margin: 0 auto 8px; max-width: 46ch; font-size: 14px; line-height: 1.6; opacity: .9; }
.z-payblock-warn { color: var(--z-gold-light); font-size: 13px; }
.z-payblock-spin {
    width: 46px; height: 46px; margin: 0 auto;
    border: 3px solid rgba(255, 255, 255, .25);
    border-top-color: var(--z-gold);
    border-radius: 50%;
    animation: z-spin 1s linear infinite;
}
@keyframes z-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .z-payblock-spin { animation-duration: 3s; }
}

/* --- review & accept ------------------------------------------------------- */
.z-rev { max-width: 1000px; margin: 0 auto; }
.z-rev-head {
    display: flex; align-items: flex-start; gap: 14px;
    padding: 20px 22px;
    border: 1px solid var(--z-line-gold);
    border-left: 3px solid var(--z-green-3);
    border-radius: 14px;
    background: #f4f9f5;
    margin-bottom: 16px;
}
.z-rev-head.is-changed { border-left-color: #a35418; background: #fdf6ec; }
.z-rev-head svg { flex: none; color: var(--z-green-3); margin-top: 2px; }
.z-rev-head.is-changed svg { color: #a35418; }
.z-rev-head h1 { margin: 0 0 6px; font-size: 21px; color: var(--z-green); }
.z-rev-head p { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--z-ink-2); }

.z-rev-changes { list-style: none; margin: 0 0 16px; padding: 0; display: grid; gap: 8px; }
.z-rev-changes li {
    display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px;
    padding: 11px 14px;
    border-radius: 10px;
    border: 1px solid #e2c3a5;
    background: #fdf6ec;
    font-size: 13px;
}
.z-rev-changes li.is-up   { border-color: #ddbdb7; background: #f9ece9; }
.z-rev-changes li.is-down { border-color: #b6d3bf; background: #eef6f0; }
.z-rev-changes b { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; }
.z-rev-changes li.is-up b   { color: #8a3024; }
.z-rev-changes li.is-down b { color: #1f6047; }
.z-rev-changes li.is-warn b { color: #a35418; }
.z-rev-changes em { font-style: normal; opacity: .6; margin: 0 4px; }
.z-rev-changes strong { color: var(--z-ink); }

.z-rev-body {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: 16px;
    align-items: start;
}
.z-rev-col { display: grid; gap: 14px; }
.z-rev-card {
    padding: 16px 18px;
    border: 1px solid var(--z-line);
    border-radius: 14px;
    background: var(--z-surface);
}
.z-rev-card h2 {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 11px;
    padding-bottom: 9px;
    border-bottom: 1px solid var(--z-line-gold);
    font-size: 11px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-rev-card h2 svg { color: var(--z-green-3); }
.z-rev-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
/* Left, and only left. A centred heading over a left-aligned list is the
   thing that reads as "not aligned". */
.z-rev-card, .z-rev-card h2, .z-rev-card p, .z-rev-card dl { text-align: left; }
.z-rev-card table { margin-top: 2px; }

.z-rev-list li {
    position: relative; padding-left: 16px;
    font-size: 13px; line-height: 1.5;
    color: var(--z-ink-2);
}
.z-rev-list li::before {
    content: ""; position: absolute; left: 3px; top: .62em;
    width: 4px; height: 4px; border-radius: 50%;
    background: var(--z-gold);
}
.z-rev-list.is-plain li { padding-left: 0; }
.z-rev-list.is-plain li::before { display: none; }

.z-rev-nonref {
    margin: 0 0 10px;
    padding: 9px 11px;
    border-radius: 9px;
    background: #f9ece9;
    border: 1px solid #ddbdb7;
    font-size: 12.5px; font-weight: 600;
    color: #8a3024;
}
.z-rev-pol { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.z-rev-pol th, .z-rev-pol td {
    padding: 7px 10px; text-align: left;
    border-bottom: 1px solid var(--z-line-soft);
}
.z-rev-pol th {
    font-size: 9.5px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-rev-pol td:last-child, .z-rev-pol th:last-child { text-align: right; }

.z-rev-card.is-money { position: sticky; top: 104px; }
.z-rev-sum { margin: 0; }
.z-rev-sum .is-total {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
.z-rev-sum dt {
    font-size: 11px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-rev-sum dd {
    margin: 0;
    font-family: var(--z-display);
    font-size: 24px; font-weight: 700;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
}
.z-rev-athotel {
    margin-top: 14px;
    padding: 12px 13px;
    border: 1px solid #e2c3a5;
    border-left: 3px solid #a35418;
    border-radius: 10px;
    background: #fbf1e8;
}
.z-rev-athotel > b {
    display: flex; align-items: center; gap: 6px;
    margin-bottom: 7px;
    font-size: 10px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: #a35418;
}
.z-rev-athotel ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.z-rev-athotel li {
    display: flex; justify-content: space-between; gap: 10px;
    font-size: 12.5px; color: var(--z-ink);
}
.z-rev-athotel li b { white-space: nowrap; font-variant-numeric: tabular-nums; }
.z-rev-athotel p { margin: 8px 0 0; font-size: 11px; color: #a35418; }

.z-rev-consent {
    display: flex; align-items: flex-start; gap: 11px;
    margin: 18px 0 0;
    padding: 15px 17px;
    border: 1px solid var(--z-line-gold);
    border-radius: 12px;
    background: var(--z-gold-wash);
    font-size: 13.5px; line-height: 1.55;
    color: var(--z-ink);
    cursor: pointer;
}
.z-rev-consent input {
    flex: none;
    width: 19px; height: 19px;
    margin-top: 1px;
    accent-color: var(--z-green-3);
}
.z-rev-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; margin-top: 16px; }
.z-rev-acts .z-btn[disabled] { opacity: .45; pointer-events: none; }

@media (max-width: 860px) {
    .z-rev-body { grid-template-columns: minmax(0, 1fr); }
    .z-rev-card.is-money { position: static; }
    .z-rev-acts { justify-content: stretch; }
    .z-rev-acts .z-btn { flex: 1 1 200px; }
}
/* =========================================== CONFIRMATION & MY BOOKINGS =====
   zaereen/hotels/confirmation.php and zaereen/users/my-bookings.php. */

.z-conf {
    text-align: center;
    padding: 30px 22px 26px;
    border: 1px solid var(--z-line-gold);
    border-radius: 16px;
    background: #f4f9f5;              /* solid: this sits over the page pattern */
    margin-bottom: 20px;
}
.z-conf.is-pending { background: #fdf6ec; }
.z-conf-mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 62px; height: 62px;
    margin-bottom: 14px;
    border-radius: 50%;
    background: var(--z-green-3);
    color: #fff;
}
.z-conf.is-pending .z-conf-mark { background: #a35418; }
.z-conf h1 {
    margin: 0 0 8px;
    font-size: 26px;
    color: var(--z-green);
}
.z-conf > p {
    margin: 0 auto;
    max-width: 62ch;
    font-size: 14px; line-height: 1.65;
    color: var(--z-ink-2);
}

/* The references, side by side and easy to read off to a hotel desk. */
.z-conf-refs {
    display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
    margin-top: 20px;
}
.z-conf-refs > div {
    padding: 10px 18px;
    border: 1px solid var(--z-line-gold);
    border-radius: 10px;
    background: var(--z-surface);
    text-align: left;
}
.z-conf-refs span {
    display: block;
    font-size: 9px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
    margin-bottom: 3px;
}
.z-conf-refs b {
    font-family: var(--z-display);
    font-size: 16px; font-weight: 600;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}

.z-conf-body {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px;
}
.z-conf-card {
    padding: 18px 20px;
    border: 1px solid var(--z-line);
    border-radius: 14px;
    background: var(--z-surface);
}
.z-conf-card h2 {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 12px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--z-line-gold);
    font-size: 12px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-conf-card h2 svg { color: var(--z-green-3); }
.z-conf-card dl { margin: 0; display: grid; gap: 8px; }
.z-conf-card dl > div {
    display: grid; grid-template-columns: 108px minmax(0, 1fr); gap: 12px;
    align-items: baseline;
}
.z-conf-card dt {
    font-size: 10px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-conf-card dd {
    margin: 0;
    font-size: 13.5px; line-height: 1.45;
    color: var(--z-ink);
    overflow-wrap: anywhere;
}
.z-conf-paid {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--z-line-gold);
}
.z-conf-paid span {
    font-size: 10px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-conf-paid b {
    font-family: var(--z-display);
    font-size: 21px; font-weight: 700;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
}

.z-conf-acts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }

/* --- confirmation: the property, and the terms it was booked on ------------
   The hotel panel is the one block on this page that is not the booking: it is
   static property content (photo, address, desk phone, check-in times), so it
   sits above the booking cards rather than among them. */
.z-conf-hotel {
    display: grid;
    grid-template-columns: 260px minmax(0, 1fr);
    gap: 0;
    margin-bottom: 16px;
    border: 1px solid var(--z-line);
    border-radius: 14px;
    background: var(--z-surface);
    overflow: hidden;
}
.z-conf-hmedia {
    position: relative;
    min-height: 190px;
    background: var(--z-green-soft);
    display: flex; align-items: center; justify-content: center;
}
.z-conf-hmedia img {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
}
.z-conf-hfall { color: var(--z-green-3); opacity: .55; }

.z-conf-hbody { padding: 16px 18px; min-width: 0; }
.z-conf-hbody > h2 {
    font-family: var(--z-display);
    margin: 0 0 4px;
    font-size: 19px; font-weight: 700; line-height: 1.25;
    color: var(--z-ink);
    text-transform: none; letter-spacing: 0;
    border: 0; padding: 0;
}
.z-conf-hstars {
    display: flex; align-items: center; gap: 2px;
    margin: 0 0 12px;
    color: var(--z-gold);
}
.z-conf-hstars span {
    margin-left: 6px;
    font-size: 11px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--z-ink-3);
}

/* Icon in its own column so every value starts on one line, whatever the
   label above it is. */
.z-conf-hrow {
    display: grid;
    grid-template-columns: 18px minmax(0, 1fr);
    gap: 10px;
    padding: 9px 0;
    border-top: 1px solid var(--z-line-soft);
}
.z-conf-hrow > svg { margin-top: 2px; color: var(--z-green-3); }
.z-conf-hrow span {
    display: block;
    margin-bottom: 2px;
    font-size: 10px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-conf-hrow b {
    display: block;
    font-size: 13.5px; font-weight: 500; line-height: 1.45;
    color: var(--z-ink);
    overflow-wrap: anywhere;
}
.z-conf-hrow b a { color: var(--z-green); text-decoration: none; }
.z-conf-hrow b a:hover { text-decoration: underline; }
.z-conf-map {
    display: inline-block;
    margin-top: 4px;
    font-size: 12px; font-weight: 600;
    color: var(--z-gold-deep); text-decoration: none;
}
.z-conf-map:hover { text-decoration: underline; }

.z-conf-times {
    display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
    margin-top: 10px; padding-top: 11px;
    border-top: 1px solid var(--z-line-gold);
}
.z-conf-times span {
    display: block; margin-bottom: 2px;
    font-size: 10px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-conf-times b {
    font-size: 14px; font-weight: 700;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
}

.z-conf-fac { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.z-conf-fac span {
    padding: 3px 9px;
    border: 1px solid var(--z-line-gold);
    border-radius: 999px;
    background: var(--z-gold-wash);
    font-size: 11px; font-weight: 600;
    color: var(--z-gold-deep);
}

/* The desk time beside a date, secondary to it. */
.z-conf-sub {
    font-size: 12px; font-weight: 500;
    color: var(--z-ink-3);
    white-space: nowrap;
}

.z-conf-pax { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.z-conf-pax li {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--z-line-soft);
}
.z-conf-pax li:last-child { padding-bottom: 0; border-bottom: 0; }
.z-conf-pax b {
    font-size: 13.5px; font-weight: 600;
    color: var(--z-ink);
    overflow-wrap: anywhere;
}
.z-conf-pax span {
    flex: 0 0 auto;
    font-size: 11px; font-weight: 600;
    letter-spacing: .04em;
    color: var(--z-ink-3);
}

/* Cancellation, desk charges and the hotel's own conditions, in the same
   z-rev-card the review and payment steps use. Full width rather than in the
   card grid: the conditions run to several paragraphs and a 280px column
   turns them into a ribbon. */
.z-conf-terms { display: grid; gap: 16px; margin-top: 16px; }

@media (max-width: 720px) {
    .z-conf-hotel { grid-template-columns: minmax(0, 1fr); }
    .z-conf-hmedia { min-height: 160px; }
    .z-conf-pax li { flex-direction: column; gap: 2px; }
}

/* The total, in the panel that confirms the booking rather than in a card about
   the guest. That panel is centred, so the figure is a centred block with its
   label above it - the card-footer rules above (space-between, a top rule) were
   written for a different place and read as a stray divider here. */
.z-conf > .z-conf-paid {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    margin: 16px 0 2px;
    padding: 10px 26px;
    border: 1px solid var(--z-line-gold);
    border-radius: 12px;
    background: var(--z-surface);
}
.z-conf > .z-conf-paid b {
    font-size: 25px;
    line-height: 1.15;
}

/* The page head states the outcome now, so the panel below it is a short
   confirmation rather than a hero: less height, and the mark sized to sit with
   the sentence instead of over a heading. */
.z-conf { padding: 24px 22px 22px; }
.z-conf-mark { width: 54px; height: 54px; margin-bottom: 12px; }

/* --- my bookings ----------------------------------------------------------- */
.z-bks { display: grid; gap: 14px; margin-bottom: 26px; }
.z-bk {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 200px;
    gap: 18px;
    padding: 16px 18px;
    border: 1px solid var(--z-line);
    border-radius: 14px;
    background: var(--z-surface);
}
.z-bk-main { min-width: 0; }
.z-bk-top {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    margin-bottom: 10px;
}
.z-bk-top h3 {
    margin: 0;
    font-family: var(--z-display);
    font-size: 17px; font-weight: 600;
    color: var(--z-ink);
}
/* The supplier's status, in the colour it means — not every status is good
   news, and a booking that failed should not look like one that did not. */
.z-bk-st {
    padding: 3px 11px;
    border-radius: 999px;
    font-size: 10px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    border: 1px solid transparent;
}
.z-bk-st.is-ok   { background: #e4efe7; border-color: #b6d3bf; color: #1f6047; }
.z-bk-st.is-wait { background: #fbf1e8; border-color: #e2c3a5; color: #a35418; }
.z-bk-st.is-off  { background: #f6e5e2; border-color: #ddbdb7; color: #8a3024; }

.z-bk-facts {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-wrap: wrap; gap: 6px 18px;
}
.z-bk-facts li {
    display: flex; align-items: center; gap: 7px;
    font-size: 12.5px;
    color: var(--z-ink-2);
}
.z-bk-facts svg { flex: none; color: var(--z-green-3); }
.z-bk-ref {
    margin: 10px 0 0;
    font-size: 11.5px;
    color: var(--z-ink-3);
    overflow-wrap: anywhere;
}

.z-bk-side {
    display: grid; gap: 8px; align-content: start;
    padding-left: 18px;
    border-left: 1px solid var(--z-line-soft);
}
.z-bk-paid { text-align: right; margin-bottom: 2px; }
.z-bk-paid span {
    display: block;
    font-size: 9px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-bk-paid b {
    font-family: var(--z-display);
    font-size: 18px; font-weight: 700;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
}

@media (max-width: 720px) {
    .z-bk { grid-template-columns: minmax(0, 1fr); }
    .z-bk-side { padding-left: 0; border-left: 0; border-top: 1px solid var(--z-line-soft); padding-top: 12px; }
    .z-bk-paid { text-align: left; }
    .z-conf-card dl > div { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}
/* ============================================================== GUEST DETAILS
   zaereen/hotels/guest-details.php — one grid per room, headed once, so the
   title, both names and the PAN line up down every guest in it. Each guest used
   to carry its own grid, which is why nothing lined up. */

/* The rating, as stars. Five are always drawn — the unlit ones are what make
   "three" read as three OUT OF five rather than just three marks. */
.z-headmeta { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.z-headsep { opacity: .5; }
.z-stars { display: inline-flex; align-items: center; gap: 2px; }
.z-stars i { display: inline-flex; line-height: 0; color: rgba(255, 255, 255, .28); }
.z-stars i.is-on { color: var(--z-gold-light, #e3c886); }
.z-stars i.is-on svg { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .35)); }
.z-stars b {
    margin-left: 6px;
    font-size: 12px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    opacity: .85;
}
/* The street, under the name in the page head. Quieter than the star/city
   line above it, because it is reference rather than headline. */
.z-headaddr {
    display: flex; align-items: flex-start; gap: 7px;
    margin: 6px 0 0;
    font-size: 13px; line-height: 1.5;
    opacity: .85;
}
.z-headaddr svg { flex: none; margin-top: 3px; }

.z-gdroom {
    border: 1px solid var(--z-line);
    border-radius: 14px;
    background: var(--z-surface);
    overflow: hidden;
    margin-bottom: 16px;
}

/* --- the room's head: who it is for, and where the confirmation goes -------- */
.z-gdroom-head {
    display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
    padding: 13px 18px;
    background: var(--z-gold-wash);
    border-bottom: 1px solid var(--z-line-gold);
}
.z-gdroom-n {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 5px 12px;
    border-radius: 999px;
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    font-size: 10.5px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-gdroom-n svg { color: var(--z-green-3); }
.z-gdroom-meta { font-size: 12px; color: var(--z-ink-2); }
.z-gdroom-lead {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 11px;
    border-radius: 999px;
    background: rgba(31, 96, 71, .12);
    border: 1px solid rgba(31, 96, 71, .34);
    font-size: 10px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--z-green-3);
}

/* Pushed to the far end of the head; drops to its own line when the head runs
   out of room rather than squeezing the room label. */
/* SIZED TO WHAT GOES IN THEM, NOT TO THE ROOM LEFT OVER.
   Both boxes were sharing whatever the head had spare, so the email ran
   half the width of the page for an address that is rarely 30 characters.
   Fixed maxima now, and the pair sits at the end of the head rather than
   stretching to reach it. */
.z-gdcontact {
    margin-left: auto;
    display: grid;
    grid-template-columns: minmax(0, 250px) minmax(0, 210px);
    gap: 12px;
    flex: 0 1 auto;
}

/* intl-tel-input, fitted to the Zaereen field — the widget draws its own
   wrapper, and without this the box inside it loses the width and the
   border radius everything else on the form has. */
.z-gdphone .iti { width: 100%; display: block; }
.z-gdphone .iti__flag-container { z-index: 2; }
.z-gdphone .iti--separate-dial-code .iti__selected-flag {
    background: var(--z-gold-wash);
    border-radius: 9px 0 0 9px;
}
.z-gdphone .iti--separate-dial-code .iti__selected-dial-code {
    font-size: 13px; font-weight: 600; color: var(--z-ink);
}
.z-gdphone input { width: 100%; }

/* --- the guests, as one table ---------------------------------------------- */
.z-gdtable { padding: 4px 18px 16px; }

.z-gdhead,
.z-gdrow {
    display: grid;
    grid-template-columns: 148px 104px minmax(0, 1fr) minmax(0, 1fr) 168px;
    gap: 12px;
    align-items: center;
}
.z-gdtable.no-pan .z-gdhead,
.z-gdtable.no-pan .z-gdrow {
    grid-template-columns: 148px 104px minmax(0, 1fr) minmax(0, 1fr);
}

.z-gdhead {
    padding: 12px 0 9px;
    border-bottom: 1px solid var(--z-line-gold);
}
.z-gdhead span {
    font-size: 9.5px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-gdhead b { color: #8a3024; font-weight: 700; }

.z-gdrow { padding: 11px 0; }
.z-gdrow + .z-gdrow { border-top: 1px dashed var(--z-line-soft); }

.z-gdcell { min-width: 0; }
/* Each cell keeps a label for the one-column layout below; the header carries
   the naming on wide screens, so they are hidden rather than duplicated. */
.z-gdlab { display: none; }

.z-gdwho { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.z-gdpill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 11px;
    border-radius: 999px;
    background: rgba(31, 96, 71, .09);
    border: 1px solid rgba(31, 96, 71, .26);
    font-size: 10.5px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--z-green-3);
    white-space: nowrap;
}
.z-gdpill.is-child {
    background: rgba(193, 154, 63, .14);
    border-color: var(--z-line-gold);
    color: var(--z-gold-deep);
}
.z-gdwho em { font-style: normal; font-size: 11px; color: var(--z-ink-3); }
.z-gdna { color: var(--z-ink-3); padding-left: 4px; }

.z-gdf { display: grid; gap: 5px; min-width: 0; }
.z-gdf label {
    display: flex; align-items: center; gap: 5px;
    font-size: 9.5px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-gdf label b { color: #8a3024; }

.z-gdf input, .z-gdf select,
.z-gdcell input, .z-gdcell select {
    width: 100%; min-width: 0;
    height: 40px;
    padding: 0 12px;
    border: 1px solid var(--z-line);
    border-radius: 9px;
    background: var(--z-surface);
    font: inherit; font-size: 13.5px;
    color: var(--z-ink);
}
.z-gdroom-head .z-gdf input,
.z-gdroom-head .z-gdf select { height: 38px; }
.z-gdf input:focus-visible, .z-gdf select:focus-visible,
.z-gdcell input:focus-visible, .z-gdcell select:focus-visible {
    outline: 2px solid var(--z-gold); outline-offset: 1px;
}
/* Only once something has been typed and is wrong. Reddening an untouched
   required field is scolding somebody for not having filled the form in yet. */
.z-gdcell input:not(:placeholder-shown):invalid { border-color: #8a3024; }
.z-gdpan { text-transform: uppercase; letter-spacing: .06em; }
.z-gdrow.is-lead .z-gdcell input { background: #fff; }

/* --- the hotel's own conditions ------------------------------------------
   Headings bold, and real space between paragraphs. Both were the whole
   complaint: as one unbroken block the section was unreadable however wide
   the box was. */
.z-rc h4 {
    margin: 18px 0 8px;
    font-size: 12px; font-weight: 700;
    letter-spacing: .06em;
    color: var(--z-green);
}
.z-rc h4:first-child { margin-top: 2px; }
.z-rc p {
    margin: 0 0 9px;
    padding-left: 14px;
    position: relative;
    font-size: 13px; line-height: 1.6;
    color: var(--z-ink-2);
    max-width: 92ch;
}
/* A dot rather than a bullet list: these are sentences the supplier ran
   together, not items it numbered. */
.z-rc p::before {
    content: ""; position: absolute; left: 2px; top: .72em;
    width: 4px; height: 4px; border-radius: 50%;
    background: var(--z-line-strong);
}
.z-rc p:last-child { margin-bottom: 0; }

/* --- the terms this rate was quoted on ------------------------------------ */
.z-gdterms {
    display: grid;
    /* One column, matching the guest table directly above it — see the note
       on .z-rev-col. */
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
    margin-top: 16px;
}
.z-gdterms section {
    padding: 14px 16px;
    border: 1px solid var(--z-line);
    border-radius: 12px;
    background: var(--z-surface);
}
.z-gdterms h3 {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 10px; padding-bottom: 9px;
    border-bottom: 1px solid var(--z-line-gold);
    font-size: 11px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-gdterms h3 svg { color: var(--z-green-3); }
.z-gdterms ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.z-gdterms li { position: relative; padding-left: 15px; font-size: 13px;
                line-height: 1.5; color: var(--z-ink-2); }
.z-gdterms li::before { content: ""; position: absolute; left: 3px; top: .62em;
                        width: 4px; height: 4px; border-radius: 50%; background: var(--z-gold); }
.z-gdterms table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.z-gdterms th, .z-gdterms td { padding: 7px 10px; text-align: left;
                               border-bottom: 1px solid var(--z-line-soft); }
.z-gdterms th { font-size: 9.5px; font-weight: 700; letter-spacing: .08em;
                text-transform: uppercase; color: var(--z-ink-3); }
.z-gdterms td { color: var(--z-ink-2); font-variant-numeric: tabular-nums; }
.z-gdterms td:last-child, .z-gdterms th:last-child {
    text-align: right; width: 1%; white-space: nowrap; padding-left: 24px;
}
.z-gdterms tr:last-child td { border-bottom: 0; }
/* The verdict, before the table that explains it. */
.z-gdfree, .z-gdnonref {
    margin: 0 0 10px; padding: 8px 11px; border-radius: 9px;
    font-size: 12.5px; font-weight: 600;
}
.z-gdfree   { background: #eef6f0; border: 1px solid #b6d3bf; color: #1f6047; }
.z-gdnonref { background: #f9ece9; border: 1px solid #ddbdb7; color: #8a3024; }
/* The whole block spans both columns of the terms grid. */
.z-gdterms > .z-cap { grid-column: 1 / -1; margin-top: 0; }

/* --- what the hotel collects at the desk -----------------------------------
   OPAQUE, DELIBERATELY. These were rgba tints, and an rgba fill shows whatever
   is behind it — here the page's own patterned ground, which made the panel
   look see-through. Same colours, composited once against the cream instead of
   left to the browser to blend at render time. */
.z-gdfees {
    margin: 18px 0 0;
    border: 1px solid #d9b393;
    border-left: 3px solid #a35418;
    border-radius: 12px;
    background: #fbf1e8;
    overflow: hidden;
}
.z-gdfees h3 {
    display: flex; align-items: center; gap: 8px;
    margin: 0;
    padding: 12px 16px;
    background: #f6e4d3;
    border-bottom: 1px solid #e2c3a5;
    font-size: 11px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: #a35418;
}
.z-gdfees table { width: 100%; border-collapse: collapse; }
.z-gdfees td {
    padding: 11px 16px;
    font-size: 13px;
    color: var(--z-ink);
    border-bottom: 1px solid #ecd8c4;
}
.z-gdfees tr:last-child td { border-bottom: 0; }
.z-gdfees td:last-child {
    text-align: right;
    white-space: nowrap;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.z-gdmust {
    display: inline-block;
    margin-right: 8px;
    padding: 2px 9px;
    border-radius: 999px;
    background: #a35418;
    font-size: 9.5px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
    color: #fff;
}
.z-gdfees p {
    margin: 0;
    padding: 10px 16px;
    background: #f6e4d3;
    border-top: 1px solid #e2c3a5;
    font-size: 11.5px; line-height: 1.5;
    color: #a35418;
}

.z-gdroomname {
    margin: 0;
    padding: 9px 12px;
    border-radius: 9px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    font-size: 12.5px; font-weight: 600; line-height: 1.4;
    color: var(--z-ink);
}
.z-gdate {
    display: block;
    font-family: var(--z-display);
    font-size: 14px; font-weight: 600;
    color: var(--z-green);
    white-space: nowrap;
}
.z-btn.is-busy { opacity: .7; pointer-events: none; }

/* Two columns hold the names side by side; below that everything stacks and the
   per-cell labels come back, because a bare box with no header above it is
   unanswerable. */
@media (max-width: 1100px) {
    .z-gdhead { display: none; }
    .z-gdrow,
    .z-gdtable.no-pan .z-gdrow {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        align-items: end;
        gap: 12px;
    }
    .z-gdwho { grid-column: 1 / -1; }
    .z-gdlab { display: block; font-size: 9.5px; font-weight: 700;
               letter-spacing: .1em; text-transform: uppercase;
               color: var(--z-gold-deep); margin-bottom: 5px; }
    .z-gdcontact { flex-basis: 100%; margin-left: 0; }
}
@media (max-width: 640px) {
    .z-gdrow, .z-gdtable.no-pan .z-gdrow { grid-template-columns: minmax(0, 1fr); }
    .z-gdcontact { grid-template-columns: minmax(0, 1fr); }
    .z-gdtable { padding: 4px 14px 14px; }
    .z-gdroom-head { padding: 12px 14px; }
}
/* ==================================================== HOTEL DETAIL TAB PANELS
   Overview, Amenities & Facilities, Contact & Location on hotels/stay.php. */

/* --- the facts a guest checks first ---------------------------------------
   A strip of equal cells rather than auto-fit cards. auto-fit stretched three
   short values — "From 2:00 PM", "By 12:00 PM", "3-star property" — to 300px
   each across the reading column, so every cell was mostly empty. */
.z-kv {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
    gap: 0;
    margin-bottom: 22px;
    border: 1px solid var(--z-line);
    border-radius: 12px;
    background: var(--z-surface);
    overflow: hidden;
}
.z-kv > div {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 16px;
    min-width: 0;
}
/* Divided rather than spaced: one strip reads as one statement about the
   property, three floating cards read as three unrelated ones. */
.z-kv > div + div { border-left: 1px solid var(--z-line-soft); }

.z-kvrow {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 11px 13px;
    border: 1px solid var(--z-line);
    border-radius: 10px;
    background: var(--z-surface);
}
.z-kv svg, .z-kvrow svg { flex: none; color: var(--z-green-3); }
.z-kvrow svg { margin-top: 1px; }
.z-kv span, .z-kvrow span { min-width: 0; }
.z-kv b, .z-kvrow b {
    display: block;
    font-size: 9.5px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep);
    margin-bottom: 3px;
}
.z-kv em, .z-kvrow em {
    display: block;
    font-style: normal;
    font-size: 13px; line-height: 1.45;
    color: var(--z-ink);
    overflow-wrap: anywhere;
}
.z-kv em { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.z-kvrow a { color: var(--z-green-3); text-decoration: none; }
.z-kvrow a:hover { text-decoration: underline; }

.z-cap {
    display: block;
    padding: 0;
    border: 0;
    background: none;
    margin: 8px 0 0;
    font-size: 11.5px; line-height: 1.55;
    color: var(--z-ink-3);
}

/* --- the property's own charges, as one sheet -----------------------------
   Both groups share this table, so every column sits on one grid. As two
   tables each sized its own columns and the two headers never lined up. */
.z-feewrap {
    border: 1px solid var(--z-line);
    border-radius: 12px;
    overflow: hidden;
    background: var(--z-surface);
}
.z-fees {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    /* Fixed, so the columns are the ones set below rather than whatever the
       longest basis string argues for — "Approximately AED 41 for adults and
       AED 20 for children" would otherwise take half the table. */
    table-layout: fixed;
}
.z-fees th, .z-fees td {
    padding: 10px 14px;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--z-line-soft);
}
.z-fees tr:last-child td { border-bottom: 0; }
.z-fees thead th {
    background: var(--z-gold-wash);
    border-bottom: 1px solid var(--z-line-gold);
    font-size: 9.5px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-fees th:nth-child(1), .z-fees td:nth-child(1) { width: 34%; }
.z-fees th:nth-child(2), .z-fees td:nth-child(2) { width: 20%; }
.z-fees td:nth-child(1) { font-weight: 600; color: var(--z-ink); }
.z-fees td:nth-child(2) {
    white-space: nowrap;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--z-ink);
}
.z-fees td:nth-child(3) { color: var(--z-ink-3); font-size: 12px; line-height: 1.5; }

/* The row that opens each group. It replaces the second table's heading, and
   carries the whole difference between money you will pay and money you might. */
.z-fees-sec td {
    padding: 8px 14px;
    background: var(--z-marble);
    border-bottom: 1px solid var(--z-line-soft);
    font-size: 9.5px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-fees-sec td svg { vertical-align: -2px; margin-right: 5px; }
.z-fees-sec.is-must td {
    background: #f7eee3;   /* rgba(163,84,24,.09) over --z-surface, composited */
    color: #a35418;
}
.z-fees-sec.is-must td svg { color: #a35418; }
/* Mandatory rows keep a rule down their edge, so the group stays legible once
   the section label above has scrolled past. */
.z-fees tr.is-must td:first-child { box-shadow: inset 3px 0 0 rgba(163, 84, 24, .55); }

@media (max-width: 620px) {
    .z-kv { grid-template-columns: 1fr; }
    .z-kv > div + div { border-left: 0; border-top: 1px solid var(--z-line-soft); }
    .z-kv em { white-space: normal; }
    .z-fees th:nth-child(1), .z-fees td:nth-child(1) { width: 40%; }
    .z-fees th:nth-child(2), .z-fees td:nth-child(2) { width: 26%; }
    .z-fees th, .z-fees td { padding: 9px 10px; }
}
/* --- amenities, in groups -------------------------------------------------- */
/* COLUMNS, NOT A GRID.
   As a grid these sat in rows, and a row is only as short as its tallest card:
   Family with three items beside Pool with twenty left a void the height of
   seventeen lines, and the page had one of those after every row. Multi-column
   layout has no rows — each card is placed under the one above it and the
   browser balances the column heights — so the cards pack tight whatever
   their sizes.

   columns: 280px 3 — at most three columns, each at least 280px, so it thins
   to two and then one on its own without a media query for each step. */
.z-fac {
    /* Stated even though block is the initial value. This began as
       .z-amen, which the CMS hotel page already owned as a GRID — and a
       grid container ignores `columns`, so the cards went on stretching
       to the row height whatever the packing said. Renamed off it; the
       explicit display is the belt to that braces. */
    display: block;
    columns: 280px 3;
    column-gap: 14px;
    margin-top: 16px;
}
.z-fac-g {
    /* inline-block with an explicit width: several engines only honour
       break-inside on a block that is not the column's own child flow. */
    display: inline-block;
    width: 100%;
    margin-bottom: 14px;
    break-inside: avoid;
    -webkit-column-break-inside: avoid;
    page-break-inside: avoid;
    padding: 14px 16px;
    border: 1px solid var(--z-line);
    border-radius: 12px;
    background: var(--z-surface);
}
.z-fac-g h4 {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 10px;
    padding-bottom: 9px;
    border-bottom: 1px solid var(--z-line-gold);
    font-size: 11px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-fac-g h4 svg { flex: none; color: var(--z-green-3); }
.z-fac-g h4 span { flex: 1 1 auto; min-width: 0; }
/* The count says how much is behind the heading before it is read. */
.z-fac-g h4 i {
    flex: none;
    font-style: normal;
    font-size: 10px; font-weight: 700;
    padding: 1px 7px;
    border-radius: 999px;
    background: rgba(193, 154, 63, .16);
    color: var(--z-gold-deep);
    font-variant-numeric: tabular-nums;
}
.z-fac-g ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.z-fac-g li {
    position: relative;
    padding-left: 15px;
    font-size: 12.5px; line-height: 1.5;
    color: var(--z-ink-2);
}
/* A dot rather than a tick on every line: 127 ticks is a texture, not a list. */
.z-fac-g li::before {
    content: "";
    position: absolute; left: 3px; top: .62em;
    width: 4px; height: 4px;
    border-radius: 50%;
    background: var(--z-gold);
}

/* --- contact and location -------------------------------------------------- */
.z-loc {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: 18px;
    align-items: start;
}
.z-loc-info { display: grid; gap: 9px; align-content: start; }
.z-loc-info .z-btn { justify-self: start; margin-top: 2px; }
.z-loc-map {
    border: 1px solid var(--z-line);
    border-radius: 12px;
    overflow: hidden;
    /* An iframe with no height falls back to its intrinsic 150px, which is why
       the map used to render as a letterbox. */
    aspect-ratio: 4 / 3;
    min-height: 260px;
    background: var(--z-cream);
}
.z-loc-map iframe { display: block; width: 100%; height: 100%; border: 0; }

/* Stacked, one section under the other, each the full width of the panel — see
   the note in stay.php for why they are no longer side by side. */
.z-loc-lists {
    display: grid;
    gap: 18px;
    margin-top: 20px;
    padding-top: 18px;
    border-top: 1px solid var(--z-line);
}
.z-loc-lists h4 {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 10px;
    font-size: 11px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-loc-lists h4 svg { flex: none; color: var(--z-green-3); }
.z-loc-lists h4 i {
    font-style: normal;
    font-size: 10px; font-weight: 700;
    padding: 1px 7px;
    border-radius: 999px;
    background: rgba(193, 154, 63, .16);
    font-variant-numeric: tabular-nums;
}

/* The places themselves, flowing across the width. auto-fill and not auto-fit:
   auto-fit collapses the empty tracks, which would stretch three airports to
   the full width of the panel and lose the alignment with the sixteen
   landmarks underneath. */
.z-poi {
    list-style: none;
    margin: 0; padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 2px 18px;
}
.z-poi li {
    display: flex; align-items: flex-start; gap: 8px;
    padding: 6px 0;
    font-size: 13px; line-height: 1.5;
    color: var(--z-ink-2);
    min-width: 0;
}
.z-poi svg { flex: none; margin-top: 3px; color: var(--z-green-3); }

@media (max-width: 860px) {
    .z-loc { grid-template-columns: 1fr; }
    .z-loc-map { min-height: 220px; }
}
/* ============================================================ AVAILABLE ROOMS
   The full rate cards in the main column of hotels/stay.php. The sidebar keeps
   its own compact list (.z-room-*, below) — same data, a third of the width. */

/* --- filter chips --------------------------------------------------------- */
/* display:flex and display:grid below both BEAT the user-agent
   [hidden]{display:none} rule, so every element this page hides with the
   hidden attribute needs saying explicitly. Without these three the
   filter bar and the note would show before the rates arrived, and
   filtering would hide nothing at all. */
.z-rfilter[hidden], .z-rnote[hidden] { display: none !important; }

.z-rfilter {
    display: flex; align-items: flex-start; gap: 12px;
    flex-wrap: wrap;
    padding: 14px 16px;
    margin-bottom: 16px;
    border: 1px solid var(--z-line-gold, rgba(193, 154, 63, .42));
    border-radius: 12px;
    background: var(--z-gold-wash, #f6efdb);
}
.z-rfilter-label {
    flex: none;
    padding-top: 5px;
    font-size: 10.5px; font-weight: 700;
    letter-spacing: .14em; text-transform: uppercase;
    color: var(--z-gold-deep, #8f6f1c);
}
.z-rfilter-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.z-rfchip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 12px;
    border: 1px solid var(--z-line-gold, rgba(193, 154, 63, .42));
    border-radius: 999px;
    background: #fff;
    font: inherit; font-size: 12px; font-weight: 600;
    color: var(--z-ink-2, #4b554a);
    cursor: pointer;
    transition: background .15s, color .15s, border-color .15s;
}
.z-rfchip i {
    font-style: normal; font-size: 10.5px; font-weight: 700;
    padding: 1px 6px;
    border-radius: 999px;
    background: rgba(193, 154, 63, .16);
    color: var(--z-gold-deep, #8f6f1c);
    font-variant-numeric: tabular-nums;
}
.z-rfchip:hover { border-color: var(--z-gold, #c19a3f); }
.z-rfchip.is-on {
    background: var(--z-green-3, #1f6047);
    border-color: var(--z-green-3, #1f6047);
    color: #fff;
}
.z-rfchip.is-on i { background: rgba(255, 255, 255, .2); color: #fff; }

/* --- the note above the list ---------------------------------------------- */
.z-rnote {
    display: flex; align-items: flex-start; gap: 9px;
    padding: 11px 14px;
    margin: 0 0 18px;
    border-left: 3px solid var(--z-gold, #c19a3f);
    border-radius: 0 8px 8px 0;
    background: rgba(193, 154, 63, .09);
    font-size: 12.5px; line-height: 1.6;
    color: var(--z-ink-2, #4b554a);
}
.z-rnote svg { flex: none; margin-top: 2px; color: var(--z-gold-deep, #8f6f1c); }

.z-rlist-head {
    display: flex; justify-content: flex-end;
    margin-bottom: 10px;
    font-size: 11.5px; font-weight: 600;
    color: var(--z-ink-3, #7f8a7e);
    font-variant-numeric: tabular-nums;
}

/* --- the rate table -------------------------------------------------------
   ONE GRID DEFINITION, USED BY THE HEADER AND EVERY ROW.

   The rates were nine separate bordered cards, each sizing its own columns, so
   nothing lined up down the page: the bed line, the meal and the policy link
   all landed at a different x in every card, and the price rail pushed its
   button to the bottom of whatever height that card happened to be — on a row
   with a long policy the figure and the button ended up an inch and a half
   apart. Fixed tracks on both the header and the rows means the three columns
   are the same width in every row, whatever is in them.

   Photo + name | Conditions | Total — what it is, what you are agreeing to,
   what it costs. */
.z-rtable {
    border: 1px solid var(--z-line-gold);
    border-radius: 14px;
    overflow: hidden;
    background: var(--z-surface);
}

.z-rr-head,
.z-rrow {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 224px 178px;
    gap: 18px;
    align-items: start;
}

.z-rr-head {
    padding: 9px 18px;
    background: var(--z-gold-wash);
    border-bottom: 1px solid var(--z-line-gold);
    font-size: 9.5px; font-weight: 700;
    letter-spacing: .13em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-rr-head span:last-child { text-align: right; }

.z-rrow {
    padding: 16px 18px;
    border: 0;
    background: none;
}
.z-rrow + .z-rrow { border-top: 1px solid var(--z-line-soft); }
.z-rrow:hover { background: rgba(193, 154, 63, .05); }
/* display:grid beats the user-agent [hidden] rule, so a filtered-out row
   would otherwise stay on screen. */
.z-rrow[hidden] { display: none !important; }

/* --- column 1: photograph and room ---------------------------------------- */
.z-rr-room { display: flex; gap: 14px; min-width: 0; }
.z-rr-rtext { min-width: 0; }

.z-rr-pic { flex: none; width: 104px; margin: 0; }
.z-rr-pic img {
    display: block;
    width: 104px; height: 74px;
    object-fit: cover;
    border-radius: 9px;
    background: var(--z-cream);
}
/* Said, not implied. TBO sends no per-room photograph, so this is the
   property's own picture and the caption has to make that plain rather than
   let a lobby shot pass for the room being booked. */
.z-rr-pic figcaption {
    margin-top: 4px;
    text-align: center;
    font-size: 9px; font-weight: 600;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--z-ink-3);
}

.z-rr-room b {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 14px; font-weight: 700; line-height: 1.35;
    color: var(--z-ink);
}
.z-rr-facts {
    list-style: none;
    margin: 8px 0 0; padding: 0;
    display: grid; gap: 5px;
}
.z-rr-facts li {
    display: flex; align-items: center; gap: 7px;
    min-width: 0;
    font-size: 12px;
    color: var(--z-ink-2);
}
.z-rr-facts svg { flex: none; color: var(--z-green-3); }
.z-rr-facts span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Real amenities for THIS room, out of TBO's RoomDescription, each as its own
   mark. The marks were drawn for this — the set had nothing for a bathtub or
   a washing machine, and the chips were words until it did. */
.z-rr-amen {
    list-style: none;
    display: flex; flex-wrap: wrap; gap: 6px;
    margin: 11px 0 0; padding: 0;
}
.z-rr-amen li {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px;
    border: 1px solid var(--z-line-soft);
    border-radius: 50%;
    background: var(--z-marble);
    color: var(--z-green-3);
    /* A mark with no label has to be askable: the title shows on hover and
       the cursor says so before the pointer stops moving. */
    cursor: help;
    font-size: 10px; font-weight: 600;
}
.z-rr-amen li:hover { border-color: var(--z-gold); background: var(--z-gold-wash); }
.z-rr-amen li svg { display: block; }

.z-rr-more { margin-top: 10px; }
.z-rr-more summary {
    cursor: pointer;
    font-size: 11.5px; font-weight: 600;
    color: var(--z-green-3);
}
.z-rr-more summary:hover { text-decoration: underline; }
.z-rr-more p {
    margin: 8px 0 0;
    font-size: 11.5px; line-height: 1.55;
    color: var(--z-ink-2);
}
.z-rr-more dl { margin: 8px 0 0; display: grid; gap: 5px; }
.z-rr-more dl > div { display: grid; grid-template-columns: 92px 1fr; gap: 10px; }
.z-rr-more dt {
    font-size: 10px; font-weight: 700;
    letter-spacing: .07em; text-transform: uppercase;
    color: var(--z-gold-deep);
    padding-top: 1px;
}
.z-rr-more dd {
    margin: 0;
    font-size: 11.5px; line-height: 1.5;
    color: var(--z-ink-2);
}

/* --- column 2: what the guest is agreeing to ------------------------------ */
.z-rr-cond {
    list-style: none;
    margin: 0; padding: 0;
    display: grid; gap: 8px;
    min-width: 0;
}
.z-rr-cond li {
    display: flex; align-items: flex-start; gap: 7px;
    font-size: 11.5px; line-height: 1.4;
}
.z-rr-cond svg { flex: none; margin-top: 1px; }
.z-rr-cond span { min-width: 0; }
.z-rr-cond b  { display: block; font-weight: 600; }
.z-rr-cond em { display: block; font-style: normal; color: var(--z-ink-3); }

.z-rr-cond .is-meal   { color: var(--z-ink-2); }
.z-rr-cond .is-meal svg { color: var(--z-gold-deep); }
.z-rr-cond .is-free   { color: var(--z-green-3); }
.z-rr-cond .is-free svg { color: var(--z-green-3); }
.z-rr-cond .is-nonref { color: #8a3024; }
.z-rr-cond .is-nonref svg { color: #8a3024; }
.z-rr-cond .is-part   { color: #a35418; }
.z-rr-cond .is-part svg { color: #a35418; }
/* A charge collected by the hotel, not by us. It sits in this column rather
   than beside the total so it can never be read as part of it. */
.z-rr-cond .is-prop   { color: #a35418; }
.z-rr-cond .is-prop svg { color: #a35418; }

/* --- column 3: the money --------------------------------------------------
   THE FARE HAS TO BE THE LOUDEST THING IN THE ROW.

   It was 19px in --z-gold-deep on white — about 4.3:1, which passes a contrast
   check and still reads as a caption rather than the price. It is the number
   the whole row exists to deliver, so it now sits on its own tinted plate, at
   25px, in the near-black green the headings use: around 14:1, and the largest
   thing on the row by a clear margin. Gold stays on the currency code and the
   rule, where it decorates instead of carrying the value. */
.z-rr-price {
    min-width: 0;
    padding: 12px 13px;
    border: 1px solid var(--z-line-gold);
    border-radius: 11px;
    background: var(--z-gold-wash);
    text-align: right;
}
.z-rr-price b {
    display: block;
    font-family: var(--z-display);
    font-size: 25px; font-weight: 700; line-height: 1.1;
    color: var(--z-green);
    font-variant-numeric: tabular-nums;
    letter-spacing: -.01em;
}
.z-rr-price b i {
    font-style: normal;
    font-family: var(--z-body, inherit);
    font-size: 11px; font-weight: 700;
    letter-spacing: .08em;
    color: var(--z-gold-deep);
    margin-right: 5px;
    vertical-align: 3px;
}
.z-rr-price em {
    display: block;
    margin: 5px 0 0;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--z-line-gold);
    font-style: normal;
    font-size: 10.5px; line-height: 1.4;
    color: var(--z-ink-2);
}
.z-rr-price .z-btn {
    width: 100%;
    margin-top: 10px;
    padding: 9px 6px;
    font-size: 12px;
}

/* --- the policy, under all three columns ---------------------------------- */
.z-rr-pol {
    grid-column: 1 / -1;
    margin-top: 12px;
    padding-top: 11px;
    border-top: 1px dashed var(--z-line);
}
.z-rr-pol summary {
    cursor: pointer;
    font-size: 11.5px; font-weight: 600;
    color: var(--z-green-3);
}
.z-rr-pol summary:hover { text-decoration: underline; }
.z-rr-pol table {
    width: 100%;
    margin-top: 9px;
    border-collapse: collapse;
    font-size: 11.5px;
}
.z-rr-pol th, .z-rr-pol td {
    padding: 6px 10px;
    text-align: left;
    border-bottom: 1px solid var(--z-line-soft);
}
.z-rr-pol th {
    font-size: 9.5px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-rr-pol td { color: var(--z-ink-2); font-variant-numeric: tabular-nums; }
.z-rr-pol th:last-child, .z-rr-pol td:last-child { text-align: right; }

/* The reading column loses about 200px below 1240px, and the two fixed tracks
   have to give it back or the room name is squeezed to a ribbon. */
@media (max-width: 1240px) {
    .z-rr-head, .z-rrow { grid-template-columns: minmax(0, 1fr) 186px 166px; gap: 14px; }
    .z-rr-price { padding: 11px; }
    .z-rr-price b { font-size: 21px; }
}

/* One column: the three cells stack, and the price block goes full width with
   the figure back on the left where the eye already is. */
@media (max-width: 860px) {
    .z-rr-head { display: none; }
    .z-rrow { grid-template-columns: 1fr; gap: 12px; padding: 16px; }
    .z-rr-price { text-align: left; }
    .z-rr-pol { margin-top: 4px; }
    .z-rr-more dl > div { grid-template-columns: 1fr; gap: 1px; }
}
@media (max-width: 480px) {
    .z-rr-pic { width: 78px; }
    .z-rr-pic img { width: 78px; height: 58px; }
    .z-rr-price b { font-size: 22px; }
}
/* The sidebar's way through to the full list. */
.z-room-all {
    display: block;
    padding: 9px;
    margin-top: 4px;
    border: 1px dashed var(--z-line-gold, rgba(193, 154, 63, .42));
    border-radius: 9px;
    text-align: center;
    font-size: 12px; font-weight: 600;
    color: var(--z-green-3, #1f6047);
    text-decoration: none;
}
.z-room-all:hover { background: rgba(193, 154, 63, .1); }

@media (max-width: 700px) {
    .z-rfilter { flex-direction: column; gap: 8px; }
    .z-rfilter-label { padding-top: 0; }
}
/* The list heading and the one line that qualifies every price under it. */
.z-room-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 10px;
    padding-bottom: 7px;
    margin: 0;
    border-bottom: 1px solid var(--z-line-gold);
}
.z-room-head h4 {
    margin: 0;
    font-size: 11px; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-gold-deep, #7d6015);
}
.z-room-head span {
    font-size: 11.5px;
    color: var(--z-ink-3, #6b6558);
}
.z-room-note {
    margin: -2px 0 0;
    font-size: 11.5px; line-height: 1.5;
    color: var(--z-ink-3, #6b6558);
}

.z-room-top { margin-bottom: 7px; }
.z-room-top b {
    font-size: 13.5px; font-weight: 700; line-height: 1.35;
    color: var(--z-ink, #1d2a24);
}

/* Meal and cancellation, as chips: they are the two things a guest compares
   between rates once the price is in view. */
.z-room-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.z-room-tag {
    padding: 3px 8px;
    border-radius: 999px;
    font-size: 10.5px; font-weight: 600;
    letter-spacing: .02em;
    border: 1px solid transparent;
}
.z-room-tag.is-meal {
    background: rgba(193, 154, 63, .14);
    border-color: rgba(193, 154, 63, .4);
    color: var(--z-gold-deep, #7d6015);
}
.z-room-tag.is-free {
    background: rgba(31, 96, 71, .12);
    border-color: rgba(31, 96, 71, .38);
    color: #1f6047;
}
/* Stated plainly rather than in alarm colours: it is a condition of the rate,
   not an error, and the guest is choosing it knowingly. */
.z-room-tag.is-nonref {
    background: rgba(138, 48, 36, .1);
    border-color: rgba(138, 48, 36, .34);
    color: #8a3024;
}

/* Charges, tax, total. A definition list because that is what it is, and the
   figures right-align so they can be read down the column. */
.z-room-sum { margin: 0 0 12px; }
.z-room .z-room-sum { margin-bottom: 12px; }
.z-room-sum div {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 10px;
    padding: 3px 0;
}
.z-room-sum dt {
    font-size: 11.5px;
    color: var(--z-ink-3, #6b6558);
    min-width: 0;
}
.z-room-sum dd {
    margin: 0;
    font-size: 12.5px;
    color: var(--z-ink-2, #40504a);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    /* Ranged right so the figures form one column under each other.
       space-between already pushes a single line to the edge, but a
       value that wraps -- a long currency plus amount in the narrow
       sidebar -- would otherwise set its second line to the left and
       break the column. */
    text-align: right;
}
.z-room-sum .is-total {
    margin-top: 4px;
    padding-top: 7px;
    border-top: 1px solid var(--z-line-gold, rgba(193, 154, 63, .3));
}
.z-room-sum .is-total dt {
    font-size: 12px; font-weight: 700;
    color: var(--z-ink, #1d2a24);
}
/* THE TOTAL: DARK, AND IN THE PLAIN FACE.
   It was Cormorant Garamond in --z-gold-deep, which measures 4.63:1 on
   the panel against 14.74:1 for the green. This is the figure the
   customer is about to pay -- the last number they check before handing
   over a card -- so it is the one that has to be unambiguous, not the
   most decorative. Same treatment as the room rates and the city-card
   prices, so a figure means the same thing wherever it appears.
   tabular-nums so the digits align with the lines above it. */
.z-room-sum .is-total dd {
    font-family: var(--z-body, inherit);
    font-size: 19px; font-weight: 700;
    letter-spacing: -.01em;
    color: var(--z-green, #0d2c22);
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Flight & Hotel tab — tour detail

   The tab used to be a bullet list of hotel names and a bare from/to strip.
   These are the same two ideas as the Oxford package page carries, redrawn in
   Zaereen's marble and gold: a flight card per leg, grouped out and back, and
   one hotel card per property with the grade tiles choosing the set.
   -------------------------------------------------------------------------- */

.z-fl-group { margin-bottom: 22px; }
.z-fl-group:last-of-type { margin-bottom: 0; }

.z-fl-head {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 14px;
    background: var(--z-green);
    color: var(--z-gold-light);
    border-radius: var(--z-radius-sm) var(--z-radius-sm) 0 0;
    font-family: var(--z-display);
    font-size: 15px; font-weight: 600;
    letter-spacing: .09em; text-transform: uppercase;
}
.z-fl-head svg { color: var(--z-gold); }

/* One leg. Airline, out, the line between, in — then the bags on their own
   row, because a five-column grid put them at 60px wide on a laptop. */
.z-fl {
    display: grid;
    grid-template-columns: minmax(120px, 1fr) minmax(90px, 1fr) minmax(110px, 1.2fr) minmax(90px, 1fr);
    gap: 14px 18px;
    align-items: center;
    padding: 16px 18px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-top: 0;
}
.z-fl:last-child { border-radius: 0 0 var(--z-radius-sm) var(--z-radius-sm); }

.z-fl-air { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; min-width: 0; }
.z-fl-air img {
    width: 44px; height: 44px; object-fit: contain;
    background: #fff;
    border: 1px solid var(--z-line);
    border-radius: 9px;
    padding: 4px;
}
.z-fl-air-ico {
    width: 44px; height: 44px; border-radius: 9px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
}
.z-fl-air b {
    font-size: 13.5px; font-weight: 600; color: var(--z-ink);
    text-transform: capitalize; line-height: 1.3;
}
.z-fl-no {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 100px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
    font-size: 11.5px; font-weight: 600; letter-spacing: .04em;
}

.z-fl-node { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.z-fl-node.is-arr { text-align: right; align-items: flex-end; }
.z-fl-lab {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 10px; font-weight: 600;
    letter-spacing: .11em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-fl-node > b {
    font-family: var(--z-display);
    font-size: 21px; font-weight: 600; color: var(--z-ink);
    letter-spacing: .03em; line-height: 1.15;
}
.z-fl-city { font-size: 12px; color: var(--z-ink-3); }
.z-fl-time {
    font-family: system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
    font-size: 19px; font-weight: 700; color: #000;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
}
.z-fl-term {
    font-size: 10.5px; font-weight: 600;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--z-ink-3);
}

/* The dotted run between the two ends, with the duration above it and the
   stop count below — the two facts a traveller compares flights on. */
.z-fl-path { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.z-fl-line {
    position: relative;
    width: 100%; height: 14px;
    display: flex; align-items: center; justify-content: flex-end;
    color: var(--z-gold-deep);
}
.z-fl-line::before {
    content: "";
    position: absolute; left: 0; right: 12px; top: 50%;
    border-top: 2px dotted var(--z-line-gold);
}
.z-fl-line svg { position: relative; }
.z-fl-chip {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 10px;
    border-radius: 100px;
    background: var(--z-cream);
    border: 1px solid var(--z-line);
    color: var(--z-ink-2);
    font-size: 11.5px; font-weight: 500;
    white-space: nowrap;
}
.z-fl-chip svg { color: var(--z-gold-deep); }

.z-fl-bags {
    grid-column: 1 / -1;
    display: flex; flex-wrap: wrap; gap: 8px;
    padding-top: 12px;
    border-top: 1px dashed var(--z-line);
}

.z-fl-note { font-size: 13px; color: var(--z-ink-3); margin: 12px 0 0; }

@media (max-width: 880px) {
    .z-fl { grid-template-columns: 1fr 1fr; gap: 14px; }
    .z-fl-air { grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 10px; }
    .z-fl-path { grid-column: 1 / -1; flex-direction: row; justify-content: center; }
    .z-fl-line { width: 40px; }
}

/* --- hotel cards ---------------------------------------------------------- */

.z-hset-lab {
    display: flex; align-items: center; gap: 7px;
    font-size: 12px; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--z-ink-3);
    margin: 18px 0 10px;
}
.z-hset-lab svg { color: var(--z-gold-deep); }

.z-hotels {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 12px;
}
.z-hcard {
    display: flex; align-items: stretch; gap: 12px;
    padding: 10px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    transition: border-color .2s ease, box-shadow .2s ease;
}
.z-hcard:hover { border-color: var(--z-line-gold); box-shadow: var(--z-shadow); }

.z-hcard-img { flex: 0 0 auto; width: 88px; }
.z-hcard-img img {
    width: 88px; height: 88px;
    object-fit: cover;
    border-radius: 9px;
    display: block;
}
.z-hcard-ph {
    width: 88px; height: 88px; border-radius: 9px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
}

.z-hcard-body {
    display: flex; flex-direction: column; justify-content: center; gap: 5px;
    min-width: 0;
}
.z-hcard-body b {
    font-family: var(--z-display);
    font-size: 16px; font-weight: 600; color: var(--z-ink);
    line-height: 1.25;
}
.z-hcard-city {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 12.5px; color: var(--z-ink-3);
}
.z-hcard-city svg { color: var(--z-gold-deep); flex: none; }
.z-hcard-stars { display: inline-flex; gap: 2px; color: var(--z-gold); }

/* The grade the traveller is on, under the hotel cards. One line, not the
   catalogue of every category the tab used to print. */
.z-hgrade {
    display: flex; align-items: center; gap: 10px;
    margin-top: 18px;
    padding: 11px 14px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius-sm);
}
.z-hgrade-ico {
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px;
    border-radius: 8px;
    background: var(--z-green);
    color: var(--z-gold-light);
}
.z-hgrade-txt { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 9px; min-width: 0; }
.z-hgrade-txt b { font-size: 15px; font-weight: 600; color: var(--z-green); }
.z-hgrade-txt [data-role="meta"] { font-size: 13px; color: var(--z-ink-2); }
.z-hgrade-txt [data-role="meta"]:empty { display: none; }

.z-hnone {
    margin: 0;
    padding: 16px;
    background: var(--z-cream);
    border: 1px dashed var(--z-line);
    border-radius: var(--z-radius-sm);
    font-size: 13.5px; color: var(--z-ink-3);
    text-align: center;
}

/* A field the PDF / Enquiry guard is waiting on. Held for a moment rather
   than left on, so it reads as an answer to the click and not as a
   permanent error state. */
.z-jfield.is-missing > label { color: var(--z-sold); }
.z-jfield.is-missing .z-jselect,
.z-jfield.is-missing .z-qty,
.z-jfield.is-missing .z-cats {
    outline: 2px solid var(--z-sold);
    outline-offset: 3px;
    border-radius: 10px;
}

/* Package inclusions as marks, all on one line. auto-fit rather than a fixed
   column count: four inclusions should not leave two gaps, and nine should
   wrap rather than shrink to nothing. */
.z-incs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
    gap: 10px;
}
.z-inc {
    text-align: center;
    padding: 14px 8px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    transition: border-color .2s ease, box-shadow .2s ease;
}
.z-inc:hover { border-color: var(--z-line-gold); box-shadow: var(--z-shadow); }
.z-inc span {
    display: flex; align-items: center; justify-content: center;
    width: 50px; height: 50px; margin: 0 auto 9px;
    border-radius: 50%;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
}
.z-inc b {
    display: block;
    font-size: 12px; font-weight: 600;
    color: var(--z-green); line-height: 1.3;
}

/* The two halves are no longer alike — a row of marks against a list of
   sentences — so they stack rather than share a line. */
.z-incex:has(.z-incs) { grid-template-columns: 1fr; }

/* --------------------------------------------------------------------------
   FAQs — tour detail

   Was a stack of plain grey bars with a hairline caret: no sense of how many
   questions there are, no reading order, and an open state you had to look
   twice to spot. Numbered rows on a gold rail, the number carrying the state.
   -------------------------------------------------------------------------- */

.z-faqs { display: flex; flex-direction: column; gap: 10px; }

.z-faq {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-left: 3px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    overflow: hidden;
    transition: border-color .25s ease, box-shadow .25s ease;
}
.z-faq:hover { border-color: var(--z-line-gold); border-left-color: var(--z-gold); }
.z-faq[open] {
    border-color: var(--z-line-gold);
    border-left-color: var(--z-gold);
    box-shadow: var(--z-shadow);
}

.z-faq > summary {
    display: flex; align-items: center; gap: 14px;
    padding: 15px 18px;
    cursor: pointer;
    list-style: none;
}
.z-faq > summary::-webkit-details-marker { display: none; }
.z-faq > summary:focus-visible { outline: 2px solid var(--z-gold-deep); outline-offset: -3px; }
.z-faq[open] > summary { background: var(--z-gold-wash); }

/* The number, which is also the open indicator. */
.z-faq-n {
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px;
    border-radius: 10px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
    font-family: var(--z-body);
    font-size: 13.5px; font-weight: 600;
    font-variant-numeric: tabular-nums;
    transition: background-color .25s ease, border-color .25s ease, color .25s ease;
}
.z-faq[open] .z-faq-n {
    background: var(--z-green);
    border-color: var(--z-green);
    color: var(--z-gold-light);
}

/* Plain body face, not the Cormorant display serif. A question is a sentence
   to be read, not a heading to be admired — set in the serif at 17.5px it
   competed with the section heading above it and read as decoration. */
.z-faq-q {
    flex: 1 1 auto; min-width: 0;
    font-family: var(--z-body);
    font-size: 15.5px; font-weight: 500;
    letter-spacing: 0; line-height: 1.45;
    color: var(--z-ink);
}
.z-faq[open] .z-faq-q { color: var(--z-green); }

/* A plus that becomes a minus — drawn, because a typed +/− sits off-centre
   at this size and shifts with the font stack. */
.z-faq-t {
    position: relative;
    flex: none;
    width: 26px; height: 26px;
    border-radius: 50%;
    background: var(--z-cream);
    border: 1px solid var(--z-line);
    transition: background-color .25s ease, border-color .25s ease;
}
.z-faq-t::before,
.z-faq-t::after {
    content: "";
    position: absolute; top: 50%; left: 50%;
    background: var(--z-gold-deep);
    border-radius: 1px;
    transform: translate(-50%, -50%);
    transition: opacity .2s ease, transform .25s ease;
}
.z-faq-t::before { width: 11px; height: 1.8px; }
.z-faq-t::after  { width: 1.8px; height: 11px; }
.z-faq[open] .z-faq-t { background: var(--z-green); border-color: var(--z-green); }
.z-faq[open] .z-faq-t::before { background: var(--z-gold-light); }
.z-faq[open] .z-faq-t::after  { opacity: 0; transform: translate(-50%, -50%) rotate(90deg); }

/* The answer, set in from the number so it reads as belonging to it. */
.z-faq-a {
    padding: 4px 20px 18px 66px;
    animation: zFaqIn .3s ease-out;
}
.z-faq-a .z-prose { font-size: 14.5px; }
@media (max-width: 560px) {
    .z-faq-a { padding-left: 20px; }
    .z-faq-q { font-size: 14.5px; }
}
@keyframes zFaqIn {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
}

/* The way out for a question nobody wrote down. */
.z-faq-ask {
    display: flex; align-items: center; gap: 14px;
    margin-top: 18px;
    padding: 16px 18px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius-sm);
}
.z-faq-ask > div { flex: 1 1 auto; min-width: 0; }
.z-faq-ask b { display: block; font-size: 15px; color: var(--z-green); }
.z-faq-ask span { font-size: 13.5px; color: var(--z-ink-2); }
.z-faq-ask .z-btn { flex: none; }
.z-faq-ask-ico {
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px;
    border-radius: 11px;
    background: var(--z-green);
    color: var(--z-gold-light);
}
@media (max-width: 560px) {
    .z-faq-ask { flex-wrap: wrap; }
    .z-faq-ask .z-btn { width: 100%; justify-content: center; }
}

/* Signed in: the enquiry form states the customer rather than asking for
   them again. The fields stay in the form and keep posting — only the labels
   and boxes come off the screen. */
.z-modal.is-signed .z-eident { display: none; }
.z-esigned {
    display: flex; align-items: center; gap: 12px;
    margin-bottom: 18px;
    padding: 12px 14px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius-sm);
}
.z-esigned > div { min-width: 0; }
.z-esigned b { display: block; font-size: 14.5px; color: var(--z-green); }
.z-esigned span { font-size: 12.5px; color: var(--z-ink-2); word-break: break-word; }
.z-esigned-ico {
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px;
    border-radius: 50%;
    background: var(--z-green);
    color: var(--z-gold-light);
}

/* The same strip, saying "we already have this request" instead of "signed
   in as". Green rather than gold, matching .z-flash.is-ok, because it is the
   same sentence the banner gives after a repeat is sent - and because gold on
   this panel already means "here is what we know about you", which this is
   not. Not red: nothing has gone wrong, and a warning here reads as a failure
   and invites the very second send it exists to prevent. */
.z-esigned.is-open-enquiry {
    background: var(--z-open-bg);
    border-color: var(--z-open);
}
.z-esigned.is-open-enquiry b { color: var(--z-open); }
.z-esigned.is-open-enquiry .z-esigned-ico { background: var(--z-open); color: #fff; }

/* The trip, stated back inside the enquiry form before anything is sent.
   Not a second set of inputs — the booking card already asked. This is the
   last chance to catch a wrong date before it reaches a PDF. */
.z-etrip {
    margin-bottom: 18px;
    padding: 14px 16px;
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius-sm);
}
.z-etrip[hidden] { display: none; }
.z-etrip-h {
    display: flex; align-items: center; gap: 7px;
    margin: 0 0 12px;
    font-size: 11px; font-weight: 600;
    letter-spacing: .14em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-etrip-g {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 10px;
}
.z-etrip-i {
    padding: 9px 11px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-radius: 9px;
}
.z-etrip-i[hidden] { display: none; }
.z-etrip-i > span {
    display: flex; align-items: center; gap: 5px;
    font-size: 9.5px; font-weight: 600;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-etrip-i > span svg { flex: none; color: var(--z-gold-deep); }
.z-etrip-i > b {
    display: block; margin-top: 3px;
    font-size: 15px; font-weight: 600; color: var(--z-green);
    font-variant-numeric: tabular-nums;
}
.z-etrip-n { margin: 10px 0 0; font-size: 12px; color: var(--z-ink-3); }
.z-etrip-n[hidden] { display: none; }


/* --------------------------------------------------------------------------
   Reservation validation

   The booking form carries novalidate, so nothing was telling a traveller
   what was outstanding. A booking for four is forty-odd inputs across four
   cards; one browser bubble on the first empty box is close to useless, so
   everything is listed at once and each line jumps to its field.
   -------------------------------------------------------------------------- */

.z-vmodal { position: fixed; inset: 0; z-index: 120; display: flex;
            align-items: center; justify-content: center; padding: 20px; }
.z-vmodal[hidden] { display: none; }
.z-vmodal-scrim { position: absolute; inset: 0; background: rgba(6, 24, 18, .58); backdrop-filter: blur(3px); }
.z-vmodal-panel {
    position: relative;
    width: min(520px, 100%);
    max-height: 82vh;
    display: flex; flex-direction: column;
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius);
    box-shadow: 0 30px 70px -20px rgba(4, 18, 13, .55);
    overflow: hidden;
}

.z-vmodal-head {
    display: flex; align-items: center; gap: 12px;
    padding: 16px 18px;
    background: var(--z-green);
    color: var(--z-gold-light);
}
.z-vmodal-head > div { flex: 1 1 auto; min-width: 0; }
.z-vmodal-head b { display: block; font-family: var(--z-display); font-size: 19px; font-weight: 600; }
.z-vmodal-head span { font-size: 12.5px; opacity: .85; }
.z-vmodal-ico {
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px;
    border-radius: 50%;
    background: rgba(227, 200, 134, .16);
    color: var(--z-gold);
}
.z-vmodal-x {
    flex: none; width: 30px; height: 30px;
    border: 0; border-radius: 50%;
    background: rgba(227, 200, 134, .14);
    color: var(--z-gold-light);
    font-size: 20px; line-height: 1; cursor: pointer;
}
.z-vmodal-x:hover { background: rgba(227, 200, 134, .26); }

.z-vmodal-list { flex: 1 1 auto; overflow-y: auto; margin: 0; padding: 10px; list-style: none; }
.z-vmodal-item {
    display: block; width: 100%; text-align: left;
    padding: 10px 12px; margin-bottom: 6px;
    background: var(--z-cream);
    border: 1px solid var(--z-line);
    border-left: 3px solid var(--z-sold);
    border-radius: 9px;
    cursor: pointer;
    font-family: var(--z-body);
    transition: background-color .18s ease, border-color .18s ease;
}
.z-vmodal-item:hover { background: var(--z-gold-wash); border-color: var(--z-line-gold); border-left-color: var(--z-sold); }
.z-vmodal-who {
    display: inline-block; margin-right: 7px;
    padding: 1px 8px; border-radius: 100px;
    background: var(--z-green); color: var(--z-gold-light);
    font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
}
.z-vmodal-item b { font-size: 14px; font-weight: 600; color: var(--z-green); }
.z-vmodal-why { display: block; margin-top: 2px; font-size: 12.5px; color: var(--z-sold); }

.z-vmodal-foot { padding: 12px 18px; border-top: 1px solid var(--z-line); text-align: right; }

/* The field itself, so the list and the form agree about what is wrong. */
.z-field.is-bad > label { color: var(--z-sold); }
.z-field.is-bad input,
.z-field.is-bad select,
.z-field.is-bad textarea {
    border-color: var(--z-sold) !important;
    background: var(--z-sold-bg);
}

/* --------------------------------------------------------------------------
   We Accept — the payment marks, under the crests in the Associated column

   Same plate as Authorized by Sigat, and for the same reason: these logos are
   supplied on white grounds, so one light plate holds them rather than each
   carrying its own pale box against the dark green footer.
   -------------------------------------------------------------------------- */

.z-contact-assoc + .z-contact-pay { margin-top: 12px; }

/* One sprite today, one file per brand if it is ever split — the row lays out
   either without a change here. */
.z-contact-pay-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 0 11px 9px;
}
.z-contact-pay-row img {
    display: block;
    /* Width-led, not height-led like the crests: the sheet is a wide grid of
       six marks, so it is the width that has to fit the plate. */
    max-width: 100%;
    height: auto;
    /* Keeps a single-brand file from blowing up to the full plate width if the
       sheet is ever split into six. */
    max-height: 76px;
    object-fit: contain;
}

/* --------------------------------------------------------------------------
   Visa detail — zaereen/visas/detail.php
   -------------------------------------------------------------------------- */

.z-vhead { background: var(--z-green); color: var(--z-cream); padding: 26px 0 30px; }
.z-vhead .z-crumbs { margin-bottom: 16px; }
.z-vhead-in { display: flex; align-items: center; gap: 20px; }
.z-vhead-flag {
    flex: none; width: 78px; height: auto;
    border-radius: 8px;
    border: 1px solid rgba(227, 200, 134, .45);
    box-shadow: 0 8px 20px rgba(4, 18, 13, .35);
}
.z-vhead-txt { min-width: 0; }
.z-vhead-txt h1 {
    margin: 0 0 6px;
    font-family: var(--z-display);
    font-size: clamp(26px, 3.2vw, 38px);
    font-weight: 600; letter-spacing: .02em;
    color: #fdf8ec; text-wrap: balance;
}
.z-vhead-txt p { margin: 0; font-size: 14.5px; color: rgba(244, 236, 218, .82); }
.z-vhead-txt p b { color: var(--z-gold-light); font-weight: 600; }
.z-vhead-badge {
    display: inline-flex; align-items: center; gap: 6px;
    margin-top: 10px; padding: 4px 12px;
    border-radius: 100px;
    background: rgba(227, 200, 134, .16);
    border: 1px solid rgba(227, 200, 134, .4);
    color: var(--z-gold-light);
    font-size: 11.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
}

/* The four figures a visa page is opened for, on the cream band under the
   head. Each says "On request" rather than a zero where the row is empty. */
.z-vfacts { background: var(--z-cream); border-bottom: 1px solid var(--z-line); padding: 16px 0; }
.z-vfacts-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 12px;
}
.z-vfact {
    padding: 10px 14px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
}
.z-vfact > span {
    display: flex; align-items: center; gap: 6px;
    font-size: 10px; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase; color: var(--z-ink-3);
}
.z-vfact > span svg { color: var(--z-gold-deep); }
.z-vfact > b {
    display: block; margin-top: 3px;
    font-family: var(--z-display); font-size: 18px; font-weight: 600; color: var(--z-green);
}

.z-vbody { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 30px; align-items: start; }
.z-vbody > aside { position: sticky; top: 96px; }

/* The fee grid scrolls inside its own box rather than widening the page. */
.z-vtable-wrap { overflow-x: auto; border: 1px solid var(--z-line); border-radius: var(--z-radius-sm); }
.z-vtable { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.z-vtable th {
    padding: 10px 12px; text-align: left; white-space: nowrap;
    background: var(--z-green); color: var(--z-gold-light);
    font-size: 10.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
}
.z-vtable th.num, .z-vtable td.num { text-align: right; }
.z-vtable td { padding: 11px 12px; border-top: 1px solid var(--z-line); color: var(--z-ink-2); }
.z-vtable td.item b { display: block; font-size: 14px; font-weight: 600; color: var(--z-green); }
.z-vtable td.item span { font-size: 11.5px; color: var(--z-ink-3); }
.z-vtable td.total { font-weight: 700; color: var(--z-green); font-variant-numeric: tabular-nums; }
.z-vtable tbody tr:nth-child(even) { background: var(--z-marble); }

.z-note-sm {
    display: flex; align-items: flex-start; gap: 6px;
    margin: 10px 0 0; font-size: 12px; color: var(--z-ink-3);
}
.z-note-sm svg { flex: none; margin-top: 2px; color: var(--z-gold-deep); }

/* The checklist is numbered: a document list is worked through in order, and
   "the third one" is how it gets referred to. */
.z-vdocs { display: flex; flex-direction: column; gap: 10px; }
.z-vdoc {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 14px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-left: 3px solid var(--z-gold);
    border-radius: var(--z-radius-sm);
}
.z-vdoc > div { flex: 1 1 auto; min-width: 0; }
.z-vdoc b { display: block; font-size: 15px; font-weight: 600; color: var(--z-green); }
.z-vdoc .z-prose { font-size: 13.5px; margin-top: 3px; }
.z-vdoc-n {
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: 9px;
    background: var(--z-gold-wash); border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
    font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.z-vdoc img { flex: none; width: 76px; border-radius: 8px; border: 1px solid var(--z-line); }

.z-vrule-h {
    margin: 16px 0 6px;
    font-size: 11px; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase; color: var(--z-gold-deep);
}
.z-vrule-h:first-child { margin-top: 0; }

.z-vembassy {
    display: flex; flex-direction: column; gap: 1px;
    background: var(--z-line);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    overflow: hidden;
}
.z-vemb-row { display: grid; grid-template-columns: 150px 1fr; gap: 14px; padding: 12px 14px; background: var(--z-surface); }
.z-vemb-row > span {
    display: flex; align-items: center; gap: 6px;
    font-size: 10.5px; font-weight: 600;
    letter-spacing: .1em; text-transform: uppercase; color: var(--z-ink-3);
}
.z-vemb-row > span svg { color: var(--z-gold-deep); }
.z-vemb-row > b { font-size: 14px; font-weight: 500; color: var(--z-ink); word-break: break-word; }
.z-vemb-row a { color: var(--z-green-3); text-decoration: underline; }

/* The apply card, shaped like Plan Your Journey on a tour so the two read as
   the same kind of control. */
.z-vapply {
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius);
    box-shadow: var(--z-shadow);
    overflow: hidden;
}
.z-vapply-head {
    display: flex; align-items: center; gap: 9px;
    padding: 14px 16px;
    background: var(--z-green); color: var(--z-gold-light);
    font-family: var(--z-display);
    font-size: 16px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase;
}
.z-vapply-head svg { color: var(--z-gold); }
.z-vapply-body { padding: 16px; }
.z-vapply-price {
    padding: 12px 14px; margin-bottom: 14px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius-sm);
    text-align: center;
}
.z-vapply-price span { display: block; font-size: 10px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--z-ink-3); }
.z-vapply-price b { display: block; font-family: var(--z-display); font-size: 26px; font-weight: 600; color: var(--z-green); }
.z-vapply-price small { font-size: 11.5px; color: var(--z-ink-3); }
.z-vapply-list { list-style: none; margin: 0 0 14px; padding: 0; }
.z-vapply-list li { display: flex; align-items: flex-start; gap: 8px; padding: 5px 0; font-size: 13.5px; color: var(--z-ink-2); }
.z-vapply-list svg { flex: none; margin-top: 2px; color: var(--z-open); }
.z-vapply-cta, .z-vapply-wa { width: 100%; justify-content: center; }
.z-vapply-wa { margin-top: 8px; }
.z-vapply-note { margin: 12px 0 0; font-size: 12px; color: var(--z-ink-3); line-height: 1.5; }

@media (max-width: 980px) {
    .z-vbody { grid-template-columns: 1fr; }
    .z-vbody > aside { position: static; }
    .z-vemb-row { grid-template-columns: 1fr; gap: 3px; }
}
@media (max-width: 560px) {
    .z-vhead-in { flex-direction: column; align-items: flex-start; gap: 14px; }
    .z-vdoc img { display: none; }
}

/* The apply-by date on the visa card. A visa is bought against a deadline, so
   this is the one figure the card exists to state. */
.z-veta {
    margin-bottom: 14px;
    padding: 12px 14px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-left: 3px solid var(--z-gold);
    border-radius: var(--z-radius-sm);
}
.z-veta[hidden] { display: none; }
.z-veta-lab {
    display: block;
    font-size: 10px; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase; color: var(--z-ink-3);
}
.z-veta b {
    display: block; margin: 2px 0 4px;
    font-family: var(--z-display); font-size: 22px; font-weight: 600; color: var(--z-green);
}
.z-veta p { margin: 0; font-size: 12px; color: var(--z-ink-2); line-height: 1.5; }
/* Past the deadline: the panel says so rather than presenting a date that has
   already gone as a plan. */
.z-veta.is-late { background: var(--z-sold-bg); border-color: var(--z-sold); border-left-color: var(--z-sold); }
.z-veta.is-late b, .z-veta.is-late p { color: var(--z-sold); }

/* ITS is asked only for Ziyarat subjects; hidden it must take no grid space. */
.z-modal .z-eits[hidden] { display: none; }

/* A stated value where a field would be — same box as an input so a read-only
   fact lines up with the ones beside it, but plainly not editable. */
.z-field .z-ro {
    margin: 0;
    padding: 10px 12px;
    background: var(--z-cream);
    border: 1px dashed var(--z-line);
    border-radius: 10px;
    font-size: 14px; font-weight: 600; color: var(--z-green);
    min-height: 40px;
    display: flex; align-items: center;
}

/* ==========================================================================
   My Bookings — zaereen/users/mybooking.php
   --------------------------------------------------------------------------
   The layout of login/my_bookings.php on the main site: a header band with
   product tiles, a left rail of filters, a travel-date rail, and one wide
   card per booking with an action bar under it. That page is navy; this one
   is not. The Zaereen header and footer wrapped around this content are
   marble, and a navy band between them reads as a different site — so the
   same structure is drawn in cream, deep green and gold, and the neon column
   accents that page uses become the five brand colours instead.

   Nothing here is shared with .z-trip (the old My Journey card), which this
   replaces.
   ========================================================================== */

.z-mybk .z-shell { max-width: var(--z-shell); }

/* Every control on this page is toggled with el.hidden. An author
   `display` value outranks the UA sheet's [hidden]{display:none}, so
   .z-mybk-find-x (display:flex) would stay visible without this. */
.z-mybk [hidden] { display: none !important; }

/* ------------------------------------------------------------- page head --- */
/* Greeting on the left of the dark band, product filter on the right. Scoped
   to .z-mybk-top so the shared .z-pagehead every other page uses is untouched
   — there its .z-shell stays a plain block. Without this rule the tiles are
   simply the next block after the subtitle, which is where they landed. */

.z-mybk-top .z-shell {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 20px 40px;
}
.z-mybk-top-text { flex: 1 1 340px; min-width: 0; }
.z-mybk-top-text h1 { margin: 14px 0 10px; }
.z-mybk-top-text p  { margin: 0; }
/* The tiles are taller than the text block, so the band needs a little more
   room under them before the crest scallop. */
.z-mybk-top .z-mybk-tiles { flex: 0 0 auto; }
.z-mybk-top { padding-bottom: 64px; }


/* ------------------------------------------------------------ stat tiles --- */
/* Squares, so five of them read as a set rather than a row of wide pills. */

.z-mybk-tiles {
    flex: 0 1 auto;
    display: grid; grid-template-columns: repeat(5, 108px); gap: 10px;
}
.z-mybk-tile {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 5px;
    aspect-ratio: 1; padding: 10px 6px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 15px;
    cursor: pointer; overflow: hidden;
    font: inherit; text-align: center;
    transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.z-mybk-tile::before {
    content: ''; position: absolute; inset: 0;
    background: radial-gradient(circle at 15% 12%, var(--tile) 0%, transparent 62%);
    opacity: .12; pointer-events: none;
}
.z-mybk-tile > * { position: relative; z-index: 2; }
.z-mybk-tile:hover {
    transform: translateY(-3px);
    border-color: var(--tile);
    box-shadow: 0 14px 28px -14px var(--tile);
}
.z-mybk-tile.is-on {
    border-color: var(--tile);
    box-shadow: inset 0 0 0 1px var(--tile), 0 12px 26px -16px var(--tile);
}
.z-mybk-tile-ic {
    display: flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; border-radius: 11px;
    color: var(--tile);
    background: var(--z-marble);
    border: 1px solid var(--z-line);
    background: color-mix(in srgb, var(--tile) 13%, transparent);
    border-color: color-mix(in srgb, var(--tile) 26%, transparent);
}
.z-mybk-tile b {
    font-family: var(--z-display); font-size: 22px; font-weight: 600;
    line-height: 1; color: var(--z-green); font-variant-numeric: tabular-nums;
}
.z-mybk-tile small {
    font-size: 9.5px; font-weight: 600; letter-spacing: .1em;
    text-transform: uppercase; color: var(--z-ink-3); white-space: nowrap;
}

/* --------------------------------------------------------- two-column --- */

.z-mybk-grid {
    display: grid; grid-template-columns: 268px minmax(0, 1fr); gap: 22px;
    align-items: start;
}
.z-mybk-rail { position: sticky; top: 92px; }

.z-mybk-panel {
    padding: 15px 14px;
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: 15px;
    box-shadow: var(--z-shadow-sm);
}
.z-mybk-panel + .z-mybk-panel { margin-top: 12px; }
.z-mybk-panel-t {
    padding-bottom: 9px; margin-bottom: 10px;
    border-bottom: 1px solid var(--z-line-soft);
    font-size: 9.5px; font-weight: 600; letter-spacing: .14em;
    text-transform: uppercase; color: var(--z-gold-deep); text-align: center;
}

/* search box */
.z-mybk-find { position: relative; display: flex; align-items: center; }
.z-mybk-find > svg {
    position: absolute; left: 10px; color: var(--z-ink-3); pointer-events: none;
}
.z-mybk-find input {
    width: 100%; padding: 8px 30px 8px 32px;
    font: inherit; font-size: 13px; font-weight: 500; color: var(--z-ink);
    background: var(--z-marble);
    border: 1px solid var(--z-line);
    border-radius: 9px;
}
.z-mybk-find input::placeholder { color: var(--z-ink-3); font-weight: 400; }
.z-mybk-find input:focus {
    outline: none; border-color: var(--z-gold);
    box-shadow: 0 0 0 3px rgba(193, 154, 63, .16);
}
.z-mybk-find-x {
    position: absolute; right: 8px;
    display: flex; padding: 2px; border: 0; background: none;
    color: var(--z-ink-3); cursor: pointer;
}
.z-mybk-find-x:hover { color: var(--z-sold); }

/* status rows */
.z-mybk-row {
    display: flex; align-items: center; width: 100%;
    padding: 7px 9px; margin-bottom: 2px;
    border: 1px solid transparent; border-radius: 9px;
    background: none; cursor: pointer;
    font: inherit; font-size: 13.5px; color: var(--z-ink-2); text-align: left;
    transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.z-mybk-row:hover { background: var(--z-marble); color: var(--z-ink); }
.z-mybk-row.is-on {
    background: var(--z-gold-wash);
    border-color: var(--z-line-gold);
    color: var(--z-green); font-weight: 600;
}
.z-mybk-row-ic {
    flex: 0 0 26px; width: 26px; height: 26px; margin-right: 10px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 8px;
}
.z-mybk-row-ic.is-all       { background: var(--z-cream-deep);  color: var(--z-ink-2); }
.z-mybk-row-ic.is-pending   { background: var(--z-few-bg);      color: var(--z-few); }
.z-mybk-row-ic.is-confirmed { background: var(--z-open-bg);     color: var(--z-open); }
.z-mybk-row-ic.is-cancelled { background: var(--z-sold-bg);     color: var(--z-sold); }
.z-mybk-row-ic.is-completed { background: var(--z-teal-wash);   color: var(--z-teal); }
.z-mybk-row-l {
    flex: 1 1 auto; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.z-mybk-row-n {
    flex: none; margin-left: 8px; padding: 2px 9px;
    border-radius: 100px; background: var(--z-marble);
    border: 1px solid var(--z-line-soft);
    font-size: 11.5px; font-weight: 600; color: var(--z-ink-2);
    font-variant-numeric: tabular-nums;
}
.z-mybk-row.is-on .z-mybk-row-n {
    background: var(--z-surface); border-color: var(--z-line-gold); color: var(--z-gold-deep);
}

/* ----------------------------------------------------------- date rail --- */
/* A horizontal rail of calendar leaves rather than a date picker: the useful
   question is "which dates do I have something on", which a picker cannot
   answer. The active leaf is filled deep green, the same way .z-trip-when
   draws a date everywhere else on the site. */

.z-dates { display: flex; align-items: center; gap: 6px; margin-bottom: 18px; }

.z-dates-rail {
    flex: 1 1 auto; min-width: 0;
    display: flex; gap: 7px;
    overflow-x: auto; scroll-behavior: smooth;
    padding: 2px 1px;
    scrollbar-width: none; -ms-overflow-style: none;
}
.z-dates-rail::-webkit-scrollbar { display: none; }

.z-date {
    flex: 0 0 auto;
    width: 70px; height: 70px;
    display: flex; flex-direction: column;
    padding: 0; overflow: hidden; cursor: pointer;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 13px;
    font: inherit;
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.z-date:hover {
    border-color: var(--z-gold);
    transform: translateY(-3px);
    box-shadow: 0 10px 20px -12px rgba(143, 111, 28, .7);
}
/* "All dates" is pinned beside the rail rather than being its first leaf: it
   is the way OUT of a date filter, and a control that scrolls out of sight is
   no use when you are forty bookings along. */
.z-date.is-all {
    margin-right: 3px; padding-right: 0;
    border-right: 1px dashed var(--z-line-strong);
}
.z-date-m {
    flex: none; padding: 3px 0 2px; text-align: center;
    font-size: 8.5px; font-weight: 700; letter-spacing: .11em; line-height: 1.2;
    color: var(--z-gold-deep);
    background: var(--z-gold-wash);
    border-bottom: 1px solid var(--z-line-gold);
}
.z-date-d {
    flex: 1 1 auto;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--z-display); font-size: 25px; font-weight: 600;
    line-height: 1; color: var(--z-green); font-variant-numeric: tabular-nums;
}
.z-date-n {
    flex: none; padding: 0 2px 5px; text-align: center;
    font-size: 8.5px; font-weight: 600; line-height: 1;
    color: var(--z-ink-3); white-space: nowrap;
}
.z-date.is-on {
    background: var(--z-green); border-color: var(--z-green);
    box-shadow: 0 10px 20px -12px rgba(13, 44, 34, .8);
}
.z-date.is-on .z-date-m {
    color: var(--z-gold-light);
    background: rgba(227, 200, 134, .16);
    border-bottom-color: rgba(227, 200, 134, .28);
}
.z-date.is-on .z-date-d { color: #fdf8ec; }
.z-date.is-on .z-date-n { color: var(--z-gold-light); }
.z-date.is-all .z-date-d { color: var(--z-gold-deep); }
.z-date.is-all.is-on .z-date-d { color: var(--z-gold-light); }
/* Dates already travelled recede but stay reachable. */
.z-date.is-past { opacity: .68; }
.z-date.is-past:hover { opacity: 1; }
.z-date.is-today { border-color: var(--z-teal); }
.z-date.is-today .z-date-m {
    color: var(--z-teal); background: var(--z-teal-wash); border-bottom-color: rgba(18, 101, 95, .28);
}

.z-dates-nav {
    flex: none; width: 26px; height: 70px;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer; border-radius: 10px;
    color: var(--z-gold-deep);
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
}
.z-dates-nav:hover { background: var(--z-gold-pale); }
/* The set ships one chevron, pointing down. */
.z-dates-nav svg { transform: rotate(90deg); }
.z-dates-nav.is-next svg { transform: rotate(-90deg); }

/* -------------------------------------------------------- booking card --- */

.z-bkc {
    position: relative;
    margin-bottom: 18px;
    background: var(--z-surface);
    /* A gold hairline rather than the grey line: these sit on cream, where a
       neutral border reads as a seam and a warm one reads as an edge. */
    border: 1px solid var(--z-line-gold);
    border-radius: 16px;
    /* Three layers doing three jobs: a hairline that keeps the edge crisp on a
       light ground, a tight contact shadow so the card sits ON the page, and a
       wide ambient one so it lifts off it. One big soft shadow alone just looks
       like a smudge. */
    box-shadow:
        0 0 0 1px rgba(193, 154, 63, .07),
        0 2px 4px rgba(13, 44, 34, .05),
        0 14px 30px -14px rgba(13, 44, 34, .22);
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
/* The parchment grain the rest of the site uses, at a fraction of its opacity —
   enough to stop a large white card reading as a plain browser box. */
.z-bkc::before {
    content: ''; position: absolute; inset: 0; z-index: 0;
    border-radius: inherit; pointer-events: none;
    background-image: var(--z-pattern);
    opacity: .16;
}
/* Lifts the content above the grain. The reference ribbon is excluded: it is
   absolutely positioned against the card, and `position: relative` here would
   drop it back into flow. Relying on source order to save it would be one
   reordered rule away from breaking. */
.z-bkc > *:not(.z-bkc-head):not(.z-bkc-ref) { position: relative; z-index: 1; }

.z-bkc:hover {
    transform: translateY(-3px);
    border-color: var(--z-gold);
    box-shadow:
        0 0 0 1px rgba(193, 154, 63, .16),
        0 4px 8px rgba(13, 44, 34, .06),
        0 24px 46px -18px rgba(13, 44, 34, .32);
}

/* No status stripe down the spine. The state is already said twice on the card
   — the badge on the action bar and the payment column — and a coloured bar
   against the gold border was a third voice competing with both. */

/* Cancelled recedes but stays legible, and comes back on hover. */
.z-bkc.is-cancelled { opacity: .8; }
.z-bkc.is-cancelled:hover { opacity: 1; }

/* The reference ribbon overlaps the top edge, so .z-bkc-main carries extra
   top padding to clear it — without that the first column starts visibly
   lower than the rest. */
/* ------------------------------------------------------------- the head --- */
/* Reference | booked on | status, across the top of the card.

   The reference used to be absolutely positioned over the corner, which is why
   it needed a z-index and a max-width and could sit on whatever was underneath
   it. In a row it needs none of that: it is simply the first item. */
 /* DESKTOP IS THE CARD IT WAS. The head, the title, and the labels beside
   every value are the phone's card; on a wide screen the row of columns is
   the card and nothing about it changed. So above 1080px the head shrinks
   back to the corner badge it has always been — absolute, over the card's
   top-left, carrying only the reference — and the date and status it holds
   are hidden, because desktop still draws those in the Booking Date column
   and the footer respectively. */
.z-bkc-head {
    position: absolute; top: 0; left: 0; z-index: 3;
    max-width: calc(100% - 14px);
    display: flex;
    align-items: center;
}
.z-bkc-head .z-bkc-on,
.z-bkc-head .z-bkc-status,
.z-bkc-title { display: none; }

.z-bkc-ref {
    flex: none;
    padding: 4px 14px;
    background: var(--z-gold-leaf);
    color: var(--z-green);
    border-radius: 16px 0 14px 0;
    font-size: 10.5px; font-weight: 700; letter-spacing: .07em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    box-shadow: 0 2px 8px rgba(13, 44, 34, .18);
}

/* The ITS chip is first in the markup because that is where the phone wants
   it. On desktop it goes back to the end of the column, where it was. */
.z-bkc-col.is-client > .z-bkc-chip { order: 9; }

/* --- the enquiry card's two arrangements ----------------------------------
   Above 1080px it wears the booking card's foot — state, subject, way out —
   so the two cards from one account read as one product. The badge and the
   outline link that say the same things inside the columns stand down here;
   below 1080px the pair swap over, because the stacked enquiry card was asked
   to stay exactly as it is. */
.z-bkc.is-enq .is-stackonly { display: none; }

/* TWO CARDS WEAR .z-bkc. mybooking's has a .z-bkc-head and the reference is
   the first item inside it; myenquiry's has no head at all and the reference
   is a bare child of the card, positioned over its corner exactly as it always
   was. So the positioning belongs to the PLACE, not to the class — written
   against the class alone, the enquiry card's badge lost its corner and
   dropped into the flow at the top of the card. */
.z-bkc > .z-bkc-ref {
    position: absolute; top: 0; left: 0; z-index: 3;
    max-width: calc(100% - 14px);
}
/* The middle takes what is left and gives it back first: at a narrow width the
   date can go before either the reference or the status does. */
.z-bkc-on {
    flex: 1 1 auto;
    min-width: 0;
    display: flex; align-items: center; justify-content: center;
    gap: 5px;
    padding: 4px 0;
    font-size: 11.5px;
    color: var(--z-ink-2);
    white-space: nowrap;
    overflow: hidden;
}
.z-bkc-on small {
    font-size: 10px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--z-ink-3);
}
.z-bkc-on b { font-weight: 700; color: var(--z-green); }
.z-bkc-on svg { flex: none; color: var(--z-gold-deep); }
.z-bkc-on-sep {
    flex: none;
    width: 1px; height: 12px;
    background: var(--z-line);
    margin: 0 3px;
}

/* ------------------------------------------------------------ the title --- */
/* The product the card is about, named once, under the head. */
.z-bkc-title {
    padding: 11px 18px 0;
}
.z-bkc-title-lbl {
    display: flex; align-items: center; gap: 6px;
    font-size: 9.5px; font-weight: 700; letter-spacing: .11em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-bkc-title-lbl svg { flex: none; }
.z-bkc-title b {
    display: block;
    margin-top: 4px;
    font-size: 15.5px; font-weight: 700; line-height: 1.35;
    color: var(--z-green);
}

.z-bkc-main {
    display: flex; align-items: flex-start;
    /* 30px of clearance for the reference badge, which is positioned over
       this corner at desktop width. The stacked card reclaims it below 1080px,
       where the badge is part of a bar in the flow instead. */
    padding: 30px 6px 15px;
}
.z-bkc-col {
    min-width: 0; padding: 0 15px;
    display: flex; flex-direction: column; gap: 3px;
}
.z-bkc-col + .z-bkc-col { border-left: 1px solid var(--z-line-soft); }
/* The booking date is a fixed-width column of three short lines, so centring
   it reads as a column rather than as text that ran out early.
   align-self:stretch is what makes the vertical centring possible: the row is
   align-items:flex-start, so without it this column is only as tall as its own
   three lines and justify-content has no room to centre anything in. */
.z-bkc-col.is-booked {
    flex: 0 0 145px;
    align-self: stretch;
    align-items: center; text-align: center;
    justify-content: center;
}
/* The state, under the date. Centred with the rest of the column, and given
   air above it so it reads as a separate statement rather than a third line of
   the timestamp. */
.z-bkc-col.is-booked > .z-bkc-status {
    margin-top: 9px;
    align-self: center;
    font-size: 9.5px;
    padding: 4px 12px;
}

/* The per-value label inside a grouped column. Off by default: above 1080px
   the card is a row of columns and the group heading is the right unit, so the
   desktop card must not grow a second column of captions. */
.z-bkc-fl { display: none; }

.z-bkc-col.is-client { flex: 1.7 1 190px; }
.z-bkc-col.is-travel { flex: 1.1 1 140px; }
.z-bkc-col.is-pax    { flex: 1.3 1 155px; }
.z-bkc-col.is-pay    { flex: 1 1 140px; align-items: flex-end; text-align: right; }

/* Each column heading takes its own brand accent, the way the main site's
   card gives each one a neon. Five colours, all already in the palette. */
.z-bkc-lbl {
    font-size: 9px; font-weight: 700; letter-spacing: .13em;
    text-transform: uppercase; margin-bottom: 3px;
}
.is-booked .z-bkc-lbl { color: var(--z-gold-deep); }
.is-client .z-bkc-lbl { color: var(--z-sold); }
.is-travel .z-bkc-lbl { color: var(--z-teal); }
.is-pax    .z-bkc-lbl { color: var(--z-green-3); }
.is-pay    .z-bkc-lbl { color: var(--z-ink-2); }

/* --- the card as a label/value table below desktop -------------------------
   Five columns side by side is a desktop shape. Wrapped onto a phone it became
   five stacked blocks, each with its heading above its values — the same
   information, read as a list of little paragraphs.

   Here it is a two-column table instead, the arrangement admin/leads uses: the
   heading right-aligned in a fixed left column, every value of that group on
   its own row in the right one, and a hairline between groups. The headings
   keep the accent colours they already carry, which is what tells the groups
   apart once the vertical rules between the columns are gone.

   `> :not(.z-bkc-lbl)` rather than naming each value: the groups hold three to
   five different children each — a name, a sub-line, a chip, a badge row — and
   listing them would need updating every time one is added. Everything that is
   not the heading goes in the right column, one per row.
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
    /* --- THE STACKED CARD ---------------------------------------------

       Everything below is the phone and tablet arrangement: a head bar
       carrying the reference, when it was booked and the status; the product
       named once beneath it; then one labelled row per value. The desktop
       pieces that say the same things elsewhere stand down. */
    .z-bkc-head {
        position: static;
        max-width: none;
        gap: 10px;
        padding: 0;
        background: linear-gradient(180deg, var(--z-cream) 0%, var(--z-cream-deep) 100%);
        border-bottom: 1px solid var(--z-line);
        border-radius: 16px 16px 0 0;
        overflow: hidden;
    }
    .z-bkc-head .z-bkc-on { display: flex; }
    .z-bkc-head .z-bkc-status { display: flex; }
    .z-bkc-title { display: block; }

    /* Scoped to the head: the enquiry card's badge is not in one, and it
       keeps the corner treatment it has at every width. */
    .z-bkc-head .z-bkc-ref {
        align-self: stretch;
        display: flex; align-items: center;
        padding: 7px 14px;
        border-radius: 15px 14px 14px 0;
        box-shadow: none;
    }

    /* Said in the head now, so not said again here — on the card that HAS a
       head. The enquiry card has none, and its "Enquired On" column is the
       only place that date appears, so it stays. */
    .z-bkc.has-head .z-bkc-col.is-booked { display: none; }

    /* The enquiry card swaps back: its foot goes, and the state badge and the
       View link return to the columns they sit in on the stacked card. */
    .z-bkc.is-enq > .z-bkc-foot { display: none; }
    .z-bkc.is-enq .z-bkc-badges.is-stackonly { display: flex; }
    .z-bkc.is-enq .z-btn.is-stackonly { display: inline-flex; }
    .z-bkc-col.is-client > .z-bkc-sub.is-pkg { display: none; }
    /* The tag only. The status pill left the footer for the Booking Date
       column, and that column is hidden wholesale on this card below 1080px
       (see .has-head above) — so the pill goes with it and the head bar's copy
       is the only one left. A selector still aimed at the footer would match
       nothing and quietly stop being the thing preventing two pills. */
    .z-bkc-foot > .z-bkc-tag { display: none; }

    /* First in the markup, first on the card — no reordering wanted here. */
    .z-bkc-col.is-client > .z-bkc-chip { order: 0; }

    /* 30px keeps the clearance for a badge that is still over the corner on
       the enquiry card; the booking card, whose badge is now a bar in the
       flow, gives it back. */
    .z-bkc-main { display: block; padding: 30px 14px 14px; position: relative; }
    .z-bkc.has-head .z-bkc-main { padding-top: 12px; }

    .z-bkc-col {
        display: grid;
        grid-template-columns: 104px minmax(0, 1fr);
        gap: 3px 12px;
        align-items: start;
        padding: 9px 0;
        border-bottom: 1px dashed var(--z-line-soft);
    }
    .z-bkc-col:last-child { border-bottom: 0; padding-bottom: 0; }

    /* THE RULE BETWEEN THE TWO COLUMNS, as admin/leads draws it. One per
       group, but the groups stack edge to edge so it reads as a single line
       running the height of the card.

       Positioned off the TRACK, not off the card: 104px of label plus half the
       12px gap, measured from the group's own left edge. Drawn against the
       card's padding first, it landed 2px inside the value column and the
       values sat on top of it — the padding is not what the earlier arithmetic
       assumed. Anchored here it cannot drift from the template above. */
    .z-bkc-col { position: relative; }
    .z-bkc-col::before {
        content: "";
        position: absolute;
        top: 0; bottom: 0; left: 110px;
        width: 1px;
        background: var(--z-line-soft);
    }
    /* The rule between columns was for the row; there is no row now. Written
       with the same two-class selector it is set with, so it wins on order. */
    .z-bkc-col + .z-bkc-col { border-left: 0; }

    .z-bkc-lbl {
        grid-column: 1; grid-row: 1;
        margin: 0;
        text-align: right;
        /* Sits on the first value's line rather than the top of the group. */
        align-self: center;
    }
    .z-bkc-col > :not(.z-bkc-lbl) { grid-column: 2; }

    /* --- ONE LABEL PER VALUE, as admin/bookings draws a card ---------------

       Three of the five groups carry more than one fact: Client & Destination
       holds four, Travellers & Plan two, Payment Status three. Stacked under a
       single heading they are a paragraph with a caption, and which line is
       which is left to the icons to say.

       .is-split marks those three. Their group heading stands down and every
       value takes a label of its own in the same 104px track — so each line of
       the card reads "label | value" against the one rule, which is what makes
       the admin card easy to follow.

       Placed in column 1 explicitly: the rule above sends every non-.z-bkc-lbl
       child to column 2, and this is written after it at the same specificity,
       so source order decides. Auto-placement then pairs each label with the
       value that follows it, one row apiece. */
    .z-bkc-col.is-split > .z-bkc-lbl { display: none; }
    .z-bkc-col.is-split > .z-bkc-fl {
        display: block;
        grid-column: 1;
        margin: 0;
        text-align: right;
        align-self: center;
        font-size: 9.5px;
        font-weight: 700;
        letter-spacing: .1em;
        text-transform: uppercase;
        color: var(--z-ink-3);
    }
    /* An empty label cell still holds its row open, or the value beside it
       climbs into the row above. */
    .z-bkc-col.is-split > .z-bkc-fl:empty { min-height: 1px; }

    /* Four labelled lines under one heading read as a block; the same air the
       groups have between them separates the rows inside a split one. */
    .z-bkc-col.is-split { row-gap: 8px; }

    /* Booking Date is centred and Payment Status right-aligned on desktop,
       both of which fight a left-hand value column. */
    .z-bkc-col.is-booked,
    .z-bkc-col.is-pay {
        align-items: start;
        justify-content: start;
        text-align: left;
    }
}

.z-bkc-day {
    font-family: var(--z-display); font-size: 18px; font-weight: 600;
    line-height: 1.15; color: var(--z-gold-deep); font-variant-numeric: tabular-nums;
}
.z-bkc-name {
    display: flex; align-items: center; gap: 6px;
    font-size: 14px; font-weight: 600; color: var(--z-green); line-height: 1.3;
}
.z-bkc-sub {
    display: flex; align-items: center; gap: 6px;
    font-size: 12.5px; color: var(--z-ink-2); line-height: 1.35;
}
.z-bkc-sub.is-quiet { color: var(--z-ink-3); font-size: 12px; }
.is-pay .z-bkc-sub { justify-content: flex-end; }
.z-bkc-name svg, .z-bkc-sub svg, .z-bkc-counts svg { flex: none; opacity: .85; }

.z-bkc-chip {
    align-self: flex-start; margin-top: 3px;
    padding: 2px 9px; border-radius: 100px;
    background: var(--z-gold-wash); border: 1px solid var(--z-line-gold);
    font-size: 10.5px; font-weight: 600; color: var(--z-gold-deep);
}

.z-bkc-counts {
    display: flex; flex-wrap: wrap; gap: 4px 12px;
    font-size: 12.5px; font-weight: 500; color: var(--z-ink-2);
}
.z-bkc-counts span { display: inline-flex; align-items: center; gap: 5px; }

.z-bkc-badges { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
.z-bkc-badge {
    padding: 2px 9px; border-radius: 100px;
    font-size: 10px; font-weight: 700; letter-spacing: .02em;
    border: 1px solid transparent;
}
.z-bkc-badge.is-tour  { background: var(--z-green-soft); color: var(--z-green-3); border-color: rgba(31, 96, 71, .22); }
.z-bkc-badge.is-hotel { background: var(--z-teal-wash);  color: var(--z-teal);    border-color: rgba(18, 101, 95, .22); }
.z-bkc-badge.is-meal  { background: var(--z-open-bg);    color: var(--z-open);    border-color: rgba(27, 99, 73, .22); }
.z-bkc-badge.is-plain { background: var(--z-marble);     color: var(--z-ink-2);   border-color: var(--z-line); }

.z-bkc-money {
    font-family: var(--z-display); font-size: 24px; font-weight: 600;
    line-height: 1.15; color: var(--z-gold-deep); font-variant-numeric: tabular-nums;
}
.z-bkc-due {
    margin-top: 3px; padding: 2px 10px; border-radius: 100px;
    background: var(--z-sold-bg); border: 1px solid rgba(138, 48, 36, .25);
    font-size: 11.5px; font-weight: 700; color: var(--z-sold);
    font-variant-numeric: tabular-nums;
}
.z-bkc-clear {
    display: inline-flex; align-items: center; gap: 5px;
    margin-top: 3px; padding: 2px 10px; border-radius: 100px;
    background: var(--z-open-bg); border: 1px solid rgba(27, 99, 73, .25);
    font-size: 11.5px; font-weight: 700; color: var(--z-open);
}

/* ---------------------------------------------------------- action bar --- */

.z-bkc-foot {
    display: flex; align-items: center; flex-wrap: wrap; gap: 9px 14px;
    padding: 11px 18px;
    background: linear-gradient(180deg, var(--z-cream) 0%, var(--z-cream-deep) 100%);
    border-top: 1px solid var(--z-line);
    border-radius: 0 0 16px 16px;
}
/* In the head it mirrors the reference at the other end: full bar height,
   square to the card's corner, rounded where it meets the bar.

   SHAPE ONLY — no `display` here. Whether this is shown is decided by the two
   rules further up: hidden at desktop width, where the status is a pill in the
   footer instead, and shown in the stacked block. Setting display:flex here
   put it back on screen at every width, because it is the same specificity as
   the hide and comes later in the file. */
.z-bkc-head .z-bkc-status {
    flex: none;
    align-self: stretch;
    align-items: center;
    border-radius: 14px 15px 0 14px;
    padding: 7px 15px;
}
.z-bkc-status {
    padding: 5px 15px; border-radius: 100px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: #fdf8ec;
}
/* A BUCKET PER STATE, AND THE ENQUIRY BUCKETS ARE NOT THE BOOKING ONES.

   .z-bkc-status sets a near-white text colour and leaves the background to the
   bucket class. Those four below are mybooking's — confirmed, pending,
   cancelled, completed — and myenquiry's are new, progress, booked and closed.
   None of them matched, so the pill had no background at all and printed
   #fdf8ec text on the cream footer: "Awaiting reply" in white on near-white,
   which is why it looked like nothing was there.

   The four are coloured for what they mean rather than borrowed:
     Awaiting reply    the amber the booking card gives pending — the ball is
                       with us, and that is the same signal
     In progress       teal, work under way
     Became a booking  the open green: the outcome the page exists for
     Closed            muted ink, since a closed enquiry is neither good news
                       nor bad and should not be coloured as either */
.z-bkc-status.is-confirmed { background: var(--z-open); }
.z-bkc-status.is-pending   { background: var(--z-few); }
.z-bkc-status.is-cancelled { background: var(--z-sold); }
.z-bkc-status.is-completed { background: var(--z-teal); }

.z-bkc-status.is-new      { background: var(--z-few); }
.z-bkc-status.is-progress { background: var(--z-teal); }
.z-bkc-status.is-booked   { background: var(--z-open); }
.z-bkc-status.is-closed   { background: var(--z-ink-2); }

.z-bkc-tag {
    display: inline-flex; align-items: center; gap: 6px;
    min-width: 0; padding: 4px 12px; border-radius: 100px;
    background: var(--z-surface); border: 1px solid var(--z-line);
    font-size: 12.5px; font-weight: 600; color: var(--z-green);
}
.z-bkc-tag svg { flex: none; color: var(--z-gold-deep); }

.z-bkc-todo {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12px; font-weight: 600; color: var(--z-few);
}
.z-bkc-todo svg { flex: none; }

.z-bkc-acts { display: inline-flex; flex-wrap: wrap; gap: 8px; margin-left: auto; }
.z-bkc-act {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 7px 15px; border-radius: 9px;
    font-size: 12.5px; font-weight: 600; text-decoration: none;
    border: 1px solid transparent;
    transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
/* Pay Now is a <button> now, not a link. A button takes the system font and
   the default cursor from the UA sheet, so beside the anchors it would render
   in a different typeface and fail to say it is clickable. */
button.z-bkc-act {
    font-family: var(--z-body);
    cursor: pointer;
    line-height: inherit;
}
.z-bkc-act svg { flex: none; }
.z-bkc-act:hover { transform: translateY(-1px); text-decoration: none; }
.z-bkc-act.is-view {
    background: var(--z-green); color: var(--z-gold-light);
    box-shadow: 0 6px 14px -8px rgba(13, 44, 34, .9);
}
.z-bkc-act.is-view:hover { background: var(--z-green-2); color: #fdf8ec; }
.z-bkc-act.is-doc {
    background: var(--z-gold-leaf); color: var(--z-green);
    box-shadow: 0 6px 14px -8px rgba(143, 111, 28, .9);
}
.z-bkc-act.is-doc:hover { color: var(--z-green-2); }

/* --- documents, both directions ---------------------------------------------
   One column carrying two grids: what the travellers owe us, and what the
   office has issued back. Each grid has a heading of its own — .z-bkc-fl,
   which every other value on the stacked card also uses as its label.

   SHOWN AT BOTH WIDTHS HERE, unlike everywhere else. On a wide card it is the
   caption above each grid; on a narrow one .is-split drops it into the label
   column and the two sets read as two ordinary rows. The column's own group
   heading stands down either way — it would be a third title over two that
   already say what they are. */
.z-bkc-col.is-docsets { flex: 0 0 auto; gap: 6px; }
.z-bkc-col.is-docsets > .z-bkc-lbl { display: none; }
.z-bkc-col.is-docsets > .z-bkc-fl {
    display: block;
    margin: 2px 0 0;
    font-size: 9.5px; font-weight: 700; letter-spacing: .11em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-bkc-col.is-docsets > .z-bkc-fl:first-of-type { margin-top: 0; }

.z-bkc-docs { display: flex; flex-wrap: wrap; gap: 7px; }

/* BIGGER THAN THE FIRST PASS. At 32px these were read as decoration on a card
   full of 15px icons; at 38px with a 17px glyph they are controls, which the
   Documents set genuinely is. */
/* A COLOUR PER DOCUMENT, carried in --z-docc from the markup. Eight grey
   squares were a row of slots; eight coloured marks are eight things, and the
   kind is readable before the tooltip is. The values are the .z-fact tints,
   not the CRM's — its palette is built for dark cards and washes out here. */
.z-bkc-doc {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px;
    border-radius: 11px;
    border: 1px solid var(--z-line);
    background: var(--z-marble);
    color: var(--z-docc, var(--z-ink-3));
    opacity: .45;
    padding: 0;
    transition: transform .15s ease, box-shadow .15s ease,
                background-color .15s ease, border-color .15s ease;
}
.z-bkc-doc svg { display: block; }

/* Issued, and openable. Given more than the un-issued slots beside it: a gold
   leaf ground, a solid edge and a contact shadow, so a document that exists
   reads as a thing you can pick up rather than a lit version of a placeholder. */
a.z-bkc-doc.is-on {
    opacity: 1;
    border-color: var(--z-docc, var(--z-gold));
    background: var(--z-surface);
    color: var(--z-docc, var(--z-gold-deep));
    text-decoration: none;
    box-shadow: 0 4px 10px -6px rgba(13, 44, 34, .35);
}
a.z-bkc-doc.is-on:hover {
    background: var(--z-cream);
    transform: translateY(-2px);
    box-shadow: 0 10px 20px -10px rgba(13, 44, 34, .5);
}

/* AND IT ASKS TO BE COLLECTED. The same ring the Documents slots use, on the
   opposite state — and deliberately so: a pulse on this site means "there is
   something here for you to do".

     Documents  pulses what is MISSING — the customer owes us that file.
     Travel Docs pulses what is READY  — the office has issued it and there is
                                         something new to download.

   The un-issued slots stay still. A greyed voucher is the office's to produce,
   not the customer's, and blinking at somebody about a thing they cannot act
   on is noise. */
@keyframes z-doc-ready {
    0%   { box-shadow: 0 4px 10px -6px rgba(13, 44, 34, .35), 0 0 0 0 rgba(13, 44, 34, .3); }
    70%  { box-shadow: 0 4px 10px -6px rgba(13, 44, 34, .35), 0 0 0 9px rgba(13, 44, 34, 0); }
    100% { box-shadow: 0 4px 10px -6px rgba(13, 44, 34, .35), 0 0 0 0 rgba(13, 44, 34, 0); }
}
a.z-bkc-doc.is-on { animation: z-doc-ready 2.6s ease-out infinite; }
/* Hovering is already attention, and the ring would fight the lift. */
a.z-bkc-doc.is-on:hover { animation: none; }

/* --- the traveller's own documents, which are buttons --------------------- */
button.z-bkc-doc.is-act { cursor: pointer; opacity: 1; }
button.z-bkc-doc.is-act:hover { transform: translateY(-2px); box-shadow: 0 8px 18px -10px rgba(13, 44, 34, .8); }

/* Three states, because "1 of 3 passports" is neither done nor untouched. */
/* The three states are told apart by WEIGHT, not by hue — the hue is the
   document's own and has to stay put, or a passport slot would change colour
   as files arrive and stop being recognisable. Nothing yet is an outline; part
   way is filled; complete is filled and ticked by its border. */
button.z-bkc-doc.is-none {
    border-color: var(--z-line);
    background: var(--z-surface);
    color: var(--z-docc, var(--z-gold-deep));
}
button.z-bkc-doc.is-part {
    border-color: var(--z-docc, var(--z-few));
    border-style: dashed;
    background: var(--z-marble);
    color: var(--z-docc, var(--z-few));
}
button.z-bkc-doc.is-all {
    border-color: var(--z-docc, var(--z-open));
    border-width: 2px;
    background: var(--z-surface);
    color: var(--z-docc, var(--z-open));
}

/* WHAT IS STILL OWED ASKS FOR ATTENTION. A ring that grows out of the slot and
   fades, on the two states that are not finished — the same figure the visa
   card's estimated date uses, so a pulse means one thing across the site.
   Complete slots never pulse: a card where everything blinks says nothing. */
@keyframes z-doc-ask {
    0%   { box-shadow: 0 0 0 0 rgba(13, 44, 34, .28); }
    70%  { box-shadow: 0 0 0 8px rgba(13, 44, 34, 0); }
    100% { box-shadow: 0 0 0 0 rgba(13, 44, 34, 0); }
}
button.z-bkc-doc.is-none,
button.z-bkc-doc.is-part { animation: z-doc-ask 2.6s ease-out infinite; }
/* Hovering is already attention; the ring stops competing with the lift. */
button.z-bkc-doc.is-act:hover { animation: none; }

/* --- the upload dialogue ----------------------------------------------------
   One card per traveller, laid out the way the CRM's passenger manifest lays
   one out: a name across the top, then the passport the desk is expecting down
   the LEFT and that traveller's own four upload slots on the RIGHT.

   The slots were four word-buttons in a 2x2 grid under the name, which said
   nothing about WHOSE passport was wanted — with three travellers the dialogue
   was the same four words three times. Marks rather than words on the right:
   the facts need the width, and four labels down a 150px column wrapped every
   one of them. Each carries its own tint through --z-docc, the same colour the
   matching chip on the booking card behind this dialogue uses. */
.z-docrow {
    padding: 13px 0;
    border-bottom: 1px dashed var(--z-line-soft);
}
.z-docrow:last-child { border-bottom: 0; }

.z-docrow-head {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 10px;
}
.z-docrow-head b {
    min-width: 0;
    /* The badge carries the number now, so nothing follows the name and it
       simply takes the rest of the row. */
    flex: 1 1 auto;
    font-size: 14px;
    font-weight: 700;
    color: var(--z-green);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* ADULT / CHILD / INFANT, as it comes out of the booking. */
.z-docrow-tag {
    flex: none;
    padding: 3px 8px;
    border-radius: 999px;
    border: 1px solid var(--z-line-gold);
    background: var(--z-gold-pale);
    color: var(--z-gold-deep);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
}
/* --- looking at what was already sent ---------------------------------------
   Over the documents dialogue, not inside it: that one scrolls, and a passport
   page is a good deal taller than the 40px square it was sent from. z-index
   clears .z-pscan's 70 so it sits above the dialogue it was opened from. */
.z-docview {
    position: fixed;
    inset: 0;
    z-index: 80;
    display: grid;
    place-items: center;
    padding: 20px;
    background: rgba(11, 34, 28, .62);
    backdrop-filter: blur(3px);
}
.z-docview[hidden] { display: none !important; }
.z-docview-box {
    width: 100%;
    max-width: 620px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    background: var(--z-surface);
    border: 1px solid var(--z-line-strong);
    border-radius: 14px;
    box-shadow: 0 30px 70px -20px rgba(4, 18, 13, .6);
    overflow: hidden;
}
.z-docview-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    background: linear-gradient(180deg, var(--z-cream), var(--z-cream-deep));
    border-bottom: 1px solid var(--z-line);
}
.z-docview-head b {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--z-green);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* The scan itself, on the deeper ground so a white passport page has an edge
   to sit against. Scrolls rather than shrinking past legibility. */
.z-docview-body {
    flex: 1 1 auto;
    min-height: 0;
    display: grid;
    place-items: center;
    padding: 14px;
    overflow: auto;
    background: var(--z-surface-2);
}
.z-docview-body img {
    max-width: 100%;
    border-radius: 8px;
    box-shadow: var(--z-shadow);
}
.z-docview-pdf {
    margin: 0;
    padding: 26px 10px;
    font-size: 13px;
    color: var(--z-ink-2);
    text-align: center;
}
.z-docview-foot {
    flex: none;
    display: flex;
    justify-content: flex-end;
    gap: 9px;
    padding: 11px 14px;
    border-top: 1px solid var(--z-line-soft);
}

@media (max-width: 560px) {
    .z-docview { padding: 12px; }
    .z-docview-foot { flex-direction: column-reverse; }
    .z-docview-foot .z-btn { justify-content: center; }
}

/* --- invoice / voucher, in a popup instead of a new tab ---------------------
   A separate shell from .z-docview above rather than a reuse of it: that one
   is a 620px box padded for a single passport photo, and an invoice is a
   full printable page - it needs the width, and the iframe has to fill the
   body edge to edge rather than sit in 14px of padding. */
.z-frame {
    position: fixed;
    inset: 0;
    z-index: 80;
    display: grid;
    place-items: center;
    padding: 20px;
    background: rgba(11, 34, 28, .62);
    backdrop-filter: blur(3px);
}
.z-frame[hidden] { display: none !important; }
.z-frame-box {
    width: 100%;
    max-width: 960px;
    height: 92vh;
    display: flex;
    flex-direction: column;
    background: var(--z-surface);
    border: 1px solid var(--z-line-strong);
    border-radius: 14px;
    box-shadow: 0 30px 70px -20px rgba(4, 18, 13, .6);
    overflow: hidden;
}
.z-frame-head {
    flex: none;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    background: linear-gradient(180deg, var(--z-cream), var(--z-cream-deep));
    border-bottom: 1px solid var(--z-line);
}
.z-frame-head b {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--z-green);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.z-frame-head-acts {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
}
/* The document itself, edge to edge - it already brings its own page
   background and padding, and a second frame of padding here would just
   look like a border no visitor asked for. */
.z-frame-body {
    flex: 1 1 auto;
    min-height: 0;
    background: var(--z-surface-2);
}
.z-frame-body iframe {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}

@media (max-width: 720px) {
    .z-frame { padding: 0; }
    .z-frame-box { max-width: none; height: 100vh; border-radius: 0; }
}

/* --- correcting the passport ------------------------------------------------
   Edit sits at the end of the traveller's own row; pressing it swaps itself
   for Save and Cancel, so the two states never both offer a way forward. */
.z-docedit {
    flex: none;
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border: 1px solid var(--z-line);
    border-radius: 8px;
    background: var(--z-surface);
    color: var(--z-ink-3);
    cursor: pointer;
    transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.z-docedit svg { display: block; }
.z-docedit:hover { border-color: var(--z-gold); color: var(--z-gold-deep); background: var(--z-gold-wash); }
.z-docedit:focus-visible { outline: 2px solid var(--z-gold); outline-offset: 1px; }
.z-docedit[disabled] { opacity: .5; pointer-events: none; }

/* Save is the affirmative one and carries the colour; Cancel stays quiet. */
.z-docedit.is-accept { border-color: rgba(27, 99, 73, .4); color: var(--z-open); background: var(--z-open-bg); }
.z-docedit.is-accept:hover { background: var(--z-open); border-color: var(--z-open); color: #fff; }
.z-docedit.is-cancel:hover { border-color: rgba(138, 48, 36, .35); color: var(--z-sold); background: var(--z-sold-bg); }

/* Exactly one pair is ever offered. */
.z-docrow-head .z-docedit.is-accept,
.z-docrow-head .z-docedit.is-cancel { display: none; }
.z-docrow-head.is-editing .z-docedit.is-edit { display: none; }
.z-docrow-head.is-editing .z-docedit.is-accept,
.z-docrow-head.is-editing .z-docedit.is-cancel { display: grid; }

/* The cell in edit mode. The label does not move, so the ten fields stay in
   the same places they were being read in a moment earlier — the box appears
   where the value was rather than the whole grid re-laying itself out. */
.z-docfacts.is-editing .z-docfact { background: var(--z-surface); }
.z-docfact-in {
    display: block;
    width: 100%;
    margin-top: 3px;
    padding: 4px 6px;
    border: 1px solid var(--z-line);
    border-radius: 6px;
    background: var(--z-surface-2);
    font: 700 12.5px/1.3 var(--z-body);
    color: var(--z-green);
    text-align: center;
}
.z-docfact-in:focus {
    outline: none;
    border-color: var(--z-fldc, var(--z-gold));
    background: var(--z-surface);
}
/* The date and select controls draw their own indicator, which is left of
   centre in every browser; centring the text around it looks like a mistake. */
.z-docfact-in[type="date"],
select.z-docfact-in { text-align: left; }

/* The two halves. minmax(0, ...) on the left or a long passport number pushes
   the buttons off the edge instead of ellipsing. */
.z-docrow-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 14px;
    align-items: start;
}

/* The whole document: ten read-only passport fields, then the two numbers the
   customer can type, under a rule inside the same block. The border lives here
   rather than on the grid so the two zones read as one page. */
.z-docpage {
    min-width: 0;
    border: 1px solid var(--z-line);
    border-radius: 11px;
    background: var(--z-line-soft);
    overflow: hidden;
}

.z-docfacts {
    /* FIVE FIXED COLUMNS, TWO ROWS — the passport page:

         Prefix | Surname | Given Name | Date of Birth | Gender
         Passport | Nationality | Issue Country | Issue Date | Expiry Date

       Fixed, not auto-fit: the second row has to sit under the first with the
       dates lining up, and auto-fit reflows to whatever happens to fit, which
       put Issue Date under Given Name on one card and under Gender on the
       next. minmax(0, 1fr) rather than 1fr, or a long given name refuses to
       shrink its track and pushes the fifth column off the edge. */
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    align-content: start;
    /* The rules BETWEEN the cells are the grid's own gap over .z-docpage's
       ground, so the page reads as one ruled document rather than ten loose
       chips and no border doubles up where two cells meet. */
    gap: 1px;
    padding: 1px 1px 0;
}

/* Each field, on the surface, with its own tint down the leading edge — the
   same --z-fldc the reserve form gives the input the customer typed it into,
   so the read-out and the form are recognisably the same ten fields. */
.z-docfact {
    min-width: 0;
    padding: 7px 8px 8px;
    background: var(--z-surface);
    box-shadow: inset 2px 0 0 var(--z-fldc, var(--z-gold));
    text-align: center;
}
.z-docfact span {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
    font-size: 8.5px;
    font-weight: 700;
    /* Tighter than the rest of the site's small caps. The label has to hold
       "Date of Birth" and "Issue Country" on one line in a column narrow
       enough that ten of them fit beside the upload block. */
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--z-ink-3);
    white-space: nowrap;
}
.z-docfact span i {
    flex: none;
    display: inline-flex;
    color: var(--z-fldc, var(--z-gold-deep));
}
.z-docfact span i svg { display: block; }
.z-docfact b {
    display: block;
    margin-top: 2px;
    font-size: 12.5px;
    line-height: 1.3;
    font-weight: 700;
    color: var(--z-green);
    /* WRAPS, never ellipses. This is the copy of the passport the desk checks
       a scan against, and "SAIFUDDIN JAIN…" is not a name — the one field
       most likely to be too long is the one it is least acceptable to cut.
       The grid stretches the whole row to match, so the five stay level.
       anywhere, not break-word: a long given name may have no space to break
       at, and without it the track just overflows instead. */
    overflow-wrap: anywhere;
}
/* Nothing on file. Kept in place rather than dropped: the gaps in a passport
   page are what the desk is chasing, and a row of five with one cell missing
   would just look like a layout fault. */
.z-docfact.is-empty { background: var(--z-surface-2); }
.z-docfact.is-empty b { color: var(--z-ink-3); font-weight: 500; }

/* --- the four fields the customer types ------------------------------------

       ITS Number | Mobile No | PAN Number | Aadhaar Number

   Under the passport, inside the same ruled page, on the deeper ground: the
   change of fill is what says these four are yours to fill in while the ten
   above are the desk's. Four columns against the passport's five, so they do
   not line up cell-for-cell with the row above and cannot be misread as an
   eleventh through fourteenth passport field. */
.z-docnums {
    /* ONE ROW, NOT A GRID. The ten passport fields above are ruled into cells
       because they are a document being read; these four are controls being
       filled in, and boxing each one put a vertical line between every input
       and its neighbour for no reason. Flex with a real gap instead — no rules,
       and the fields take the width they need rather than a column's share.

       Wrapping is left on so a narrow window drops the row to two and then to
       one, which the media queries no longer have to legislate. */
    display: flex;
    flex-wrap: wrap;
    /* CENTRED, because the boxes are now sized to what they hold rather than
       stretched to fill: left-aligned they left a growing empty margin down
       the right of the strip as the dialogue got wider. */
    justify-content: center;
    gap: 9px 14px;
    padding: 10px;
    /* Sits on the deeper ground with the page's own hairline above it: that
       one rule stays, because it is what separates what the desk holds from
       what the customer fills in. */
    margin-top: 1px;
    background: var(--z-surface-2);
}
.z-docnum {
    /* NO GROW. Each box is the width of what goes in it — set per field in
       NUMS, in ch — and the row centres what is left over rather than sharing
       it out. The tint that used to run down each cell's edge now lives on the
       label's mark alone, since an edge stripe on a field with no box IS the
       column line this row was asked to lose. */
    flex: 0 0 auto;
    max-width: 100%;
    padding: 0;
    background: none;
    text-align: center;
}
.z-docnum-lbl {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
    font-size: 8.5px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--z-ink-3);
    white-space: nowrap;
}
.z-docnum-lbl i { flex: none; display: inline-flex; color: var(--z-fldc, var(--z-gold-deep)); }
.z-docnum-lbl i svg { display: block; }

.z-docnum-in {
    display: flex;
    margin-top: 3px;
    border: 1px solid var(--z-line);
    border-radius: 7px;
    background: var(--z-surface);
    overflow: hidden;
}
.z-docnum-in input {
    /* Width comes from the element's own style attribute (see NUMS), and
       content-box is what makes that width mean what it says: the sheet sets
       border-box globally, so a 9ch box was 9ch MINUS its 14px of padding and
       clipped the eighth digit of an ITS number. flex is 0 1 so the box holds
       that width rather than stretching to the row. */
    box-sizing: content-box;
    flex: 0 1 auto;
    min-width: 0;
    padding: 5px 7px;
    border: 0;
    background: none;
    font: 700 12.5px/1.3 var(--z-body);
    color: var(--z-green);
    letter-spacing: .02em;
    /* LEFT, against the centred label above it. A number being typed reads
       from its first digit, and a centred one shifts under the cursor as it
       grows — the label is a caption and can centre, the value cannot. */
    text-align: left;
}
.z-docnum-in input::placeholder { font-weight: 500; color: var(--z-ink-3); letter-spacing: 0; }
.z-docnum-in input:focus { outline: none; }
.z-docnum-in:focus-within { border-color: var(--z-fldc, var(--z-gold)); }

.z-docnum-save {
    flex: none;
    display: grid;
    place-items: center;
    width: 28px;
    border: 0;
    border-left: 1px solid var(--z-line);
    background: var(--z-cream);
    color: var(--z-ink-3);
    cursor: pointer;
    transition: background .16s ease, color .16s ease;
}
.z-docnum-save svg { display: block; }
.z-docnum-save:hover { background: var(--z-fldc, var(--z-gold)); color: #fff; }
.z-docnum-save[disabled] { opacity: .5; pointer-events: none; }

/* Typed but not sent. The button is the only way to save, so it has to be
   obvious that the box is holding something the desk cannot see yet. */
.z-docnum.is-dirty .z-docnum-in { border-color: var(--z-few); }
.z-docnum.is-dirty .z-docnum-save { background: var(--z-few-bg); color: var(--z-few); }
.z-docnum.is-busy { opacity: .6; pointer-events: none; }
.z-docnum.is-saved .z-docnum-in { border-color: var(--z-open); }
.z-docnum.is-saved .z-docnum-save { background: var(--z-open-bg); color: var(--z-open); }

/* intl-tel-input inside the Mobile No box. The library wraps the input in a
   .iti div, which defaults to inline-block and would otherwise collapse the
   flex child to its own idea of a width. Everything else here is the same
   treatment .z-modal-grid gives the picker, scaled to this smaller field. */
/* Sized in px, not ch: with separateDialCode the library pads the input to
   clear the flag, so a ch width would be mostly padding. The flag block is
   pinned at 68px below and a ten-digit national number wants about 78px, so
   168 holds one with room to spare — and this box is the row's biggest single
   consumer, which is where the width had to come from to keep all four on one
   line once Jost loads and every ch gets wider. */
.z-docnum.is-phone .iti { flex: 0 0 auto; display: block; width: 168px; max-width: 100%; }

/* THE NUMBER STARTS FLUSH AGAINST THE DIVIDER.

   The library measures the flag block once at init and writes the input's
   padding-left by hand, as an INLINE style — so !important is the only way
   past it. Left to itself it wrote 70px against a 64px block, parking the
   first digit six pixels adrift of the rule it should sit behind, which is
   what read as the field not being left aligned.

   Pinning both to one number is what keeps them honest: the block cannot grow
   past the padding and the padding cannot exceed the block. 68px holds a flag
   and a three-digit dial code, which is every country this picker offers
   first — +971, +966, +964 — not just +91. */
.z-docnum.is-phone .iti__flag-container { width: 68px; }
.z-docnum.is-phone .iti--separate-dial-code .iti__selected-flag { width: 100%; }
.z-docnum.is-phone .iti--separate-dial-code input { padding-left: 68px !important; }
/* BORDER-BOX AGAIN, undoing the content-box above for this one input. With
   separateDialCode the library pads the input's LEFT to clear the flag — about
   70px — so under content-box a width:100% input measured 184 + that padding,
   overflowed its group by 46px and had the save tick clipped off the end by
   the group's own overflow:hidden. */
.z-docnum.is-phone .iti input { box-sizing: border-box; width: 100%; }
.z-docnum .iti__flag-container { z-index: 2; }
.z-docnum .iti--separate-dial-code .iti__selected-flag {
    padding: 0 3px 0 5px;
    background: var(--z-surface-2);
    border-right: 1px solid var(--z-line);
}
.z-docnum .iti--separate-dial-code .iti__selected-dial-code {
    margin-left: 4px;
    font-size: 11.5px;
    font-weight: 700;
    color: var(--z-ink-2);
}
.z-docnum .iti__arrow { margin-left: 4px; }
/* The list is appended to <body> (see dropdownContainer in the page's script),
   so it is styled off .iti__country-list directly rather than through a
   .z-docnum ancestor that is no longer above it in the tree. */
.iti--container .iti__country-list {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 8px;
    box-shadow: var(--z-shadow-lg);
    color: var(--z-ink);
    font: 400 13px/1.4 var(--z-body);
}
.iti--container .iti__country.iti__highlight { background: var(--z-gold-wash); }
.iti--container .iti__dial-code { color: var(--z-ink-3); }
/* Above the dialogue, which sits at 70. */
.iti--container { z-index: 90; }

.z-docups {
    flex: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: flex-start;
}
.z-docups-cap {
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--z-ink-3);
}
/* TWO BY TWO, read across then down:

       Passport | Photo
       PAN card | Aadhaar

   Not one row of four. The passport grid beside this wants every pixel it can
   get, and a 2x2 block gives back nearly a hundred of them — which is a whole
   column of the document. The pairing is also the real one: two passport
   things on top, two Indian ID cards under them. */
.z-docrow-grid {
    display: grid;
    grid-template-columns: repeat(2, 40px);
    gap: 8px;
}
.z-docbtn {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    /* Dashed until it holds something, solid once it does — the same grammar
       the card's own chips use, readable without the colour. */
    border: 1px dashed var(--z-line-gold);
    background: var(--z-surface);
    color: var(--z-ink-3);
    cursor: pointer;
    transition: transform .16s ease, border-color .16s ease,
                background .16s ease, color .16s ease;
}
.z-docbtn svg { display: block; }
.z-docbtn:hover {
    transform: translateY(-1px);
    border-color: var(--z-docc, var(--z-gold));
    color: var(--z-docc, var(--z-green));
}
.z-docbtn:focus-within { outline: 2px solid var(--z-gold); outline-offset: 2px; }
.z-docbtn.is-on {
    border-style: solid;
    border-color: var(--z-docc, var(--z-open));
    /* The tint at 12% over the surface: colour enough to read as filled,
       light enough that the mark on top stays legible. */
    background: color-mix(in srgb, var(--z-docc, #1b6349) 12%, var(--z-surface));
    color: var(--z-docc, var(--z-open));
}
.z-docbtn.is-busy { opacity: .55; pointer-events: none; }

/* Wider than the passport scanner it shares a shell with — five columns of
   passport beside the upload block do not fit in 620px — but narrower than it
   was: the slots stacked 2x2 gave back a column's worth of width, and it went
   into shrinking the dialogue rather than into stretching the cells. At 820
   the narrowest cell is about 128px, which holds "Date of Birth" over
   "17 Mar 1958" with neither wrapping. */
.z-pscan-box.is-docs { max-width: 820px; }

/* Widest first, so each step overrides the one above it. Two blocks for the
   same width would otherwise have to be read in source order to know which
   wins, and .z-docnums was being set by both. */
@media (max-width: 880px) {
    /* The slots go under the passport rather than beside it, in one row —
       the five columns need the whole width before the buttons do. */
    .z-docrow-split { grid-template-columns: minmax(0, 1fr); gap: 11px; }
    .z-docups {
        flex-direction: row;
        align-items: center;
        gap: 10px;
    }
    /* Under the passport there is room for the row of four again. */
    .z-docrow-grid { grid-template-columns: repeat(4, 40px); }
}
@media (max-width: 700px) {
    /* Five columns stop holding a date. TWO, not three: the ten fields have to
       divide by the column count or the last row is part empty, and an empty
       grid track is not a cell — it has no fill of its own, so the page's rule
       colour shows through as a grey hole. Ten into two is five clean rows. */
    .z-docfacts { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* AND THE FOUR NUMBERS BECOME A GRID TOO, on the same two columns.

       On a wide dialogue they are a centred row of boxes each sized to what it
       holds. Once they have to wrap, that stops working: four different widths
       centred over two lines gave ITS beside Mobile and PAN beside Aadhaar
       with no two edges meeting, which reads as four things dropped on the
       page rather than one set of fields. Two stretched columns line them up
       with each other AND with the ten passport cells above.

       The widths are set on the elements themselves (see NUMS), so overriding
       them here needs !important — and border-box with it, or the padding is
       added on top of the 100% and every box overflows its column.

       THE COLUMNS ARE NOT EQUAL, AND THE ORDER OF THE FIELDS IS WHY.

       NUMS runs ITS, Mobile, PAN, Aadhaar, so two columns put the two SHORT
       fields down the left and the two LONG ones down the right:

           ITS  8 digits    |  Mobile  flag block + 10 digits
           PAN  10 chars    |  Aadhaar 12 digits

       On equal columns the left pair float in space they cannot use while the
       mobile — the only field carrying a 58px flag block AND a save tick
       before its first digit — runs out and clips the number. Equal tracks
       are the fair split of the row, not the useful one.

       0.72fr against 1fr moves about 27px from the left column to the right,
       which is the difference between the number fitting and not. The left
       column still clears its widest content ("PAN NUMBER" as a label, a
       ten-character value) with room to spare.

       THE COST, stated because it is real: .z-docfacts above is a 50/50 grid,
       so the numbers below it no longer line up with the passport cells. That
       alignment was worth having when both grids could hold their content;
       it is not worth a phone number the customer cannot read. */
    .z-docnums {
        display: grid;
        grid-template-columns: minmax(0, 0.72fr) minmax(0, 1fr);
        gap: 10px 12px;
    }
    .z-docnum { max-width: none; }
    .z-docnum-in { width: 100%; }
    .z-docnum-in input {
        box-sizing: border-box;
        width: 100% !important;
    }
    /* Fills what the save button leaves, rather than 100% of the group —
       width:100% on a flex child takes the whole row and pushes the tick out
       past the group's overflow:hidden, which is exactly how it vanished. */
    .z-docnum.is-phone .iti { flex: 1 1 auto; width: auto; min-width: 0; }
}
@media (max-width: 480px) {
    .z-docrow-grid { grid-template-columns: repeat(4, 38px); }
}
/* PHONES KEEP THE TWO COLUMNS.

       ITS Number | Mobile No
       PAN Number | Aadhaar Number

   This block used to drop to one column here, on the grounds that "AADHAAR
   NUMBER" over a twelve-digit box needs the width to itself. Measured, that
   is not what happens: the label is 8.5px, uppercase, at .04em — fourteen
   characters plus its 12px mark comes to about 93px, and even a 320px phone
   leaves a 117px column. The label was never the problem.

   The field that IS tight is the mobile, and it is tight at every width this
   grid is two columns wide — including the 431px the old rule was happy to
   allow. At 431px the flag block takes 68 of the column's 170px and the save
   tick another 28, leaving 58px of text room for a number that wants 76. So
   one column below 430px was not protecting anything; it was drawing the line
   a few pixels above the same squeeze.

   So the two columns stay, and the width is bought back from the chrome
   instead — a narrower flag block, a smaller dial code, a tighter save tick.
   The net is MORE room for the number here than the old rule gave it at
   431px, not less.

   Below 360px the sums stop working however they are shuffled, so that is
   where one column now begins — narrower than any phone in common use, and
   the honest place for the fallback rather than 430px. */
@media (max-width: 430px) {
    /* Gap and padding come down first: cheapest width there is, and 4px of
       padding is not what makes this panel readable. */
    .z-docnums { gap: 9px 10px; padding: 10px 8px; }

    /* 68px held a flag, a three-digit dial code and an arrow with room to
       spare. 58px holds the same four things once the dial code drops a point
       and the two margins tighten — the arrow STAYS, because it is the only
       thing saying the flag opens a country list.

       The library writes the input's padding-left inline to clear this block,
       and the base rule answers that with !important; both numbers have to
       move together or the first digit sits adrift of the divider again. */
    .z-docnum.is-phone .iti__flag-container { width: 58px; }
    .z-docnum.is-phone .iti--separate-dial-code input { padding-left: 58px !important; }
    .z-docnum .iti--separate-dial-code .iti__selected-flag { padding: 0 2px 0 4px; }
    .z-docnum .iti--separate-dial-code .iti__selected-dial-code { margin-left: 2px; font-size: 10.5px; }
    .z-docnum .iti__arrow { margin-left: 2px; }

    /* A point off the value and two off its side padding. It stays 700 —
       these are numbers being checked against a document, and weight is what
       keeps them legible at this size. */
    .z-docnum-in input { font-size: 11.5px; padding: 5px 5px; }
    .z-docnum-save { width: 26px; }
}
@media (max-width: 389px) {
    /* A 360px Android is the last width where the number still fits, and at
       0.72fr it misses by about six pixels — which shows as the final digit
       sheared off, because an unfocused input shows the START of its value.
       0.62fr moves another ten across. The left column comes down to ~105px,
       which still clears "PAN NUMBER" and a ten-character value; below this
       width it would not, which is where the single column takes over. */
    .z-docnums { grid-template-columns: minmax(0, 0.62fr) minmax(0, 1fr); }
}
@media (max-width: 359px) {
    /* Past here the mobile field has nothing left to give: the flag block and
       the save tick alone are 84 of a 117px column. One column, and every
       box gets the room it needs. */
    .z-docnums { grid-template-columns: minmax(0, 1fr); }
}

/* --- the Booking Summary panel ---------------------------------------------
   The hotel booking, read one at a time. A name and its two documents across
   the top, then everything else as an even grid of small facts — the shape the
   main site's summary uses, in this site's palette. */
.z-sum-top {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 14px; flex-wrap: wrap;
    padding-bottom: 14px; margin-bottom: 16px;
    border-bottom: 1px solid var(--z-line-gold);
}
.z-sum-name b {
    display: block;
    font-family: var(--z-display); font-size: 19px; font-weight: 700;
    color: var(--z-green); line-height: 1.25;
}
.z-sum-name span { display: block; margin-top: 2px; font-size: 12.5px; color: var(--z-ink-3); }
.z-sum-acts { display: flex; gap: 8px; flex: none; }

.z-sum-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
}
.z-sum-cell {
    padding: 10px 12px;
    background: var(--z-marble);
    border: 1px solid var(--z-line);
    border-radius: 10px;
    min-width: 0;
}
.z-sum-cell small {
    display: block;
    font-size: 9px; font-weight: 700; letter-spacing: .11em;
    text-transform: uppercase; color: var(--z-ink-3);
}
.z-sum-cell b {
    display: block; margin-top: 3px;
    font-size: 13.5px; font-weight: 700; color: var(--z-green);
    overflow: hidden; text-overflow: ellipsis;
}

@media (max-width: 900px) { .z-sum-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 640px) {
    .z-sum-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .z-sum-acts { width: 100%; }
    .z-sum-acts .z-btn { flex: 1 1 0; justify-content: center; }
}
@media (max-width: 360px) { .z-sum-grid { grid-template-columns: minmax(0, 1fr); } }

/* Reschedule and Cancel. Both file a request rather than doing the thing, so
   neither is dressed as a finished action: Reschedule is the amber this palette
   uses for "in hand", and Cancel is outlined rather than filled red — a solid
   red button invites the accidental press, and this one opens a form the
   customer still has to complete. */
.z-bkc-act.is-move {
    background: var(--z-few-bg, #f7efdd);
    color: var(--z-few);
    border-color: rgba(145, 96, 15, .4);
}
.z-bkc-act.is-move:hover { background: #f2e6cd; color: #7a5210; }

.z-bkc-act.is-cancel {
    background: transparent;
    color: var(--z-sold);
    border-color: rgba(138, 48, 36, .45);
}
.z-bkc-act.is-cancel:hover { background: var(--z-sold-bg); border-color: var(--z-sold); }

/* --- the printable invoice ------------------------------------------------ */
.z-inv-bar { display: flex; gap: 10px; justify-content: flex-end; margin-bottom: 16px; }
.z-inv {
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: 14px;
    padding: 26px 28px;
    box-shadow: var(--z-shadow-sm);
}
.z-inv-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 20px; flex-wrap: wrap;
    padding-bottom: 16px; margin-bottom: 18px;
    border-bottom: 2px solid var(--z-line-gold);
}
.z-inv-kicker {
    display: block;
    font-size: 10px; font-weight: 700; letter-spacing: .18em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-inv-ref {
    display: block; margin: 2px 0;
    font-family: var(--z-display); font-size: 26px; font-weight: 700; color: var(--z-green);
}
.z-inv-date { font-size: 12px; color: var(--z-ink-3); }
.z-inv-brand { text-align: right; }
.z-inv-brand b {
    display: block;
    font-family: var(--z-display); font-size: 18px; color: var(--z-green);
}
.z-inv-brand span { display: block; font-size: 11.5px; color: var(--z-ink-3); }

.z-inv-parties {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px;
    margin-bottom: 22px;
}
.z-inv-parties h3 {
    margin: 0 0 5px;
    font-size: 9.5px; font-weight: 700; letter-spacing: .12em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-inv-parties b { display: block; font-size: 14px; color: var(--z-green); }
.z-inv-parties span { display: block; font-size: 12.5px; color: var(--z-ink-2); }

.z-inv-h {
    margin: 22px 0 10px;
    font-size: 10px; font-weight: 700; letter-spacing: .12em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-inv-pax { margin: 0; padding-left: 18px; }
.z-inv-pax li { font-size: 13.5px; color: var(--z-ink); margin-bottom: 3px; }
.z-inv-pax small { color: var(--z-ink-3); font-size: 11.5px; margin-left: 6px; }

.z-inv-table { width: 100%; border-collapse: collapse; }
.z-inv-table th {
    padding: 8px 10px;
    background: var(--z-cream);
    border-bottom: 1px solid var(--z-line-gold);
    font-size: 10px; font-weight: 700; letter-spacing: .1em;
    text-transform: uppercase; color: var(--z-ink-2); text-align: left;
}
.z-inv-table td {
    padding: 10px;
    border-bottom: 1px solid var(--z-line-soft);
    font-size: 13px; color: var(--z-ink);
}
.z-inv-table td b { display: block; color: var(--z-green); }
.z-inv-table td span { display: block; font-size: 11.5px; color: var(--z-ink-3); }
.z-inv-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.z-inv-table tfoot td {
    font-weight: 700;
    border-bottom: 0;
    border-top: 1px solid var(--z-line);
}
.z-inv-table tfoot tr.is-due td {
    font-size: 15px;
    color: var(--z-sold);
    border-top: 2px solid var(--z-line-gold);
}
.z-inv-note {
    margin: 20px 0 0;
    font-size: 11.5px; line-height: 1.6; color: var(--z-ink-3);
}

@media (max-width: 720px) {
    .z-inv { padding: 18px 16px; }
    .z-inv-parties { grid-template-columns: minmax(0, 1fr); gap: 14px; }
    .z-inv-brand { text-align: left; }
}

/* ON PAPER. The site's chrome is not part of the document — a printed invoice
   carrying a navigation bar and a footer of links is a screenshot, not a
   record. What is left is the invoice, in black on white, edge to edge. */
@media print {
    .z-noprint,
    .z-header, .z-quicktop, .z-quickbot, .z-footer, .z-sticky, .z-skip { display: none !important; }
    body.zaereen { background: #fff; color: #000; padding: 0; font-size: 12px; }
    .z-section { padding: 0; }
    .z-shell { max-width: none; padding: 0; }
    .z-inv {
        border: 0; border-radius: 0; box-shadow: none; padding: 0;
        background: #fff;
    }
    .z-inv-table th { background: #f2f2f2; }
    /* A table that breaks across a page boundary loses its heading; keeping
       each row whole is the least a printed statement should do. */
    .z-inv-table tr { page-break-inside: avoid; }
}

/* Pay Now. Green because it is the one action on the card that settles
   something — the same green the ledger uses for money received — and it must
   not be mistaken for the gold document buttons beside it. */
.z-bkc-act.is-pay {
    background: var(--z-open);
    color: #f2f9f4;
    box-shadow: 0 6px 14px -8px rgba(27, 99, 73, .9);
}
.z-bkc-act.is-pay:hover { background: #17553e; color: #fff; }

/* Shown when the filters leave nothing standing. */
.z-empty.is-inline { padding: 34px 20px; }

/* ------------------------------------------------------------ responsive --- */

@media (max-width: 1240px) {
    .z-mybk-grid { grid-template-columns: 240px minmax(0, 1fr); }
    .z-mybk-tiles { grid-template-columns: repeat(5, 98px); gap: 10px; }
}

@media (max-width: 1080px) {
    .z-mybk-grid { grid-template-columns: minmax(0, 1fr); }
    /* The rail lies down above the list rather than stacking two tall panels. */
    .z-mybk-rail {
        position: static;
        display: grid; grid-template-columns: minmax(220px, 1fr) 2fr; gap: 12px;
    }
    .z-mybk-panel + .z-mybk-panel { margin-top: 0; }
    .z-mybk-rail .z-mybk-panel:last-child {
        display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    }
    .z-mybk-rail .z-mybk-panel:last-child .z-mybk-panel-t {
        flex: 1 0 100%; margin-bottom: 4px;
    }
    .z-mybk-rail .z-mybk-panel:last-child .z-mybk-row { width: auto; margin-bottom: 0; }
}

@media (max-width: 900px) {
    /* Under the greeting once there is no room beside it. */
    .z-mybk-top .z-shell { display: block; }
    .z-mybk-top-text { margin-bottom: 22px; }
    .z-mybk-tiles { grid-template-columns: repeat(5, minmax(0, 1fr)); width: 100%; justify-content: stretch; }

    /* Two per row rather than five squeezed columns with hairlines between. */
    .z-bkc-main { flex-wrap: wrap; gap: 14px 0; padding: 30px 6px 16px; }
    .z-bkc.has-head .z-bkc-main { padding-top: 12px; }
    .z-bkc-col { flex: 1 1 50% !important; }
    .z-bkc-col + .z-bkc-col { border-left: 0; }
    .z-bkc-col.is-pay { align-items: flex-start; text-align: left; }
    .is-pay .z-bkc-sub { justify-content: flex-start; }
    .z-bkc-acts { margin-left: 0; }
}

@media (max-width: 640px) {
    .z-mybk-rail { grid-template-columns: minmax(0, 1fr); }
    .z-mybk-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .z-bkc-col { flex: 1 1 100% !important; }


    /* --- THE FOOT, STACKED ------------------------------------------------

       Four items wrap onto three rows here, and each was taking its natural
       width: a status pill, a tag as long as the package name, and two buttons
       ending wherever their labels ended. Three different right edges down the
       foot of the card, against a card whose every other row is ruled.

       So the rows are made rows: the tag and the action pair each take the
       full width, and the two buttons split it evenly. The status pill keeps
       its own size — it is a badge, not a control, and stretching it to the
       card would read as a fourth button. */
    .z-bkc-foot { gap: 8px 10px; }
    .z-bkc-todo { flex: 1 1 100%; max-width: 100%; }

    /* The head gives up its middle first. "Booking On 01 Sep 2026 | 08:19 PM"
       beside a reference and a status wants more than a phone has, and of the
       three it is the one whose absence costs least — the date is stated again
       in the rows below, where the reference and the status are not. */
    .z-bkc-on small { display: none; }

    /* A GRID, NOT A ROW — the card grew from two actions to five.

       These were `flex: 1 1 0` with `white-space: nowrap`, which is a row that
       divides evenly between however many buttons there are. That is right for
       two and impossible for five: nowrap means none of them can shrink below
       its label, so they stopped dividing and started overlapping, and
       Reschedule sat on top of Cancel sat on top of Pay Now.

       Two per row instead, and the odd one out takes the full width rather
       than half a row with a hole beside it. Five actions land as 2 + 2 + 1. */
    .z-bkc-acts {
        flex: 1 1 100%;
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }
    .z-bkc-act {
        min-width: 0;
        justify-content: center;
        padding: 9px 10px;
        white-space: nowrap;
        /* The label yields before the row does: a long one is clipped, not
           spilled over the button beside it. */
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .z-bkc-act:last-child:nth-child(odd) { grid-column: 1 / -1; }
    .z-bkc-tag span, .z-bkc-tag { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* THE COUNTER TILES GO below desktop, on My Bookings and My Enquiries alike —
   both build them from the same .z-mybk-tiles block. Five tiles wrap to two
   rows on a phone and take most of the first screen before a single booking
   shows.

   WHAT GOES WITH THEM: each tile carries data-product-filter, so they are the
   product filter as well as the count — hidden, the list can only ever show
   All. The buttons stay in the DOM (display:none, not removed) so the script
   that binds them still finds them and nothing throws; the filter simply has
   no control on these widths.

   AND THE BAND ITSELF GOES WITH THEM, from the page rather than from here:
   both pages carry .z-desk-only on the <section>. Once the tiles are hidden
   and the greeting beside them is too, .z-mybk-top holds nothing but its own
   padding — which is precisely what it was drawing on a phone, some 50px of
   empty green between the nav strip and the crenellation below it. */
@media (max-width: 1080px) {
    .z-mybk-tiles { display: none; }
}

/* ==========================================================================
   My Profile — zaereen/users/profile.php
   --------------------------------------------------------------------------
   The ground login/user_profile_settings.php covers on the main site: a photo
   and completeness rail on the left, and tabbed panes on the right carrying
   personal details, address, documents and the family a customer books for.
   Drawn in the house palette, and leaning on what already exists — .z-tabs,
   .z-field, .z-res-grid and the .z-c* column spans are all reused as-is, so
   only the rail, the section headings, the document rows and the traveller
   cards are defined here.
   ========================================================================== */

.z-pf-grid {
    display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 24px;
    align-items: start;
}
.z-pf-rail { position: sticky; top: 92px; }
/* A grid item defaults to min-width:auto, which lets a wide table push the
   column wider than its track instead of scrolling inside .z-pf-tw — the
   whole page would then scroll sideways. */
.z-pf-main { min-width: 0; }

/* ------------------------------------------------------------- the rail --- */

.z-pf-card {
    padding: 22px 20px;
    text-align: center;
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: 16px;
    box-shadow: var(--z-shadow);
}

.z-pf-avatar { position: relative; display: inline-block; margin-bottom: 14px; }
.z-pf-avatar-img {
    width: 108px; height: 108px;
    display: grid; place-items: center;
    border-radius: 50%;
    color: var(--z-gold-deep);
    background: var(--z-gold-wash) center / cover no-repeat;
    border: 2px solid var(--z-line-gold);
    box-shadow: 0 8px 22px -12px rgba(13, 44, 34, .7);
}
/* A <label> on My Profile, because it wraps the file input (kept off-screen
   rather than display:none so it stays keyboard reachable); a plain <a> to the
   profile on My Account, which has no form to submit it with.

   Both element types are named explicitly below. A bare .z-pf-avatar-btn is one
   class, so any `.something a` rule anywhere in this sheet outranks it and
   repaints the anchor form only — which is exactly the shape of "it is fine on
   one page and unreadable on the other". Naming the tag raises this to
   (0,1,1) and settles it, and text-decoration is spelled out because an <a>
   carries an underline from the UA sheet that a <label> never does. */
.z-pf-avatar-btn,
a.z-pf-avatar-btn,
label.z-pf-avatar-btn {
    position: absolute; right: -6px; bottom: -6px;
    display: inline-flex; align-items: center; gap: 5px;
    padding: 6px 13px; border-radius: 100px; cursor: pointer;
    background: var(--z-green);
    color: #fdf8ec;
    /* A cream ring so the pill reads as a pill against a dark photograph as
       well as against the empty gold-wash circle. */
    border: 2px solid var(--z-surface);
    font-size: 11.5px; font-weight: 700; letter-spacing: .01em;
    line-height: 1.25; white-space: nowrap;
    text-decoration: none;
    box-shadow: 0 6px 16px -8px rgba(13, 44, 34, .95);
}
a.z-pf-avatar-btn:hover,
label.z-pf-avatar-btn:hover,
.z-pf-avatar-btn:hover { background: var(--z-green-2); color: #fff; text-decoration: none; }
/* The caption is the point of the control; nothing may collapse it. */
.z-pf-avatar-btn span { display: inline; color: inherit; font: inherit; }
.z-pf-avatar-btn input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.z-pf-avatar-btn svg { flex: none; }

.z-pf-name {
    margin: 0 0 2px;
    font-family: var(--z-display); font-size: 22px; font-weight: 600;
    color: var(--z-green); line-height: 1.2;
}
.z-pf-sub {
    /* A flag, a dialling code and the number: one line, centred as a unit.
       inline-flex rather than flex so it centres inside the card's text-align
       rather than stretching across it. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin: 0 0 16px;
    font-size: 13px; color: var(--z-ink-3); font-variant-numeric: tabular-nums;
}
.z-pf-sub-flag {
    flex: none;
    display: block;
    border-radius: 3px;
    /* The India flag's white band runs to its edge; without this the flag
       dissolves into the card. */
    box-shadow: 0 0 0 1px var(--z-line);
}
.z-pf-sub-isd { font-weight: 700; color: var(--z-ink-2); }
.z-pf-sub-num { letter-spacing: .02em; }

/* How much of the record is filled in — the one number that says whether this
   page still wants attention before a visa file is put together. */
.z-pf-meter {
    height: 6px; border-radius: 100px; overflow: hidden;
    background: var(--z-cream-deep);
    border: 1px solid var(--z-line-soft);
}
.z-pf-meter span {
    display: block; height: 100%;
    background: var(--z-gold-leaf);
    transition: width .4s ease;
}
.z-pf-meter-t {
    margin: 7px 0 16px;
    font-size: 11.5px; color: var(--z-ink-3);
}
.z-pf-meter-t b { color: var(--z-gold-deep); font-weight: 700; }

.z-pf-facts {
    display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
    background: var(--z-line-soft);
    border: 1px solid var(--z-line-soft);
    border-radius: 10px; overflow: hidden;
    margin-bottom: 16px;
}
.z-pf-facts > div { padding: 9px 8px; background: var(--z-marble); }
.z-pf-facts small {
    display: block; font-size: 9px; font-weight: 600;
    letter-spacing: .11em; text-transform: uppercase; color: var(--z-ink-3);
}
.z-pf-facts b {
    font-size: 13.5px; font-weight: 600; color: var(--z-green);
    font-variant-numeric: tabular-nums;
}

.z-pf-rail-cta { display: grid; gap: 8px; }
.z-pf-note {
    margin: 14px 0 0;
    font-size: 11.5px; line-height: 1.5; color: var(--z-ink-3);
}

/* ------------------------------------------------------------ the panes --- */

/* A count beside the Family tab, so the tab says whether there is anything
   behind it without being opened. */
.z-tab-n {
    min-width: 19px; padding: 1px 6px; border-radius: 100px;
    background: var(--z-gold-wash); border: 1px solid var(--z-line-gold);
    font-size: 10.5px; font-weight: 700; color: var(--z-gold-deep);
    font-variant-numeric: tabular-nums;
}
.z-tab.is-active .z-tab-n {
    background: rgba(227, 200, 134, .18);
    border-color: rgba(227, 200, 134, .3);
    color: var(--z-gold-light);
}

.z-pf-block + .z-pf-block {
    margin-top: 30px; padding-top: 26px;
    border-top: 1px solid var(--z-line-soft);
}

/* Each section takes its own accent, the way the main site's profile gives
   each card a tone. Four colours, all already in the palette. */
.z-pf-h {
    display: flex; align-items: center; gap: 10px;
    margin: 0 0 16px;
    font-family: var(--z-display); font-size: 20px; font-weight: 600;
    color: var(--z-green);
}
.z-pf-h span {
    flex: none; width: 30px; height: 30px;
    display: grid; place-items: center; border-radius: 9px;
}
.z-pf-h .is-a1 { background: var(--z-sold-bg);    color: var(--z-sold); }
.z-pf-h .is-a2 { background: var(--z-teal-wash);  color: var(--z-teal); }
.z-pf-h .is-a3 { background: var(--z-gold-wash);  color: var(--z-gold-deep); }
.z-pf-h .is-a4 { background: var(--z-green-soft); color: var(--z-green-3); }

/* The one-line intro under a section heading. Named apart from .z-pf-lead
   (the lead-person CARD below), which would otherwise style this paragraph
   as a bordered box — same prefix, entirely different job. */
.z-pf-intro {
    margin: -8px 0 16px;
    font-size: 13.5px; line-height: 1.55; color: var(--z-ink-2);
}
/* A passport inside six months stops a visa, so it is called out rather than
   left for the customer to work out from the date. */
.z-pf-warn {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 16px; padding: 10px 14px;
    background: var(--z-few-bg);
    border: 1px solid rgba(145, 96, 15, .32);
    border-radius: 10px;
    font-size: 13px; font-weight: 600; color: #91600f;
}
.z-pf-warn svg { flex: none; }

/* ------------------------------------------------------------- documents --- */

.z-pf-files {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px;
    margin-top: 18px;
}
.z-pf-file {
    display: flex; align-items: center; gap: 11px;
    padding: 11px 13px;
    background: var(--z-marble);
    border: 1px solid var(--z-line);
    border-radius: 11px;
}
.z-pf-file-ic {
    flex: none; width: 32px; height: 32px;
    display: grid; place-items: center; border-radius: 9px;
    background: var(--z-gold-wash); border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
}
.z-pf-file-b { flex: 1 1 auto; min-width: 0; }
.z-pf-file-b b {
    display: block; font-size: 13px; font-weight: 600; color: var(--z-green);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.z-pf-file-b small { font-size: 11.5px; color: var(--z-ink-3); }
.z-pf-file-b a {
    font-size: 11.5px; color: var(--z-teal);
    text-decoration: underline; text-underline-offset: 3px;
}
.z-pf-file-b a:hover { color: var(--z-green); }
.z-pf-file-btn {
    flex: none; padding: 6px 13px; border-radius: 8px; cursor: pointer;
    background: var(--z-surface); border: 1px solid var(--z-line-strong);
    font-size: 12px; font-weight: 600; color: var(--z-green);
}
.z-pf-file-btn:hover { background: var(--z-gold-wash); border-color: var(--z-gold); }
.z-pf-file-btn input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

/* --------------------------------------------------------- family rows --- */

/* A traveller card IS a lead-person card — same shell, same head, same two
   field rows — so it carries .z-pf-lead as well and only the differences live
   here: a relationship where the lead has an email, and a remove button where
   the lead has a mobile. */
.z-pf-person { margin-bottom: 14px; }

.z-pf-lead-head.is-person {
    grid-template-columns: minmax(0, 1fr) minmax(190px, 260px) auto;
    align-items: start;
}
.z-pf-lbl.is-plum { color: #7b2d5e; }
.z-pf-idic.is-rel { background: #f3e6ee; border-color: rgba(123, 45, 94, .22); color: #7b2d5e; }

.z-pf-person-x {
    flex: none; align-self: center;
    width: 32px; height: 32px;
    display: grid; place-items: center; cursor: pointer;
    border-radius: 9px;
    background: var(--z-surface); border: 1px solid var(--z-line);
    color: var(--z-ink-3);
}
.z-pf-person-x:hover {
    background: var(--z-sold-bg); border-color: rgba(138, 48, 36, .3); color: var(--z-sold);
}
.z-pf-person .z-pf-files { margin-top: 14px; }
.z-pf-person .z-field input,
.z-pf-person .z-field select { background: var(--z-surface); }

/* ------------------------------------------------------------- the save --- */

.z-pf-save {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    margin-top: 22px; padding: 15px 18px;
    background: linear-gradient(180deg, var(--z-cream), var(--z-cream-deep));
    border: 1px solid var(--z-line-gold);
    border-radius: 13px;
}
.z-pf-save small { font-size: 12px; color: var(--z-ink-3); }

/* ------------------------------------------------------------ responsive --- */

@media (max-width: 1080px) {
    .z-pf-grid { grid-template-columns: minmax(0, 1fr); }
    /* Lying down, the rail becomes a banner: photo and name to the left of the
       meter and the two facts, rather than a tall column above the form. */
    .z-pf-rail { position: static; }
    .z-pf-card {
        display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 20px;
        align-items: center; text-align: left;
    }
    .z-pf-avatar { grid-row: span 3; margin-bottom: 0; }
    .z-pf-facts { margin-bottom: 0; }
    .z-pf-rail-cta { grid-column: 2; grid-auto-flow: column; justify-content: start; margin-top: 12px; }
    .z-pf-note { grid-column: 1 / -1; }
}

@media (max-width: 760px) {
    .z-pf-files { grid-template-columns: minmax(0, 1fr); }
    .z-pf-card { grid-template-columns: minmax(0, 1fr); text-align: center; justify-items: center; }
    .z-pf-avatar { grid-row: auto; }

    /* THE PILL CENTRES ON THE PHOTO. It is anchored to the circle's bottom
       RIGHT corner, which is right on a wide card where the avatar sits in a
       column of its own — but here the card is centred and the pill is wider
       than the 108px circle it hangs off, so anchoring by its right edge threw
       it left of the photo it belongs to.

       And it needs somewhere to hang. The pill drops about 22px below the
       avatar's box against the 14px of margin under it, so it was sitting on
       the name. The margin covers the overhang instead. */
    .z-pf-avatar { margin-bottom: 26px; }
    .z-pf-avatar-btn,
    a.z-pf-avatar-btn,
    label.z-pf-avatar-btn {
        right: auto;
        left: 50%;
        transform: translateX(-50%);
        bottom: -13px;
    }
    /* TWO BY TWO:  My Bookings | My Enquiries
                      My Account  | Sign out

       Four full-width bars was half a screen of chrome under a card that is
       itself the length of the viewport. Both pages that draw this rail always
       show exactly four — the fifth link is the page you are already on, and
       it is dropped — so the pair of rows is a whole layout, not a grid with a
       gap at the end.

       Centred, not start-aligned: that was right while they were full-width
       bars, where each label began at whatever x its own icon left it. At half
       width a tile is read as a tile and wants its contents in the middle. */
    .z-pf-rail-cta {
        grid-column: auto;
        grid-auto-flow: row;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        width: 100%;
    }
    .z-pf-rail-cta .z-btn {
        justify-content: center;
        gap: 7px;
        min-width: 0;
        padding-left: 10px;
        padding-right: 10px;
        white-space: nowrap;
    }
    /* THE ARROW GOES. It is a flourish on a full-width bar and 19px a
       half-width tile does not have: with it, "My bookings" wants 133px
       against the 120px a 320px phone gives each column. The tile is already
       a link; nothing is lost but the decoration. */
    .z-pf-rail-cta .z-arrow { display: none; }

    /* The span collapse at 640px is already in the sheet; nothing to add. */
    .z-pf-save { flex-direction: column; align-items: stretch; }
}

/* Below this the two columns are narrower than "My enquiries" needs with its
   icon, so the pair of rows becomes a single file rather than the labels being
   clipped. 340, not 360: at 360 each column is 140px against the 120px the
   longest of the four wants. */
@media (max-width: 340px) {
    .z-pf-rail-cta { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   My Profile — the lead-person card, the identity fields and the scan dialog
   --------------------------------------------------------------------------
   login/user_profile_settings.php groups Personal Information into one card:
   a head naming who this is and the two identifiers we can reach them on, and
   a body carrying the passport bio-data page in the order a passport prints
   it. Same structure here, in the house palette, and Address & Location and
   Documents reuse the same card so the three sections read as one set.
   ========================================================================== */

.z-pf-lead {
    background: var(--z-marble);
    border: 1px solid var(--z-line);
    border-radius: 14px;
    overflow: hidden;
}

/* Three columns: who, email, mobile. Each takes what it needs and the two
   identity boxes hold their width, so a long name never squeezes them. */
.z-pf-lead-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(230px, 300px) minmax(210px, 260px);
    gap: 14px 20px;
    padding: 15px 16px;
    background: linear-gradient(180deg, var(--z-cream), var(--z-cream-deep));
    border-bottom: 1px solid var(--z-line);
}
.z-pf-lead-body { padding: 16px; }
.z-pf-lead-body > .z-res-grid + .z-res-grid { margin-top: 14px; }

/* The tiny coloured caption over each control, matching the main site's
   per-field tone. Its own element rather than a <label> where the control
   underneath is a composite box rather than one input. */
.z-pf-lbl {
    display: flex; align-items: center; gap: 6px;
    margin-bottom: 7px;
    font-size: 10px; font-weight: 700; letter-spacing: .13em;
    text-transform: uppercase; color: var(--z-ink-3);
}
.z-pf-lbl svg { flex: none; }
.z-pf-lbl.is-gold  { color: var(--z-gold-deep); }
.z-pf-lbl.is-blue  { color: #2a4d8f; }
.z-pf-lbl.is-green { color: var(--z-green-3); }

/* The green tick that says an identifier is confirmed. */
.z-pf-tick {
    display: inline-flex; align-items: center; justify-content: center;
    width: 14px; height: 14px; border-radius: 50%;
    background: var(--z-open); color: #fdf8ec;
}
.z-pf-tick svg { stroke-width: 2.6; }

.z-pf-who { min-width: 0; }
.z-pf-who-row { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.z-pf-pill {
    display: inline-flex; align-items: center; gap: 7px;
    min-width: 0; padding: 9px 15px; border-radius: 100px;
    background: var(--z-green); color: #fdf8ec;
    font-size: 14px; font-weight: 600;
}
.z-pf-pill svg { flex: none; color: var(--z-gold-light); }

.z-pf-scan {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 16px; border-radius: 100px; cursor: pointer;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-gold);
    color: var(--z-gold-deep);
    font: inherit; font-size: 13.5px; font-weight: 600;
}
.z-pf-scan:hover { background: var(--z-gold-pale); border-color: var(--z-gold-deep); }
.z-pf-scan svg { flex: none; }

/* Email and mobile: an icon or flag, an optional prefix, then the input —
   one box rather than three controls in a row. */
.z-pf-idf { min-width: 0; }
.z-pf-idbox {
    display: flex; align-items: center; gap: 9px;
    padding: 7px 10px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 11px;
}
.z-pf-idbox:focus-within { border-color: var(--z-gold); box-shadow: 0 0 0 3px rgba(193, 154, 63, .16); }
.z-pf-idbox.is-locked { background: var(--z-cream); }
.z-pf-idbox input {
    flex: 1 1 auto; min-width: 0;
    padding: 0; border: 0; background: none; outline: none;
    font-family: var(--z-body); font-size: 15px; font-weight: 500; color: var(--z-ink);
}
.z-pf-idbox.is-locked input { color: var(--z-ink-2); cursor: default; }
.z-pf-idic {
    flex: none; width: 30px; height: 30px;
    display: grid; place-items: center; border-radius: 8px;
    background: var(--z-gold-wash); color: var(--z-gold-deep);
}
.z-pf-idic.is-mail { background: #2a4d8f; color: #fff; }
.z-pf-flag { flex: none; border-radius: 3px; box-shadow: 0 0 0 1px var(--z-line); }
.z-pf-isd {
    flex: none; font-size: 14px; font-weight: 600; color: var(--z-ink-2);
    font-variant-numeric: tabular-nums;
}
.z-pf-idf .z-hint { display: block; margin-top: 6px; }

/* Passport bio data is five fields on one line, the way it is printed. */
.z-pf-penta { grid-template-columns: repeat(5, minmax(0, 1fr)) !important; }
.z-pf-penta > .z-field { grid-column: auto !important; }

/* The field captions inside this card are centred over their control and each
   takes its own hue, the way the main site's profile colours them. The nine
   there are dark-theme neons (#22c55e, #60a5fa, #fbbf24 …) which sit around
   2:1 on cream; these are the same hues taken deep enough to read on marble,
   and they are reused across Personal, Address and Documents so no two
   captions standing next to each other ever share one. */
.z-pf-lead-body .z-field label {
    display: flex; align-items: center; justify-content: center; gap: 5px;
    text-align: center;
}
.z-pf-lead-body .z-field label svg { flex: none; opacity: .9; }

.z-pf-lead-body .z-field label.tone-green  { color: #1f7a4d; }
.z-pf-lead-body .z-field label.tone-navy   { color: #2a4d8f; }
.z-pf-lead-body .z-field label.tone-gold   { color: #8f6f1c; }
.z-pf-lead-body .z-field label.tone-rose   { color: #a63b73; }
.z-pf-lead-body .z-field label.tone-orange { color: #a35418; }
.z-pf-lead-body .z-field label.tone-violet { color: #6b4d9e; }
.z-pf-lead-body .z-field label.tone-teal   { color: #12655f; }
.z-pf-lead-body .z-field label.tone-cyan   { color: #1177a8; }
.z-pf-lead-body .z-field label.tone-clay   { color: #8a3024; }
.z-pf-lead-body .z-field input,
.z-pf-lead-body .z-field select { background: var(--z-surface); }

/* ---------------------------------------------------------- scan dialog --- */

.z-pscan {
    position: fixed; inset: 0; z-index: 70;
    display: grid; place-items: center;
    padding: 20px; overflow-y: auto;
    background: rgba(11, 34, 28, .55);
    backdrop-filter: blur(3px);
}
/* Scanning is an offer, never a step. The dialog opens only from the Scan
   Passport button and every close route — the X, Escape, a click on the
   backdrop — simply drops it; nothing on the form depends on it having run.
   This rule is what keeps that true: `display:grid` above outranks the UA
   sheet's [hidden]{display:none}, so without it the dialog painted itself
   open on load and read as a compulsory first step. Applies to everything
   the page toggles with el.hidden, so a panel added later cannot repeat it. */
.z-pscan[hidden],
.z-pscan [hidden],
.z-pf [hidden] { display: none !important; }
.z-pscan-box {
    width: 100%; max-width: 620px;
    background: var(--z-surface);
    border: 1px solid var(--z-line-strong);
    border-radius: 16px;
    box-shadow: 0 30px 70px -20px rgba(4, 18, 13, .6);
    overflow: hidden;
}
.z-pscan-head {
    display: flex; align-items: center; gap: 12px;
    padding: 14px 16px;
    background: linear-gradient(180deg, var(--z-cream), var(--z-cream-deep));
    border-bottom: 1px solid var(--z-line);
}
.z-pscan-head h2 {
    display: flex; align-items: center; gap: 9px;
    margin: 0; font-family: var(--z-display); font-size: 20px; font-weight: 600;
    color: var(--z-green);
}
.z-pscan-head svg { flex: none; color: var(--z-gold-deep); }
.z-pscan-x {
    margin-left: auto; flex: none;
    width: 30px; height: 30px; display: grid; place-items: center;
    border-radius: 8px; cursor: pointer;
    background: var(--z-surface); border: 1px solid var(--z-line); color: var(--z-ink-2);
}
.z-pscan-x:hover { background: var(--z-sold-bg); border-color: rgba(138, 48, 36, .3); color: var(--z-sold); }

.z-pscan-body { padding: 16px; }

.z-pscan-drop {
    display: grid; place-items: center; gap: 8px;
    min-height: 168px; padding: 20px; cursor: pointer; text-align: center;
    background: var(--z-marble);
    border: 2px dashed var(--z-line-strong);
    border-radius: 13px;
    color: var(--z-gold-deep);
}
.z-pscan-drop:hover { border-color: var(--z-gold); background: var(--z-gold-wash); }
.z-pscan-drop b { display: block; font-size: 14.5px; color: var(--z-green); }
.z-pscan-drop small { display: block; font-size: 12px; color: var(--z-ink-3); max-width: 42ch; }
.z-pscan-drop img { max-height: 190px; border-radius: 9px; }
.z-pscan-drop.is-busy { border-color: var(--z-teal); background: var(--z-teal-wash); }

.z-pscan-status {
    margin: 12px 0 0; padding: 9px 13px; border-radius: 9px;
    font-size: 13px; font-weight: 600;
    background: var(--z-cream); color: var(--z-ink-2);
}
.z-pscan-status.is-ok  { background: var(--z-open-bg); color: var(--z-open); }
.z-pscan-status.is-bad { background: var(--z-sold-bg); color: var(--z-sold); }

.z-pscan-fields { margin-top: 14px; }
.z-pscan-note {
    margin: 12px 0 0;
    font-size: 12px; line-height: 1.5; color: var(--z-ink-3);
}

.z-pscan-foot {
    display: flex; justify-content: flex-end; gap: 9px;
    padding: 13px 16px;
    background: var(--z-cream);
    border-top: 1px solid var(--z-line);
}
.z-pscan-foot .z-btn[disabled] { opacity: .5; pointer-events: none; }

/* ------------------------------------------------------------ responsive --- */

@media (max-width: 1240px) {
    .z-pf-lead-head { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .z-pf-who { grid-column: 1 / -1; }
}

@media (max-width: 900px) {
    /* Five passport fields become a 2-2-1 block rather than five slivers —
       except the count is odd, so one of them is always left alone on a row.
       The passport NUMBER takes that place deliberately: it is the longest
       value of the five and the one the rest of the block is about, so it
       reads as a heading with its details paired underneath rather than as an
       orphan at the end. 1 + 2 + 2, no ragged edge. */
    .z-pf-penta { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
    .z-pf-penta > .z-field:first-child { grid-column: 1 / -1 !important; }
}

@media (max-width: 1240px) {
    .z-pf-lead-head.is-person { grid-template-columns: minmax(0, 1fr) auto; }
    .z-pf-lead-head.is-person .z-pf-who { grid-column: 1; }
}

@media (max-width: 640px) {
    .z-pf-lead-head { grid-template-columns: minmax(0, 1fr); }
    .z-pf-lead-head.is-person { grid-template-columns: minmax(0, 1fr) auto; }
    .z-pf-lead-head.is-person .z-pf-who { grid-column: 1 / -1; }
    /* STILL PAIRED ON A PHONE. These five were dropping to a single column
       here, which is five full-width rows for a passport — taller than the
       name and date fields above them that stay two-up at the same width, so
       the block stopped matching the form it belongs to. They hold: the widest
       of them is a date input, and Date of Birth is already sitting two-up in
       the row above at this width. The number keeps the full-width row it is
       given in the 900px block. */
    .z-pf-who-row { flex-direction: column; align-items: stretch; }
    .z-pf-pill, .z-pf-scan { justify-content: center; }
    .z-pscan-foot { flex-direction: column-reverse; }
}

/* "optional" said on the control itself, so the shortcut never reads as a
   gate the customer has to pass before the form will take their details. */
.z-pf-opt {
    padding: 1px 7px; border-radius: 100px;
    background: var(--z-surface); border: 1px solid var(--z-line-gold);
    font-size: 9.5px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--z-ink-3);
}
.z-pscan-opt {
    margin: 0 0 14px; padding: 9px 13px;
    background: var(--z-cream); border: 1px solid var(--z-line-soft);
    border-radius: 9px;
    font-size: 12.5px; line-height: 1.5; color: var(--z-ink-2);
}

/* ==========================================================================
   My Profile — the Account tab
   --------------------------------------------------------------------------
   What login/my_account.php shows: the balance, the ledger behind it, and the
   payments a customer has declared. The four summary cards name their own
   source, because the ledger and the bookings table hold different sets of
   sales and a single reconciled "balance" would be wrong for whichever half
   it left out.
   ========================================================================== */

.z-pf-h .is-a5 { background: #f3e6ee; color: #7b2d5e; }

/* An "owed" marker on the tab itself, so money outstanding is visible without
   opening it. */
.z-tab-n.is-owed {
    background: var(--z-sold-bg); border-color: rgba(138, 48, 36, .3);
    color: var(--z-sold); letter-spacing: .1em;
}
.z-tab.is-active .z-tab-n.is-owed {
    background: rgba(248, 180, 170, .2); border-color: rgba(248, 180, 170, .35); color: #f6cfc8;
}

.z-pf-sum {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px;
    margin-bottom: 16px;
}
.z-pf-sum-c {
    padding: 13px 15px;
    background: var(--z-marble);
    border: 1px solid var(--z-line);
    border-radius: 12px;
}
.z-pf-sum-c.is-owed { background: var(--z-few-bg); border-color: rgba(145, 96, 15, .3); }
.z-pf-sum-c small {
    display: flex; align-items: center; gap: 5px;
    font-size: 9.5px; font-weight: 700; letter-spacing: .12em;
    text-transform: uppercase; color: var(--z-ink-3);
}
.z-pf-sum-c small svg { flex: none; }
.z-pf-sum-c b {
    display: block; margin: 5px 0 2px;
    font-family: var(--z-display); font-size: 24px; font-weight: 600;
    color: var(--z-green); font-variant-numeric: tabular-nums;
}
.z-pf-sum-c.is-owed b { color: #91600f; }
.z-pf-sum-c span { font-size: 11.5px; color: var(--z-ink-3); }

.z-pf-sum-act { display: flex; flex-wrap: wrap; gap: 9px; margin-bottom: 24px; }

.z-pf-sub {
    display: flex; align-items: center; gap: 8px;
    margin: 24px 0 10px;
    font-size: 11px; font-weight: 700; letter-spacing: .15em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-pf-sub svg { flex: none; }
.z-pf-blank {
    margin: 0; padding: 18px;
    text-align: center; font-size: 13px; color: var(--z-ink-3);
    background: var(--z-marble);
    border: 1px dashed var(--z-line); border-radius: 11px;
}

/* The table scrolls inside its own box; the page never scrolls sideways. */
.z-pf-tw {
    overflow-x: auto;
    border: 1px solid var(--z-line);
    border-radius: 12px;
    background: var(--z-surface);
}
.z-pf-t { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 640px; }
.z-pf-t th {
    padding: 10px 13px; text-align: left; white-space: nowrap;
    background: linear-gradient(180deg, var(--z-cream), var(--z-cream-deep));
    border-bottom: 1px solid var(--z-line);
    font-size: 9.5px; font-weight: 700; letter-spacing: .12em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-pf-t td {
    padding: 10px 13px; color: var(--z-ink-2);
    border-bottom: 1px solid var(--z-line-soft);
}
.z-pf-t tbody tr:last-child td { border-bottom: 0; }
.z-pf-t tbody tr:hover td { background: var(--z-marble); }
.z-pf-t .is-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.z-pf-t .is-nw  { white-space: nowrap; }
.z-pf-t .is-dr  { color: var(--z-sold); font-weight: 600; }
.z-pf-t .is-cr  { color: var(--z-open); font-weight: 600; }
.z-pf-t .is-run { color: var(--z-green); font-weight: 600; }
.z-pf-t a { color: var(--z-teal); text-decoration: underline; text-underline-offset: 3px; }

/* The voucher type, beside the detail it belongs to. */
.z-pf-vt {
    display: inline-block; margin-left: 6px;
    padding: 1px 7px; border-radius: 100px;
    background: var(--z-gold-wash); border: 1px solid var(--z-line-gold);
    font-size: 9.5px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--z-gold-deep);
}

.z-pf-st {
    display: inline-block; padding: 2px 10px; border-radius: 100px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .05em;
}
.z-pf-st.is-ok   { background: var(--z-open-bg); color: var(--z-open); }
.z-pf-st.is-wait { background: var(--z-few-bg);  color: var(--z-few); }
.z-pf-st.is-no   { background: var(--z-sold-bg); color: var(--z-sold); }

@media (max-width: 1080px) {
    .z-pf-sum { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
    /* THE FOUR STAY TWO BY TWO:

           Ledger balance    | Due on bookings
           Payments verified | Credits received

       They were dropping to a single file here, which is four tall cards
       before the ledger itself — and they read as a set, not as a list: the
       first pair is what is owed and the second is what has been settled, so
       the grid is doing the comparing that a column makes the reader do from
       memory.

       They hold at this width. The figure is the tall thing in each card and it
       is short — under 100px at 24px — so the column is sized by the third
       line instead ("₹5,000 awaiting checking", about 130px). A 360px phone
       gives each card 127px of content once its own 15px padding is taken off,
       so that line wraps to two on the narrowest handsets. That is a wrap, not
       a break: grid rows take the height of the taller card, so the pair stay
       level either way. */
    .z-pf-sum { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .z-pf-sum-act .z-btn { flex: 1 1 100%; justify-content: center; }
}

/* A floor well under any handset in service — 320px is the smallest still
   sold and it keeps the pair. This is here so the layout has a defined end
   rather than because a real screen reaches it. */
@media (max-width: 300px) {
    .z-pf-sum { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   My Account — two columns
   The shell is the profile page's (.z-pf-grid / .z-pf-rail / .z-pf-main), and
   the rail itself is the shared account card, so nothing is redefined here.
   The summary figures sit above both columns at full width; the four-across
   grid they already use needs no override.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Submit Payment — the two-column dialog
   The balance across the top, the choice down the left, and a right panel that
   swaps with the method: Razorpay's own call to action, or the reference and
   receipt that let an accounts person match a transfer by hand.
   -------------------------------------------------------------------------- */

.z-pscan-box.is-pay { max-width: 880px; }

.z-pay-bal {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    padding: 12px 16px; margin-bottom: 16px;
    background: var(--z-marble);
    border: 1px solid var(--z-line);
    border-radius: 12px;
}
.z-pay-bal span {
    font-size: 10px; font-weight: 700; letter-spacing: .13em;
    text-transform: uppercase; color: var(--z-ink-3);
}
.z-pay-bal b {
    font-family: var(--z-display); font-size: 24px; font-weight: 600;
    color: var(--z-green); font-variant-numeric: tabular-nums;
}
.z-pay-bal b.is-owed { color: #91600f; }
.z-pay-bal b small {
    margin-left: 5px; font-family: var(--z-body);
    font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
}

.z-pay-cols {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px;
}
.z-pay-l { border-right: 1px solid var(--z-line-soft); padding-right: 20px; }
.z-pay-l > .z-field + .z-field { margin-top: 16px; }
.z-pay-r { display: flex; flex-direction: column; justify-content: center; }
.z-pay-r > .z-pay-manual > .z-field + .z-field { margin-top: 16px; }

/* The rupee sits inside the box with the number, not floating beside it. */
.z-pay-amt {
    display: flex; align-items: center; gap: 8px;
    padding: 0 13px;
    background: var(--z-surface-2);
    border: 1px solid var(--z-line);
    border-radius: 8px;
}
.z-pay-amt:focus-within { border-color: var(--z-gold); box-shadow: 0 0 0 3px rgba(193, 154, 63, .16); }
.z-pay-amt > span {
    flex: none; font-family: var(--z-display); font-size: 19px; color: var(--z-gold-deep);
}
.z-pay-amt input {
    flex: 1 1 auto; min-width: 0;
    padding: 12px 0; border: 0; background: none; outline: none;
    font-family: var(--z-body); font-size: 17px; font-weight: 600; color: var(--z-ink);
    font-variant-numeric: tabular-nums;
}
/* ONE BOX, NOT TWO. The rule above already says outline:none, and it was
   already being overruled: `.zaereen :focus-visible` up at the top of this
   file is a class plus a pseudo-class (0,2,0) against this selector's class
   plus an element (0,1,1), so the moment the field took focus the global gold
   outline came back — drawn at outline-offset 3px around an input that is
   itself inset behind the rupee sign, which is the second rounded box that
   appeared inside the first.

   Focus is NOT lost by removing it: .z-pay-amt:focus-within already puts a
   gold border and a 3px glow on the wrapper, which is the whole control and
   the better target to ring. Named with :focus as well as :focus-visible so
   it does not depend on which one the browser decides to apply. */
.z-pay-amt input:focus,
.z-pay-amt input:focus-visible { outline: none; box-shadow: none; }

/* Three tiles, the third across the full width — the shape the main site uses. */
.z-pay-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.z-pay-tile {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
    padding: 14px 10px; cursor: pointer;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 11px;
    font: inherit; font-size: 13px; font-weight: 600; color: var(--z-ink-2);
    transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.z-pay-tile.is-wide { grid-column: 1 / -1; flex-direction: row; }
.z-pay-tile svg { flex: none; color: var(--z-gold-deep); }
.z-pay-tile:hover { border-color: var(--z-gold); background: var(--z-gold-wash); }
.z-pay-tile.is-on {
    background: var(--z-green); border-color: var(--z-green); color: #fdf8ec;
    box-shadow: 0 8px 18px -10px rgba(13, 44, 34, .9);
}
.z-pay-tile.is-on svg { color: var(--z-gold-light); }

/* Razorpay's panel: a dashed frame, the way the main site frames it. */
.z-pay-rzp {
    display: flex; flex-direction: column; align-items: center; gap: 9px;
    padding: 22px 18px; text-align: center;
    background: var(--z-gold-wash);
    border: 2px dashed var(--z-gold);
    border-radius: 14px;
}
.z-pay-rzp-ic {
    display: grid; place-items: center;
    width: 58px; height: 58px; border-radius: 15px;
    background: var(--z-surface); border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
}
.z-pay-rzp b {
    font-family: var(--z-display); font-size: 20px; font-weight: 600; color: var(--z-green);
}
.z-pay-rzp p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--z-ink-2); }
.z-pay-rzp .z-btn { margin-top: 4px; }

.z-pay-safe {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12px; font-weight: 600; color: var(--z-open);
}
.z-pay-safe svg { flex: none; }

.z-pay-msg {
    margin: 6px 0 0 !important;
    padding: 8px 12px; border-radius: 9px;
    font-size: 12.5px; font-weight: 600;
    background: var(--z-surface); color: var(--z-ink-2);
}
.z-pay-msg.is-bad { background: var(--z-sold-bg); color: var(--z-sold); }

.z-pscan-foot.is-split { justify-content: space-between; align-items: center; }
.z-pay-foot-btns { display: inline-flex; gap: 9px; }

@media (max-width: 720px) {
    .z-pay-cols { grid-template-columns: minmax(0, 1fr); gap: 16px; }
    .z-pay-l { border-right: 0; padding-right: 0; padding-bottom: 16px; border-bottom: 1px solid var(--z-line-soft); }
    .z-pscan-foot.is-split { flex-direction: column-reverse; align-items: stretch; gap: 10px; }
    .z-pay-foot-btns { justify-content: stretch; }
    .z-pay-foot-btns .z-btn { flex: 1 1 0; justify-content: center; }
    .z-pay-safe { justify-content: center; }
}

/* The dialog's title is set in caps like the screen it copies; Cormorant at
   this size reads as small caps, which is the house equivalent of that band. */
.z-pscan-box.is-pay .z-pscan-head h2 { text-transform: uppercase; letter-spacing: .04em; }

/* --------------------------------------------------------------------------
   THE DIALOG, BELOW DESKTOP

   `place-items: center` on a scrollable overlay is the classic overflow trap:
   while the box is shorter than the screen it centres, and the moment it is
   taller the surplus goes out of BOTH ends — and the half that went off the
   top cannot be scrolled back to, because scrolling only ever moves toward
   the bottom. On a 412x915 phone that put the "Submit Payment" heading and
   its close button above the top edge, unreachable, with the Cancel button
   below the bottom one.

   Aligning to the start fixes it outright: the box begins under the top
   padding and everything below it is reachable by scrolling, which is what
   the overlay's own overflow-y was there to do. Applied at the tablet
   breakpoint, where the payment dialog's two columns have already stacked
   into something taller than most screens.
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
    .z-pscan {
        place-items: start center;
        /* Room at the foot for the fixed bottom bar the dialog floats over
           (z-index 70 against its 40), so the last button is never left
           sitting on the crenellation. */
        padding: 14px 12px calc(72px + env(safe-area-inset-bottom, 0px));
    }
}

/* The dialog toggles its two right-hand panels and the submit button with
   el.hidden; .z-pay-rzp and .z-pay-manual both carry a display of their own,
   which outranks the UA sheet's [hidden] rule without this. */
.z-pscan [hidden] { display: none !important; }

/* --------------------------------------------------------------------------
   Submit Payment — the ICICI UPI QR panel
   Sits where the Razorpay panel sits and shares its frame, so the two payment
   routes read as two faces of one control rather than two designs.
   -------------------------------------------------------------------------- */

.z-pay-qr {
    display: flex; flex-direction: column; align-items: center; gap: 9px;
    padding: 20px 18px; text-align: center;
    background: var(--z-gold-wash);
    border: 2px dashed var(--z-gold);
    border-radius: 14px;
}
.z-pay-qr-idle,
.z-pay-qr-live { display: flex; flex-direction: column; align-items: center; gap: 9px; width: 100%; }
.z-pay-qr b {
    font-family: var(--z-display); font-size: 20px; font-weight: 600; color: var(--z-green);
}
.z-pay-qr p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--z-ink-2); }

/* The code itself sits on white: a UPI camera wants maximum contrast, and the
   gold wash behind this panel is not it. */
.z-pay-qr-img {
    display: grid; place-items: center;
    padding: 12px; border-radius: 12px;
    background: #fff; border: 1px solid var(--z-line);
    box-shadow: 0 8px 20px -12px rgba(13, 44, 34, .6);
}
.z-pay-qr-img img, .z-pay-qr-img canvas { display: block; }

.z-pay-qr-amt {
    font-variant-numeric: tabular-nums;
    color: var(--z-gold-deep) !important;
}
.z-pay-qr-tick {
    font-size: 12.5px !important; font-weight: 600; color: var(--z-ink-2) !important;
}
.z-pay-qr-tick span { color: var(--z-sold); font-variant-numeric: tabular-nums; }
.z-pay-qr-hint { font-size: 11.5px !important; color: var(--z-ink-3) !important; max-width: 34ch; }

/* --------------------------------------------------------------------------
   Submit Payment — the QR's verdict
   One panel, both answers. The seal draws itself: the ring sweeps round, then
   the tick or the cross is stroked on, so the outcome lands before the sentence
   under it is read. Before this the panel said nothing at all when a payment
   confirmed, which is indistinguishable from a payment that failed.
   -------------------------------------------------------------------------- */

.z-pay-qr-done {
    display: flex; flex-direction: column; align-items: center; gap: 10px;
    width: 100%; text-align: center;
    animation: z-qr-rise .34s cubic-bezier(.2, .8, .3, 1) both;
}

.z-qr-seal { display: block; width: 76px; height: 76px; }
.z-qr-seal svg { display: block; width: 100%; height: 100%; overflow: visible; }
.z-qr-seal svg * {
    fill: none; stroke-width: 4.5; stroke-linecap: round; stroke-linejoin: round;
}

/* Each stroke is hidden by an offset the length of its own path, then drawn.
   The dash values are that path's own length rounded up by a hair — 2*pi*29 for
   the ring, and Pythagoras on the two segments of each mark. Too generous and
   the stroke completes early and then sits still for the rest of its duration;
   too short and the pattern repeats, leaving a gap in a finished line. */
.z-qr-seal-ring {
    stroke: currentColor; opacity: .3;
    stroke-dasharray: 185; stroke-dashoffset: 185;
    animation: z-qr-draw .5s cubic-bezier(.5, 0, .3, 1) both;
}
.z-qr-seal-tick,
.z-qr-seal-x1,
.z-qr-seal-x2 { stroke: currentColor; }
.z-qr-seal-tick { stroke-dasharray: 40; stroke-dashoffset: 40; }
.z-qr-seal-x1,
.z-qr-seal-x2  { stroke-dasharray: 29; stroke-dashoffset: 29; }

.z-pay-qr-done.is-good { color: var(--z-open); }
.z-pay-qr-done.is-bad  { color: var(--z-sold); }

/* The wrong mark for the verdict is not drawn at all, so a red tick can never
   flash between the two states. */
.z-pay-qr-done.is-good .z-qr-seal-x1,
.z-pay-qr-done.is-good .z-qr-seal-x2,
.z-pay-qr-done.is-bad  .z-qr-seal-tick { display: none; }

.z-pay-qr-done.is-good .z-qr-seal-tick {
    animation: z-qr-draw .34s cubic-bezier(.6, 0, .4, 1) .42s both;
}
/* The pop is on the box, not the path: a transform on an SVG path scales about
   the viewBox origin, which throws the mark off its own circle. */
.z-pay-qr-done.is-good .z-qr-seal { animation: z-qr-pop .32s ease-out .72s both; }
.z-pay-qr-done.is-bad .z-qr-seal-x1 { animation: z-qr-draw .22s ease-out .42s both; }
.z-pay-qr-done.is-bad .z-qr-seal-x2 { animation: z-qr-draw .22s ease-out .60s both; }
.z-pay-qr-done.is-bad .z-qr-seal    { animation: z-qr-shake .42s ease-in-out .5s both; }

.z-pay-qr-done > b {
    font-family: var(--z-display); font-size: 21px; font-weight: 600; color: currentColor;
    animation: z-qr-rise .3s ease-out .5s both;
}
.z-pay-qr-done > p {
    margin: 0 !important; max-width: 34ch;
    font-size: 13px !important; line-height: 1.55; color: var(--z-ink-2) !important;
    animation: z-qr-rise .3s ease-out .58s both;
}

.z-pay-qr-ref {
    padding: 5px 11px; border-radius: 999px;
    background: var(--z-surface); border: 1px solid var(--z-line);
    font-size: 11px; font-weight: 600; letter-spacing: .04em;
    color: var(--z-ink-3); word-break: break-all;
    animation: z-qr-rise .3s ease-out .66s both;
}

.z-pay-qr-acts {
    display: inline-flex; flex-wrap: wrap; gap: 8px; justify-content: center;
    animation: z-qr-rise .3s ease-out .74s both;
}
.z-pay-qr-acts:empty { display: none; }

@keyframes z-qr-draw  { to { stroke-dashoffset: 0; } }
@keyframes z-qr-rise  { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }
@keyframes z-qr-pop   { 0% { transform: scale(1); } 45% { transform: scale(1.13); } 100% { transform: scale(1); } }
@keyframes z-qr-shake {
    0%, 100% { transform: translateX(0); }
    20%      { transform: translateX(-5px); }
    45%      { transform: translateX(4px); }
    70%      { transform: translateX(-2px); }
}

/* A drawn-on tick is decoration; the words below it carry the same news. */
@media (prefers-reduced-motion: reduce) {
    .z-pay-qr-done,
    .z-pay-qr-done *,
    .z-qr-seal, .z-qr-seal * { animation: none !important; stroke-dashoffset: 0 !important; }
}

/* --------------------------------------------------------------------------
   About Us
   Full .z-shell width, like every other page in the section — a column of type
   beside a standing summary rail. What is added here is only what the shared
   components have no equivalent for: the ruled authority list, the two tile
   grids, and the sub-heading that organises them.
   -------------------------------------------------------------------------- */

/* The About strip carries six PROSE values where the tour strip carries five
   short ones ("07 Sep 2026", "—"). Laid out the tour way they measure ~1350px
   against a 1352px inner shell, so the row wrapped on any screen under 1400px
   — and a wrapped row breaks the dividers up and stops reading as a strip.
   
   So the wrapping happens inside each cell instead: 15ch keeps "Oxford
   Travels" and "Raza Mubarak" on one line while folding "Dawoodi Bohra
   Mumineen" and "Ziyarat & Pilgrimage" onto two, which is still a strip. That
   takes the row to roughly 1100px, comfortable on a 1280px laptop. */
.z-facts.is-about .z-facts-row { gap: 10px 20px; }
.z-facts.is-about .z-fact { padding-right: 20px; }
.z-facts.is-about .z-fact p { white-space: normal; max-width: 15ch; }
/* The destination chips are the one cell that must not fold: six on one row is
   187px, six over two rows makes that cell twice as tall as its neighbours. */
.z-facts.is-about .z-fact-inc-row { flex-wrap: nowrap; }

@media (max-width: 1120px) {
    .z-facts.is-about .z-facts-row { gap: 10px 16px; }
    .z-facts.is-about .z-fact { padding-right: 16px; }
}

/* On the tour page the tab already names the section, so the panel hides the
   first block's h2. Here it does not: the tab says "Who We Are" while the
   heading says "Serving Mumineen Since 2010" — different words carrying
   different information, and hiding one loses it. */
.z-about-main .z-tabpanel .z-block.z-block-first > h2 { display: block; }

/* The section nav sits close under the strip, so this band does not also carry
   the full 68px of section padding above it. */
.z-section.is-short { padding-top: 34px; }

.z-about-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 400px;
    gap: 56px;
    align-items: start;
}
.z-about-main,
.z-about-rail { min-width: 0; }

/* --- type ----------------------------------------------------------------- */

.z-about-main .z-block { margin-bottom: 48px; }
.z-about-main .z-block:last-child { margin-bottom: 0; }

/* Larger than the site default on purpose. This column runs to about 900px, and
   at 15.5px that is roughly a hundred characters a line; the extra size and
   leading are what keep a full-width measure readable. */
.z-about-main .z-prose { font-size: 16.5px; line-height: 1.75; }
.z-about-main .z-prose p:last-child { margin-bottom: 0; }
.z-about-main .z-prose b { color: var(--z-green); font-weight: 600; }

/* The opening sentence of a block carries it; the rest supports it. */
.z-about-lede {
    font-size: 18.5px !important;
    line-height: 1.6;
    color: var(--z-ink) !important;
}

/* Sub-headings inside a block. A short gold rule above rather than a rule
   under, so they read as subordinate to the block's own underlined h2 instead
   of competing with it. */
.z-about-sub {
    margin: 34px 0 17px;
    padding-top: 14px;
    font-family: var(--z-body);
    font-size: 11.5px; font-weight: 700;
    letter-spacing: .18em; text-transform: uppercase;
    color: var(--z-gold-deep);
    border-top: 1px solid var(--z-line-soft);
    position: relative;
}
.z-about-sub::before {
    content: "";
    position: absolute; left: 0; top: -1px; width: 42px; height: 2px;
    background: var(--z-gold);
}

.z-about-note {
    margin: 20px 0 0;
    font-size: 14.5px; line-height: 1.65;
    color: var(--z-ink-3);
}
.z-about-note.is-lead { margin: 0 0 15px; }

/* --- a statement set apart from the prose --------------------------------- */
/* About uses it for the raza; Terms for the itinerary-sequence note. */

.z-callout {
    display: flex; gap: 15px; align-items: flex-start;
    padding: 18px 20px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-left: 3px solid var(--z-gold);
    border-radius: var(--z-radius-sm);
}
.z-callout-ic { flex: none; color: var(--z-gold-deep); line-height: 0; margin-top: 2px; }
.z-callout p {
    margin: 0;
    font-size: 15.5px; line-height: 1.65;
    color: var(--z-ink-2);
}
.z-callout b { color: var(--z-green); font-weight: 600; }

/* --- the authorisations, as a reference list ------------------------------ */

.z-auth-list { list-style: none; margin: 0; padding: 0; }
.z-auth-list li {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) auto;
    align-items: center;
    gap: 16px;
    padding: 13px 2px;
    border-bottom: 1px solid var(--z-line-soft);
}
.z-auth-list li:first-child { border-top: 1px solid var(--z-line-soft); }
.z-auth-ic { color: var(--z-gold-deep); line-height: 0; }
.z-auth-name { font-size: 15px; font-weight: 600; color: var(--z-green); }
.z-auth-where { font-size: 13.5px; color: var(--z-ink-3); text-align: right; }

/* --- destination and inclusion tiles -------------------------------------- */

.z-tiles {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
}
.z-tiles li {
    display: flex; align-items: center; gap: 10px;
    padding: 13px 15px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    font-size: 14.5px; color: var(--z-green); font-weight: 500;
}
.z-tiles li svg { flex: none; color: var(--z-gold-deep); }

/* The inclusions are a longer list of plainer things, so they get no card — a
   second grid of bordered boxes directly under the first read as one
   thirteen-item block rather than two lists of different kinds. */
/* One panel holding all seven rather than seven bordered boxes. Per-item rules
   were tried and are wrong here: seven items across three columns leaves the
   last row holding one, and its rule reads as a stub under a third of the
   width. The panel edge closes the block instead. */
.z-tiles.is-plain {
    grid-template-columns: repeat(3, 1fr);
    gap: 4px 30px;
    padding: 16px 20px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
}
.z-tiles.is-plain li {
    background: none; border: 0; border-radius: 0;
    padding: 8px 0;
    font-weight: 400; color: var(--z-ink-2);
}

/* --- the rail ------------------------------------------------------------- */

/* The brand plate. Its own block rather than .z-book-head, which is written
   for "₹48,000 / per person" — a 32px figure with an inline caption. Three
   centred lines of decreasing weight: mark, who, what. */
.z-about-brand {
    padding: 28px 22px 24px;
    text-align: center;
    background-color: var(--z-green);
    background-image: var(--z-pattern-dark);
    background-size: 26px 26px;
    border-bottom: 1px solid var(--z-line-gold);
}

/* zaereen-lockup-light.png is 765x742 — very nearly SQUARE, because it stacks
   the calligraphic mark above the wordmark. Sizing it by height the way a wide
   horizontal lockup is sized gives a logo as wide as it is tall: at the 46px
   used here before, that was a 47px stamp. Width is the honest dimension for
   this piece, and 150px is what fills the plate without crowding it. */
.z-about-logo {
    display: block;
    width: 150px; max-width: 72%; height: auto;
    margin: 0 auto;
}
.z-about-brand-tag {
    margin: 16px 0 0;
    font-size: 10.5px; font-weight: 700;
    letter-spacing: .2em; text-transform: uppercase;
    color: var(--z-gold-light);
}
/* A rule under the tagline rather than a gap: it separates the brand from the
   sentence about the business without adding a fourth stacked block. */
.z-about-brand-tag::after {
    content: "";
    display: block; width: 40px; height: 1px;
    margin: 13px auto 0;
    background: var(--z-gold); opacity: .55;
}
/* balance evens the two lines instead of leaving a long first line over one
   orphaned word; the max-width is the fallback where it is not supported, and
   is wide enough that the sentence never breaks to three. */
.z-about-brand-line {
    margin: 13px auto 0;
    max-width: 30ch;
    font-size: 13.5px; line-height: 1.6;
    color: rgba(240, 232, 214, .76);
    text-wrap: balance;
}

.z-about-seal {
    display: flex; gap: 10px; align-items: flex-start;
    margin-top: 16px; padding: 13px 14px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius-sm);
    font-size: 12.5px; line-height: 1.5;
    color: var(--z-ink-2);
}
.z-about-seal svg { flex: none; color: var(--z-gold-deep); margin-top: 1px; }

/* --- narrower ------------------------------------------------------------- */

@media (max-width: 1120px) {
    .z-about-body { grid-template-columns: minmax(0, 1fr) 330px; gap: 40px; }
}
@media (max-width: 900px) {
    .z-about-body { grid-template-columns: minmax(0, 1fr); gap: 34px; }
    .z-book { position: static; }
    .z-about-main .z-prose { font-size: 15.5px; }
    .z-about-lede { font-size: 17px !important; }
}
@media (max-width: 620px) {
    .z-tiles,
    .z-tiles.is-plain { grid-template-columns: repeat(2, 1fr); }
    .z-about-lede { font-size: 16px !important; }
    /* Two lines beat a squeezed two-column row on a phone. */
    .z-auth-list li { grid-template-columns: 26px minmax(0, 1fr); gap: 4px 12px; }
    .z-auth-ic { grid-row: span 2; align-self: start; margin-top: 3px; }
    .z-auth-where { text-align: left; }
}
@media (max-width: 460px) {
    .z-tiles,
    .z-tiles.is-plain { grid-template-columns: 1fr; }
    .z-tiles.is-plain { gap: 0; }
}

/* --------------------------------------------------------------------------
   Terms & Conditions
   The About shell with a different rail: twenty-five clauses are read by
   jumping to one and reading around it, so the rail holds a standing index
   rather than tabs, and every clause stays on the page.
   -------------------------------------------------------------------------- */

/* The clause number, in the heading's own gold rather than a filled badge —
   a solid chip beside twenty-five headings reads as a list of buttons. */
.z-block-n {
    display: inline-block;
    min-width: 1.9em;
    font-family: var(--z-display);
    font-size: .92em; font-weight: 600;
    color: var(--z-gold-deep);
    font-variant-numeric: tabular-nums;
}

/* The preamble: above the tab bar and owned by no tab, because it says what the
   terms apply to rather than being one of them. No panel — the panel starts at
   the bar. */
.z-terms-lead { margin-bottom: 26px; }
.z-terms-lead h2 {
    font-size: 23px;
    letter-spacing: .07em;
    text-transform: uppercase;
    padding-bottom: 12px;
    margin: 0 0 18px;
    border-bottom: 1px solid var(--z-line);
    position: relative;
}
.z-terms-lead h2::after {
    content: "";
    position: absolute; left: 0; bottom: -1px; width: 56px; height: 2px;
    background: var(--z-gold);
}

/* --- the index ------------------------------------------------------------ */

/* The index and the note under it stick together, never separately: a sticky
   element moves relative to its siblings, so a sticky index slid down over the
   note that follows it and hid it. */
.z-rail-stick { position: sticky; top: 84px; }

.z-toc {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    box-shadow: var(--z-shadow-sm);
    padding: 18px;
}
.z-toc h2 {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 12px; padding-bottom: 11px;
    font-family: var(--z-body);
    font-size: 11.5px; font-weight: 700;
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--z-gold-deep);
    border-bottom: 1px solid var(--z-line-soft);
}
.z-toc h2 svg { flex: none; }

/* All twenty-five at once, with no scroller of its own — an index is a map, and
   a map you have to scroll to read is a worse map. The rows are set tight
   enough that the whole list clears about 710px, so it fits a sticky card on a
   normal desktop; the short-viewport rule at the bottom of this block handles
   the screens where it does not. */
.z-toc ol {
    counter-reset: toc;
    list-style: none;
    margin: 0; padding: 0;
}
.z-toc li { counter-increment: toc; }
.z-toc a {
    display: grid;
    grid-template-columns: 1.9em minmax(0, 1fr);
    gap: 4px;
    padding: 4px 0;
    font-size: 13px; line-height: 1.32;
    color: var(--z-ink-2);
    border-radius: 5px;
}
.z-toc a::before {
    content: counter(toc);
    color: var(--z-ink-3);
    font-variant-numeric: tabular-nums;
}
.z-toc a:hover { color: var(--z-green); }
.z-toc a:hover::before { color: var(--z-gold-deep); }
/* Clauses on a tab that is not open. Dimmed, never hidden: the index is the map
   of the whole document, and dropping twenty of its twenty-five entries every
   time a tab changes would make it useless as one. */
.z-toc a.is-off { color: var(--z-ink-3); opacity: .62; }
.z-toc a.is-off:hover { color: var(--z-green); opacity: 1; }
/* :target styles the clause the reader has jumped to, not the link, so the
   rail cannot claim a position the page is not actually at. */
.z-block:target > h2 { color: var(--z-gold-deep); }

.z-toc-note { margin-top: 14px; }
.z-toc-note p { font-size: 13px; }

/* --- the two itinerary sequences ------------------------------------------ */

.z-seq {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
    margin: 4px 0 18px;
}
.z-seq-opt {
    display: inline-flex; align-items: center; gap: 9px;
    padding: 11px 17px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius-sm);
    font-size: 15px; font-weight: 600; color: var(--z-green);
}
.z-seq-opt svg { flex: none; color: var(--z-gold-deep); }
.z-seq-opt i { font-style: normal; color: var(--z-gold-deep); padding: 0 2px; }
.z-seq-or {
    font-size: 11.5px; font-weight: 700;
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--z-ink-3);
}

/* A sticky box taller than the viewport pins at `top` and its lower half can
   never be scrolled to — the one failure mode worse than an inner scrollbar.
   Index plus note clears about 830px, so below the height that needs it stops
   sticking and travels with the page. Either way everything is readable and
   nothing scrolls inside the card. */
@media (max-height: 940px) {
    .z-rail-stick { position: static; }
}

@media (max-width: 900px) {
    /* Stacked, the rail sits under the clauses, where sticky means nothing. */
    .z-rail-stick { position: static; }
}

/* --------------------------------------------------------------------------
   Privacy Policy — the grievance contact block
   Everything else on this page is shared with /terms.
   -------------------------------------------------------------------------- */

.z-privacy-contact {
    padding: 20px 22px;
    margin-bottom: 4px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
}
.z-privacy-contact-name {
    margin: 0;
    font-family: var(--z-display);
    font-size: 21px; font-weight: 600; letter-spacing: .03em;
    color: var(--z-green);
}
.z-privacy-contact-sub {
    margin: 3px 0 0;
    font-size: 11px; font-weight: 700;
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-privacy-contact address {
    margin: 14px 0 0;
    font-style: normal;
    font-size: 14.5px; line-height: 1.65;
    color: var(--z-ink-2);
}
.z-privacy-reach {
    display: flex; flex-wrap: wrap; gap: 10px 26px;
    margin-top: 16px; padding-top: 15px;
    border-top: 1px solid var(--z-line-soft);
}
.z-privacy-reach a {
    display: inline-flex; align-items: center; gap: 9px;
    font-size: 14px; font-weight: 500; color: var(--z-green);
}
.z-privacy-reach a:hover { color: var(--z-gold-deep); }
.z-privacy-reach svg { flex: none; color: var(--z-gold-deep); }

/* --------------------------------------------------------------------------
   Terms / Privacy — the tab bar
   Six tabs whose labels are phrases ("Documents & Security") rather than the
   single words a tour page carries ("Gallery", "FAQs"). At the shared 400px
   rail the content column is about 896px and these need roughly 1017px, so the
   bar overflowed the panel it sits on. Two changes, both scoped: give the
   column the width back, and set the tabs a size down.
   -------------------------------------------------------------------------- */

/* The document rail holds an index and a note — it does not need the 400px the
   About rail's brand card and buttons do. 60px back to the tabs. */
.z-about-body.is-doc { grid-template-columns: minmax(0, 1fr) 340px; }

.z-tabs.is-doc { gap: 5px; padding: 0 12px; }
.z-tabs.is-doc .z-tab {
    padding: 10px 14px 11px;
    font-size: 13.5px;
    gap: 7px;
}
.z-tabs.is-doc .z-tab.is-active { padding-bottom: 12px; }

/* Below this the six phrases stop fitting however they are set, so the bar
   becomes a scroller — the same fallback .z-tabs already uses on a phone. The
   active tab's 1px overlap into the panel cannot survive overflow clipping, so
   it is dropped here too rather than left half-painted. */
@media (max-width: 1180px) {
    .z-tabs.is-doc {
        overflow-x: auto;
        overflow-y: hidden;
        scrollbar-width: none;
    }
    .z-tabs.is-doc::-webkit-scrollbar { display: none; }
    .z-tabs.is-doc .z-tab.is-active { margin-bottom: 0; padding-bottom: 11px; }
}

@media (max-width: 1120px) {
    .z-about-body.is-doc { grid-template-columns: minmax(0, 1fr) 310px; }
}
@media (max-width: 900px) {
    .z-about-body.is-doc { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   Cancellation Policy — the charge schedule
   Six rows of window against percentage. As a bullet list the windows and the
   charges never line up in a column, so comparing two rows means reading two
   sentences; here the charge is pulled into its own column and tinted, so the
   cost of leaving it late is legible before a word is read.
   -------------------------------------------------------------------------- */

.z-tiers { list-style: none; margin: 0; padding: 0; }
.z-tiers li {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 2px 18px;
    padding: 14px 16px;
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    background: var(--z-surface);
    /* The tone band: a bar down the leading edge rather than a wash behind the
       row, which at six rows would read as six alerts. */
    border-left: 3px solid var(--z-tier-c, var(--z-line));
}
.z-tiers li + li { margin-top: 8px; }

.z-tiers li.is-ok   { --z-tier-c: var(--z-open); }
.z-tiers li.is-warn { --z-tier-c: var(--z-gold); }
.z-tiers li.is-bad  { --z-tier-c: var(--z-sold); }

.z-tier-when {
    font-size: 15px; font-weight: 600; color: var(--z-green);
}
.z-tier-pct {
    font-family: var(--z-display);
    font-size: 21px; font-weight: 600;
    color: var(--z-tier-c, var(--z-green));
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    text-align: right;
}
/* Row two, under the window and clear of the percentage column. */
.z-tier-note {
    grid-column: 1;
    font-size: 13px; line-height: 1.5; color: var(--z-ink-3);
}

@media (max-width: 560px) {
    .z-tiers li { grid-template-columns: minmax(0, 1fr); }
    .z-tier-pct { text-align: left; font-size: 19px; }
    .z-tier-note { grid-column: 1; }
}

/* --------------------------------------------------------------------------
   Footer link columns — glyph + label
   The label wraps under itself rather than under the glyph: inline-flex with a
   fixed, non-shrinking icon is what keeps a two-word link like "Upcoming
   Departures" aligned to one text edge when the column narrows.
   -------------------------------------------------------------------------- */

.z-footer-links a {
    display: inline-flex;
    align-items: center;
    gap: 9px;
}
.z-footer-links svg {
    flex: none;
    color: var(--z-gold-light);
    opacity: .78;
    transition: opacity .18s ease, color .18s ease;
}
.z-footer-links a:hover svg { opacity: 1; color: var(--z-gold); }

/* --------------------------------------------------------------------------
   My Enquiries
   Wears mybooking.php's shell — .z-mybk-top, .z-mybk-grid, .z-bkc — so the two
   pages read as one pair. Only what an enquiry has and a booking does not is
   added here: four states of its own, and the line of what was asked.
   -------------------------------------------------------------------------- */

/* The rail's status dots. Named for what a customer sees rather than borrowing
   the booking page's confirmed/cancelled keys, which would have put "Awaiting
   reply" behind a class called is-pending and left the next person guessing. */
.z-mybk-row-ic.is-new      { background: var(--z-few-bg);    color: var(--z-few); }
.z-mybk-row-ic.is-progress { background: var(--z-teal-wash); color: var(--z-teal); }
.z-mybk-row-ic.is-booked   { background: var(--z-open-bg);   color: var(--z-open); }
.z-mybk-row-ic.is-closed   { background: var(--z-sold-bg);   color: var(--z-sold); }

/* A closed enquiry is dimmed the way a cancelled booking is, and lifts on
   hover so it can still be read. */
.z-bkc.is-closed { opacity: .78; }
.z-bkc.is-closed:hover { opacity: 1; }

/* What they actually wrote, under the card's columns. Clamped in PHP to 240
   characters — this is a reminder of the enquiry, not a transcript. */
.z-enq-msg {
    display: flex; align-items: flex-start; gap: 9px;
    margin: 2px 16px 16px;
    padding: 11px 14px;
    background: var(--z-marble);
    border: 1px solid var(--z-line-soft);
    border-radius: var(--z-radius-sm);
    font-size: 13px; line-height: 1.55; color: var(--z-ink-2);
}
.z-enq-msg svg { flex: none; color: var(--z-gold-deep); margin-top: 2px; }
/* The message is a flex item, and a flex item's min-width is auto — it will
   not shrink below its own min-content. One enquiry whose text carried an
   unbreakable run measured 542px inside a 358px card and pushed the whole
   page sideways: 207px of horizontal scroll on a 390px phone, which then
   dragged the fixed bottom bar out with it. min-width lets it shrink and
   overflow-wrap breaks the run that would not. */
.z-enq-msg > span { min-width: 0; overflow-wrap: anywhere; }

/* The rail's cross-link to the bookings page. */
.z-mybk-panel .z-btn-block { width: 100%; justify-content: center; }

/* --------------------------------------------------------------------------
   UPI QR — "I have already paid", and the verdict it draws
   A third state between the green tick and the red cross: filed, not
   confirmed. It must not borrow either of their colours — a customer who sees
   a green tick believes the money is settled.
   -------------------------------------------------------------------------- */

.z-pay-qr-paid {
    display: inline-flex; align-items: center; gap: 7px;
    margin-top: 2px;
    padding: 7px 14px;
    background: none;
    border: 1px dashed var(--z-line-gold);
    border-radius: 999px;
    font: inherit; font-size: 12.5px; font-weight: 600;
    color: var(--z-gold-deep);
    cursor: pointer;
    transition: background-color .18s ease, border-color .18s ease;
}
.z-pay-qr-paid:hover { background: var(--z-surface); border-color: var(--z-gold); }
.z-pay-qr-paid:disabled { opacity: .6; cursor: default; }
.z-pay-qr-paid svg { flex: none; }

/* Amber, and the ring alone — no tick and no cross. Neither mark is honest
   here: nothing has been confirmed and nothing has failed. */
.z-pay-qr-done.is-wait { color: var(--z-few); }
.z-pay-qr-done.is-wait .z-qr-seal-tick,
.z-pay-qr-done.is-wait .z-qr-seal-x1,
.z-pay-qr-done.is-wait .z-qr-seal-x2 { display: none; }
.z-pay-qr-done.is-wait .z-qr-seal-ring { opacity: .55; }

/* ==========================================================================
   Track a Booking  —  zaereen/track-booking.php

   The public status page: a reference and a mobile number in, one booking
   out.

   ONE STATE AT A TIME. The page draws either the lookup or a result, never
   both — see the note in track-booking.php.

   The lookup half is not styled here at all: it reuses .z-login, the wall and
   panel the sign-in page is built from, because a page that is one field pair
   on an empty cream ground looks unfinished however well the box is drawn.
   Only the form INSIDE that panel is below (.z-tk-find and friends), and the
   result is a card of its own (.z-tkr).
   ========================================================================== */

.z-tk { width: min(1080px, 100%); margin: 0 auto; }

/* Section headings, shared by "Progress" and the reference guide. Small caps
   in gold rather than another serif line: the titles under them are the
   serif, and two display faces stacked read as two competing headings. */
.z-tk-h {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 14px;
    font-family: var(--z-body);
    font-size: 11.5px; font-weight: 600; letter-spacing: .14em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-tk-h svg { flex: none; }

/* --- the lookup, inside the .z-login panel -------------------------------
   No box of its own: .z-login-gate is already the surface, and two nested
   cards read as a mistake. */

.z-tkhero { margin-top: 0; }

.z-tk-eyebrow {
    margin: 0 0 7px;
    font-size: 10.5px; font-weight: 600; letter-spacing: .18em;
    text-transform: uppercase; color: var(--z-gold-deep);
}
.z-tk-find h3 {
    margin: 0 0 8px;
    font-family: var(--z-display); font-size: 29px; font-weight: 600;
    letter-spacing: .01em; line-height: 1.15; color: var(--z-green);
}
.z-tk-lede {
    margin: 0 0 24px;
    font-size: 14.5px; line-height: 1.65; color: var(--z-ink-2);
}

/* The two fields stacked and the button along the full width beneath them.
   The panel is a column roughly 420px wide, and two fields side by side in it
   leave neither wide enough to show a reference as it is typed. */
.z-tk-form { display: grid; gap: 16px; }
.z-tk-form .z-field input { padding: 13px 14px; font-size: 15.5px; }
/* The same focus ring the reserve form and the modals draw — a translucent
   gold halo, not this block's own invention. */
.z-tk-form .z-field input:focus {
    outline: none;
    border-color: var(--z-gold);
    box-shadow: 0 0 0 3px rgba(193, 154, 63, .18);
}
.z-tk-form .z-btn {
    width: 100%; justify-content: center;
    padding: 14px 22px;
    font-size: 14px; letter-spacing: .09em;
}

.z-tk-foot {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 8px 18px;
    margin-top: 22px; padding-top: 16px;
    border-top: 1px solid var(--z-line-soft);
    font-size: 12.5px; color: var(--z-ink-3);
}
.z-tk-foot span { display: inline-flex; align-items: flex-start; gap: 7px; }
.z-tk-foot svg  { flex: none; margin-top: 1px; color: var(--z-gold-deep); }
.z-tk-foot a {
    color: var(--z-teal); font-weight: 600; text-decoration: none;
    border-bottom: 1px solid transparent;
}
.z-tk-foot a:hover { border-bottom-color: currentColor; }

/* The miss message, above the form inside the panel. */
.z-tk-err { margin-bottom: 22px; }

/* The wall's headline is an h2 here, not the h1 it is on the sign-in page —
   the page already has one, up in the pagehead. Same type, different tag. */
.z-tkhero .z-login-brand h2 {
    margin: 0 0 14px;
    font-family: var(--z-display);
    font-size: clamp(28px, 2.9vw, 38px);
    font-weight: 600; letter-spacing: .035em; line-height: 1.14;
    color: #fdf8ec;
    text-wrap: balance;
}

/* --- the result: one record ---------------------------------------------
   Head, facts, travellers, progress, footer — one card, in that order. It was
   four separate boxes stacked with air between them, which read as four
   unrelated widgets rather than as one document about one booking.
   -------------------------------------------------------------------------- */

/* A plain GET back to the empty page, set above the record like the back link
   on a file. The arrow icon only exists pointing right. */
.z-tk-back { margin-bottom: 14px; }
.z-tk-back a {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 13px; font-weight: 600; color: var(--z-ink-3);
    text-decoration: none;
}
.z-tk-back svg { flex: none; transform: scaleX(-1); }
.z-tk-back a:hover { color: var(--z-green); }

.z-tkr {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 18px;
    overflow: hidden;               /* keeps the dark head inside the radius */
    box-shadow: var(--z-shadow-lg);
}

/* The head is the sign-in wall's ground, at the height of a header band: the
   same dome-green gradient, the same blind arcading watermark and the same
   merlons along the top edge. */
.z-tkr-head {
    position: relative;
    display: flex; align-items: flex-start; justify-content: space-between;
    flex-wrap: wrap; gap: 18px 26px;
    padding: 26px 30px 24px;
    background:
        radial-gradient(120% 90% at 12% 0%, rgba(31, 96, 71, .55) 0%, rgba(13, 44, 34, 0) 60%),
        linear-gradient(158deg, var(--z-green-2) 0%, var(--z-green) 62%);
    color: var(--z-cream);
    isolation: isolate;
}
.z-tkr-head::before {
    content: "";
    position: absolute; inset: 0;
    background-repeat: repeat;
    background-size: 62px 62px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='62' height='62' viewBox='0 0 62 62'%3E%3Cpath d='M31 8c-7 0-12 5-12 12v18c0 5 5 9 12 9s12-4 12-9V20c0-7-5-12-12-12z' fill='none' stroke='%23c19a3f' stroke-width='1.1'/%3E%3C/svg%3E");
    opacity: .13;
    z-index: -1;
    pointer-events: none;
}
.z-tkr-head::after {
    content: "";
    position: absolute; top: 0; left: 0; right: 0; height: 12px;
    background-repeat: repeat-x;
    background-size: auto 12px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='14' viewBox='0 0 24 18'%3E%3Cpath d='M0,18 L0,13 L4,13 L4,8 L8,8 L8,3 L12,0 L16,3 L16,8 L20,8 L20,13 L24,13 L24,18 Z' fill='%23c19a3f'/%3E%3C/svg%3E");
    opacity: .45;
    transform: scaleY(-1);
    pointer-events: none;
}

.z-tkr-id { flex: 1 1 340px; min-width: 0; }
.z-tkr-kind {
    display: inline-flex; align-items: center; gap: 7px;
    margin-bottom: 10px;
    padding: 4px 12px; border-radius: 100px;
    background: rgba(227, 200, 134, .13);
    border: 1px solid rgba(227, 200, 134, .32);
    font-size: 10px; font-weight: 600; letter-spacing: .13em;
    text-transform: uppercase; color: var(--z-gold-light);
}
.z-tkr-kind svg { flex: none; }
.z-tkr-id h2 {
    margin: 0 0 6px;
    font-family: var(--z-display); font-size: 27px; font-weight: 600;
    letter-spacing: .02em; line-height: 1.2; color: #fdf8ec;
    text-wrap: balance;
}
.z-tkr-id p {
    display: flex; align-items: center; gap: 7px;
    margin: 0;
    font-size: 13.5px; color: rgba(242, 233, 213, .78);
}
.z-tkr-id p svg { flex: none; color: var(--z-gold-light); opacity: .85; }

/* The reference and the verdict, right-aligned as a pair — the two things
   somebody reads a tracking page to see. */
.z-tkr-meta {
    flex: none;
    display: flex; flex-direction: column; align-items: flex-end; gap: 11px;
    text-align: right;
}
.z-tkr-ref small {
    display: block; margin-bottom: 3px;
    font-size: 9.5px; font-weight: 600; letter-spacing: .14em;
    text-transform: uppercase; color: rgba(242, 233, 213, .55);
}
.z-tkr-ref b {
    font-family: var(--z-display); font-size: 25px; font-weight: 600;
    letter-spacing: .06em; color: var(--z-gold-light);
    font-variant-numeric: tabular-nums;
}

/* AUTO-FIT, not a fixed five. An agent booking withholds the two money cells
   and a fixed grid left the row with two empty columns hanging off it. The
   1px gap over a --z-line ground is what draws the hairlines between cells. */
.z-tkr-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1px;
    background: var(--z-line);
    border-bottom: 1px solid var(--z-line);
}
.z-tkr-fact { padding: 14px 18px; background: var(--z-marble); }
.z-tkr-fact small {
    display: block; margin-bottom: 3px;
    font-size: 9.5px; font-weight: 600; letter-spacing: .12em;
    text-transform: uppercase; color: var(--z-ink-3);
}
.z-tkr-fact b {
    font-size: 15px; font-weight: 600; color: var(--z-green);
    font-variant-numeric: tabular-nums;
}
.z-tkr-fact b.is-owed  { color: var(--z-few); }
.z-tkr-fact b.is-clear { color: var(--z-open); }

.z-tkr-pax {
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
    padding: 16px 30px 0;
}
.z-tkr-pax-lbl {
    display: inline-flex; align-items: center; gap: 7px;
    margin-right: 4px;
    font-size: 10px; font-weight: 600; letter-spacing: .12em;
    text-transform: uppercase; color: var(--z-ink-3);
}
.z-tkr-pax-lbl svg { flex: none; color: var(--z-gold-deep); }
.z-tkr-name {
    padding: 4px 12px; border-radius: 100px;
    background: var(--z-marble); border: 1px solid var(--z-line);
    font-size: 12.5px; color: var(--z-ink-2);
}

.z-tkr-body { padding: 22px 30px 4px; }

.z-tkr-foot {
    display: flex; align-items: center; flex-wrap: wrap; gap: 14px 18px;
    padding: 16px 30px;
    background: var(--z-cream);
    border-top: 1px solid var(--z-line);
}
.z-tkr-note {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 13px; font-weight: 500; color: var(--z-few);
}
.z-tkr-note.is-done { color: var(--z-open); }
.z-tkr-note svg { flex: none; }
/* What is still owed, given the weight of the thing that needs doing. */
.z-tkr-owed {
    padding: 7px 15px;
    background: var(--z-gold-wash); border: 1px solid var(--z-line-gold);
    border-radius: 11px;
}
.z-tkr-owed small {
    display: block;
    font-size: 9.5px; font-weight: 600; letter-spacing: .12em;
    text-transform: uppercase; color: var(--z-ink-3);
}
.z-tkr-owed b {
    font-family: var(--z-display); font-size: 21px; font-weight: 600;
    color: #91600f; font-variant-numeric: tabular-nums;
}
.z-tkr-acts { display: flex; flex-wrap: wrap; gap: 10px; margin-left: auto; }

/* --- the progress strip --------------------------------------------------
   A vertical list, not a horizontal stepper. Each note carries a whole
   sentence — "Rs 2 received, Rs 2,84,998 still to pay by 12 Oct 2026" — and a
   five-column stepper would set every one of them in a 150px column.

   The rail is drawn by each dot's ::before rather than by one line behind the
   list, so it cannot fall out of alignment with the dots at any width, and
   the last step simply does not draw one. */

.z-tk-steps { list-style: none; margin: 0; padding: 0; }
.z-tk-step {
    position: relative;
    display: flex; align-items: flex-start; gap: 14px;
    padding-bottom: 20px;
}
.z-tk-step:last-child { padding-bottom: 4px; }

.z-tk-step-dot {
    position: relative; z-index: 1;
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; margin-top: 1px;
    border-radius: 50%;
    background: var(--z-surface);
    border: 2px solid var(--z-line-strong);
    color: #fdf8ec;
}
.z-tk-step-dot svg { width: 12px; height: 12px; }

/* The rail, hung off every dot except the last. */
.z-tk-step:not(:last-child) .z-tk-step-dot::before {
    content: "";
    position: absolute; top: 20px; left: 50%;
    width: 2px; height: calc(100% + 20px);
    transform: translateX(-50%);
    background: var(--z-line);
}

.z-tk-step-body b {
    display: block;
    font-size: 14.5px; font-weight: 600; color: var(--z-green);
    margin-bottom: 2px;
}
.z-tk-step-body p {
    margin: 0;
    font-size: 13px; line-height: 1.55; color: var(--z-ink-2);
}

/* Behind us: filled green, and the rail under it filled too, so the strip
   reads as a line coloured in as far as the booking has actually got. */
.z-tk-step.is-done .z-tk-step-dot { background: var(--z-open); border-color: var(--z-open); }
.z-tk-step.is-done .z-tk-step-dot::before { background: var(--z-open); opacity: .45; }

/* Where it is sitting right now. Amber — the colour "pending" carries
   everywhere else on the site — with a halo, so the eye lands here first. */
.z-tk-step.is-now .z-tk-step-dot {
    background: var(--z-few); border-color: var(--z-few);
    box-shadow: 0 0 0 5px var(--z-few-bg);
}
.z-tk-step.is-now .z-tk-step-body b { color: var(--z-few); }

/* Not started: an outline dot and a quieter heading. This is information
   about the future, not about the booking. */
.z-tk-step.is-todo .z-tk-step-body b { color: var(--z-ink-2); }

/* A step this booking will never reach. Struck through rather than dropped: a
   cancelled booking whose strip simply stops after three steps looks like a
   page that failed to finish rendering. */
.z-tk-step.is-off { opacity: .6; }
.z-tk-step.is-off .z-tk-step-dot { border-style: dashed; }
.z-tk-step.is-off .z-tk-step-body b { color: var(--z-ink-3); text-decoration: line-through; }

.z-tk-asof {
    display: flex; align-items: center; gap: 7px;
    margin: 12px 0 0; padding: 12px 0 14px;
    border-top: 1px solid var(--z-line-soft);
    font-size: 11.5px; letter-spacing: .04em; color: var(--z-ink-3);
    font-variant-numeric: tabular-nums;
}
.z-tk-asof svg { flex: none; opacity: .7; }

/* --- where to find your reference ---------------------------------------
   Three tiles, one per product. This was a bulleted list in a dashed box,
   which read as small print rather than as the help it is. */

.z-tk-guide { margin-top: 40px; }
.z-tk-guide-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
}
.z-tk-guide-card {
    padding: 18px 18px 16px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    box-shadow: var(--z-shadow-sm);
}
.z-tk-guide-ic {
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; margin-bottom: 11px;
    border-radius: 10px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    color: var(--z-gold-deep);
}
.z-tk-guide-card b {
    display: block; margin-bottom: 8px;
    font-size: 14px; font-weight: 600; color: var(--z-green);
}
.z-tk-guide-card code {
    display: inline-block; margin-bottom: 9px;
    padding: 3px 10px; border-radius: 6px;
    background: var(--z-marble); border: 1px solid var(--z-line);
    font-family: var(--z-body); font-size: 12px; font-weight: 600;
    letter-spacing: .08em; color: var(--z-ink-2);
}
.z-tk-guide-card p {
    margin: 0;
    font-size: 12.5px; line-height: 1.6; color: var(--z-ink-3);
}

/* --- narrow -------------------------------------------------------------- */

@media (max-width: 860px) {
    .z-tk-guide-grid { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
    .z-tk-find h3 { font-size: 25px; }
    .z-tk-lede { font-size: 14px; margin-bottom: 20px; }
    .z-tk-foot { justify-content: flex-start; }

    .z-tkr-head { padding: 22px 18px 20px; }
    .z-tkr-id h2 { font-size: 22px; }
    /* The reference drops under the name rather than clinging to a right edge
       that is no longer there. */
    .z-tkr-meta { align-items: flex-start; text-align: left; }
    .z-tkr-ref b { font-size: 21px; }

    .z-tkr-pax  { padding: 14px 18px 0; }
    .z-tkr-body { padding: 18px 18px 2px; }
    .z-tkr-foot { padding: 14px 18px; }
    .z-tkr-acts { margin-left: 0; width: 100%; }
    .z-tkr-acts .z-btn { flex: 1 1 100%; justify-content: center; }
}


/* --------------------------------------------------------------------------
   About the destination + its FAQs — the holidays listing

   The band at the foot of /holidays/karbala-tours/, carrying the two things
   the Oxford destination page has always had and this listing did not: the
   write-up, and the questions people ask.

   TWO COLUMNS, and NOT .z-incex. That grid is the same shape today, but it
   belongs to inclusions/exclusions and already carries a :has(.z-incs)
   override that collapses it to one column — borrowing it here would mean a
   change made for an inclusions list silently re-laying out a page about
   Karbala. Its own class costs four lines.

   FAQ LEFT, ABOUT RIGHT on a wide screen, matching the Oxford page. The DOM
   order is About FIRST and the columns are swapped with `order`, so the
   single-column stack a phone gets reads the way it should: what this place
   is, and then the questions about it. A visitor who has never heard of
   Karbala should not meet "Do I need a visa?" before the description.
   -------------------------------------------------------------------------- */

.z-destinfo {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 34px;
    align-items: start;
}

.z-destinfo > .z-destinfo-faq   { order: 1; }
.z-destinfo > .z-destinfo-about { order: 2; }

/* ONE COLUMN, when only one of the pair has anything in it. Not every place
   has both: Umrah Tours has ten questions and no write-up, Egypt Tours has the
   write-up and no questions, and Armenia's visa has one FAQ and nothing else.
   Left in the two-column grid, the single card takes the left half and the
   other half stays empty — which does not read as "there is only one of
   these", it reads as the second one having failed to load.

   Centred and capped rather than stretched full width: 1200px of running text
   is 150 characters a line, and the whole point of a written introduction is
   that somebody reads it.

   A CLASS AND NOT :has(> :only-child). The selector would do this without the
   pages being told anything, but every page that builds this band already
   knows which halves it is rendering — it decides in the `if` immediately
   above — so the class costs one ternary and works in every browser. */
.z-destinfo.is-single { grid-template-columns: minmax(0, 780px); justify-content: center; }

/* The heading pair inside each column. .z-section-head is centred and sized
   for a full-width band; these sit at the head of a half-width column, so
   they are left-aligned and a step smaller. */
.z-destinfo-head { margin-bottom: 22px; }
.z-destinfo-head h2 {
    font-size: 26px;
    line-height: 1.25;
    margin: 0;
    color: var(--z-green);
}
.z-destinfo-head .z-eyebrow { margin-bottom: 8px; }

/* A CARD, as the Oxford page has it (.about-card-v2) — and here it also earns
   its keep structurally. The write-up is clipped with a fade below, and a
   gradient has to end in the colour actually behind it: the page ground is
   --z-cream UNDER TWO REPEATING TEXTURES, so a fade to flat cream would show
   its own rectangle against the pattern. On a flat surface the fade is
   invisible, which is the whole point of it. */
.z-destinfo-card {
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius);
    padding: 26px;
}

/* Where the place is. The pin sits on the text baseline rather than the line
   box, or it rides high next to a two-line label. */
.z-destinfo-place {
    display: flex;
    align-items: flex-start;
    gap: 7px;
    margin: 10px 0 0;
    font-size: 13.5px;
    color: var(--z-ink-2);
}
.z-destinfo-place svg { flex: none; margin-top: 2px; color: var(--z-gold-deep); }

.z-destinfo-about .z-prose { margin: 0; }

/* ---- read more ----------------------------------------------------------
   The write-up runs long — Karbala's is four thousand characters — and an
   unbroken wall of it pushes the FAQ column's foot a screen below its head.
   Clipped, faded, and opened by the control under it.

   A CHECKBOX AND NOT <details>, which is what this wanted to be. A closed
   <details> hides every child that is not its <summary>: there is no clipped
   preview to fade, only nothing, and the UA rule that hides them is not
   reliably overridable from author CSS across browsers. The checkbox gives
   the same no-JS behaviour with a preview — and the same keyboard operation,
   because a real checkbox with a real <label> is focusable and togglable on
   Space without a line of script.

   The input is moved off-screen rather than display:none'd: display:none
   takes it out of the focus order, and then the control cannot be reached by
   keyboard at all. */
.z-destinfo-more { position: relative; }

.z-destinfo-chk {
    position: absolute;
    width: 1px; height: 1px;
    opacity: 0;
    margin: 0;
    pointer-events: none;
}

.z-destinfo-clip {
    position: relative;
    /* Tuned against the FAQ column beside it, not picked round: ten
       collapsed rows plus their heading run about 720px, and a 320px clip
       left the card ending less than halfway down with a column of empty
       cream under it — which reads as a layout fault rather than a
       deliberate trim. This lands the two columns within a row of each
       other on a wide screen. */
    max-height: 520px;
    overflow: hidden;
}

/* The fade only belongs over clipped text. Once it is open there is nothing
   below the fold to hint at, and leaving it there washes out the last two
   lines of the prose for no reason. */
.z-destinfo-clip::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 96px;
    background: linear-gradient(to bottom, rgba(255, 253, 247, 0), var(--z-surface) 72%);
    pointer-events: none;
}

.z-destinfo-chk:checked ~ .z-destinfo-clip { max-height: none; overflow: visible; }
.z-destinfo-chk:checked ~ .z-destinfo-clip::after { content: none; }

.z-destinfo-toggle {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 14px;
    cursor: pointer;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-destinfo-toggle:hover { color: var(--z-green); }

/* The focus ring belongs on the thing that LOOKS like the control. The input
   carrying focus is off-screen, so without this a keyboard user tabs onto it
   and nothing on the page changes. */
.z-destinfo-chk:focus-visible ~ .z-destinfo-toggle {
    outline: 2px solid var(--z-gold-deep);
    outline-offset: 3px;
    border-radius: 2px;
}

.z-destinfo-less { display: none; }
.z-destinfo-chk:checked ~ .z-destinfo-toggle .z-destinfo-less { display: inline; }
.z-destinfo-chk:checked ~ .z-destinfo-toggle .z-destinfo-open { display: none; }

@media (max-width: 980px) {
    /* One column, and the swap comes off with it — the DOM order is already
       About then FAQs, which is the order it should stack in. */
    .z-destinfo { grid-template-columns: 1fr; gap: 30px; }
    .z-destinfo > .z-destinfo-faq,
    .z-destinfo > .z-destinfo-about { order: 0; }
    .z-destinfo-head h2 { font-size: 23px; }
    .z-destinfo-card { padding: 22px; }
}

/* ===========================================================================
   LIVE FLIGHT SEARCH
   ---------------------------------------------------------------------------
   Three surfaces, all reading the same fares from TBO:

     .z-ts-pax / .z-ts-ac   additions to the hero's Flights tab, which searches
                            live fares now instead of filtering our charters
     .z-fr-*                the results page — its own search bar, the filter
                            rail, the fare cards, and the round-trip pair
     .z-fstep-*             the booking steps after it, which render shared
                            Oxford views inside Zaereen chrome

   A flight card is a horizontal object: an airline, a pair of times with a
   line between them, and a price. That shape is what the whole file below is
   arranged around, and it is why the results are a LIST and not the card grid
   the hotels and tours use — a fare is compared against the one under it, not
   browsed.
   ========================================================================= */

/* --- Hero: travellers & class popover --------------------------------------
   Four selects in a row is what a desk agent's screen looks like, not what
   somebody books a flight on. One button, and the selects behind it.

   The panel is only closed once script is here to reopen it (.is-js), so with
   scripting off it stands open and the selects submit exactly as they are.
   -------------------------------------------------------------------------- */
.z-ts-pax { position: relative; display: inline-flex; }

.z-ts-paxbtn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 40px;
    padding: 0 13px;
    background: var(--z-cream);
    border: 1px solid var(--z-line);
    border-radius: 999px;
    font-family: var(--z-body);
    font-size: 13px;
    font-weight: 600;
    color: var(--z-ink);
    cursor: pointer;
    white-space: nowrap;
}
.z-ts-paxbtn svg { flex: none; color: var(--z-gold-deep); }
.z-ts-paxbtn:hover { border-color: var(--z-gold); }
.z-ts-paxbtn:focus-visible { outline: 2px solid var(--z-gold); outline-offset: 2px; }

/* Without script the button is decoration the panel does not answer to, so it
   is not shown at all. */
.z-ts-pax:not(.is-js) .z-ts-paxbtn { display: none; }

.z-ts-paxpanel {
    display: grid;
    gap: 10px;
    padding: 14px;
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius-sm, 9px);
    box-shadow: var(--z-shadow-lg);
}
/* THE `hidden` ATTRIBUTE ONLY WORKS IF THE RULE ABOVE LETS IT.
   `[hidden] { display: none }` is a UA rule, and any class rule that sets
   `display` silently outranks it — so a panel styled `display: grid` ignores
   `panel.hidden = true` entirely and can never be closed. This stylesheet has
   no blanket `[hidden]` reset; every component that sets display pairs it with
   its own guard (.z-fx-swap, .z-gr-panel, .z-modal and the rest all do), and
   these two popovers must too. Without it the travellers panel stands open
   from first paint, over the fields beneath it, with a Done button that does
   nothing. */
.z-ts-paxpanel[hidden] { display: none; }
/* And the other half of that: the panel SHIPS hidden, so it cannot flash open
   before the script that owns it runs. When no script ever arrives, .is-js is
   never added and the panel is put back — these selects are the only way to
   state a party size, so they cannot be left switched off. */
.z-ts-pax:not(.is-js) .z-ts-paxpanel[hidden] { display: grid; }
.z-ts-pax.is-js .z-ts-paxpanel {
    position: absolute;
    z-index: 40;
    top: calc(100% + 8px);
    right: 0;
    min-width: 268px;
}
.z-ts-paxrow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
}
.z-ts-paxrow label {
    display: flex;
    flex-direction: column;
    font-size: 13px;
    font-weight: 600;
    color: var(--z-ink);
}
.z-ts-paxrow label small {
    font-size: 11px;
    font-weight: 400;
    color: var(--z-ink-3);
}
.z-ts-paxrow select {
    min-width: 96px;
    height: 34px;
    padding: 0 8px;
    background: var(--z-surface-2);
    border: 1px solid var(--z-line);
    border-radius: 7px;
    font-family: var(--z-body);
    font-size: 13px;
    color: var(--z-ink);
}
.z-ts-paxdone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 34px;
    background: var(--z-green);
    border: 0;
    border-radius: 7px;
    color: #f2e9d5;
    font-family: var(--z-body);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.z-ts-pax:not(.is-js) .z-ts-paxdone { display: none; }

/* --- Airport suggestions ----------------------------------------------------
   Shared shape for both bars. Absolutely positioned so the row does not jump
   as the list opens, and above the pickers, which are z-index 40 next door.
   -------------------------------------------------------------------------- */
.z-ts-ac, .z-fr-ac { position: relative; }

.z-ts-sugg, .z-fr-sugg {
    position: absolute;
    z-index: 60;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    max-height: 292px;
    overflow-y: auto;
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius-sm, 9px);
    box-shadow: var(--z-shadow-lg);
}
.z-ts-sugg button, .z-fr-sugg button {
    display: block;
    width: 100%;
    padding: 9px 13px;
    background: none;
    border: 0;
    border-bottom: 1px solid var(--z-line-soft);
    font-family: var(--z-body);
    font-size: 13px;
    color: var(--z-ink-2);
    text-align: left;
    cursor: pointer;
}
.z-ts-sugg button:last-child, .z-fr-sugg button:last-child { border-bottom: 0; }
.z-ts-sugg button b, .z-fr-sugg button b {
    display: inline-block;
    min-width: 38px;
    color: var(--z-green);
    font-weight: 700;
}
.z-ts-sugg button:hover, .z-fr-sugg button:hover { background: var(--z-gold-wash); color: var(--z-ink); }

/* The way back to the charters this tab used to search. */
.z-fx-groups {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--z-gold-deep);
    text-decoration: none;
}
.z-fx-groups svg { flex: none; }
.z-fx-groups:hover { color: var(--z-green); text-decoration: underline; }

/* --- Results page: the search, restated ------------------------------------
   Sticky, because filtering happens down the page and changing a date is the
   commonest thing a fare list makes somebody want to do.
   -------------------------------------------------------------------------- */
.z-fr-barwrap {
    position: sticky;
    top: 0;
    z-index: 30;
    padding: 14px 0;
    background: var(--z-cream);
    border-bottom: 1px solid var(--z-line);
}

.z-fr-bar { display: grid; gap: 11px; }

.z-fr-trip {
    display: inline-flex;
    gap: 4px;
    padding: 3px;
    background: var(--z-surface-2);
    border-radius: 999px;
    justify-self: start;
}

.z-fr-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px;
}

.z-fr-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1 1 168px;
    min-width: 0;
}
.z-fr-field > label {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--z-ink-3);
}
.z-fr-field > label svg { flex: none; color: var(--z-gold-deep); }
.z-fr-field input[type="text"],
.z-fr-field input[type="date"] {
    height: 42px;
    padding: 0 12px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm, 9px);
    font-family: var(--z-body);
    font-size: 14px;
    color: var(--z-ink);
    width: 100%;
}
.z-fr-field input:focus {
    outline: none;
    border-color: var(--z-gold);
    box-shadow: 0 0 0 3px var(--z-gold-wash);
}
.z-fr-field.is-date { flex: 0 1 168px; }
/* The Return field is carried hidden on a one-way rather than removed, so the
   date survives a mind changed twice — which only works if `hidden` beats the
   `display: flex` above. */
.z-fr-field[hidden] { display: none; }

.z-fr-swap {
    flex: none;
    width: 34px; height: 34px;
    margin-bottom: 4px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 50%;
    color: var(--z-gold-deep);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.z-fr-swap svg { transform: rotate(90deg); }
.z-fr-swap:hover { border-color: var(--z-gold); color: var(--z-green); }
/* Ships hidden and is revealed by script, so without the guard it would sit
   there doing nothing on a page with no JavaScript. */
.z-fr-swap[hidden] { display: none; }

.z-fr-pax { position: relative; flex: 0 1 210px; }
.z-fr-paxbtn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    height: 42px;
    padding: 0 12px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm, 9px);
    font-family: var(--z-body);
    font-size: 14px;
    color: var(--z-ink);
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
}
.z-fr-paxbtn svg { flex: none; color: var(--z-gold-deep); }
.z-fr-pax:not(.is-js) .z-fr-paxbtn { display: none; }

.z-fr-paxpanel {
    display: grid;
    gap: 10px;
    padding: 14px;
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius-sm, 9px);
    box-shadow: var(--z-shadow-lg);
}
/* See .z-ts-paxpanel[hidden] above for why both of these are not optional. */
.z-fr-paxpanel[hidden] { display: none; }
.z-fr-pax:not(.is-js) .z-fr-paxpanel[hidden] { display: grid; }
.z-fr-pax.is-js .z-fr-paxpanel {
    position: absolute;
    z-index: 50;
    top: calc(100% + 6px);
    left: 0;
    min-width: 258px;
}
.z-fr-paxrow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
}
.z-fr-paxrow label {
    display: flex;
    flex-direction: column;
    font-size: 13px;
    font-weight: 600;
    color: var(--z-ink);
}
.z-fr-paxrow label small { font-size: 11px; font-weight: 400; color: var(--z-ink-3); }
.z-fr-paxrow select {
    min-width: 92px;
    height: 34px;
    padding: 0 8px;
    background: var(--z-surface-2);
    border: 1px solid var(--z-line);
    border-radius: 7px;
    font-family: var(--z-body);
    font-size: 13px;
}

.z-fr-go {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 42px;
    padding: 0 22px;
    background: var(--z-green);
    border: 0;
    border-radius: var(--z-radius-sm, 9px);
    color: #f2e9d5;
    font-family: var(--z-body);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}
.z-fr-go svg { flex: none; color: var(--z-gold-light); }
.z-fr-go:hover { background: var(--z-green-2); }

.z-fr-nonstop { justify-self: start; }

/* --- Results page: rail + list ---------------------------------------------- */
.z-fr-section { padding-top: 26px; }

.z-fr-layout {
    display: grid;
    grid-template-columns: 258px minmax(0, 1fr);
    gap: 26px;
    align-items: start;
}

.z-fr-filters { position: sticky; top: 148px; }
/* THE SHARED FIELD RULES DO NOT MEAN THESE.
   `.z-field label` is the small letter-spaced uppercase cap above a control,
   and `.z-field input` is a full-width bordered text box. A tick and its word
   are both of those by tag name, so without this the filter read as a column of
   large cream squares labelled "N O N - S T O P". Undone here rather than by
   narrowing the shared rules, which every other Zaereen listing depends on. */
.z-fr-filters .z-fx-check {
    font-size: 13px;
    font-weight: 500;
    letter-spacing: normal;
    text-transform: none;
    color: var(--z-ink-2);
}
.z-fr-filters .z-fx-check input {
    flex: none;
    width: 16px;
    height: 16px;
    padding: 0;
    border: 0;
    border-radius: 3px;
    background: none;
    appearance: auto;
    accent-color: var(--z-green);
}
.z-fr-filters .z-fx-check span { color: var(--z-ink-2); font-weight: 500; }

.z-fr-checks { display: grid; gap: 7px; }
/* The airline list can run to thirty carriers; the rest of the rail must stay
   reachable without scrolling past all of them. */
.z-fr-airlines { max-height: 232px; overflow-y: auto; padding-right: 4px; }
.z-fr-checks .z-fx-check span { display: flex; align-items: center; gap: 6px; width: 100%; }
.z-fr-checks .z-fx-check span i {
    margin-left: auto;
    font-style: normal;
    font-size: 12px;
    color: var(--z-ink-3);
}
/* The fare slider, for the same reason as the ticks above: `.z-field input`
   was giving it a bordered cream box with 12px of padding, inside which the
   browser drew its own default track and a bright blue thumb. Rebuilt as a
   gold rail with a green handle, in both vendor spellings — Firefox and the
   WebKit/Blink family need separate rules and will not accept a shared one. */
.z-fr-filters input[type="range"] {
    width: 100%;
    height: 18px;
    padding: 0;
    border: 0;
    background: none;
    appearance: none;
    cursor: pointer;
}
.z-fr-filters input[type="range"]::-webkit-slider-runnable-track {
    height: 4px;
    border-radius: 999px;
    background: var(--z-line-strong);
}
.z-fr-filters input[type="range"]::-moz-range-track {
    height: 4px;
    border-radius: 999px;
    background: var(--z-line-strong);
}
.z-fr-filters input[type="range"]::-webkit-slider-thumb {
    appearance: none;
    width: 16px; height: 16px;
    margin-top: -6px;              /* centres a 16px thumb on a 4px track */
    border-radius: 50%;
    background: var(--z-green);
    border: 2px solid var(--z-surface);
    box-shadow: 0 1px 4px rgba(23, 32, 26, .3);
}
.z-fr-filters input[type="range"]::-moz-range-thumb {
    width: 16px; height: 16px;
    border-radius: 50%;
    background: var(--z-green);
    border: 2px solid var(--z-surface);
    box-shadow: 0 1px 4px rgba(23, 32, 26, .3);
}
.z-fr-filters input[type="range"]:disabled { opacity: .45; cursor: not-allowed; }

.z-fr-rangeout { display: block; margin-top: 5px; font-size: 12.5px; color: var(--z-ink-2); }
.z-fr-dim { font-size: 13px; color: var(--z-ink-3); }

.z-fr-topbar { align-items: center; }
.z-fr-sort { display: inline-flex; gap: 3px; padding: 3px; background: var(--z-surface-2); border-radius: 999px; }
.z-fr-sort button {
    padding: 7px 14px;
    background: none;
    border: 0;
    border-radius: 999px;
    font-family: var(--z-body);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--z-ink-2);
    cursor: pointer;
}
.z-fr-sort button.is-on { background: var(--z-green); color: #f2e9d5; }

.z-fr-list { display: grid; gap: 12px; }

/* --- The fare card ----------------------------------------------------------
   ONE CARD IS ONE JOURNEY, NOT ONE FARE. TBO returns a result per sellable
   fare, so the same flight comes back many times over; the card carries the
   journey on the left, every fare for it in the middle, and the total and the
   action on the right. A combined return states BOTH directions in full, which
   is why the left column is a stack of leg blocks and not a single row.
   -------------------------------------------------------------------------- */
.z-fr-card {
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius, 14px);
    overflow: hidden;
    transition: box-shadow .16s ease, border-color .16s ease;
    /* THE CARD RESPONDS TO ITS OWN WIDTH, NOT THE WINDOW'S — see the
       @container block below for why that distinction is the whole fix. */
    container-type: inline-size;
    container-name: frcard;
}
.z-fr-card:hover { box-shadow: var(--z-shadow); border-color: var(--z-gold); }
.z-fr-card.is-chosen { border-color: var(--z-green-3); box-shadow: 0 0 0 2px var(--z-green-soft); }

.z-fr-card.is-skeleton { display: grid; gap: 10px; padding: 22px; pointer-events: none; }
.z-fr-card.is-skeleton:hover { box-shadow: none; border-color: var(--z-line-gold); }

.z-fr-combo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 216px 172px;
    align-items: start;
}

/* --- left: the journey, one block per direction ------------------------------ */
.z-fr-legs { display: grid; padding: 16px 18px; gap: 14px; min-width: 0; }
/* A dashed rule, not a solid one: the two directions are parts of one booking,
   and a solid line reads as two separate cards butted together. */
.z-fr-leg + .z-fr-leg { padding-top: 14px; border-top: 1px dashed var(--z-line); }

.z-fr-leghead {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 10px;
}
.z-fr-leghead b {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--z-teal);
}
.z-fr-leghead span { font-size: 12.5px; color: var(--z-ink-3); }
.z-fr-leghead span::before { content: "| "; color: var(--z-line-strong); }

/* Every track is minmax(0, …) and every child may shrink. A bare `168px` or
   `auto` track refuses to go below its content, so in a container too narrow to
   hold the row the overflow spilled sideways and painted over the fare rail
   beside it. This is the floor under the @container rules below: even where
   those do not run, the row crowds rather than overlaps. */
.z-fr-legrow {
    display: grid;
    grid-template-columns: minmax(0, 168px) minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
    gap: 14px;
    align-items: center;
}
.z-fr-legrow > * { min-width: 0; }

.z-fr-air { display: flex; align-items: center; gap: 11px; min-width: 0; }
.z-fr-air img { width: 34px; height: 34px; object-fit: contain; flex: none; }
.z-fr-nologo {
    flex: none;
    width: 34px; height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--z-gold-wash);
    border-radius: 7px;
    font-size: 12px;
    font-weight: 700;
    color: var(--z-gold-deep);
}
.z-fr-air div { min-width: 0; }
.z-fr-air b {
    display: block;
    font-size: 14px;
    font-weight: 700;
    color: var(--z-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.z-fr-air span { font-size: 12px; color: var(--z-ink-3); }

.z-fr-end { text-align: left; }
.z-fr-end.is-end { text-align: right; }
.z-fr-end b { display: block; font-size: 19px; font-weight: 700; color: var(--z-ink); line-height: 1.2; }
.z-fr-end span { display: block; font-size: 13px; font-weight: 600; color: var(--z-gold-deep); }
.z-fr-plus { font-size: 11px; color: var(--z-sold); vertical-align: super; margin-left: 2px; }

/* The line between the two times is what says "this is a journey"; the label
   under it is what says how much of one. */
.z-fr-mid { display: grid; gap: 3px; justify-items: center; text-align: center; min-width: 96px; }
.z-fr-mid i { font-style: normal; font-size: 11.5px; color: var(--z-ink-3); }
.z-fr-mid i.is-direct { color: var(--z-open); font-weight: 600; }
.z-fr-mid i.is-stops { color: var(--z-few); }
.z-fr-line { display: block; width: 100%; height: 1px; background: var(--z-line-strong); position: relative; }
.z-fr-line em {
    position: absolute;
    top: 50%; right: -1px;
    width: 6px; height: 6px;
    margin-top: -3px;
    background: var(--z-gold-deep);
    border-radius: 50%;
}

/* What this direction actually carries. Per direction, because an outbound and
   a return can differ and stating one twice would be inventing the other. */
.z-fr-legmeta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 10px;
    padding-top: 9px;
    border-top: 1px solid var(--z-line-soft);
    font-size: 12px;
    color: var(--z-ink-2);
}
.z-fr-legmeta i { font-style: normal; color: var(--z-line-strong); }
.z-fr-refund { color: var(--z-open); font-weight: 600; }
.z-fr-norefund { color: var(--z-ink-3); }

/* --- middle: every fare for that journey ------------------------------------- */
.z-fr-fares {
    display: grid;
    gap: 6px;
    align-content: start;
    padding: 16px 0;
    border-left: 1px solid var(--z-line-soft);
    padding-left: 14px;
}
.z-fr-fare {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    background: var(--z-surface-2);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm, 9px);
    cursor: pointer;
}
.z-fr-fare input { accent-color: var(--z-green); flex: none; margin: 0; }
.z-fr-fare.is-on { background: var(--z-gold-wash); border-color: var(--z-gold); }
.z-fr-fare:hover { border-color: var(--z-gold); }
.z-fr-farename {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--z-ink-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.z-fr-farename em { font-style: normal; margin-left: 4px; color: var(--z-open); }
.z-fr-fareprice { flex: none; font-size: 13px; font-weight: 700; color: var(--z-green); }

/* Beyond the third fare the rest stay in the DOM — their radios still work —
   but folded away, so a card with seventeen fares is not a scroll trap inside
   a scrolling page. */
.z-fr-fare.is-extra { display: none; }
.z-fr-fares.is-open .z-fr-fare.is-extra { display: flex; }
.z-fr-faremore {
    justify-self: start;
    margin-top: 2px;
    background: none;
    border: 0;
    padding: 2px 0;
    font-family: var(--z-body);
    font-size: 12px;
    font-weight: 600;
    color: var(--z-gold-deep);
    cursor: pointer;
}
.z-fr-faremore:hover { color: var(--z-green); text-decoration: underline; }

/* --- right: the total, and the one action ------------------------------------ */
.z-fr-total {
    display: grid;
    gap: 7px;
    justify-items: center;
    text-align: center;
    padding: 16px 18px;
    border-left: 1px solid var(--z-line-soft);
}
.z-fr-total small { font-size: 11px; color: var(--z-ink-3); line-height: 1.3; }
.z-fr-totalamt { font-size: 21px; font-weight: 700; color: var(--z-green); line-height: 1.1; }
.z-fr-total .z-btn { width: 100%; justify-content: center; }
/* In the two-group shape the sticky bar carries the one action for the pair, so
   the card says which state it is in instead of offering a second way on. */
.z-fr-chosenmark { font-size: 12px; font-weight: 600; color: var(--z-ink-3); }
.z-fr-card.is-chosen .z-fr-chosenmark { color: var(--z-open); }

.z-fr-foot {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 18px;
    background: var(--z-gold-wash);
    border-top: 1px solid var(--z-line-soft);
}
.z-fr-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.z-fr-tag {
    padding: 3px 9px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    color: var(--z-ink-2);
}
.z-fr-more {
    margin-left: auto;
    background: none;
    border: 0;
    font-family: var(--z-body);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--z-gold-deep);
    cursor: pointer;
}
.z-fr-more:hover { color: var(--z-green); text-decoration: underline; }

.z-fr-detail { padding: 16px 18px; border-top: 1px solid var(--z-line-soft); background: var(--z-surface-2); }
.z-fr-detdir h4 {
    margin: 0 0 8px;
    font-family: var(--z-body);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--z-gold-deep);
}
.z-fr-detdir + .z-fr-detdir { margin-top: 14px; padding-top: 14px; border-top: 1px dashed var(--z-line); }

.z-fr-seg { display: grid; gap: 3px; padding: 8px 0; }
.z-fr-segair { font-size: 11.5px; font-weight: 600; color: var(--z-ink-3); }
.z-fr-segleg { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; font-size: 13px; color: var(--z-ink-2); }
.z-fr-segleg b { font-size: 14px; font-weight: 700; color: var(--z-ink); }
.z-fr-segleg i { font-style: normal; font-size: 11.5px; color: var(--z-ink-3); }
/* A layover is the part of an itinerary people are actually surprised by, so it
   gets its own rule and its own colour rather than a line of small print. */
.z-fr-layover {
    margin: 4px 0;
    padding: 6px 10px;
    background: var(--z-few-bg);
    border-left: 3px solid var(--z-few);
    border-radius: 0 6px 6px 0;
    font-size: 12px;
    color: var(--z-few);
}

/* --- The card, stacked ------------------------------------------------------
   A CONTAINER QUERY, NOT A MEDIA QUERY, AND THAT IS THE POINT.

   The three-column card needs roughly 620px. On a round trip that comes back as
   two result groups, the two directions are chosen side by side, so every card
   gets HALF the results width — about 550px on a full desktop screen. A
   viewport-keyed rule never fires there: the window is wide, the card is not.
   That is exactly how the fare rail ended up drawn over the flight times.

   Keyed to the card's own width, one block covers every case that matters — the
   round-trip pair at any screen size, a narrowed window, and a phone — instead
   of a viewport breakpoint per situation that each have to be kept in step.
   -------------------------------------------------------------------------- */
@container frcard (max-width: 620px) {
    .z-fr-combo { grid-template-columns: 1fr; }
    .z-fr-legs { padding: 14px; }

    .z-fr-fares {
        padding: 12px 14px;
        border-left: 0;
        border-top: 1px dashed var(--z-line);
    }

    /* The total stops being a column and becomes a row: label across the top,
       then the amount and the action facing each other. */
    .z-fr-total {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;
        text-align: left;
        gap: 4px 12px;
        padding: 12px 14px;
        border-left: 0;
        border-top: 1px dashed var(--z-line);
    }
    .z-fr-total small { flex: 1 1 100%; order: 1; }
    .z-fr-totalamt { order: 2; }
    .z-fr-total .z-btn, .z-fr-chosenmark { order: 3; width: auto; }

    /* The airline, both times and the line between them will not sit in one row
       at this width, so the airline takes its own line above them. */
    .z-fr-legrow { grid-template-columns: minmax(0, auto) minmax(0, 1fr) minmax(0, auto); gap: 10px; }
    .z-fr-air { grid-column: 1 / -1; }
}

/* --- Round trip chosen as a pair -------------------------------------------- */
.z-fr-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; align-items: start; }
.z-fr-colhead {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin: 0 0 10px;
    padding-bottom: 8px;
    border-bottom: 2px solid var(--z-gold);
    font-family: var(--z-body);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--z-green);
}
.z-fr-colhead span { font-size: 12px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--z-ink-3); }

/* Nothing can be booked until BOTH directions are chosen, so the total and the
   one button that continues live here rather than on either column's cards. */
.z-fr-sticky {
    position: sticky;
    bottom: 0;
    z-index: 35;
    margin-top: 18px;
    padding: 12px 0;
    background: var(--z-green);
    border-top: 2px solid var(--z-gold);
}
.z-fr-stickyin { display: flex; flex-wrap: wrap; align-items: center; gap: 18px; }
.z-fr-stickylegs { display: flex; gap: 22px; flex: 1 1 auto; min-width: 0; }
.z-fr-stickylegs > div { display: grid; gap: 2px; min-width: 0; }
.z-fr-stickylegs b {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--z-gold-light);
}
.z-fr-stickylegs span {
    font-size: 13px;
    color: rgba(242, 233, 213, .62);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.z-fr-stickylegs .is-set span { color: #f2e9d5; }
.z-fr-stickytotal { display: grid; gap: 2px; text-align: right; }
.z-fr-stickytotal small { font-size: 11px; color: var(--z-gold-light); }
.z-fr-stickytotal b { font-size: 21px; font-weight: 700; color: #f2e9d5; }
.z-fr-sticky .z-btn[disabled] { opacity: .45; cursor: not-allowed; }

/* --- The group-charter listing's door to the live search --------------------- */
.z-flive { padding: 22px 0 0; }
.z-flive-in {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    padding: 18px 22px;
    background: var(--z-gold-wash);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius, 14px);
}
.z-flive-icon {
    flex: none;
    width: 46px; height: 46px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--z-surface);
    border: 1px solid var(--z-gold);
    border-radius: 50%;
    color: var(--z-gold-deep);
}
.z-flive-say { flex: 1 1 260px; min-width: 0; }
.z-flive-say b { display: block; font-size: 15px; font-weight: 700; color: var(--z-ink); }
.z-flive-say p { margin: 3px 0 0; font-size: 13px; color: var(--z-ink-2); }

/* --- Booking steps: the rail, and the frame the shared views sit in ---------- */
.z-fstep-rail { padding: 16px 0; background: var(--z-cream); border-bottom: 1px solid var(--z-line); }
.z-fstep-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 26px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.z-fstep-list li { display: inline-flex; align-items: center; gap: 8px; }
.z-fstep-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px; height: 24px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: 50%;
    font-size: 12px;
    font-weight: 700;
    color: var(--z-ink-3);
}
.z-fstep-label { font-size: 12.5px; font-weight: 600; color: var(--z-ink-3); }
.z-fstep-list .is-done .z-fstep-dot { background: var(--z-green-soft); border-color: var(--z-open); color: var(--z-open); }
.z-fstep-list .is-done .z-fstep-label { color: var(--z-ink-2); }
.z-fstep-list .is-now .z-fstep-dot { background: var(--z-green); border-color: var(--z-green); color: var(--z-gold-light); }
.z-fstep-list .is-now .z-fstep-label { color: var(--z-green); }

.z-fstep-body { padding-top: 22px; }

/* The borrowed views bring their own dark-navy components and their own
   Bootstrap grid. The frame gives them a ground to sit on rather than letting
   them float on Zaereen's cream, and clips anything that assumed the full
   width of an Oxford page. */
.z-fstep-frame { min-width: 0; }
.z-fstep-frame > .container,
.z-fstep-frame > .container-fluid { padding-left: 0; padding-right: 0; max-width: none; }

/* --- Narrower screens --------------------------------------------------------
   The rail collapses at 780px and NOT before, because 780 is where zaereen.css
   reveals .z-filters-toggle and starts honouring .z-filters[hidden]. Collapsing
   it earlier would give a screen of filters above the first fare with no button
   to fold them away — the exact state that partial exists to prevent.
   -------------------------------------------------------------------------- */
@media (max-width: 1100px) {
    /* Still two columns, just a narrower rail: the fares need the width more
       than the checkboxes do. */
    .z-fr-layout { grid-template-columns: 220px minmax(0, 1fr); gap: 20px; }
    .z-fr-cols { grid-template-columns: 1fr; }
    /* The fare rail and the total give up width before the journey does — the
       times and the route are what a fare list is read for. */
    .z-fr-combo { grid-template-columns: minmax(0, 1fr) 184px 148px; }
    .z-fr-legrow { grid-template-columns: 140px auto minmax(0, 1fr) auto; gap: 10px; }
}

@media (max-width: 860px) {
    /* Sticky costs a third of a phone screen and the bar is five fields tall
       there, so it scrolls away with the page instead. */
    .z-fr-barwrap { position: static; }

    /* The CARD's own stacking is not here — it is the @container block above,
       which fires on the card's width and therefore covers a phone and the
       half-width round-trip columns with one set of rules. What stays in this
       media query is the page furniture, which genuinely does depend on the
       size of the window. */
    .z-fr-field, .z-fr-field.is-date, .z-fr-pax { flex: 1 1 100%; }
    .z-fr-swap { align-self: center; margin: 0 auto; transform: rotate(90deg); }
    .z-fr-go { flex: 1 1 100%; justify-content: center; }

    .z-fr-stickyin { gap: 10px; }
    .z-fr-stickylegs { flex: 1 1 100%; gap: 16px; }
    .z-fr-sticky .z-btn { flex: 1 1 100%; justify-content: center; }

    .z-fstep-list { gap: 6px 14px; }
    .z-fstep-label { display: none; }
    .z-fstep-list .is-now .z-fstep-label { display: inline; }
}

@media (max-width: 780px) {
    /* One column, and the rail stops being one — from here the shared
       .z-filters-toggle drives it. Restated rather than inherited: this file
       loads after the .z-filters rules, so its own sticky would otherwise win
       over the site's `position: static`. */
    .z-fr-layout { grid-template-columns: 1fr; gap: 16px; }
    .z-fr-filters { position: static; }
}

/* --- The single-direction card ----------------------------------------------
   One flight, so everything that identifies it fits on one line: airline, out,
   the line between, in, the chosen fare. The facts sit in a strip beneath, and
   the other fares for the same flight fold out under that.

   This is the shape a one-way uses, and the shape EITHER HALF of a two-group
   round trip uses — which is the case that has to work in half the page width,
   so the row is built to compress rather than to fill.
   -------------------------------------------------------------------------- */
.z-fr-lrow {
    display: grid;
    grid-template-columns:
        minmax(0, auto)      /* airline + flight numbers */
        minmax(0, auto)      /* depart  */
        minmax(0, 1fr)       /* the line */
        minmax(0, auto)      /* arrive  */
        minmax(0, auto)      /* the chosen fare */
        auto;                /* the chevron */
    gap: 12px;
    align-items: center;
    padding: 14px 16px;
}
.z-fr-lrow > * { min-width: 0; }

.z-fr-lair { display: flex; align-items: center; gap: 10px; }
.z-fr-lair img {
    width: 38px; height: 38px;
    flex: none;
    object-fit: contain;
    background: var(--z-surface-2);
    border: 1px solid var(--z-line);
    border-radius: 9px;
    padding: 3px;
}
.z-fr-lno {
    font-size: 12px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--z-ink-3);
    white-space: nowrap;
}

.z-fr-lend { text-align: left; }
.z-fr-lend.is-end { text-align: right; }
.z-fr-lend b { display: block; font-size: 18px; font-weight: 700; color: var(--z-ink); line-height: 1.2; }
.z-fr-lend span { display: block; font-size: 12.5px; font-weight: 600; color: var(--z-gold-deep); }

/* Duration above, the line, then how many stops under it — the one part of the
   row that has to read at a glance. */
.z-fr-lpath { display: grid; gap: 3px; justify-items: center; text-align: center; }
.z-fr-ldur { font-style: normal; font-size: 11.5px; color: var(--z-ink-3); }
.z-fr-lline {
    display: block;
    width: 100%;
    min-width: 54px;
    height: 1px;
    background: var(--z-line-strong);
    position: relative;
}
.z-fr-lline em {
    position: absolute;
    top: 50%; right: -1px;
    width: 6px; height: 6px;
    margin-top: -3px;
    background: var(--z-gold-deep);
    border-radius: 50%;
}
.z-fr-lpath .is-direct { font-style: normal; font-size: 11.5px; font-weight: 600; color: var(--z-open); }
.z-fr-lstops {
    padding: 0;
    background: none;
    border: 0;
    font-family: var(--z-body);
    font-size: 11.5px;
    font-weight: 600;
    color: var(--z-few);
    cursor: pointer;
}
.z-fr-lstops:hover { text-decoration: underline; }

/* The chosen fare, restated in the row. It is a radio because on a two-group
   round trip this IS the choice of that direction's flight. */
.z-fr-lpick {
    display: grid;
    gap: 1px;
    justify-items: end;
    text-align: right;
    padding: 5px 10px 5px 12px;
    border: 1px solid transparent;
    border-radius: var(--z-radius-sm, 9px);
    cursor: pointer;
}
.z-fr-lpick input {
    position: absolute;
    width: 1px; height: 1px;
    opacity: 0;
    pointer-events: none;
}
.z-fr-lprice { font-size: 18px; font-weight: 700; color: var(--z-green); line-height: 1.15; white-space: nowrap; }
.z-fr-lfare { font-size: 11.5px; font-weight: 600; color: var(--z-ink-3); white-space: nowrap; }
.z-fr-lfare em { font-style: normal; margin-left: 4px; color: var(--z-open); }
.z-fr-lpick:hover { border-color: var(--z-line); }
.z-fr-lpick input:checked ~ .z-fr-lprice { color: var(--z-gold-deep); }
.z-fr-lpick input:focus-visible ~ .z-fr-lprice { outline: 2px solid var(--z-gold); outline-offset: 3px; }

/* The chevron carries the fare COUNT rather than an arrow: "3" says there is
   something behind it and how much, where a bare chevron says only "more". */
.z-fr-lexpand {
    flex: none;
    width: 30px; height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--z-surface-2);
    border: 1px solid var(--z-line);
    border-radius: 50%;
    font-family: var(--z-body);
    font-size: 12px;
    font-weight: 700;
    color: var(--z-gold-deep);
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.z-fr-lexpand:hover { border-color: var(--z-gold); }
.z-fr-lexpand.is-open { background: var(--z-green); border-color: var(--z-green); color: var(--z-gold-light); }
/* A card with one fare keeps the slot so the rows above and below still line
   up down the column, but shows nothing in it. */
.z-fr-lexpand.is-none { visibility: hidden; }

.z-fr-lmeta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    padding: 9px 16px;
    background: var(--z-gold-wash);
    border-top: 1px solid var(--z-line-soft);
    font-size: 12px;
    color: var(--z-ink-2);
}
.z-fr-lbits { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.z-fr-lbits i { font-style: normal; color: var(--z-line-strong); }
.z-fr-lfew { color: var(--z-few); font-weight: 600; }
.z-fr-lacts { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.z-fr-lrules {
    background: none;
    border: 0;
    padding: 0;
    font-family: var(--z-body);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--z-gold-deep);
    cursor: pointer;
    white-space: nowrap;
}
.z-fr-lrules:hover { color: var(--z-green); text-decoration: underline; }
.z-fr-lrules[disabled] { opacity: .5; cursor: progress; }

/* The other fares for this same flight, across rather than down: each is a
   price and a name, which is a small block, and three of them side by side read
   as a choice where a list reads as a queue. */
.z-fr-lfares {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
    gap: 10px;
    padding: 14px 16px;
    border-top: 1px dashed var(--z-line);
}
/* Ships hidden and opens on the chevron — which a `display` rule with no
   guard silently prevents, since `[hidden]` is only a UA rule. See
   .z-ts-paxpanel[hidden] for the full note. */
.z-fr-lfares[hidden] { display: none; }
.z-fr-lfarebox {
    display: grid;
    gap: 3px;
    justify-items: center;
    text-align: center;
    padding: 12px 10px;
    background: var(--z-surface-2);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm, 9px);
    cursor: pointer;
}
.z-fr-lfarebox:hover { border-color: var(--z-gold); }
.z-fr-lfarebox.is-on { background: var(--z-gold-wash); border-color: var(--z-gold); box-shadow: 0 0 0 1px var(--z-gold); }
.z-fr-lfarebox input { accent-color: var(--z-green); margin: 0 0 3px; }
.z-fr-lfarebox b { font-size: 15px; font-weight: 700; color: var(--z-green); }
.z-fr-lfarebox.is-on b { color: var(--z-gold-deep); }
.z-fr-lfarebox span { font-size: 11.5px; font-weight: 600; color: var(--z-ink-2); }
.z-fr-lfarebox span em { font-style: normal; margin-left: 3px; color: var(--z-open); }

/* --- Fare rules ------------------------------------------------------------- */
.z-fr-modal {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(13, 44, 34, .55);
}
.z-fr-modal[hidden] { display: none; }
.z-fr-modalbox {
    width: min(680px, 100%);
    max-height: 84vh;
    display: flex;
    flex-direction: column;
    background: var(--z-surface);
    border: 1px solid var(--z-line-gold);
    border-radius: var(--z-radius, 14px);
    box-shadow: var(--z-shadow-lg);
    overflow: hidden;
}
.z-fr-modalhead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 18px;
    background: var(--z-green);
    color: #f2e9d5;
}
.z-fr-modalhead b { font-family: var(--z-display); font-size: 19px; font-weight: 600; }
.z-fr-modalx {
    background: none;
    border: 0;
    font-size: 26px;
    line-height: 1;
    color: var(--z-gold-light);
    cursor: pointer;
}
.z-fr-modalbody { padding: 18px; overflow-y: auto; }

.z-fr-rulewarn {
    margin: 0 0 14px;
    padding: 9px 12px;
    background: var(--z-sold-bg);
    border-left: 3px solid var(--z-sold);
    border-radius: 0 6px 6px 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--z-sold);
}
.z-fr-ruleblock + .z-fr-ruleblock { margin-top: 20px; padding-top: 16px; border-top: 1px dashed var(--z-line); }
.z-fr-ruleblock h4 {
    margin: 0 0 10px;
    font-family: var(--z-body);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--z-teal);
}
.z-fr-rulenr {
    margin-left: 6px;
    padding: 2px 7px;
    border-radius: 999px;
    background: var(--z-sold-bg);
    font-size: 10.5px;
    letter-spacing: 0;
    text-transform: none;
    color: var(--z-sold);
}
.z-fr-rulelist { margin: 0 0 12px; padding-left: 18px; font-size: 13px; color: var(--z-ink-2); }
.z-fr-ruletable { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.z-fr-ruletable th,
.z-fr-ruletable td { padding: 7px 9px; text-align: left; border-bottom: 1px solid var(--z-line-soft); vertical-align: top; }
.z-fr-ruletable th {
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--z-ink-3);
    font-weight: 600;
}
.z-fr-ruletable td { color: var(--z-ink-2); }

/* --- The single-direction card, in a narrow container ------------------------
   Same reasoning as the combined card's own @container block: on a two-group
   round trip these sit two to a row at ANY viewport width, so this has to key
   on the card, not the window.

   BUT AT A MUCH TIGHTER WIDTH THAN THE COMBINED CARD. That one carries three
   columns of substance and needs ~620px; this row is a logo, two clock times, a
   line and a price, and measures about 470px — so 620 would break a row that
   still fits comfortably and leave the card half empty, which is exactly what
   it did. 440px is just under what the row actually needs.
   -------------------------------------------------------------------------- */
@container frcard (max-width: 440px) {
    /* The fare leaves the row and joins the meta strip's line, which is the
       only way the times and the route survive at this width. */
    .z-fr-lrow {
        grid-template-columns: minmax(0, auto) minmax(0, auto) minmax(0, 1fr) minmax(0, auto) auto;
        gap: 10px;
        padding: 12px 14px;
    }
    .z-fr-lpick {
        grid-column: 1 / -1;
        justify-items: start;
        text-align: left;
        padding: 8px 0 0;
        border-top: 1px dashed var(--z-line);
        border-radius: 0;
    }
    .z-fr-lpick .z-fr-lprice,
    .z-fr-lpick .z-fr-lfare { display: inline; }
    .z-fr-lfare { margin-left: 8px; }
    .z-fr-lair img { width: 32px; height: 32px; }
    .z-fr-lend b { font-size: 16px; }
    .z-fr-lfares { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; padding: 12px 14px; }
}

/* The airline's penalty grid can run six columns wide; it scrolls inside its
   own box rather than widening the dialog or wrapping into an unreadable mess. */
.z-fr-ruletablewrap { overflow-x: auto; margin-bottom: 12px; }
.z-fr-ruletablewrap .z-fr-ruletable { min-width: 460px; }
.z-fr-rulenote {
    margin: 0 0 12px;
    font-size: 13px;
    font-weight: 600;
    color: var(--z-ink-2);
}
/* "Not Allowed" is the answer people are looking for and the one that costs
   the most to miss. */
.z-fr-rulestop { color: var(--z-sold); font-weight: 700; }

/* ---- the stay panel while its calendar is open -------------------------- */
/* .z-journey carries overflow:hidden so the panel's rounded corners clip its
   contents. flatpickr renders its calendar INLINE, right after the input, so
   that same rule was cutting the calendar off at the panel edge -- the picker
   opened, and most of it was simply not visible.

   appendTo:<body> is not the answer and was tried: altInput leaves the real
   input as a hidden field with no layout box, so flatpickr positions the
   calendar against nothing and it lands off the bottom of the page at opacity
   0. The note in zaereen/index.php records that.

   So the clip is lifted only while a calendar is open, and only on the panel
   that owns it. z-index is raised at the same time because the sticky panel
   sits in its own stacking context. */
.z-journey.is-cal-open {
    overflow: visible;
    z-index: 60;
}
.z-journey.is-cal-open .flatpickr-calendar {
    z-index: 61;
}

/* ---- the stay panel's date fields, once flatpickr has bound ------------- */
/* .z-occf gives its date boxes their border, height and centring through
   `input[type="date"]`. flatpickr changes that type to text and hides the
   original behind a NEW visible input, so the attribute selector stops
   matching and both date fields lose every bit of that styling -- they render
   as bare unstyled boxes next to the styled Nights and Rooms steppers.

   Matched on .z-fp-input, which is the altInputClass the panel asks for, and
   NOT on input[type="text"]: the Nights, Rooms, Adults and Children steppers
   in this same container are text inputs too, and would be restyled as date
   fields. */
.z-occf .z-fp-input {
    width: 100%;
    min-width: 0;
    height: 36px;
    padding: 0 8px;
    border: 1px solid var(--z-line);
    border-radius: 8px;
    background-color: var(--z-surface);
    font: inherit; font-size: 12px;
    color: var(--z-ink);
    text-align: center;
    white-space: nowrap;
    /* Room for the calendar glyph, kept as tight as it can be. Three
       fields share this row and the sidebar is narrow, so every pixel
       here is one the year needs. Paired with the weekday coming out of
       altFormat -- "13 Sep 2026" rather than "Sun, 13 Sep 2026". */
    padding-left: 4px;
    padding-right: 19px;
    background-position: right 4px center;
    background-size: 12px 12px;
}
.z-occf .z-fp-input:focus-visible {
    outline: 2px solid var(--z-gold);
    outline-offset: 1px;
}

/* ---- the night counter keeps its width ---------------------------------- */
/* I narrowed this to 58px to buy the dates room, and that broke the
   stepper: .z-step is `30px minmax(0,1fr) 30px`, so its two buttons alone
   need 60px and the figure between them had nothing left -- the night
   count simply vanished.

   84px was right and the dates never needed it. The year was being cut by
   two other things, both since fixed: the weekday in altFormat, and the
   42px glyph reserve .z-fp-input applies by default. With those dealt
   with, a 400px sidebar gives each date 136px for a 69px date. */

/* THE CALENDAR GLYPH STAYS. I removed it earlier on the arithmetic that a
   date field was ~66px, which came from assuming a 260px sidebar. It is
   not: .z-tourbody gives the aside 400px, 340px under 1240 and 300px
   under 1080, so the field is 149 / 119 / 99px and there is room for both
   the icon and the year. The clipping that started all this was the
   weekday plus a 12.5px face in the 84px-Nights layout, not the icon. */
.z-journey .z-occf .z-fp-input {
    padding-left: 6px;
    padding-right: 20px;
    background-position: right 5px center;
    background-size: 13px 13px;
}

/* ==========================================================================
   PILGRIM GUIDES — /ziyarat/umrah/, /ziyarat/kunsafar/  (ziyarat/guide.php)
   Layout is About's (.z-about-body, .z-tabs, .z-book); these are the three
   things a guide has that About does not: mansak cards, audio rows, video.
   ========================================================================== */

.z-guide-docs {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px;
}
.z-guide-doc {
    display: flex; align-items: center; gap: 14px;
    padding: 16px 18px;
    background: var(--z-surface);
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    color: var(--z-green); text-decoration: none;
    transition: border-color .15s, box-shadow .15s, transform .15s;
}
.z-guide-doc:hover {
    border-color: var(--z-line-gold);
    box-shadow: var(--z-shadow);
    transform: translateY(-1px);
}
.z-guide-doc-ic {
    flex: none; display: grid; place-items: center;
    width: 44px; height: 44px; border-radius: 10px;
    background: var(--z-gold-wash); color: var(--z-gold-deep);
    border: 1px solid var(--z-line-gold);
}
.z-guide-doc-txt { flex: 1; min-width: 0; display: grid; gap: 3px; }
.z-guide-doc-txt b { font-size: 15.5px; font-weight: 600; }
.z-guide-doc-txt small { font-size: 13px; color: var(--z-ink-3); }
.z-guide-doc-go { flex: none; color: var(--z-gold-deep); line-height: 0; }

.z-guide-audio {
    list-style: none; margin: 0; padding: 0;
    border: 1px solid var(--z-line);
    border-radius: var(--z-radius-sm);
    background: var(--z-surface);
    overflow: hidden;
}
.z-guide-audio li {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) minmax(220px, 300px);
    align-items: center; gap: 14px;
    padding: 12px 16px;
}
.z-guide-audio li + li { border-top: 1px solid var(--z-line-soft); }
.z-guide-audio li:nth-child(even) { background: var(--z-marble); }
.z-guide-num {
    display: grid; place-items: center;
    width: 32px; height: 32px; border-radius: 50%;
    background: var(--z-green); color: var(--z-gold-light);
    font-family: var(--z-display); font-size: 17px; font-weight: 700;
}
.z-guide-num.is-icon { background: var(--z-gold-wash); color: var(--z-gold-deep); border: 1px solid var(--z-line-gold); }
.z-guide-title { font-size: 15px; font-weight: 500; color: var(--z-green); }
.z-guide-audio audio { width: 100%; height: 38px; }

.z-guide-video {
    border-radius: var(--z-radius);
    overflow: hidden;
    background: var(--z-green);
    box-shadow: var(--z-shadow);
}
.z-guide-video video { display: block; width: 100%; max-height: 72vh; background: #000; }

@media (max-width: 760px) {
    .z-guide-docs { grid-template-columns: minmax(0, 1fr); }
    .z-guide-audio li {
        grid-template-columns: 32px minmax(0, 1fr);
        row-gap: 10px; padding: 14px;
    }
    .z-guide-audio audio { grid-column: 1 / -1; }
}
