@charset "utf-8";
/* ===========================================================================
   Duma Tours & Travels — public site
   ---------------------------------------------------------------------------
   Duma is Swahili for cheetah. The palette comes from that animal's world at
   the hours it hunts: charcoal from a cold campfire, bleached bone, the ochre
   of its coat, acacia in shade, and one rust accent used almost nowhere.

   The signature device is the tear line — the dark stripe running from a
   cheetah's eye to its mouth. Here it is a hairline that drops from section
   eyebrows and from active navigation. It appears once per section and never
   as decoration alone: it always marks where the eye should start.
   ========================================================================= */

:root {
  /* --- Colour ------------------------------------------------------- */
  --char:       #16110E;   /* charcoal, warm not blue */
  --char-lift:  #241C17;   /* raised surface on charcoal */
  --char-line:  #3A2E25;

  --bone:       #F4EFE6;   /* page ground */
  --sand:       #E7DECD;   /* alternating band */
  --sand-line:  #D4C8B2;

  --ochre:      #C2782B;   /* cheetah coat — the one warm signal */
  --ochre-lift: #D89448;
  --acacia:     #5E6A4E;   /* thorn tree in shade */
  --rust:       #9A3B1F;   /* used for one thing per page, at most */

  --ink:        #16110E;
  --ink-soft:   #4A3F36;
  --mist:       #857A6C;   /* captions, meta, disabled */

  /* --- Type --------------------------------------------------------- */
  /* Defaults. Typography::cssVariables() overrides these with whatever
     pairing is chosen in Studio, emitted inline so the right faces apply on
     first paint instead of flashing. */
  --display: 'Bodoni Moda', 'Didot', 'Times New Roman', serif;
  --ui:      'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --display-weight: 400;
  --display-tracking: -0.015em;

  /* Fluid scale. Clamps mean no breakpoint jumps in headline size. */
  --t-hero:  clamp(2.75rem, 1.2rem + 6.4vw, 7rem);
  --t-h1:    clamp(2.25rem, 1.3rem + 3.8vw, 4.25rem);
  --t-h2:    clamp(1.75rem, 1.2rem + 2.2vw, 2.875rem);
  --t-h3:    clamp(1.3rem,  1.05rem + 1vw,  1.75rem);
  --t-lead:  clamp(1.0625rem, 1rem + 0.5vw, 1.3125rem);
  --t-body:  1.0625rem;
  --t-small: 0.875rem;
  --t-micro: 0.6875rem;   /* eyebrows and labels, always tracked out */

  --track-eyebrow: 0.22em;
  --track-nav:     0.14em;

  /* --- Space -------------------------------------------------------- */
  --s-1: 0.25rem;  --s-2: 0.5rem;   --s-3: 0.75rem;  --s-4: 1rem;
  --s-5: 1.5rem;   --s-6: 2rem;     --s-7: 3rem;     --s-8: 4rem;
  --s-9: 6rem;     --s-10: 8rem;

  --pad-sm: clamp(1.5rem, 3vw, 2.5rem);
  --pad-md: clamp(2.5rem, 5vw, 4.5rem);
  --pad-lg: clamp(4rem, 8vw, 7.5rem);
  --pad-xl: clamp(5.5rem, 11vw, 11rem);

  --gutter: clamp(1.25rem, 4vw, 3.5rem);

  /* --- Measure ------------------------------------------------------ */
  --w-narrow: 46rem;
  --w-normal: 68rem;
  --w-wide:   84rem;

  /* --- Motion ------------------------------------------------------- */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur: 0.45s;

  --nav-h: 4.5rem;
}

/* ---------------------------------------------------------------------------
   Reset
   ------------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 1rem);
}

body {
  font-family: var(--ui);
  font-size: var(--t-body);
  line-height: 1.65;
  color: var(--ink);
  background: var(--bone);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, picture, svg, video { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
ul, ol { list-style: none; padding: 0; }

:focus-visible {
  outline: 2px solid var(--ochre);
  outline-offset: 3px;
  border-radius: 2px;
}

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

/* ---------------------------------------------------------------------------
   Typography
   ------------------------------------------------------------------------ */
.display, h1, h2, h3 {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-weight: 400;
  line-height: 1.06;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); line-height: 1.2; }

/* The one typographic move: an italic phrase inside a roman headline, which
   Bodoni's high contrast makes land hard. Used for the emphasised idea only. */
.display em, h1 em, h2 em {
  font-style: italic;
  font-weight: 400;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.55;
  color: var(--ink-soft);
  text-wrap: pretty;
}

/* Eyebrow: small, tracked out, always paired with the tear line. */
.eyebrow {
  font-family: var(--ui);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--mist);
  display: block;
  position: relative;
  padding-bottom: var(--s-5);
  margin-bottom: var(--s-4);
}

/* --- The tear line ------------------------------------------------------ */
.eyebrow::after {
  content: "";
  position: absolute;
  left: 0;
  top: 1.6em;
  width: 1px;
  height: 0;
  background: var(--ochre);
  animation: tear 0.9s var(--ease-out) forwards;
}

@keyframes tear {
  to { height: 1.4rem; }
}

@media (prefers-reduced-motion: reduce) {
  .eyebrow::after { height: 1.4rem; animation: none; }
}

.prose p + p { margin-top: 1.15em; }
.prose h2, .prose h3 { margin: 1.8em 0 0.6em; }
.prose ul { margin: 1.15em 0; }
.prose li { padding-left: 1.4em; position: relative; margin-bottom: 0.5em; }
.prose li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.72em;
  width: 0.5rem; height: 1px;
  background: var(--ochre);
}
.prose a {
  text-decoration: underline;
  text-decoration-color: var(--sand-line);
  text-underline-offset: 0.22em;
  transition: text-decoration-color var(--dur) var(--ease);
}
.prose a:hover { text-decoration-color: var(--ochre); }

.prose blockquote {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-size: var(--t-h3);
  font-style: italic;
  line-height: 1.35;
  padding-left: var(--s-5);
  border-left: 1px solid var(--ochre);
  margin: 1.8em 0;
}

/* ---------------------------------------------------------------------------
   Layout primitives — driven by the block settings schema
   ------------------------------------------------------------------------ */
.blk { position: relative; }
.blk__inner {
  margin-inline: auto;
  padding-inline: var(--gutter);
  width: 100%;
}

.w-narrow > .blk__inner { max-width: var(--w-narrow); }
.w-normal > .blk__inner { max-width: var(--w-normal); }
.w-wide   > .blk__inner { max-width: var(--w-wide); }
.w-full   > .blk__inner { max-width: none; padding-inline: 0; }

.pt-none { padding-top: 0; }
.pt-sm   { padding-top: var(--pad-sm); }
.pt-md   { padding-top: var(--pad-md); }
.pt-lg   { padding-top: var(--pad-lg); }
.pt-xl   { padding-top: var(--pad-xl); }
.pb-none { padding-bottom: 0; }
.pb-sm   { padding-bottom: var(--pad-sm); }
.pb-md   { padding-bottom: var(--pad-md); }
.pb-lg   { padding-bottom: var(--pad-lg); }
.pb-xl   { padding-bottom: var(--pad-xl); }

.surface--bone { background: var(--bone); }
.surface--sand { background: var(--sand); }

.surface--char,
.surface--acacia {
  --ink: var(--bone);
  --ink-soft: rgba(244, 239, 230, 0.78);
  --mist: rgba(244, 239, 230, 0.55);
  --sand-line: rgba(244, 239, 230, 0.2);
  color: var(--bone);
}
.surface--char   { background: var(--char); }
.surface--acacia { background: var(--acacia); }

/* A block that follows one with matching space collapses the pair, so two
   large gaps never stack into a hole. */
.blk + .blk.pt-lg:not(.surface) { padding-top: calc(var(--pad-lg) * 0.6); }
.blk + .blk.pt-xl:not(.surface) { padding-top: calc(var(--pad-xl) * 0.7); }

/* ---------------------------------------------------------------------------
   Buttons
   ------------------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  font-family: var(--ui);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  padding: 1.05rem 1.9rem;
  border: 1px solid transparent;
  background: none;
  cursor: pointer;
  position: relative;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}

.btn--primary {
  background: var(--ochre);
  color: var(--char);
  border-color: var(--ochre);
}
.btn--primary:hover { background: var(--ochre-lift); border-color: var(--ochre-lift); }

.btn--ghost {
  border-color: currentColor;
  color: inherit;
  opacity: 0.85;
}
.btn--ghost:hover { opacity: 1; background: rgba(194, 120, 43, 0.12); border-color: var(--ochre); }

/* Text link with an arrow that extends on hover — the tear line, horizontal. */
.btn--text {
  padding: 0;
  color: inherit;
}
.btn--text::after {
  content: "";
  width: 1.5rem; height: 1px;
  background: var(--ochre);
  transition: width var(--dur) var(--ease);
}
.btn--text:hover::after { width: 2.75rem; }

/* ---------------------------------------------------------------------------
   Header
   ------------------------------------------------------------------------ */
.site-head {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 900;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  padding-inline: var(--gutter);
  gap: var(--s-6);
  color: var(--bone);
  transition: background-color var(--dur) var(--ease), backdrop-filter var(--dur) var(--ease);
}
.site-head::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(244,239,230,0.22), transparent);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.site-head[data-stuck="true"] {
  background: rgba(22, 17, 14, 0.92);
  backdrop-filter: blur(14px) saturate(1.2);
}
.site-head[data-stuck="true"]::after { opacity: 1; }

.brand {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-size: 1.375rem;
  letter-spacing: 0.06em;
  line-height: 1;
  margin-right: auto;
}
.brand span {
  display: block;
  font-family: var(--ui);
  font-size: 0.5625rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--ochre);
  margin-top: 0.32rem;
}

.nav { display: flex; align-items: center; gap: var(--s-6); }

.nav__link {
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  position: relative;
  padding: 0.4rem 0;
  white-space: nowrap;
}
/* Nav tear line: drops down from the label rather than sliding across. */
.nav__link::after {
  content: "";
  position: absolute;
  left: 0; top: 100%;
  width: 1px; height: 0;
  background: var(--ochre);
  transition: height 0.3s var(--ease-out);
}
.nav__link:hover::after,
.nav__link[aria-current="page"]::after { height: 0.6rem; }

.nav__cta { margin-left: var(--s-4); }

/* The header is a fixed 4.5rem. A default .btn is taller than that, so the
   nav variant is tightened rather than letting it overflow the bar. */
.nav .btn {
  padding: 0.72rem 1.35rem;
  font-size: 0.625rem;
  letter-spacing: 0.18em;
}

.nav-toggle { display: none; background: none; border: 0; padding: var(--s-2); cursor: pointer; }

@media (max-width: 60rem) {
  .nav { display: none; }
  .nav-toggle { display: block; }
}

/* ---------------------------------------------------------------------------
   Hero
   ------------------------------------------------------------------------ */
.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  align-items: end;
  color: var(--bone);
  overflow: hidden;
}

.hero__media { position: absolute; inset: 0; }
/*
 * The <picture> wrapper needs the height too.
 *
 * .hero__media is absolutely positioned to fill the hero, and the img is set
 * to 100% — but 100% of a <picture> that has no height of its own, so it
 * collapsed to the photograph's own aspect ratio. On a phone that meant a
 * 260px band of image at the top of an 844px hero and a large empty gradient
 * below it, which is what made every hero look broken on mobile.
 *
 * Desktop hid the fault because a 16:9 photograph in a wide viewport happens
 * to be about the right height anyway.
 */
.hero__media picture { display: block; width: 100%; height: 100%; }
.hero__media img,
.hero__media video { width: 100%; height: 100%; object-fit: cover; }

/* Two-stop scrim: dark enough to read against, light enough to see the animal. */
.hero__media::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(22,17,14,0.90) 0%, rgba(22,17,14,0.42) 45%, rgba(22,17,14,0.14) 72%),
    linear-gradient(to right, rgba(22,17,14,0.72) 0%, rgba(22,17,14,0.34) 38%, transparent 68%);
}

.hero__body {
  position: relative;
  padding: var(--gutter);
  padding-bottom: clamp(3.5rem, 9vh, 7rem);
  max-width: var(--w-wide);
  margin-inline: auto;
  width: 100%;
}

.hero__title {
  font-size: var(--t-hero);
  line-height: 0.98;
  letter-spacing: -0.025em;
  max-width: 15ch;
}

.hero__lead {
  margin-top: var(--s-5);
  max-width: 42ch;
  color: rgba(244, 239, 230, 0.82);
  font-size: var(--t-lead);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  margin-top: var(--s-7);
}

.hero .eyebrow { color: rgba(244, 239, 230, 0.65); }

/* Page-load sequence: the hero settles rather than fading in wholesale. */
.hero [data-rise] {
  opacity: 0;
  transform: translateY(1.25rem);
  animation: rise 1s var(--ease-out) forwards;
}
.hero [data-rise="1"] { animation-delay: 0.15s; }
.hero [data-rise="2"] { animation-delay: 0.3s; }
.hero [data-rise="3"] { animation-delay: 0.45s; }
.hero [data-rise="4"] { animation-delay: 0.6s; }

@keyframes rise {
  to { opacity: 1; transform: none; }
}

@media (max-width: 40rem) {
  .hero__actions,
  .cta__actions { flex-direction: column; align-items: stretch; }
  .hero__actions .btn,
  .cta__actions .btn { justify-content: center; }
  .figures { grid-template-columns: repeat(2, 1fr); }
}

/* ---------------------------------------------------------------------------
   Section heading
   ------------------------------------------------------------------------ */
.sec-head { max-width: 52rem; margin-bottom: var(--s-8); }
.sec-head__title { font-size: var(--t-h2); }
.sec-head__lead { margin-top: var(--s-4); }

/* ---------------------------------------------------------------------------
   Split: image beside text, alternating
   ------------------------------------------------------------------------ */
.split {
  display: grid;
  gap: clamp(var(--s-6), 5vw, var(--s-9));
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 52rem) {
  .split { grid-template-columns: 1fr 1fr; }
  .split[data-flip="true"] .split__media { order: 2; }
}

.split__media { position: relative; aspect-ratio: 4 / 5; overflow: hidden; }
.split__media img { width: 100%; height: 100%; object-fit: cover; }

.split__caption {
  font-size: var(--t-small);
  color: var(--mist);
  margin-top: var(--s-3);
}

/* ---------------------------------------------------------------------------
   Destination rail — horizontal scroll on every viewport, deliberately.
   Browsing places is a lateral act, and it keeps phone parity with desktop.
   ------------------------------------------------------------------------ */
.rail {
  --rail-pad: max(var(--gutter), calc((100vw - var(--w-wide)) / 2 + var(--gutter)));
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(15rem, 22rem);
  gap: var(--s-5);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* Start flush with the text column above, not the viewport edge, so the
     rail reads as part of the section. The trailing pseudo-element restores
     the end padding that flex/grid overflow containers drop. */
  padding-inline: var(--rail-pad);
  /* Without a matching scroll-padding, mandatory snapping pulls the first
     card flush to the scrollport edge and silently cancels the padding above. */
  scroll-padding-inline: var(--rail-pad);
  padding-bottom: var(--s-4);
  scrollbar-width: thin;
  scrollbar-color: var(--sand-line) transparent;
}
.rail::-webkit-scrollbar { height: 3px; }
.rail::-webkit-scrollbar-thumb { background: var(--sand-line); }

.rail > * { scroll-snap-align: start; }

.rail::after {
  content: "";
  width: calc(var(--rail-pad) - var(--s-5));
  min-width: 1px;
}

.place {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--char);
}
.place img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1.1s var(--ease-out), filter var(--dur) var(--ease);
  filter: saturate(0.92);
}
.place:hover img { transform: scale(1.05); filter: saturate(1); }

.place::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to top,
      rgba(22,17,14,0.94) 0%,
      rgba(22,17,14,0.80) 22%,
      rgba(22,17,14,0.30) 52%,
      rgba(22,17,14,0.04) 78%);
}

.place__body {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--s-5);
  color: var(--bone);
  z-index: 1;
}
.place__name { font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking); font-size: 1.5rem; line-height: 1.1; }
.place__note {
  font-size: var(--t-small);
  color: rgba(244,239,230,0.72);
  margin-top: var(--s-2);
  max-width: 28ch;
}
.place__when {
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ochre);
  margin-top: var(--s-3);
}

/* ---------------------------------------------------------------------------
   Card grid
   ------------------------------------------------------------------------ */
.grid {
  display: grid;
  gap: clamp(var(--s-5), 3vw, var(--s-7));
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
}

.card { display: flex; flex-direction: column; gap: var(--s-4); }
.card__media { aspect-ratio: 3 / 2; overflow: hidden; background: var(--sand); }
.card__media img { width: 100%; height: 100%; object-fit: cover; }
.card__title { font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking); font-size: var(--t-h3); }
.card__text { color: var(--ink-soft); font-size: var(--t-small); }

.card__meta {
  display: flex;
  gap: var(--s-4);
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mist);
}

/* ---------------------------------------------------------------------------
   Pull quote
   ------------------------------------------------------------------------ */
.quote { text-align: center; max-width: 40rem; margin-inline: auto; }
.quote__text {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-size: var(--t-h2);
  font-style: italic;
  line-height: 1.24;
  text-wrap: balance;
}
.quote__by {
  margin-top: var(--s-6);
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--mist);
}

/* ---------------------------------------------------------------------------
   Figures — the count of something real, not a vanity metric
   ------------------------------------------------------------------------ */
.figures {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
}
.figure__value {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
  font-size: clamp(2.5rem, 1.5rem + 3vw, 4rem);
  line-height: 1;
}
.figure__label {
  margin-top: var(--s-3);
  font-size: var(--t-small);
  color: var(--ink-soft);
  max-width: 22ch;
}

/* ---------------------------------------------------------------------------
   Call to action band
   ------------------------------------------------------------------------ */
.cta { text-align: center; max-width: 44rem; margin-inline: auto; }
.cta__title { font-size: var(--t-h1); }
.cta__lead { margin-top: var(--s-5); }
.cta__actions {
  margin-top: var(--s-7);
  display: flex;
  gap: var(--s-4);
  justify-content: center;
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------------ */
.site-foot {
  background: var(--char);
  color: var(--bone);
  padding: var(--pad-lg) var(--gutter) var(--s-6);
}
.site-foot__grid {
  max-width: var(--w-wide);
  margin-inline: auto;
  display: grid;
  gap: var(--s-8);
  grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
}
.site-foot h4 {
  font-family: var(--ui);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: var(--s-5);
}
.site-foot li { margin-bottom: var(--s-3); }
.site-foot a { color: rgba(244,239,230,0.75); transition: color var(--dur) var(--ease); }
.site-foot a:hover { color: var(--bone); }

.site-foot__base {
  max-width: var(--w-wide);
  margin: var(--s-8) auto 0;
  padding-top: var(--s-5);
  border-top: 1px solid var(--char-line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  justify-content: space-between;
  font-size: var(--t-small);
  color: rgba(244,239,230,0.5);
}

/* ---------------------------------------------------------------------------
   Scroll reveal — one shared observer, applied sparingly
   ------------------------------------------------------------------------ */
/*
 * Scroll-reveal, for the public pages only.
 *
 * The wizard uses data-reveal for something entirely different — which panel
 * a date option opens — and this rule was hiding those buttons at opacity 0
 * until an IntersectionObserver that does not run on the wizard marked them
 * seen. Two of the three date options were invisible and the step looked
 * broken. Scoped to the site body so the two meanings cannot collide.
 */
body:not(.wz-page) [data-reveal] {
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity 0.85s var(--ease-out), transform 0.85s var(--ease-out);
}
body:not(.wz-page) [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  body:not(.wz-page) [data-reveal] { opacity: 1; transform: none; }
  .hero [data-rise] { opacity: 1; transform: none; animation: none; }
}

/* ---------------------------------------------------------------------------
   Editor-only
   ------------------------------------------------------------------------ */
.blk-error {
  border: 1px dashed var(--rust);
  background: rgba(154, 59, 31, 0.06);
  padding: var(--s-5);
  font-family: var(--ui);
  font-size: var(--t-small);
  color: var(--rust);
}

.img--empty {
  background: repeating-linear-gradient(45deg, var(--sand) 0 8px, var(--bone) 8px 16px);
  aspect-ratio: 3 / 2;
}

.skip-link {
  position: absolute;
  left: var(--s-4); top: var(--s-4);
  transform: translateY(-200%);
  background: var(--ochre);
  color: var(--char);
  padding: var(--s-3) var(--s-5);
  z-index: 1000;
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  transition: transform 0.2s var(--ease);
}
.skip-link:focus { transform: none; }

/* ---------------------------------------------------------------------------
   Gallery
   ---------------------------------------------------------------------------
   Safari sells on photographs, so a portrait is allowed to stay a portrait
   rather than being cropped square to keep a grid tidy.
   ------------------------------------------------------------------------ */
.gal {
  display: grid;
  gap: var(--s-3);
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  grid-auto-rows: 14rem;
}
.gal__item { margin: 0; overflow: hidden; position: relative; background: var(--sand); }
.gal__item img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.1s var(--ease-out); }
.gal__item:hover img { transform: scale(1.04); }
.gal__item figcaption {
  position: absolute; inset: auto 0 0 0;
  padding: 2rem var(--s-4) var(--s-3);
  background: linear-gradient(to top, rgba(22,17,14,.85), transparent);
  color: var(--bone); font-size: var(--t-small);
}

@media (min-width: 46rem) {
  .gal--mosaic .gal__item--wide { grid-column: span 2; }
  .gal--mosaic .gal__item--tall { grid-row: span 2; }
}
.gal--even { grid-auto-rows: 13rem; }
.gal--strip {
  grid-auto-flow: column;
  grid-auto-columns: minmax(15rem, 1fr);
  grid-template-columns: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
.gal--strip .gal__item { scroll-snap-align: start; }
.gal__caption { margin-top: var(--s-4); font-size: var(--t-small); color: var(--mist); }

/* ---------------------------------------------------------------------------
   Questions
   ------------------------------------------------------------------------ */
.faq { max-width: var(--w-narrow); }
.faq__item { border-bottom: 1px solid var(--sand-line); }
.faq__q {
  padding: var(--s-5) 2rem var(--s-5) 0;
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-size: var(--t-h3);
  line-height: 1.3;
  cursor: pointer;
  list-style: none;
  position: relative;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {
  content: "";
  position: absolute; right: .25rem; top: 50%;
  width: .75rem; height: 1px;
  background: var(--ochre);
  transition: transform .3s var(--ease);
}
.faq__q::before {
  content: "";
  position: absolute; right: .25rem; top: 50%;
  width: .75rem; height: 1px;
  background: var(--ochre);
  transform: rotate(90deg);
  transition: opacity .3s var(--ease);
}
.faq__item[open] .faq__q::before { opacity: 0; }
.faq__a { padding-bottom: var(--s-5); max-width: 60ch; }

/* ---------------------------------------------------------------------------
   Cards
   ------------------------------------------------------------------------ */
.cards {
  display: grid;
  gap: clamp(var(--s-5), 3vw, var(--s-7));
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
}
@media (min-width: 60rem) {
  .cards { grid-template-columns: repeat(var(--cols, 3), 1fr); }
}

.cards__card { display: flex; flex-direction: column; gap: var(--s-4); }
a.cards__card:hover .cards__title { color: var(--ochre); }
a.cards__card:hover .cards__media img { transform: scale(1.05); }

.cards__media { aspect-ratio: 3 / 2; overflow: hidden; background: var(--sand); }
.cards__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.1s var(--ease-out); }

.cards__eyebrow {
  font-size: var(--t-micro); letter-spacing: var(--track-eyebrow);
  text-transform: uppercase; color: var(--mist); display: block; margin-bottom: var(--s-2);
}
.cards__title {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking); font-size: var(--t-h3); line-height: 1.2;
  transition: color var(--dur) var(--ease);
}
.cards__text { font-size: var(--t-small); color: var(--ink-soft); line-height: 1.6; margin-top: var(--s-2); }
.cards__meta {
  margin-top: var(--s-3); font-size: var(--t-micro);
  letter-spacing: .1em; text-transform: uppercase; color: var(--ochre);
}

/* Text over the photograph, for a shorter, more dramatic card. */
.cards--overlay .cards__card { position: relative; aspect-ratio: 3 / 4; }
.cards--overlay .cards__media { position: absolute; inset: 0; aspect-ratio: auto; }
.cards--overlay .cards__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(22,17,14,.9), rgba(22,17,14,.05) 60%);
}
.cards--overlay .cards__body {
  position: relative; z-index: 1; margin-top: auto; padding: var(--s-5); color: var(--bone);
}
.cards--overlay .cards__text { color: rgba(244,239,230,.78); }

/* ---------------------------------------------------------------------------
   Itinerary — the same rail as the proposal, so website and quote agree
   ------------------------------------------------------------------------ */
.itin { max-width: var(--w-narrow); }
.itin__day { display: grid; grid-template-columns: 2.75rem 1fr; gap: var(--s-4); }
.itin__rail { position: relative; display: flex; justify-content: center; }
.itin__rail::before {
  content: ""; position: absolute; top: 0; bottom: 0; width: 1px; background: var(--sand-line);
}
.itin__day:first-child .itin__rail::before { top: 1.4rem; }
.itin__day:last-child .itin__rail::before { bottom: calc(100% - 1.4rem); }
.itin__n {
  position: relative; z-index: 1;
  width: 2rem; height: 2rem; margin-top: .4rem;
  border-radius: 50%; background: var(--bone);
  border: 1px solid var(--sand-line);
  display: grid; place-items: center;
  font-size: var(--t-small);
  font-variant-numeric: lining-nums;
  color: var(--ink-soft);
}
.itin__body { padding-bottom: var(--s-8); min-width: 0; }
.itin__where {
  font-size: var(--t-micro); letter-spacing: var(--track-eyebrow);
  text-transform: uppercase; color: var(--ochre); margin-top: .8rem;
}
.itin__title { font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking); font-size: var(--t-h3); margin-top: .2rem; }
.itin__img { margin-top: var(--s-4); aspect-ratio: 3 / 2; overflow: hidden; }
.itin__img img { width: 100%; height: 100%; object-fit: cover; }
.itin__text { margin-top: var(--s-4); color: var(--ink-soft); line-height: 1.65; }
.itin__stay {
  margin-top: var(--s-3); padding: var(--s-3) var(--s-4);
  background: var(--white); border: 1px solid var(--sand-line);
  font-size: var(--t-small);
}

/* ---------------------------------------------------------------------------
   Photo band
   ------------------------------------------------------------------------ */
.band { position: relative; overflow: hidden; }
.band--short { height: clamp(16rem, 38vh, 26rem); }
.band--tall  { height: clamp(24rem, 66vh, 40rem); }
.band img { width: 100%; height: 100%; object-fit: cover; }
.band::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(22,17,14,.6), rgba(22,17,14,.1));
}
.band__text {
  position: absolute; inset: auto 0 0 0; z-index: 1;
  padding: var(--gutter);
  max-width: var(--w-wide); margin-inline: auto;
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-size: var(--t-h2);
  line-height: 1.15;
  color: var(--bone);
  text-wrap: balance;
}

/* Shown only to a signed-in operator when the schema is behind the code. */
.updatebar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: .75rem;
  padding: .625rem var(--gutter);
  background: var(--rust);
  color: var(--bone);
  font-size: var(--t-small);
  text-align: center;
}
.updatebar a {
  color: var(--bone);
  text-decoration: underline;
  text-underline-offset: .2em;
  font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Mobile drawer
   ---------------------------------------------------------------------------
   Below 60rem the bar collapses to a single control. The same items as the
   desktop menu, as an accordion — nobody should have to hunt for something on
   a phone that was one hover away on a laptop.
   ------------------------------------------------------------------------ */
.drawer { position: fixed; inset: 0; z-index: 950; }
.drawer[hidden] { display: none; }
.drawer::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(22, 17, 14, .62);
  animation: drawer-fade .2s ease both;
}
@keyframes drawer-fade { from { opacity: 0 } to { opacity: 1 } }

.drawer__sheet {
  position: absolute;
  inset: 0 0 0 auto;
  width: min(23rem, 92vw);
  background: var(--bone);
  color: var(--ink);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding-bottom: env(safe-area-inset-bottom);
  animation: drawer-slide .28s var(--ease-out) both;
}
@keyframes drawer-slide { from { transform: translateX(100%) } to { transform: none } }
@media (prefers-reduced-motion: reduce) { .drawer__sheet { animation: none } }

.drawer__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  padding: var(--s-5);
  border-bottom: 1px solid var(--sand-line);
}
.drawer__head .brand { color: var(--ink); margin-right: 0; }
.drawer__close {
  background: none; border: 0; cursor: pointer;
  font-size: 1.75rem; line-height: 1; color: var(--ink);
  padding: 0 .25rem;
}

.drawer__list { flex: 1; padding: var(--s-2) 0; }
.drawer__item { border-bottom: 1px solid var(--sand-line); }
.drawer__link,
.drawer__group summary {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s-4) var(--s-5);
  font-size: 1.0625rem;
  cursor: pointer;
  list-style: none;
}
.drawer__group summary::-webkit-details-marker { display: none; }
.drawer__group summary svg { width: 10px; height: 6px; transition: transform .2s var(--ease); }
.drawer__group[open] summary svg { transform: rotate(180deg); }
.drawer__sub { padding: 0 var(--s-5) var(--s-4); }
.drawer__sub a { display: block; padding: .5rem 0; font-size: .9375rem; color: var(--ink-soft); }
.drawer__sub em { font-style: normal; color: var(--ochre); }
.drawer__link--cta { color: var(--ochre); }

.drawer__foot { padding: var(--s-5); border-top: 1px solid var(--sand-line); }
.drawer__foot .btn { width: 100%; justify-content: center; }
.drawer__foot p { margin-top: var(--s-4); font-size: var(--t-small); color: var(--mist); text-align: center; }


/* ---------------------------------------------------------------------------
   Menu panels
   ---------------------------------------------------------------------------
   These float over the page rather than covering it. No full-width bar, no
   opaque backdrop — the hero stays visible behind, and each panel is only as
   wide as it needs to be, positioned under the item that opened it.

   That is the whole difference between navigation that feels light and a
   dropdown that feels like leaving the page.
   ------------------------------------------------------------------------ */

.nav__group { position: relative; }

/* A toggle must be indistinguishable from a link in the bar. Without this it
   renders as a default browser button — a white box with a giant chevron. */
.nav__link--toggle {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  background: none;
  border: 0;
  padding: .4rem 0;
  cursor: pointer;
  color: inherit;
  font-family: var(--ui);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  white-space: nowrap;
  position: relative;
}
.nav__chev {
  width: 8px;
  height: 5px;
  flex: none;
  opacity: .7;
  transition: transform .25s var(--ease);
}
[aria-expanded="true"] .nav__chev { transform: rotate(180deg); }

/* The tear line drops from an open panel's label too. */
.nav__link--toggle::after {
  content: "";
  position: absolute;
  left: 0; top: 100%;
  width: 1px; height: 0;
  background: var(--ochre);
  transition: height .3s var(--ease-out);
}
.nav__link--toggle:hover::after,
.nav__link--toggle[aria-expanded="true"]::after { height: .6rem; }
.nav__link--toggle[aria-expanded="true"] { color: var(--ochre); }

.megapanel {
  position: absolute;
  top: calc(100% + 0.9rem);
  z-index: 20;
  /* Sized to its contents. A panel of seven tiles and a panel of eight links
     have no business being the same width. */
  width: max-content;
  max-width: min(58rem, calc(100vw - 2 * var(--gutter)));
}

/* Under its own item by default; the wide ones are nudged so they never run
   off the right edge of the window. */
.megapanel { left: 50%; transform: translateX(-50%); }
.nav__group:nth-last-child(-n+3) .megapanel { left: auto; right: 0; transform: none; }

.megapanel[aria-hidden="true"] {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}
.megapanel[aria-hidden="false"] {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  animation: panel-drop .26s var(--ease-out) both;
}
@keyframes panel-drop {
  from { opacity: 0; transform: translateY(-8px) translateX(var(--panel-x, -50%)); }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .megapanel[aria-hidden="false"] { animation: none; }
}

.megapanel__inner { padding: 0; }
.megapanel__intro { display: none; }

/* A way through to the full list, since a panel only shows the first eight.
   Set on its own line beneath the tiles rather than floated, so it reads as
   the end of the set rather than a stray link. */
.megapanel__all {
  display: inline-block;
  margin-top: .7rem;
  font-size: var(--t-micro);
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  color: var(--bone);
  text-shadow: 0 1px 10px rgba(0, 0, 0, .6);
}
.megapanel__all:hover { color: var(--ochre); }
/* The link panels are already a bounded sheet and do not need it. */
.megapanel:has(.megalinks) .megapanel__all,
.megapanel:has(.megacols) .megapanel__all { display: none; }

/* --- Tiles: a photograph with the label over it -------------------------- */
.megatiles {
  display: grid;
  gap: .5rem;
  grid-template-columns: repeat(4, 11.5rem);
  grid-auto-rows: 8.6rem;
}
/* The list item is the grid cell; the link must fill it, or an absolutely
   positioned label measures against the wrong box and lands outside it. */
.megatiles > li,
.megacards > li { display: flex; min-height: 0; }
.megatiles > li > a,
.megacards > li > a { flex: 1; min-height: 0; }
@media (max-width: 68rem) {
  .megatiles { grid-template-columns: repeat(3, 11rem); }
}



.megatile {
  position: relative;
  display: block;
  height: 100%;
  overflow: hidden;
  /* 2px, not 6. The rest of the site is squared off — buttons, blocks, the
     hero. Softly rounded tiles would belong to a different design. */
  border-radius: 2px;
  background: rgba(22, 17, 14, .3);
  box-shadow: 0 10px 26px -12px rgba(0, 0, 0, .55);
}
.megatile picture { display: block; width: 100%; height: 100%; }
.megatile img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .9s var(--ease-out);
}
.megatile::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top,
              rgba(15, 12, 10, .78) 0%,
              rgba(15, 12, 10, .28) 45%,
              rgba(15, 12, 10, 0) 72%);
}
.megatile:hover img { transform: scale(1.05); }

/* A small label above the name — "our home", "new for 2027". Sits inside the
   scrim so it stays legible on any photograph. */
.megatile__body {
  position: absolute;
  left: .75rem; right: .75rem; bottom: .6rem;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: .1rem;
}
.megatile__eyebrow {
  font-size: .5625rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ochre);
  text-shadow: 0 1px 10px rgba(0, 0, 0, .6);
}

.megatile__label {
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: .9375rem;
  line-height: 1.25;
  color: var(--bone);
  text-shadow: 0 1px 12px rgba(0, 0, 0, .5);
}

/* --- Cards: same tile, with a line of detail beneath --------------------- */
.megacards {
  display: grid;
  gap: .5rem;
  grid-template-columns: repeat(4, 11.5rem);
  grid-auto-rows: 8.6rem;
}
@media (max-width: 68rem) { .megacards { grid-template-columns: repeat(3, 11rem); } }


.megacard {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 2px;
  background: rgba(22, 17, 14, .3);
  box-shadow: 0 10px 26px -12px rgba(0, 0, 0, .55);
}
.megacard__media { display: block; width: 100%; height: 100%; }
.megacard__media picture { display: block; width: 100%; height: 100%; }
.megacard__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .9s var(--ease-out);
}
.megacard::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top,
              rgba(15, 12, 10, .8) 0%,
              rgba(15, 12, 10, .3) 48%,
              rgba(15, 12, 10, 0) 75%);
}
.megacard:hover .megacard__media img { transform: scale(1.05); }
/* One positioned box holding both lines in normal flow.
   Two absolutely positioned elements at fixed offsets collide the moment a
   title wraps to a second line — which most of them do. */
.megacard__body {
  position: absolute;
  left: .75rem; right: .75rem; bottom: .6rem;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: .15rem;
}
.megacard__name {
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: .9375rem;
  line-height: 1.2;
  color: var(--bone);
  text-shadow: 0 1px 12px rgba(0, 0, 0, .5);
}
.megacard__meta {
  font-size: .625rem;
  letter-spacing: .06em;
  color: rgba(244, 239, 230, .74);
  text-shadow: 0 1px 10px rgba(0, 0, 0, .6);
}

/* --- Link panels: a narrow translucent sheet ----------------------------- */
.megapanel:has(.megalinks) .megapanel__inner,
.megapanel:has(.megacols) .megapanel__inner {
  background: rgba(28, 40, 32, .78);
  backdrop-filter: blur(16px) saturate(1.15);
  border-radius: 6px;
  padding: 1.1rem 1.35rem;
  box-shadow: 0 16px 40px -18px rgba(0, 0, 0, .6);
}

.megacols {
  display: grid;
  gap: 2rem;
  grid-auto-flow: column;
  grid-auto-columns: max-content;
}
.megalinks--wrap { display: grid; grid-template-columns: repeat(2, max-content); gap: 0 2rem; }

.megapanel__heading {
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: .5rem;
}
.megalinks a { display: block; padding: .38rem 0; }
.megalinks span {
  display: block;
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: .9375rem;
  color: var(--bone);
  white-space: nowrap;
}
.megalinks a:hover span { color: var(--ochre); }
/* The descriptions belong on the page, not in a dropdown someone is passing
   through. They made the panel three times taller for no gain. */
.megalinks em { display: none; }

/* --- Featured: a tile like the others ------------------------------------ */
.megafeature { display: none; }

@media (max-width: 60rem) { .megapanel { display: none; } }

/* ---------------------------------------------------------------------------
   What makes these Duma's rather than anyone's
   ---------------------------------------------------------------------------
   Three deliberate departures from the standard photo-tile menu:

   1. The tear line. The site's signature device is a hairline that drops
      downward — under section eyebrows, under the active nav item. Here it
      draws down the left edge of whichever tile is under the cursor, which
      ties the menu to the rest of the design rather than leaving it as a
      component borrowed from somewhere else.

   2. Colour as focus. Tiles rest slightly desaturated and come to full
      strength on hover, so the one being considered is the only one fully
      present. Seven photographs at full saturation compete; one does not.

   3. A staggered arrival. The tiles come in over about 200ms rather than
      all at once, left to right, which reads as a hand laying out cards.
   ------------------------------------------------------------------------ */

.megatile img,
.megacard__media img {
  filter: saturate(.78) contrast(1.02);
  transition: transform .9s var(--ease-out), filter .45s var(--ease);
}
.megatile:hover img,
.megacard:hover .megacard__media img {
  filter: saturate(1.06) contrast(1.03);
}

/* The tear line, drawn on the tile itself. */
.megatile::before,
.megacard::before {
  content: "";
  position: absolute;
  left: 0; top: 0;
  width: 2px;
  height: 0;
  z-index: 2;
  background: var(--ochre);
  transition: height .34s var(--ease-out);
}
.megatile:hover::before,
.megacard:hover::before { height: 2.2rem; }

/* Focus gets the same treatment, so keyboard use is not a second-class path. */
.megatile:focus-visible::before,
.megacard:focus-visible::before { height: 2.2rem; }

/* The cascade. Each tile is held back a little longer than the one before,
   which is what makes it read as dealt rather than switched on. */
.megapanel[aria-hidden="false"] .megatiles > li,
.megapanel[aria-hidden="false"] .megacards > li {
  animation: tile-in .34s var(--ease-out) both;
}
.megapanel[aria-hidden="false"] li:nth-child(1) { animation-delay: 0ms; }
.megapanel[aria-hidden="false"] li:nth-child(2) { animation-delay: 32ms; }
.megapanel[aria-hidden="false"] li:nth-child(3) { animation-delay: 64ms; }
.megapanel[aria-hidden="false"] li:nth-child(4) { animation-delay: 96ms; }
.megapanel[aria-hidden="false"] li:nth-child(5) { animation-delay: 118ms; }
.megapanel[aria-hidden="false"] li:nth-child(6) { animation-delay: 140ms; }
.megapanel[aria-hidden="false"] li:nth-child(7) { animation-delay: 158ms; }
.megapanel[aria-hidden="false"] li:nth-child(n+8) { animation-delay: 172ms; }

@keyframes tile-in {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .megapanel[aria-hidden="false"] .megatiles > li,
  .megapanel[aria-hidden="false"] .megacards > li { animation: none; }
  .megatile::before, .megacard::before { transition: none; }
}



/* ---------------------------------------------------------------------------
   Polish
   ------------------------------------------------------------------------ */

/* A tile lifts very slightly when hovered. Two pixels — enough to register as
   a response, not enough to make the grid feel loose. */
.megatile,
.megacard {
  transition: transform .28s var(--ease-out), box-shadow .28s var(--ease-out);
  will-change: transform;
}
.megatile:hover,
.megacard:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 32px -14px rgba(0, 0, 0, .62);
}

/* The scrim deepens with it, so the label stays as legible on a lifted tile
   as on a resting one. */
.megatile::after,
.megacard::after { transition: background .3s var(--ease); }
.megatile:hover::after,
.megacard:hover::after {
  background: linear-gradient(to top,
              rgba(15, 12, 10, .84) 0%,
              rgba(15, 12, 10, .34) 48%,
              rgba(15, 12, 10, 0) 76%);
}

/* Tiles that carry an eyebrow get a fraction more room at the foot, so the
   two lines are not crowded into the corner. */
.megatile__body:has(.megatile__eyebrow) { bottom: .7rem; }

/* The link between panel and bar. Without it an open panel looks detached —
   a floating rectangle with no relationship to what opened it. */
.nav__link--toggle[aria-expanded="true"]::after { height: .9rem; }

/* The "all …" link sits under the tiles as a quiet last item rather than
   competing with them. */
.megapanel__all {
  opacity: .82;
  transition: opacity .2s var(--ease), color .2s var(--ease);
}
.megapanel__all:hover { opacity: 1; }

/* Link panels: a hairline rule between columns, so three groups read as three
   groups rather than one wide block of names. */
.megacols > * + * {
  padding-left: 2rem;
  margin-left: 0;
  border-left: 1px solid rgba(244, 239, 230, .12);
}
.megacols { gap: 0; }

/* And a little more air inside the sheet, which was tight against its edges. */
.megapanel:has(.megalinks) .megapanel__inner,
.megapanel:has(.megacols) .megapanel__inner { padding: 1.25rem 1.5rem; }

/* Focus visible on every panel link, since a keyboard user gets no hover. */
.megatile:focus-visible,
.megacard:focus-visible,
.megalinks a:focus-visible {
  outline: 1px solid var(--ochre);
  outline-offset: 2px;
}

/* A tile holds its dominant colour until its photograph arrives, so a panel
   opening before the images land shows blocks of the right colour rather than
   empty sand. */
.megatile img[data-panel-src],
.megacard img[data-panel-src] { opacity: 0; }
.megatile img,
.megacard__media img { transition: opacity .4s var(--ease), transform .9s var(--ease-out); }


/* ---------------------------------------------------------------------------
   Hero slider
   ---------------------------------------------------------------------------
   Slides are heroes, stacked. Everything about how one looks — the scrim, the
   type, the rise of the words, the buttons — comes from .hero itself, so this
   file only decides which is showing. Restyle the hero and the slider follows.
   ------------------------------------------------------------------------ */

.heroslider { position: relative; isolation: isolate; }

.heroslider__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .9s var(--ease);
}
/* The current slide is in normal flow, so the block takes its height from
   whichever is showing rather than needing one hard-coded. */
.heroslider__slide.is-current {
  position: relative;
  opacity: 1;
  visibility: visible;
}

/* The photograph for a slide that has not been fetched yet is painted as a
   background, so swapping it never disturbs the srcset on the first. */
.heroslider__slide .hero__media > span {
  display: block;
  width: 100%;
  height: 100%;
  background-size: cover;
  background-position: center;
}

/* Only the visible slide animates its words in; otherwise every slide would
   run its rise at page load and the timings would be spent by the time
   anybody saw them. */
.heroslider__slide:not(.is-current) [data-rise] { animation: none; opacity: 0; }

/* --- Dots ---------------------------------------------------------------- */
.heroslider__controls {
  position: absolute;
  z-index: 5;
  left: 0;
  right: 0;
  bottom: clamp(1.5rem, 4vh, 3rem);
  display: flex;
  justify-content: center;
  pointer-events: none;
}
.heroslider__dots {
  display: flex;
  align-items: center;
  gap: .5rem;
  pointer-events: auto;
}
.heroslider__dot {
  /* The mark is small; the target is not. A 2px line is unusable on a phone,
     so the button stays finger-sized and only its contents are small. */
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  cursor: pointer;
}
.heroslider__dot span {
  display: block;
  width: 1.75rem;
  height: 2px;
  background: rgba(244, 239, 230, .32);
  transition: background-color .3s var(--ease), transform .3s var(--ease);
}
.heroslider__dot:hover span { background: rgba(244, 239, 230, .75); }
.heroslider__dot.is-on span { background: var(--ochre); transform: scaleY(2); }
.heroslider__dot:focus-visible { outline: 1px solid var(--ochre); outline-offset: -6px; }

@media (prefers-reduced-motion: reduce) {
  .heroslider__slide { transition: none; }
}

/* ---------------------------------------------------------------------------
   Where to next
   ---------------------------------------------------------------------------
   The way down from a country to its parks, and from a park to the safaris
   that go there. A destination page used to end at its own description, which
   left a reader interested and with nowhere to go.
   ------------------------------------------------------------------------ */
.dtree {
  max-width: var(--w-wide);
  margin-inline: auto;
  padding: var(--s-8) var(--gutter);
}
.dtree--tours { padding-top: 0; }

.dtree__title {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-size: clamp(1.5rem, 1.1rem + 1.2vw, 2.125rem);
  margin-bottom: var(--s-6);
}

.dtree__grid {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
}

.dcard { display: block; }
.dcard__media {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--sand);
  margin-bottom: var(--s-3);
}
.dcard__media picture { display: block; width: 100%; height: 100%; }
.dcard__media img {
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(.85);
  transition: transform .8s var(--ease-out), filter .35s var(--ease);
}
.dcard:hover .dcard__media img { transform: scale(1.04); filter: saturate(1.02); }

.dcard__kind {
  display: block;
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: .2rem;
}
.dcard__name {
  display: block;
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.1875rem;
  line-height: 1.2;
}
.dcard:hover .dcard__name { color: var(--ochre); }
.dcard__line {
  display: block;
  font-size: var(--t-small);
  color: var(--mist);
  line-height: 1.5;
  margin-top: .25rem;
}
.dcard__price {
  display: block;
  font-size: var(--t-micro);
  color: var(--ink-soft);
  margin-top: .35rem;
}


/* ---------------------------------------------------------------------------
   Safari details
   ---------------------------------------------------------------------------
   The first version gave every section the same full-width band and the same
   weight, so the page ran long and nothing led. What sells a safari is the
   note and the highlights; what a guest checks before booking is the rates and
   the inclusions. The second group is set tighter, side by side, and folded.
   ------------------------------------------------------------------------ */

.tfacts, .tnote, .thigh, .tstays, .tref {
  max-width: var(--w-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Tighter than the rest of the site. These sections belong to each other and
   reading them as one passage is the point. */
.tnote, .thigh, .tstays { padding-block: var(--s-6); }

.tsection__eyebrow {
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ochre);
  /* Close to its title, so the two read as one unit rather than two lines. */
  margin-bottom: .5rem;
}
.tsection__title {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  /* Smaller than a page title. These are signposts inside a page, and at the
     old size four of them read as four separate pages. */
  font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);
  line-height: 1.15;
  margin-bottom: var(--s-5);
}
.tsection__title em { font-style: italic; }

/* --- Facts: one quiet line ----------------------------------------------- */
.tfacts {
  padding-block: var(--s-5);
  border-block: 1px solid var(--sand-line);
}
.tfacts__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-5) 0;
  margin: 0;
}
/* A hairline between facts rather than relying on the gap alone, which left
   "Amboseli · Maasai Mara" looking like it belonged to the label before it. */
.tfacts__item + .tfacts__item {
  padding-left: var(--s-6);
  margin-left: var(--s-6);
  border-left: 1px solid var(--sand-line);
}
@media (max-width: 46rem) {
  .tfacts__item + .tfacts__item {
    padding-left: 0; margin-left: 0; border-left: 0;
    flex-basis: 100%;
  }
}
/* The inline version lived here and was overridden two lines later by the
   stacked one — the same stale-rule pattern that made the score pill
   unreadable. Removed rather than left to confuse the next reader. */
/* Stacked, not inline. A label beside its value at the same size reads as a
   form; above it, quieter and smaller, it reads as a fact. */
.tfacts__item { display: block; }
.tfacts__item dt {
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--mist);
  margin-bottom: .2rem;
}
.tfacts__item dd {
  margin: 0;
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.0625rem;
  line-height: 1.25;
}

/* --- The note ------------------------------------------------------------ */
/* Measure, not width. The note ran to 84rem — two lines of roughly 140
   characters, which nobody reads properly. --w-text never existed, so the
   constraint silently did nothing. */
.tnote {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}
.tnote__body { max-width: 62ch; }
.tnote__label {
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: .5rem;
}
.tnote__body {
  font-family: var(--display);
  font-size: clamp(1.125rem, 1rem + .6vw, 1.5rem);
  line-height: 1.45;
  text-wrap: pretty;
}

/* --- Highlights: two columns, close together ----------------------------- */
/* Two columns, not three. Four highlights across three columns leaves one
   stranded on a second row with two empty cells beside it, and most safaris
   have an even number of things worth saying. */
.thigh__list {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--s-5) var(--s-8);
  grid-template-columns: repeat(auto-fit, minmax(min(26rem, 100%), 1fr));
}
.thigh__item { display: flex; gap: var(--s-4); }
.thigh__num {
  flex: none;
  font-family: var(--display);
  font-size: .8125rem;
  letter-spacing: .06em;
  color: var(--ochre);
  /* Sits on the baseline of the title rather than the top of the box. */
  padding-top: .05rem;
  min-width: 1.375rem;
  text-align: right;
}
.thigh__title { font-weight: 600; font-size: var(--t-body); margin-bottom: .25rem; line-height: 1.35; }
.thigh__body { font-size: var(--t-small); color: var(--mist); line-height: 1.55; }

/* --- Where you sleep: a row of cards, not a stack of banners -------------- */
.tstays__list {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
}
.tstay { display: block; }
.tstay__media {
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: var(--sand);
  margin-bottom: var(--s-3);
}
.tstay__media img {
  filter: saturate(.88);
  transition: transform .8s var(--ease-out), filter .35s var(--ease);
}
.tstay:hover .tstay__media img { transform: scale(1.03); filter: saturate(1.02); }
.tstay__media picture { display: block; width: 100%; height: 100%; }
.tstay__media img { width: 100%; height: 100%; object-fit: cover; }
.tstay__where {
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: .15rem;
}
.tstay__name {
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.0625rem;
  line-height: 1.25;
}
.tstay__nights { font-size: var(--t-micro); color: var(--mist); margin-top: .15rem; }
.tstay__text {
  margin-top: .5rem;
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--mist);
}

/* --- Before you book: everything factual, together ----------------------- */
.tref {
  padding-block: var(--s-7);
  margin-top: var(--s-4);
  border-top: 1px solid var(--sand-line);
}
.tref__cols {
  display: grid;
  gap: var(--s-7);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
@media (max-width: 52rem) { .tref__cols { grid-template-columns: 1fr; } }

.tref__title {
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.125rem;
  margin-bottom: var(--s-4);
}

.trates__table { width: 100%; border-collapse: collapse; font-size: var(--t-small); }
.trates__table th {
  text-align: left;
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--mist);
  font-weight: 500;
  padding-bottom: .5rem;
  border-bottom: 1px solid var(--sand-line);
}
.trates__table td { padding: .625rem 0; border-bottom: 1px solid var(--sand-line); }
/* The figures are what people compare, so they line up — and the heading
   lines up with them, which it did not. */
.trates__table th:last-child { text-align: right; }
.trates__table td:last-child {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: right;
  font-weight: 500;
}
/* No rule under the last row: the note beneath it already closes the table,
   and two lines together read as a mistake. */
.trates__table tr:last-child td { border-bottom: 0; }
.trates__note { margin-top: var(--s-3); font-size: var(--t-micro); color: var(--mist); }

.tincl__cols { display: grid; gap: var(--s-5); }
.tincl__col h4 {
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--mist);
  margin-bottom: .625rem;
}
.tincl__col ul { list-style: none; padding: 0; display: grid; gap: .375rem; }
.tincl__col li {
  position: relative;
  padding-left: .875rem;
  font-size: var(--t-small);
  line-height: 1.5;
}
.tincl__col li::before {
  content: "";
  position: absolute;
  left: 0; top: .62em;
  width: .3125rem; height: 1px;
  background: var(--ochre);
}
/* Folded until asked for: four lines is enough to judge by. */
.tincl__col li.is-extra { display: none; }
.tincl__col.is-open li.is-extra { display: block; }
.tincl__more {
  margin-top: .5rem;
  padding: 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--sand-line);
  font-size: var(--t-micro);
  color: var(--ink-soft);
  cursor: pointer;
}
.tincl__more:hover { color: var(--ochre); border-color: var(--ochre); }
.tincl__col.is-open .tincl__more { display: none; }

/* ---------------------------------------------------------------------------
   Safaris in a category
   ---------------------------------------------------------------------------
   The "safaris for" pages were prose with no way through to a safari. Cards
   carry what somebody chooses between — where it goes, how long, from-price —
   rather than a name they have to click to understand.
   ------------------------------------------------------------------------ */
.ctours {
  max-width: var(--w-wide);
  margin-inline: auto;
  padding: var(--s-7) var(--gutter);
}
.ctours__title {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2.125rem);
  line-height: 1.15;
}
.ctours__title em { font-style: italic; }
.ctours__intro {
  margin-top: var(--s-3);
  max-width: 58ch;
  color: var(--ink-soft);
  line-height: 1.65;
}
.ctours__grid {
  list-style: none;
  padding: 0;
  margin-top: var(--s-6);
  display: grid;
  gap: var(--s-6) var(--s-5);
  grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr));
}

.ctour { display: block; }
.ctour__media {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--sand);
  margin-bottom: var(--s-3);
}
.ctour__media picture { display: block; width: 100%; height: 100%; }
.ctour__media img {
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(.86);
  transition: transform .8s var(--ease-out), filter .35s var(--ease);
}
.ctour:hover .ctour__media img { transform: scale(1.04); filter: saturate(1.02); }

.ctour__where {
  display: block;
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: .2rem;
}
.ctour__name {
  display: block;
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.1875rem;
  line-height: 1.2;
}
.ctour:hover .ctour__name { color: var(--ochre); }
.ctour__line {
  display: block;
  font-size: var(--t-small);
  color: var(--mist);
  line-height: 1.5;
  margin-top: .25rem;
}
/* Nights and price on one line, separated by a rule rather than a bullet: the
   two facts are different kinds of thing and should not read as a list. */
.ctour__facts {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem var(--s-3);
  margin-top: var(--s-3);
  padding-top: var(--s-3);
  border-top: 1px solid var(--sand-line);
  font-size: var(--t-micro);
  color: var(--mist);
}
.ctour__price { color: var(--ink-soft); font-weight: 500; }

/* ---------------------------------------------------------------------------
   What makes or breaks a kind of trip
   ---------------------------------------------------------------------------
   Above the safaris on purpose: somebody reading the family page wants to know
   what makes a family safari good before being shown four of them.
   ------------------------------------------------------------------------ */
.cnotes {
  max-width: var(--w-wide);
  margin-inline: auto;
  padding: var(--s-7) var(--gutter) var(--s-5);
}
.cnotes__list {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--s-5) var(--s-8);
  grid-template-columns: repeat(auto-fit, minmax(min(24rem, 100%), 1fr));
}
.cnotes__item { display: flex; gap: var(--s-4); }
.cnotes__num {
  flex: none;
  font-family: var(--display);
  font-size: .875rem;
  font-variant-numeric: tabular-nums;
  color: var(--ochre);
  padding-top: .1rem;
  min-width: 1.5rem;
}
.cnotes__title { font-weight: 600; margin-bottom: .25rem; line-height: 1.35; }
.cnotes__body { font-size: var(--t-small); color: var(--mist); line-height: 1.6; }

/* The first version of the score pill lived here, styled for a light
   background. When it was redesigned as a dark pill the old rules were left
   behind, so ".revs__score-src" still set dark text — which then sat on the
   charcoal and was unreadable. Removed; the current rules are further down. */

/* --- "All journeys", as a tile --------------------------------------------
   It used to sit under the grid as bare text over whatever photograph the page
   had behind it — pale letters on a busy background, effectively invisible.
   As the last tile it sits on solid ground with everything it belongs to. */
.megatile--more {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: .35rem;
  min-height: 100%;
  padding: var(--s-4);
  background: rgba(22, 17, 14, .55);
  border: 1px dashed rgba(244, 239, 230, .35);
  backdrop-filter: blur(6px);
  transition: background-color .2s var(--ease), border-color .2s var(--ease);
}
.megatile--more:hover {
  background: var(--ochre);
  border-color: var(--ochre);
  border-style: solid;
}
.megatile--more__label {
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.0625rem;
  line-height: 1.2;
  color: var(--bone);
}
.megatile--more__arrow { font-size: 1.125rem; color: var(--ochre); line-height: 1; }
.megatile--more:hover .megatile--more__arrow { color: var(--bone); }

/* The old free-floating version is gone from the tile panels; the link panels
   never had tiles and still use it. */
.megapanel:has(.megatiles) .megapanel__all { display: none; }

/* ---------------------------------------------------------------------------
   Reviews
   ---------------------------------------------------------------------------
   The first version was three grey boxes of small text, which nobody reads —
   and an unread review persuades nobody. What changed: the quote itself is now
   the largest thing on the card and set in the display face, the stars are
   ochre rather than a muted grey, and the cards sit at slightly different
   heights so the set looks like people rather than a table.

   Long reviews are clamped to a readable length with the rest a click away,
   because a card that runs to fourteen lines makes the two beside it look
   unfinished.
   ------------------------------------------------------------------------ */
.revs {
  max-width: var(--w-wide);
  margin-inline: auto;
  padding: var(--s-7) var(--gutter);
}
.revs__title {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2.125rem);
  line-height: 1.15;
}
.revs__title em { font-style: italic; }
.revs__intro { margin-top: var(--s-3); max-width: 58ch; color: var(--ink-soft); line-height: 1.65; }

.revs__grid {
  list-style: none;
  padding: 0;
  margin-top: var(--s-6);
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr));
  align-items: start;
}

.rev {
  display: flex;
  flex-direction: column;
  position: relative;
  padding: var(--s-6) var(--s-5) var(--s-5);
  background: #fff;
  border: 1px solid var(--sand-line);
  border-radius: 3px;
  /* Barely there, but enough to lift the card off the page so it reads as
     something somebody handed you rather than a row in a table. */
  box-shadow: 0 1px 2px rgba(22, 17, 14, .04), 0 8px 24px -12px rgba(22, 17, 14, .10);
  transition: transform .3s var(--ease-out), box-shadow .3s var(--ease);
}
.rev:hover {
  transform: translateY(-2px);
  box-shadow: 0 1px 2px rgba(22, 17, 14, .05), 0 16px 34px -14px rgba(22, 17, 14, .16);
}

/* A quotation mark, set as decoration rather than punctuation — big, pale and
   behind the text, so it reads as a flourish and never as a stray character. */
.rev::before {
  content: "\201C";
  position: absolute;
  top: -.35rem;
  left: var(--s-4);
  font-family: var(--display);
  font-size: 5rem;
  line-height: 1;
  color: var(--ochre);
  opacity: .16;
  pointer-events: none;
}

/* Every third card sits a little lower, so a row reads as a handful of
   separate voices rather than a grid. */
@media (min-width: 64rem) {
  .revs__grid > li:nth-child(3n + 2) { margin-top: var(--s-5); }
}

.rev__stars { display: flex; gap: .2rem; margin-bottom: var(--s-3); }
.rev__star { width: 1rem; height: 1rem; fill: var(--sand-line); }
.rev__star.is-on { fill: var(--ochre); }

.rev__head {
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.125rem;
  line-height: 1.25;
  margin-bottom: var(--s-3);
}

/* The quote is the point of the card, so it is the biggest thing on it. */
.rev__body {
  margin: 0;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--ink);
  flex: 1;
  /* Six lines, then "read it in full" — a fourteen-line card makes the ones
     beside it look empty. */
  display: -webkit-box;
  -webkit-line-clamp: 7;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.rev__body::before,
.rev__body::after { content: none; }
.rev.is-open .rev__body { -webkit-line-clamp: unset; overflow: visible; }

.rev__more {
  align-self: flex-start;
  margin-top: .5rem;
  padding: 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--sand-line);
  font-size: var(--t-micro);
  letter-spacing: .04em;
  color: var(--ochre);
  cursor: pointer;
}
.rev__more:hover { border-color: var(--ochre); }
.rev.is-open .rev__more { display: none; }

.rev__who {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--sand-line);
  font-size: var(--t-small);
}
.rev__author { font-weight: 600; }
.rev__from { color: var(--mist); }
.rev__from::before { content: " · "; }

.rev__source { margin-top: .2rem; font-size: var(--t-micro); color: var(--mist); }
.rev__source a {
  color: var(--ochre);
  text-decoration: underline;
  text-underline-offset: .15em;
}

/* --- The score, made to look like the fact it is -------------------------- */
.revs__score {
  display: inline-flex;
  align-items: center;
  gap: .75rem;
  margin-top: var(--s-5);
  padding: .625rem 1.125rem;
  background: var(--char);
  border-radius: 999px;
  color: var(--bone);
  transition: background-color .2s var(--ease);
}
/*
 * On hover the pill turns ochre, so the text must turn dark.
 *
 * It kept the pale bone colour, which measures 3.05:1 against ochre — below
 * the 4.5:1 small text needs — so the score collided with its own background
 * the moment somebody moved the pointer over it. Charcoal on ochre is 5.37:1.
 */
.revs__score:hover {
  background: var(--ochre);
  color: var(--char);
}
.revs__score-num {
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.5rem;
  line-height: 1;
  color: var(--ochre);
}
.revs__score:hover .revs__score-num { color: var(--char); }

/*
 * "out of 5" was set at 70% opacity, which is fine on charcoal and far too
 * faint once the pill is ochre. Given its own colour per state instead.
 */
.revs__score-of { font-size: var(--t-micro); color: rgba(244, 239, 230, .72); }
.revs__score:hover .revs__score-of { color: rgba(22, 17, 14, .72); }
.revs__score-src {
  font-size: var(--t-small);
  padding-left: .75rem;
  border-left: 1px solid rgba(244, 239, 230, .25);
}
.revs__score:hover .revs__score-src { border-left-color: rgba(22, 17, 14, .28); }

/* ---------------------------------------------------------------------------
   All safaris
   ---------------------------------------------------------------------------
   Restored. An earlier edit that removed one block of review styles cut a far
   wider range than intended and took this whole section with it, which is why
   /safaris rendered unstyled.

   Filters are plain links, so every combination is a real URL a consultant can
   send and a search engine can index.
   ------------------------------------------------------------------------ */
.sindex {
  max-width: var(--w-wide);
  margin-inline: auto;
  padding: var(--s-6) var(--gutter) var(--s-8);
}

.sfilters {
  display: grid;
  gap: var(--s-4);
  padding-bottom: var(--s-6);
  margin-bottom: var(--s-6);
  border-bottom: 1px solid var(--sand-line);
}
.sfilter { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-3); }
.sfilter__label {
  flex: none;
  width: 5rem;
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--mist);
}
@media (max-width: 40rem) { .sfilter__label { width: 100%; } }
.sfilter__set { display: flex; flex-wrap: wrap; gap: .375rem; }

.schip {
  padding: .3rem .7rem;
  font-size: var(--t-small);
  color: var(--ink-soft);
  border: 1px solid var(--sand-line);
  border-radius: 999px;
  transition: border-color .15s var(--ease), background-color .15s var(--ease), color .15s var(--ease);
}
.schip:hover { border-color: var(--mist); }
.schip.is-on { background: var(--ochre); border-color: var(--ochre); color: var(--bone); }

.sfilters__count { font-size: var(--t-micro); color: var(--mist); }
.sindex__none { color: var(--ink-soft); line-height: 1.7; }
.sindex__none a { color: var(--ochre); text-decoration: underline; text-underline-offset: .15em; }

.sindex__grid {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--s-6) var(--s-5);
  grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr));
}

.scard { display: block; }
.scard__media {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--sand);
  margin-bottom: var(--s-3);
}
.scard__media picture { display: block; width: 100%; height: 100%; }
.scard__media img {
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(.86);
  transition: transform .8s var(--ease-out), filter .35s var(--ease);
}
.scard:hover .scard__media img { transform: scale(1.04); filter: saturate(1.02); }

/* The length sits on the photograph: it is the first thing anybody filters by
   in their head, and it keeps the card's text to name and price. */
.scard__nights {
  position: absolute;
  left: .625rem;
  bottom: .625rem;
  padding: .2rem .5rem;
  background: rgba(22, 17, 14, .72);
  color: var(--bone);
  font-size: var(--t-micro);
  letter-spacing: .04em;
  backdrop-filter: blur(4px);
}

.scard__where {
  display: block;
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: .2rem;
}
.scard__name {
  display: block;
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.125rem;
  line-height: 1.25;
}
.scard:hover .scard__name { color: var(--ochre); }
.scard__price {
  display: block;
  margin-top: .35rem;
  font-size: var(--t-small);
  font-weight: 500;
}
.scard__price span { font-weight: 400; color: var(--mist); }

/* --- Ask, once the reading is done ----------------------------------------
   Also lost in that edit. The page opened well and then ran out: facts,
   itinerary, rates, and nothing to do at the end of it. */
.tcta {
  max-width: var(--w-wide);
  margin-inline: auto;
  padding: var(--s-7) var(--gutter);
}
.tcta__inner {
  display: grid;
  gap: var(--s-5);
  align-items: center;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  padding: var(--s-6);
  background: var(--char);
  color: var(--bone);
  border-radius: 2px;
}
@media (max-width: 46rem) { .tcta__inner { grid-template-columns: 1fr; } }
.tcta__title {
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);
  line-height: 1.2;
}
.tcta__title em { font-style: italic; }
.tcta__text {
  margin-top: var(--s-3);
  color: rgba(244, 239, 230, .78);
  line-height: 1.65;
  max-width: 46ch;
}
.tcta__actions { display: flex; flex-wrap: wrap; gap: .625rem; }

/* A ghost button on a dark panel. The default ghost is dark-on-light, so on
   the tour call-to-action it was invisible against the charcoal. */
.btn--light {
  color: var(--bone);
  border-color: rgba(244, 239, 230, .45);
}
.btn--light:hover {
  background: var(--bone);
  border-color: var(--bone);
  color: var(--char);
}

/* ---------------------------------------------------------------------------
   Ways to get in touch
   ---------------------------------------------------------------------------
   The contact page carried the right details inside a paragraph — a telephone
   number as a hyperlink in a sentence, an address in bold, nothing that looked
   pressable. Somebody who has decided to make contact should not have to read
   a paragraph to work out how.
   ------------------------------------------------------------------------ */
.ways {
  max-width: var(--w-wide);
  margin-inline: auto;
  padding: var(--s-7) var(--gutter);
}
.ways__title {
  font-family: var(--display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2.125rem);
  line-height: 1.15;
  margin-bottom: var(--s-6);
}
.ways__title em { font-style: italic; }

.ways__grid {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
}

.way {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: var(--s-5);
  background: #fff;
  border: 1px solid var(--sand-line);
  border-radius: 3px;
  transition: transform .25s var(--ease-out), box-shadow .25s var(--ease),
              border-color .25s var(--ease);
}
.way:hover {
  transform: translateY(-2px);
  border-color: var(--ochre);
  box-shadow: 0 14px 30px -16px rgba(22, 17, 14, .22);
}

/* The one most people should use is the one that looks different. */
.way--primary { background: var(--char); border-color: var(--char); }
.way--primary:hover { background: var(--ochre); border-color: var(--ochre); }

.way__icon {
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--sand);
  margin-bottom: var(--s-4);
}
.way__icon svg { width: 1.125rem; height: 1.125rem; fill: var(--ochre); }
.way--primary .way__icon { background: rgba(244, 239, 230, .12); }
.way--primary .way__icon svg { fill: var(--bone); }

.way__kind {
  display: block;
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: .2rem;
}
.way__title {
  display: block;
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.25rem;
  line-height: 1.2;
}
.way__body {
  display: block;
  margin-top: .5rem;
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--ink-soft);
  flex: 1;
}
.way__meta {
  display: block;
  margin-top: var(--s-4);
  padding-top: var(--s-3);
  border-top: 1px solid var(--sand-line);
  font-size: var(--t-micro);
  color: var(--mist);
}

/* On the dark card everything lightens, including the rule. */
.way--primary .way__title { color: var(--bone); }
.way--primary .way__body  { color: rgba(244, 239, 230, .8); }
.way--primary .way__meta  { color: rgba(244, 239, 230, .6); border-color: rgba(244, 239, 230, .2); }
.way--primary:hover .way__kind { color: var(--bone); }

/* --- The WhatsApp button --------------------------------------------------
   Most safari enquiries from within East Africa arrive this way, and for
   somebody abroad it costs nothing and needs no roaming. It expands to a
   label on hover so it reads as an offer rather than an unexplained circle. */
.wafloat {
  position: fixed;
  right: var(--s-5);
  bottom: var(--s-5);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  height: 3.25rem;
  padding: 0 1rem;
  border-radius: 999px;
  background: #25D366;
  color: #fff;
  box-shadow: 0 8px 24px -8px rgba(22, 17, 14, .45);
  transition: transform .2s var(--ease-out), box-shadow .2s var(--ease);
}
.wafloat:hover { transform: translateY(-2px); box-shadow: 0 14px 30px -10px rgba(22, 17, 14, .5); }
.wafloat svg { width: 1.5rem; height: 1.5rem; fill: #fff; flex: none; }

.wafloat__label {
  font-size: var(--t-small);
  font-weight: 500;
  white-space: nowrap;
  /* Collapsed by default so it never covers content on a small screen, and
     opens on hover where there is a pointer to hover with. */
  max-width: 0;
  overflow: hidden;
  transition: max-width .3s var(--ease-out);
}
@media (hover: hover) {
  .wafloat:hover .wafloat__label { max-width: 8rem; }
}
@media (max-width: 40rem) {
  .wafloat { right: var(--s-4); bottom: var(--s-4); padding: 0; width: 3.25rem; justify-content: center; }
  .wafloat__label { display: none; }
}

/* The planner has its own full-screen layout and its own call to action; a
   floating button there would compete with the question on screen. */
.wz-page .wafloat { display: none; }

/* --- The email link in the header -----------------------------------------
   .nav__link--icon carried no rules at all, so the envelope and the words sat
   as inline content with no shared baseline — the icon rode above the text and
   the whole thing sat higher than the links beside it. */
.nav__link--icon {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  /*
   * On one line with its label.
   *
   * .nav__link sets white-space: nowrap, which a flex container ignores for
   * its own children — so the envelope wrapped onto a line above "Email us"
   * and the item stood a whole line taller than every other in the bar.
   */
  flex-wrap: nowrap;
  /*
   * Match the height of a plain nav item.
   *
   * .nav__link pads 0.4rem top and bottom around a normal line box; a flex
   * container with line-height 1 collapses to the glyph height, so this item
   * sat 7px shorter than its neighbours and its underline sat higher.
   */
  line-height: inherit;
}
.nav__link--icon svg {
  /* The envelope is wider than it is tall, so centring on the cap height of
     the label looks better than centring on the whole line box. */
  width: .875rem;
  height: auto;
  flex: none;
  position: relative;
  top: -.5px;
}

/* --- The same <picture> fix, everywhere else it applies -------------------
   A <picture> has no height of its own, so an img set to height:100% inside
   one collapses to the photograph's aspect ratio rather than filling the box
   it was meant to fill. It showed up first on the hero — where on a phone it
   left a 260px band of image above a large empty gradient — and these three
   have the same shape. */
.card__media picture,
.cards__media picture,
.split__media picture { display: block; width: 100%; height: 100%; }

/* ---------------------------------------------------------------------------
   Mobile
   ---------------------------------------------------------------------------
   Most people will see this site on a phone, so the small end is the one that
   matters. These are the adjustments a sweep across eight device widths turned
   up — nothing structural, since the layout already reflows correctly.
   ------------------------------------------------------------------------ */
@media (max-width: 46rem) {

  /* Eyebrows, captions and metadata sat at 11px, which is where people begin
     squinting on a phone held at arm's length. 12px reads without moving
     anything. */
  :root { --t-micro: 0.75rem; }

  /* Hero titles were sized for a wide viewport and wrapped to five or six
     lines on a narrow one, pushing the button below the fold. */
  .hero__title { font-size: clamp(2rem, 8vw, 2.75rem); }
  .hero__lead  { font-size: 1rem; max-width: 34ch; }

  /* A hero exactly as tall as the screen means the first thing a visitor does
     is scroll past a photograph with no sign anything follows. 88% leaves the
     next section peeking. */
  .hero { min-height: 88svh; }

  /* Buttons: full width and a proper touch target. Two side by side at 35px
     each is the most common thing people mis-tap on a phone. */
  .hero__actions { flex-direction: column; align-items: stretch; gap: .625rem; }
  .hero__actions .btn,
  .tcta__actions .btn,
  .cta__actions .btn { width: 100%; text-align: center; padding-block: .875rem; }

  /* Section headings were clamped for desktop and still ran large here. */
  .tsection__title,
  .ways__title,
  .revs__title,
  .ctours__title,
  .dtree__title { font-size: clamp(1.375rem, 5.5vw, 1.75rem); }

  /* The three filter rows on /safaris wrapped into a tall block that pushed
     the safaris themselves off the screen. Scrolling them sideways keeps the
     cards in view. */
  /*
   * The chips wrap. They do not scroll.
   *
   * A horizontally scrolling row seemed neater than three rows of wrapped
   * chips, and it was — until it stretched the page 367px wider than the
   * phone, because a flex row inside a grid sizes to its content unless every
   * ancestor is told otherwise. Three attempts at containing it each moved the
   * overflow somewhere else.
   *
   * Wrapping costs a little vertical space and cannot break the page. On a
   * filter row that is the right trade.
   */
  .sfilter { flex-wrap: wrap; }
  .sfilter__label { width: 100%; }
  .sfilter__set { flex-wrap: wrap; }


  /* 44px is the accepted minimum touch target; these were 35. */
  .schip,
  .tsuit,
  .rev__more,
  .tincl__more {
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
  }

  /*
   * The rate table scrolls inside its own column, not across the page.
   *
   * white-space:nowrap made the table as wide as its widest row, and because
   * a grid column sizes to its content that width propagated all the way up
   * and pushed the page 352px wider than the phone. The min-width:0 chain is
   * what stops it: without it, every ancestor happily grows.
   */
  .tref__cols,
  .tref__col { min-width: 0; }

  .trates__table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }
  .trates__table td,
  .trates__table th { padding-inline: .5rem; }

  .tref__cols { gap: var(--s-5); }
}

/* --- Large and high-resolution screens ------------------------------------
   Everything is capped at --w-wide, so on a 2560px monitor the site sat in a
   column down the middle with vast empty margins. Letting the wide container
   grow uses the space without stretching text past a readable measure. */
@media (min-width: 100rem) {
  :root { --w-wide: 96rem; }
  .hero__title { font-size: clamp(3rem, 4.5vw, 5rem); }
}

/* --- Short laptops --------------------------------------------------------
   1366×768 is still the most common laptop resolution, and a full-height hero
   fills the entire screen there with no hint that anything follows. */
@media (min-width: 46rem) and (max-height: 50rem) {
  .hero { min-height: 92svh; }
}

/* --- Others people also look at -------------------------------------------
   A package page ended with an invitation and nothing else, so somebody who
   liked the idea but not this trip had to go back to the menu and start over.
   Most of them will not. */
.trel {
  max-width: var(--w-wide);
  margin-inline: auto;
  padding: var(--s-7) var(--gutter) 0;
}
.trel__grid {
  list-style: none;
  padding: 0;
  margin-top: var(--s-5);
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
}
.trel__card { display: block; }
.trel__media {
  display: block;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: var(--sand);
  margin-bottom: var(--s-3);
}
.trel__media picture { display: block; width: 100%; height: 100%; }
.trel__media img {
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(.86);
  transition: transform .8s var(--ease-out), filter .35s var(--ease);
}
.trel__card:hover .trel__media img { transform: scale(1.04); filter: saturate(1.02); }
.trel__name {
  display: block;
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.0625rem;
  line-height: 1.25;
}
.trel__card:hover .trel__name { color: var(--ochre); }
.trel__meta { display: block; margin-top: .25rem; font-size: var(--t-small); color: var(--mist); }

/* --- Where else Duma exists -----------------------------------------------
   These were in settings and handed to search engines, but appeared nowhere a
   visitor could see — so eighty-eight reviews sat one click away with no link
   going there. */
.site-foot__social {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .75rem 1.25rem;
  padding: var(--s-5) 0;
  border-top: 1px solid rgba(244, 239, 230, .12);
}
.site-foot__social-label {
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--mist);
}
.site-foot__social ul {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1.25rem;
  list-style: none;
  padding: 0;
}
.site-foot__social a {
  font-size: var(--t-small);
  color: var(--bone);
  border-bottom: 1px solid rgba(244, 239, 230, .25);
  padding-bottom: 1px;
}
.site-foot__social a:hover { color: var(--ochre); border-color: var(--ochre); }

/* The note under "Where you sleep": these names describe a standard rather
   than a booked property, and saying so is more honest than letting a guest
   assume we have held a specific room. */
.tstays__note {
  margin-top: calc(var(--s-5) * -1 + .5rem);
  margin-bottom: var(--s-5);
  max-width: 58ch;
  font-size: var(--t-small);
  color: var(--mist);
  line-height: 1.6;
}


/* The drawback. Set apart, because a reader who finds it believes the rest. */
.dcheck__watch {
  margin-top: var(--s-4);
  padding: var(--s-4);
  background: rgba(194, 120, 43, .07);
  border-left: 2px solid var(--ochre);
  max-width: 62ch;
  line-height: 1.65;
  font-size: var(--t-small);
}

.dcheck__meters {
  list-style: none;
  padding: 0;
  margin-top: var(--s-5);
  display: grid;
  gap: var(--s-3);
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
}
.dmeter { display: flex; align-items: center; gap: .625rem; }
.dmeter__label { font-size: var(--t-micro); color: var(--mist); min-width: 6.5rem; }
.dmeter__bar { display: inline-flex; gap: 3px; }
.dmeter__bar i {
  width: 1.125rem;
  height: .375rem;
  border-radius: 1px;
  background: var(--sand-line);
}
.dmeter__bar i.is-on { background: var(--ochre); }
.dmeter__word { font-size: var(--t-small); font-weight: 500; }

.dcheck__places, .dcheck__trips { margin-top: var(--s-5); }
.dcheck__placeslabel {
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--mist);
  margin-bottom: .5rem;
}
.dcheck__places ul, .dcheck__trips ul { list-style: none; padding: 0; display: grid; gap: .5rem; }
.dcheck__places li, .dcheck__trips li { line-height: 1.5; }
.dcheck__places a, .dcheck__trips a {
  font-weight: 500;
  border-bottom: 1px solid var(--sand-line);
}
.dcheck__places a:hover, .dcheck__trips a:hover { border-color: var(--ochre); color: var(--ochre); }
.dcheck__places span, .dcheck__trips span { color: var(--mist); font-size: var(--t-small); }

/* Where we would not send you — the section no competitor has. */
.dcheck__places--avoid strong { color: var(--ink); }

.dcheck__cta { margin-top: var(--s-6); }

@media (max-width: 46rem) {
  .dcheck__answer { padding: var(--s-5) var(--s-4); }
  .dmeter__label { min-width: 5.5rem; }
}
