/* ==========================================================================
   TALA Travel & Tours
   Palette and type are drawn from the logo: deep navy, gold, and the teal of
   the wave. The page alternates between "night" bands (navy, carrying the star
   and the brand story) and "day" bands (cool daylight, carrying the photos and
   the practical detail) — light against dark, which is the brand's own idea.
   ========================================================================== */

/* --- Tokens --------------------------------------------------------------- */

:root {
  /* Night — the hero scrim, the footer, and little else. Kept deep and
     neutral so photography sits on it without a colour cast. */
  --ink-900: #0a1526;
  --ink-800: #122036;
  --ink-700: #1b2d47;
  --ink-600: #27405f;

  /* Gold — the one accent, taken straight from the logo. */
  --star-500: #c8963e;
  --star-300: #e8c87e;
  --star-600: #ac7c2c;
  --star-ink: #7d5a1c; /* gold dark enough for text on light grounds */

  /* Sea — a restrained secondary, used sparingly for links and focus. */
  --sea-600: #2d7a8c;
  --sea-700: #22606f;

  /* Day — the site is mostly these. White is the default surface; sand is
     the warm alternate that keeps long pages from going clinical. */
  --white: #fff;
  --sand-50: #faf8f4;
  --sand-100: #f3efe8;
  --day-100: #f4f6f9;
  --day-50: #f9fafc;

  /* Text */
  --text: #16223a;
  --text-soft: #566579;
  --text-on-night: #eef2f7;
  --text-on-night-soft: #b9c6d6;

  --line: #e4e8ef;
  --line-strong: #d2d9e4;
  --line-night: rgba(255, 255, 255, 0.16);

  --font-display: "Lora", "Hoefler Text", "Iowan Old Style", Georgia, serif;
  /* DM Sans for body copy. The client asked for a face with more life in it;
     DM Sans is wider and rounder than the alternatives tried, with open
     counters and a tall x-height, so it reads as warmer and sits more
     visibly on the page at the small sizes most of this text is set at. */
  --font-body: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, Helvetica, Arial, sans-serif;

  --wrap: 1180px;
  --radius: 3px;
  --band-y: clamp(2.6rem, 5vw, 4.4rem);
  --header-h: 72px;

  --shadow-lift: 0 18px 44px -24px rgba(8, 18, 42, 0.55);
}

/* --- Base ----------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* The canvas, not the page. Without this the body's pale background
     propagates to the canvas, and two things show it: the sub-pixel sliver
     left under the footer when its height lands on a fraction, and the
     overscroll area past either end. Both now match the navy header and
     footer instead of flashing a pale strip. */
  background: var(--ink-900);
}

body {
  margin: 0;
  background: var(--day-100);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Beats the display value of any component class, so toggling the `hidden`
   attribute in JavaScript always actually hides the element. */
[hidden] {
  display: none !important;
}

a {
  color: inherit;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.12;
  letter-spacing: -0.015em;
  margin: 0 0 0.6em;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.1rem, 4.6vw, 3.2rem);
  line-height: 1.04;
  letter-spacing: -0.025em;
}

h2 {
  font-size: clamp(1.55rem, 2.7vw, 2.15rem);
}

h3 {
  font-size: clamp(1.08rem, 1.45vw, 1.22rem);
  letter-spacing: -0.01em;
}

p {
  margin: 0 0 1.1em;
  max-width: 41rem;
}

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--star-500);
  color: var(--ink-900);
  padding: 0.75rem 1.25rem;
  font-weight: 600;
  z-index: 200;
}

.skip-link:focus {
  left: 0;
}

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

/* --- Layout --------------------------------------------------------------- */

.wrap {
  width: min(var(--wrap), 100% - 2.5rem);
  margin-inline: auto;
}

.wrap--narrow {
  width: min(760px, 100% - 2.5rem);
}

.band {
  padding-block: var(--band-y);
}

/* A short band used as a pause between longer ones. */
.band--slim {
  padding-block: clamp(2.75rem, 5vw, 4.25rem);
}

.band--night {
  background: var(--ink-800);
  color: var(--text-on-night);
  /* The glow behind the logo is deliberately wider than the column it sits in,
     and on a narrow phone its outer edge reached past the screen. Only the
     fully transparent fringe of the gradient is trimmed here; the rings sit
     inside the viewport and are untouched. `clip` rather than `hidden` so the
     band never becomes a scroll container. */
  overflow-x: clip;
}

.band--night-deep {
  background: var(--ink-900);
  color: var(--text-on-night);
}

.band--day {
  background: var(--day-100);
}

.band--paper {
  background: var(--white);
}

/* Warm neutral — keeps long light pages from reading clinical. */
.band--sand {
  background: var(--sand-50);
}

.band--night h1,
.band--night h2,
.band--night h3,
.band--night-deep h1,
.band--night-deep h2,
.band--night-deep h3 {
  color: var(--white);
}

.lede {
  font-size: clamp(1rem, 1.15vw, 1.1rem);
  line-height: 1.6;
  color: var(--text-soft);
  max-width: 41rem;
  /* Stops a single word being left alone on the last line. Browsers that do
     not support it just wrap as before. */
  text-wrap: pretty;
}

.band--night .lede,
.band--night-deep .lede {
  color: var(--text-on-night-soft);
}

/* The client asked for particular sentences to begin a line of their own in
   three places. A span rather than a <br> so the break can be dropped on a
   phone, where the column is too narrow for it to land anywhere sensible and
   forcing it just strands a short line. */
.line {
  display: block;
}

@media (max-width: 680px) {
  .line {
    display: inline;
  }
}

/* Section heading with a hairline that carries the eye across the band. */
.band-head {
  margin-bottom: clamp(1.4rem, 2.4vw, 2.1rem);
}

.band-head p {
  margin-bottom: 0;
}

.rule {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 0 0 2.2rem;
}

.band--night .rule,
.band--night-deep .rule {
  border-top-color: var(--line-night);
}

/* --- Star glyph ----------------------------------------------------------- */

.star-glyph {
  width: 1em;
  height: 1em;
  flex: none;
  fill: var(--star-500);
}

/* --- Buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.85rem 1.6rem;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  border: 1.5px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease,
    border-color 0.18s ease,
    transform 0.2s cubic-bezier(0.2, 0.8, 0.25, 1);
}

/* Feedback, not movement — displacement stays under 3px. */
.btn:hover {
  transform: translateY(-2px);
}

.btn:active {
  transform: translateY(0);
}

.btn--gold {
  background: var(--star-500);
  color: var(--ink-900);
  border-color: var(--star-500);
}

.btn--gold:hover {
  background: var(--star-300);
  border-color: var(--star-300);
}

.btn--ink {
  background: var(--ink-800);
  color: var(--white);
  border-color: var(--ink-800);
}

.btn--ink:hover {
  background: var(--ink-600);
  border-color: var(--ink-600);
}

.btn--ghost-light {
  background: transparent;
  color: var(--white);
  border-color: rgba(228, 235, 243, 0.45);
}

.btn--ghost-light:hover {
  border-color: var(--star-300);
  color: var(--star-300);
}

.btn--ghost-dark {
  background: transparent;
  color: var(--ink-800);
  border-color: var(--ink-800);
}

.btn--ghost-dark:hover {
  background: var(--ink-800);
  color: var(--white);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: 2rem;
}

.btn svg {
  width: 1.1em;
  height: 1.1em;
  fill: currentColor;
}

/* --- Header --------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--ink-900);
  border-bottom: 1px solid rgba(200, 150, 62, 0.18);
  transition: box-shadow 0.35s ease, border-color 0.35s ease;
}

/* Lifts off the page once you start scrolling. */
.site-header[data-scrolled="true"] {
  box-shadow: 0 14px 34px -22px rgba(0, 0, 0, 0.9);
  border-bottom-color: rgba(200, 150, 62, 0.34);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: var(--header-h);
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
  color: var(--white);
  padding-block: 0.5rem;
}

.brand img {
  width: 46px;
  height: auto;
}

.brand-name {
  font-family: var(--font-display);
  font-size: 1.32rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1;
  display: block;
}

.brand-sub {
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  color: var(--star-300);
  display: block;
  margin-top: 0.28rem;
}

.nav {
  display: flex;
  align-items: center;
  gap: 1.9rem;
}

.nav a {
  color: var(--text-on-night);
  text-decoration: none;
  font-size: 0.97rem;
  font-weight: 500;
  padding-block: 0.4rem;
  border-bottom: 2px solid transparent;
  transition: color 0.18s ease, border-color 0.18s ease;
}

.nav a:hover {
  color: var(--star-300);
}

.nav a[aria-current="page"] {
  color: var(--star-300);
  border-bottom-color: var(--star-500);
}

.nav .btn {
  padding: 0.6rem 1.15rem;
  font-size: 0.92rem;
  border-bottom-width: 1.5px;
}

/* `.nav a` sets a light colour and outranks `.btn--gold`, which would leave
   pale text on the gold fill. Put the dark ink back. */
.nav .btn--gold,
.nav .btn--gold:hover {
  color: var(--ink-900);
}

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid rgba(228, 235, 243, 0.35);
  border-radius: var(--radius);
  color: var(--white);
  padding: 0.55rem 0.7rem;
  cursor: pointer;
  line-height: 0;
}

.nav-toggle svg {
  width: 22px;
  height: 22px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
}

.nav-toggle .icon-close {
  display: none;
}

.nav-toggle[aria-expanded="true"] .icon-open {
  display: none;
}

.nav-toggle[aria-expanded="true"] .icon-close {
  display: block;
}

@media (max-width: 900px) {
  .nav-toggle {
    display: block;
  }

  .nav {
    position: fixed;
    inset: var(--header-h) 0 0;
    background: var(--ink-900);
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    padding: 1.25rem;
    overflow-y: auto;
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    visibility: hidden;
    transition: opacity 0.22s ease, transform 0.22s ease, visibility 0.22s;
  }

  .nav[data-open="true"] {
    opacity: 1;
    transform: none;
    pointer-events: auto;
    visibility: visible;
  }

  .nav a {
    padding: 1rem 0.25rem;
    font-size: 1.15rem;
    border-bottom: 1px solid rgba(200, 150, 62, 0.18);
  }

  .nav a[aria-current="page"] {
    border-bottom-color: var(--star-500);
  }

  .nav .btn {
    margin-top: 1.4rem;
    padding: 0.95rem 1.25rem;
    font-size: 1.02rem;
    justify-content: center;
    border-bottom-width: 1.5px;
  }
}

/* --- Hero ------------------------------------------------------------------
   A full-bleed slideshow of the destinations, dimmed behind a scrim so the
   headline stays legible on any photograph. The slides crossfade and drift
   slowly, which reads as film rather than a slideshow. Everything here works
   as a single still image if JavaScript never runs. */

.hero {
  position: relative;
  min-height: clamp(560px, 82svh, 760px);
  display: flex;
  align-items: center;
  background: var(--ink-900);
  color: var(--white);
  overflow: hidden;
  isolation: isolate;
}

.hero-slides {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.hero-slide {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  transition: opacity 0.65s ease-in-out;
}

.hero-slide[data-active="true"] {
  opacity: 1;
}

.hero-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Each slide moves differently — one pushes in and drifts right, the next
   rises, the next pulls back and travels left. Consecutive slides never share
   a motion, which is what stops the hero reading as a zooming photograph and
   starts it reading as footage of a place.

   Every keyframe stays at scale 1.12 or above: that over-scale is the
   headroom the panning moves within, so an edge of the photograph can never
   come into view. The animations run longer than a slide is on screen, so
   the movement is always mid-flight and never freezes before the crossfade. */

.js .hero-slide[data-active="true"] img {
  animation: kb-push-right 6.4s ease-out both;
}

/* The cycle alternates: push in, pull back, rise, pull back and left, drift
   in. Going in and out on alternate slides is what keeps it feeling like a
   camera working a place rather than a single repeated trick. Motion 6 is
   spare — give it to a sixth slide if one is added. */
.js .hero-slide[data-motion="2"][data-active="true"] img {
  animation-name: kb-pull-back;
}

.js .hero-slide[data-motion="3"][data-active="true"] img {
  animation-name: kb-rise;
}

.js .hero-slide[data-motion="4"][data-active="true"] img {
  animation-name: kb-pull-left;
}

.js .hero-slide[data-motion="5"][data-active="true"] img {
  animation-name: kb-drift-in;
}

.js .hero-slide[data-motion="6"][data-active="true"] img {
  animation-name: kb-sink;
}

@keyframes kb-push-right {
  from {
    transform: scale(1.13) translate3d(-1.4%, 0.4%, 0);
  }
  to {
    transform: scale(1.22) translate3d(1.4%, -0.6%, 0);
  }
}

/* A straight pull-back: the widest scale change of the set and almost no
   lateral travel, so it reads unmistakably as the camera drawing away to
   reveal the whole place. */
@keyframes kb-pull-back {
  from {
    transform: scale(1.28) translate3d(0.6%, -0.5%, 0);
  }
  to {
    transform: scale(1.12) translate3d(-0.4%, 0.4%, 0);
  }
}

@keyframes kb-rise {
  from {
    transform: scale(1.14) translate3d(0.6%, 2.2%, 0);
  }
  to {
    transform: scale(1.23) translate3d(-0.5%, -1.8%, 0);
  }
}

@keyframes kb-pull-left {
  from {
    transform: scale(1.24) translate3d(1.8%, -0.8%, 0) rotate(0.35deg);
  }
  to {
    transform: scale(1.13) translate3d(-1.2%, 0.6%, 0) rotate(0deg);
  }
}

@keyframes kb-sink {
  from {
    transform: scale(1.13) translate3d(-0.8%, -2%, 0);
  }
  to {
    transform: scale(1.22) translate3d(0.6%, 1.9%, 0);
  }
}

@keyframes kb-drift-in {
  from {
    transform: scale(1.12) translate3d(1.5%, 1.4%, 0) rotate(-0.3deg);
  }
  to {
    transform: scale(1.24) translate3d(-1.5%, -1.2%, 0) rotate(0deg);
  }
}

/* No drifting for anyone who has asked for less movement — the photograph
   just sits still, uncropped by a half-finished pan. */
@media (prefers-reduced-motion: reduce) {
  .js .hero-slide[data-active="true"] img {
    animation: none !important;
    transform: none;
  }
}

/* Two layers: a vertical wash for overall legibility, and a stronger pull
   from the left where the copy sits. */
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
      to right,
      rgba(10, 21, 38, 0.88) 0%,
      rgba(10, 21, 38, 0.72) 38%,
      rgba(10, 21, 38, 0.35) 70%,
      rgba(10, 21, 38, 0.28) 100%
    ),
    linear-gradient(
      to bottom,
      rgba(10, 21, 38, 0.55) 0%,
      rgba(10, 21, 38, 0.15) 40%,
      rgba(10, 21, 38, 0.65) 100%
    );
}

.hero-inner {
  position: relative;
  padding-block: clamp(4.5rem, 10vw, 7rem);
  width: min(var(--wrap), 100% - 2.5rem);
}

/* A fixed measure rather than `ch`. The ch unit is the width of a "0" in the
   current font, so a column sized in ch silently narrows or widens whenever
   the body typeface changes. A font swap once shrank this column enough to
   wrap both the eyebrow and the headline. */
.hero-copy {
  max-width: min(34rem, 100%);
}

.hero-eyebrow {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--star-300);
  margin: 0 0 1rem;
  max-width: none;
}

.hero h1 {
  color: var(--white);
  font-size: clamp(1.8rem, 3vw, 2.6rem);
  line-height: 1.14;
  letter-spacing: -0.015em;
  margin-bottom: 0.5em;
  text-shadow: 0 2px 24px rgba(10, 21, 38, 0.5);
}

.hero-lede {
  color: rgba(255, 255, 255, 0.88);
  font-size: clamp(1.02rem, 1.35vw, 1.15rem);
  line-height: 1.65;
  max-width: 48ch;
  margin: 0;
}

.hero .btn-row {
  margin-top: 2.2rem;
}

/* Caption for the photograph currently showing — it tells you where you are
   looking, which is the point of putting destinations in the hero at all. */
.hero-slide-label {
  position: absolute;
  right: clamp(1.25rem, 4vw, 3rem);
  bottom: clamp(4.5rem, 8vw, 5.5rem);
  text-align: right;
  opacity: 0;
  transition: opacity 0.8s ease 0.3s;
}

.hero-slide[data-active="true"] .hero-slide-label {
  opacity: 1;
}

.hero-slide-place {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1.8vw, 1.4rem);
  color: var(--white);
  text-shadow: 0 1px 3px rgba(10, 21, 38, 0.9), 0 2px 18px rgba(10, 21, 38, 0.8);
}

.hero-slide-region {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--star-300);
  margin-top: 0.25rem;
  text-shadow: 0 1px 3px rgba(10, 21, 38, 0.9);
}

.hero-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(1.5rem, 3vw, 2.25rem);
  display: flex;
  justify-content: center;
}

.hero-dots {
  display: flex;
  gap: 0.6rem;
  padding: 0.55rem 0.85rem;
  border-radius: 999px;
  background: rgba(10, 21, 38, 0.4);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.hero-dot {
  width: 30px;
  height: 4px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.35);
  cursor: pointer;
  transition: background-color 0.3s ease, width 0.3s ease;
}

.hero-dot:hover {
  background: rgba(255, 255, 255, 0.6);
}

.hero-dot[aria-current="true"] {
  background: var(--star-500);
  width: 44px;
}

@media (max-width: 700px) {
  .hero {
    min-height: clamp(520px, 76svh, 640px);
  }

  .hero-scrim {
    background: linear-gradient(
      to bottom,
      rgba(10, 21, 38, 0.62) 0%,
      rgba(10, 21, 38, 0.55) 45%,
      rgba(10, 21, 38, 0.82) 100%
    );
  }

  .hero-slide-label {
    display: none;
  }
}

/* --- Page header (inner pages) --------------------------------------------
   The same treatment as the home hero, scaled down: a dimmed photograph
   behind the title, so every page of the site feels like one piece. */

.page-head {
  position: relative;
  background: var(--ink-900);
  color: var(--text-on-night);
  padding-block: clamp(3.5rem, 8vw, 6rem) clamp(3rem, 6vw, 4.5rem);
  overflow: hidden;
  isolation: isolate;
}

.page-head-media {
  position: absolute;
  inset: 0;
  z-index: -1;
}

.page-head-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* On a phone this band is tall and narrow, so the banner is cropped in from
   both sides and only its middle survives. That is fine for a landscape, but
   not for a photograph with one subject off to one side — the aeroplane on
   the Inquire page sits well right of centre and a centred crop loses it. */
.page-head-media--right img {
  object-position: 78% center;
}

.page-head-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to right,
    rgba(10, 21, 38, 0.92) 0%,
    rgba(10, 21, 38, 0.78) 45%,
    rgba(10, 21, 38, 0.55) 100%
  );
}

.page-head .wrap {
  position: relative;
}

.page-head h1 {
  color: var(--white);
  font-size: clamp(1.75rem, 2.9vw, 2.4rem);
  max-width: 20ch;
  text-shadow: 0 2px 20px rgba(10, 21, 38, 0.5);
}

.page-head p {
  color: rgba(255, 255, 255, 0.86);
  font-size: clamp(1.02rem, 1.4vw, 1.16rem);
  max-width: 54ch;
  margin-bottom: 0;
}

/* --- Services ------------------------------------------------------------- */

.services {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 0 clamp(2rem, 5vw, 4.5rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.services li {
  border-top: 1px solid var(--line);
  padding-block: 1.6rem;
}

.band--night .services li,
.band--night-deep .services li {
  border-top-color: var(--line-night);
}

.services h3 {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-bottom: 0.35rem;
}

.services p {
  margin: 0;
  color: var(--text-soft);
  font-size: 0.99rem;
  line-height: 1.62;
}

.band--night .services p,
.band--night-deep .services p {
  color: var(--text-on-night-soft);
}

/* --- Meet the team -------------------------------------------------------- */
/* Same hairline-and-column pattern as the services list, with a role line
   between the name and the description. */

.team-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(265px, 1fr));
  gap: 0 clamp(2rem, 5vw, 4.5rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.team-list li {
  border-top: 1px solid var(--line);
  padding-block: 1.6rem;
}

.team-list h3 {
  margin-bottom: 0.35rem;
}

.team-role {
  margin-bottom: 0.7rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.11em;
  line-height: 1.45;
  text-transform: uppercase;
  color: var(--star-ink);
}

.team-list li > p:last-child {
  margin: 0;
  color: var(--text-soft);
  font-size: 0.99rem;
  line-height: 1.62;
}

/* --- Destination grid ----------------------------------------------------- */
/* Deliberately uneven: a lead card twice the size of the rest, so the grid
   reads as an edit rather than a row of identical tiles. */

.places {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

.place {
  position: relative;
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
}

.place-figure {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--ink-700);
  aspect-ratio: 4 / 3;
}

.place-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s cubic-bezier(0.2, 0.6, 0.2, 1);
}

.place:hover .place-figure img,
.place:focus-visible .place-figure img {
  transform: scale(1.04);
}

/* Fixed three-up so cards stay the same size whatever the group holds — the
   destinations page splits them into regions of two and three. */
.places--grid {
  grid-template-columns: repeat(3, 1fr);
}

@media (max-width: 900px) {
  .places--grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Feature row: one wide landscape next to two portraits. The aspect ratios are
   picked so all three figures land on the same height, which keeps the captions
   on one line rather than stepping down the page. */
.places--feature {
  grid-template-columns: repeat(4, 1fr);
}

.places--feature .place-figure {
  aspect-ratio: 3 / 4;
}

.places--feature .place--lead {
  grid-column: span 2;
}

.places--feature .place--lead .place-figure {
  aspect-ratio: 16 / 10;
}

@media (max-width: 900px) {
  .places--feature {
    grid-template-columns: repeat(2, 1fr);
  }

  .places--feature .place--lead {
    grid-column: span 2;
  }

  .places--feature .place-figure,
  .places--feature .place--lead .place-figure {
    aspect-ratio: 4 / 3;
  }
}

.place-body {
  padding-top: 1rem;
}

.place h3 {
  margin-bottom: 0.3rem;
}

.place-region {
  font-size: 0.86rem;
  color: var(--star-ink);
  letter-spacing: 0.04em;
  margin-bottom: 0.5rem;
}

.band--night .place-region,
.band--night-deep .place-region {
  color: var(--star-300);
}

.place p {
  margin: 0;
  color: var(--text-soft);
  font-size: 0.97rem;
  line-height: 1.6;
}

.band--night .place p,
.band--night-deep .place p {
  color: var(--text-on-night-soft);
}

@media (max-width: 620px) {
  .places,
  .places--grid,
  .places--feature {
    grid-template-columns: 1fr;
  }

  .places--feature .place--lead {
    grid-column: span 1;
  }
}

/* Region groups on the destinations page. The rule under each title marks
   where one island group ends and the next begins. */
.region + .region {
  margin-top: clamp(2.75rem, 5vw, 4.5rem);
}

.region-title {
  font-family: var(--font-display);
  font-size: clamp(1.18rem, 1.6vw, 1.38rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  margin: 0 0 1.5rem;
  padding-bottom: 0.8rem;
  border-bottom: 1px solid var(--line);
}

/* --- The name / scripture band -------------------------------------------- */

.meaning {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: center;
}

.meaning-mark {
  display: flex;
  justify-content: center;
}

/* The logo sits on the navy in its light form, with nothing behind it. It
   had been the full-colour artwork on a white plate with a glow and two
   rings, which gave a single image six pieces of decoration and made it read
   as a sticker dropped on the page. The mark carries itself. */
/* The <picture> needs the width too. Left to itself it shrink-wraps to the
   image's intrinsic 512px, and the 300px image then sits at the left edge of
   that box — which put the logo 100px off the centre of its column. */
.meaning-mark picture,
.meaning-mark img {
  display: block;
  width: min(300px, 100%);
  height: auto;
}


/* --- Closing call-to-action band ------------------------------------------
   Used at the foot of a page, directly above the navy footer. The photograph
   is what keeps the two apart: without it the section and the footer merge
   into one flat navy block. */

.cta-band {
  position: relative;
  padding-block: clamp(4.5rem, 10vw, 7rem);
  background: var(--ink-900);
  color: var(--white);
  overflow: hidden;
  isolation: isolate;
  text-align: center;
}

.cta-band-media {
  position: absolute;
  inset: 0;
  z-index: -1;
}

.cta-band-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 62%;
}

.cta-band-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(10, 21, 38, 0.74) 0%,
    rgba(10, 21, 38, 0.6) 45%,
    rgba(10, 21, 38, 0.88) 100%
  );
}

.cta-band-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.cta-band h2 {
  color: var(--white);
  font-size: clamp(1.55rem, 2.6vw, 2.1rem);
  margin-bottom: 0.4em;
  text-shadow: 0 2px 20px rgba(10, 21, 38, 0.55);
}

.cta-band p {
  color: rgba(255, 255, 255, 0.88);
  font-size: clamp(1.02rem, 1.4vw, 1.16rem);
  max-width: 52ch;
  margin: 0 auto;
}

.cta-band .btn-row {
  justify-content: center;
  margin-top: 2rem;
}

blockquote.scripture {
  margin: 2.4rem 0 0;
  padding-top: 1.8rem;
  border-top: 1px solid var(--line-night);
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.5vw, 1.25rem);
  font-style: italic;
  line-height: 1.45;
  color: var(--white);
  max-width: 30ch;
}

blockquote.scripture cite {
  display: block;
  margin-top: 0.9rem;
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-style: normal;
  letter-spacing: 0.05em;
  color: var(--star-300);
}

@media (max-width: 820px) {
  .meaning {
    grid-template-columns: 1fr;
  }

  .meaning-mark {
    order: -1;
  }
}

/* --- Gallery -------------------------------------------------------------- */

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: clamp(0.75rem, 1.5vw, 1.1rem);
}

.gallery button {
  padding: 0;
  border: 0;
  background: var(--ink-700);
  border-radius: var(--radius);
  overflow: hidden;
  cursor: zoom-in;
  aspect-ratio: 1;
  display: block;
}

.gallery img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.45s cubic-bezier(0.2, 0.6, 0.2, 1);
}

.gallery button:hover img,
.gallery button:focus-visible img {
  transform: scale(1.05);
}

/* --- Bento gallery -------------------------------------------------------- */
/* An uneven tile wall. Column and row spans are assigned by js/main.js so the
   rows always come out flush whatever number of photos is in the markup —
   drop more tiles in and the layout re-tiles itself. */

.bento {
  display: grid;
  grid-template-columns: repeat(var(--bento-cols, 4), minmax(0, 1fr));
  grid-auto-rows: clamp(56px, 7vw, 92px);
  gap: clamp(10px, 1.1vw, 16px);
}

.bento-tile {
  position: relative;
  display: block;
  padding: 0;
  border: 0;
  border-radius: 5px;
  overflow: hidden;
  background: var(--ink-700);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  will-change: transform;
}

.bento-tile.is-dragging {
  z-index: 5;
  cursor: grabbing;
  box-shadow: 0 26px 50px -18px rgba(8, 18, 42, 0.6);
}

/* The inner span carries the entrance move so a drag can own the tile's own
   transform without the two fighting each other. Once a tile has finished its
   entrance, js/main.js also drives a slow-scrolling drift here — see "Bento
   parallax" further down — so this element ends up owning two different
   transforms across its lifetime, never both at once. */
.bento-inner {
  position: absolute;
  inset: 0;
  display: block;
  opacity: 1;
}

.js .bento[data-animate] .bento-inner {
  opacity: 0;
  transform: translateY(26px) scale(0.94);
  transition: opacity 0.62s ease, transform 0.62s cubic-bezier(0.2, 0.75, 0.24, 1);
}

.js .bento[data-animate] .bento-tile.is-in .bento-inner {
  opacity: 1;
  transform: none;
}

/* The photo layer, and only the photo layer, drifts with the scroll. It sits
   14px proud of the tile top and bottom so the drift (capped at 10px) can
   never pull an edge into view — the tile's own overflow:hidden clips the
   excess. The caption is a sibling, so it stays anchored while this moves. */
.bento-media {
  position: absolute;
  inset: -14px 0;
  display: block;
  overflow: hidden;
}

.bento-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.25, 1);
}

.bento-tile:hover img,
.bento-tile:focus-visible img {
  transform: scale(1.055);
}

/* The place name stays legible at all times — it is the useful part, and a
   phone has no hover to reveal it. Hovering only deepens the scrim and lifts
   the type; the full description belongs to the viewer. */
.bento-caption {
  position: absolute;
  inset: auto 0 0 0;
  display: block;
  padding: clamp(0.7rem, 1.4vw, 1.05rem);
  /* The small gold region line sits high in this box, so the scrim has to
     still be carrying weight up there — several of the photographs are a
     bright sky or pale sand behind exactly that line. */
  background: linear-gradient(
    to top,
    rgba(8, 18, 42, 0.93) 0%,
    rgba(8, 18, 42, 0.8) 48%,
    rgba(8, 18, 42, 0.46) 80%,
    transparent 100%
  );
  color: var(--white);
  /* Photographs vary; the shadow keeps the type readable over a bright sky. */
  text-shadow: 0 1px 4px rgba(8, 18, 42, 0.6);
  transition: background 0.35s ease, transform 0.35s ease;
}

.bento-tile:hover .bento-caption,
.bento-tile:focus-visible .bento-caption {
  background: linear-gradient(
    to top,
    rgba(8, 18, 42, 0.94) 0%,
    rgba(8, 18, 42, 0.58) 58%,
    rgba(8, 18, 42, 0.1) 100%
  );
  transform: translateY(-3px);
}

.bento-region {
  display: block;
  font-size: 0.74rem;
  letter-spacing: 0.08em;
  color: var(--star-300);
  margin-bottom: 0.15rem;
}

.bento-name {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(0.98rem, 1.5vw, 1.2rem);
  font-weight: 500;
  line-height: 1.2;
}

.bento-hint {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 1.3rem 0 0;
  font-size: 0.88rem;
  color: var(--text-soft);
}

.bento-hint .star-glyph {
  width: 0.8em;
  height: 0.8em;
}

/* --- Viewer --------------------------------------------------------------- */
/* Shared by the bento wall and the gallery page. */

.viewer {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(8, 18, 42, 0.95);
  place-items: center;
  padding: clamp(0.85rem, 3vw, 2.5rem);
  /* Keep the picture and caption clear of the dock sitting along the bottom. */
  padding-bottom: clamp(5.75rem, 13vh, 8rem);
  /* The browser gives <dialog> fit-content sizing and auto margins; override
     all of it so the overlay actually covers the viewport. */
  margin: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  border: 0;
  color: var(--text-on-night);
  overflow: hidden;
}

/* Only lay it out when it is open. Setting `display` on the dialog itself
   would beat the browser's `dialog:not([open]) { display: none }` and leak the
   close button and dock onto the page. */
.viewer[open] {
  display: grid;
}

.viewer::backdrop {
  background: rgba(8, 18, 42, 0.9);
}

.viewer-figure {
  margin: 0;
  display: grid;
  justify-items: center;
  gap: clamp(0.85rem, 2vw, 1.4rem);
  max-width: min(1000px, 100%);
}

.viewer-frame {
  display: block;
  border-radius: 6px;
  overflow: hidden;
  background: var(--ink-700);
  box-shadow: 0 40px 80px -40px rgba(0, 0, 0, 0.8);
  max-width: 100%;
}

.viewer-frame img {
  display: block;
  max-width: 100%;
  max-height: min(54vh, 560px);
  width: auto;
  height: auto;
}

.viewer-caption {
  text-align: center;
  max-width: 56ch;
  padding-inline: 0.5rem;
}

/* Centring the text is not enough on its own: these are paragraphs, so the
   global `p { max-width: 64ch }` applies, and 64ch measured at this small font
   size comes out well under the caption's width. That leaves a narrow box sat
   against the left edge with its text centred inside it — which reads as the
   region label being off-centre from the title above it. The box has to be
   centred too, at every width. */
.viewer-caption p {
  margin-inline: auto;
}

.viewer-region {
  font-size: 0.8rem;
  letter-spacing: 0.09em;
  color: var(--star-300);
  margin: 0 auto 0.3rem;
}

.viewer-caption h3 {
  color: var(--white);
  margin: 0 0 0.4rem;
  font-size: clamp(1.15rem, 1.8vw, 1.4rem);
}

.viewer-caption p.viewer-desc {
  margin: 0 auto;
  color: var(--text-on-night-soft);
  font-size: 0.97rem;
  line-height: 1.55;
}

.viewer-cta {
  margin-top: 1.1rem;
}

/* Sits in the corner rather than under the caption, which needs the room. */
.viewer-count {
  position: absolute;
  top: clamp(0.95rem, 2vw, 1.7rem);
  left: clamp(0.95rem, 2vw, 1.7rem);
  margin: 0;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  color: #8ea0b8;
}

.viewer-close,
.viewer-nav {
  position: absolute;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: rgba(8, 18, 42, 0.72);
  border: 1px solid rgba(228, 235, 243, 0.28);
  color: var(--white);
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease,
    transform 0.18s ease;
  z-index: 3;
}

.viewer-close:hover,
.viewer-nav:hover {
  background: var(--ink-600);
  border-color: var(--star-500);
  transform: scale(1.06);
}

.viewer-close {
  top: clamp(0.75rem, 2vw, 1.5rem);
  right: clamp(0.75rem, 2vw, 1.5rem);
}

.viewer-prev {
  left: clamp(0.5rem, 2vw, 1.5rem);
  top: 50%;
  margin-top: -23px;
}

.viewer-next {
  right: clamp(0.5rem, 2vw, 1.5rem);
  top: 50%;
  margin-top: -23px;
}

.viewer svg {
  width: 20px;
  height: 20px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
}

/* --- Viewer dock ---------------------------------------------------------- */

.viewer-dock {
  position: absolute;
  left: 50%;
  bottom: clamp(0.75rem, 2.5vw, 1.5rem);
  /* The centring translate stays put; dragging only adds to it. */
  transform: translate(calc(-50% + var(--dock-x, 0px)), var(--dock-y, 0px));
  z-index: 4;
  max-width: calc(100% - 1.5rem);
}

.viewer-dock[data-draggable="true"] {
  touch-action: none;
}

.viewer-dock-inner {
  display: flex;
  align-items: center;
  gap: 0;
  padding: 0.55rem 0.85rem;
  border-radius: 12px;
  background: rgba(14, 27, 58, 0.72);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(200, 150, 62, 0.34);
  box-shadow: 0 20px 44px -22px rgba(0, 0, 0, 0.85);
  overflow-x: auto;
  scrollbar-width: none;
}

.viewer-dock-inner::-webkit-scrollbar {
  display: none;
}

.viewer-dock[data-draggable="true"] .viewer-dock-inner {
  cursor: grab;
}

.viewer-dock[data-draggable="true"].is-dragging .viewer-dock-inner {
  cursor: grabbing;
}

.dock-thumb {
  position: relative;
  flex: none;
  width: clamp(34px, 8vw, 44px);
  height: clamp(34px, 8vw, 44px);
  margin-inline: -5px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  overflow: hidden;
  background: var(--ink-700);
  cursor: pointer;
  box-shadow: 0 6px 14px -6px rgba(0, 0, 0, 0.7);
  transition: transform 0.32s cubic-bezier(0.2, 0.8, 0.25, 1),
    box-shadow 0.25s ease, outline-color 0.2s ease;
  outline: 2px solid transparent;
  outline-offset: 1px;
}

.dock-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Fanned out like a handful of prints, then straightened when picked. */
.dock-thumb[data-tilt="left"] {
  transform: rotate(-8deg);
}

.dock-thumb[data-tilt="right"] {
  transform: rotate(8deg);
}

.dock-thumb:hover,
.dock-thumb:focus-visible {
  transform: translateY(-9px) rotate(0deg) scale(1.22);
  z-index: 3;
}

.dock-thumb[aria-current="true"] {
  transform: translateY(-8px) rotate(0deg) scale(1.2);
  outline-color: var(--star-300);
  z-index: 4;
  box-shadow: 0 10px 22px -8px rgba(0, 0, 0, 0.8),
    0 0 22px rgba(232, 200, 126, 0.35);
}

@media (max-width: 600px) {
  .viewer-prev,
  .viewer-next {
    top: auto;
    bottom: calc(clamp(0.75rem, 2.5vw, 1.5rem) + 74px);
    margin-top: 0;
  }

  .viewer-frame img {
    max-height: 46vh;
  }

  .viewer-caption p.viewer-desc {
    font-size: 0.92rem;
  }
}

/* --- Steps ---------------------------------------------------------------- */
/* Numbered because planning a trip genuinely is a sequence. */

/* Two steps to a row, on the same rhythm as the About copy above, so the
   band is filled rather than leaving a wide margin down one side. Four across
   would be the usual treatment for a numbered process, but the team list on
   this page is already a row of hairline-topped columns and a second one
   reads as a repeat. */
.steps {
  list-style: none;
  counter-reset: step;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(2rem, 5vw, 4.5rem);
}

@media (max-width: 860px) {
  .steps {
    grid-template-columns: 1fr;
  }
}

.steps li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 2.4rem 1fr;
  gap: 0 1.4rem;
  border-top: 1px solid var(--line);
  padding-block: 1.7rem;
}

.steps li::before {
  content: counter(step);
  grid-row: span 2;
  font-family: var(--font-display);
  font-size: 1.6rem;
  line-height: 1;
  color: var(--star-ink);
  padding-top: 0.12rem;
}

.steps h3 {
  margin-bottom: 0.3rem;
}

.steps p {
  margin: 0;
  color: var(--text-soft);
}

/* --- Trust ---------------------------------------------------------------- */

.credentials {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.5rem;
  margin: 0 0 3rem;
  padding: 0;
}

.credentials > div {
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 3px solid var(--star-500);
  border-radius: var(--radius);
  padding: 1.4rem 1.5rem;
}

.credentials dt {
  font-weight: 600;
  font-size: 0.92rem;
  letter-spacing: 0.06em;
  color: var(--text-soft);
  margin-bottom: 0.35rem;
}

.credentials dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: var(--ink-800);
}

.placeholder-note {
  background: #fff8e8;
  border: 1px dashed var(--star-500);
  border-radius: var(--radius);
  padding: 1.1rem 1.3rem;
  color: #6b4f14;
  font-size: 0.95rem;
  margin-bottom: 2.5rem;
}

.placeholder-note p {
  margin: 0;
  max-width: none;
}

.feedback {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1.25rem;
}

.feedback figure {
  margin: 0;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-lift);
}

.slot {
  display: grid;
  place-items: center;
  text-align: center;
  aspect-ratio: 4 / 3;
  background: repeating-linear-gradient(
    45deg,
    var(--day-50),
    var(--day-50) 12px,
    #e7edf4 12px,
    #e7edf4 24px
  );
  color: var(--text-soft);
  font-size: 0.9rem;
  padding: 1rem;
  border-radius: var(--radius);
}

/* --- Contact -------------------------------------------------------------- */

.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(1.5rem, 4vw, 3rem);
}

.contact-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.contact-list li {
  border-top: 1px solid var(--line);
  padding-block: 1.15rem;
}

.contact-list .label {
  display: block;
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--star-ink);
  margin-bottom: 0.3rem;
}

/* Two numbers under one "Mobile" label, each on its own line with the country
   in front of it, so a visitor knows which one to ring from where. */
.contact-pair {
  display: grid;
  gap: 0.35rem;
  font-size: 1.08rem;
  color: var(--text-soft);
}

.contact-list a,
.contact-list span.value {
  font-size: 1.08rem;
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid rgba(200, 150, 62, 0.55);
  transition: color 0.18s ease, border-color 0.18s ease;
}

.contact-list a:hover {
  color: var(--star-ink);
  border-bottom-color: var(--star-ink);
}

.contact-list span.value {
  border-bottom: 0;
}

.socials {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin-top: 1.6rem;
  padding: 0;
  list-style: none;
}

.socials a {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.6rem 1.05rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
  font-size: 0.93rem;
  font-weight: 500;
  transition: border-color 0.18s ease, color 0.18s ease,
    background-color 0.18s ease;
}

.socials a:hover {
  border-color: var(--star-500);
  color: var(--star-ink);
  background: rgba(200, 150, 62, 0.08);
}

.socials svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

/* --- Form ----------------------------------------------------------------- */

.inquire-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.65fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

@media (max-width: 900px) {
  .inquire-grid {
    grid-template-columns: 1fr;
  }
}

.form {
  display: grid;
  gap: 1.35rem;
}

.field {
  display: grid;
  gap: 0.45rem;
  /* Fields in a row stretch to match the tallest one. Without this, those
     spare pixels are handed to the rows inside — so a neighbour's error
     message drops this field's input down the page and stretches it. */
  align-content: start;
}

.field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 1.35rem;
}

/* --- "What can we help you arrange?" tick list ---------------------------- */
/* A fieldset rather than a div so the question is announced once, as the group's
   label, instead of being read out again for every box. */
.checkset {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0; /* fieldsets refuse to shrink inside a grid without this */
}

.checkset legend {
  padding: 0;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text);
  margin-bottom: 0.6rem;
}

.checkset-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0.5rem 1.2rem;
}

.check {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 400;
  font-size: 0.95rem;
  color: var(--text);
  cursor: pointer;
  padding: 0.3rem 0;
  /* a comfortable target without making the rows feel loose */
  min-height: 34px;
}

.check input[type="checkbox"] {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  accent-color: var(--star-500);
  cursor: pointer;
  margin: 0;
}

.check:hover span {
  color: var(--ink-900);
}

.check input:focus-visible {
  outline: 3px solid var(--star-500);
  outline-offset: 2px;
}

/* The box that opens under "Other". The rule on its left ties it back to the
   tick list above, so it reads as a follow-up question rather than a stray
   field that appeared from nowhere. */
.other-field {
  display: grid;
  gap: 0.45rem;
  margin-top: 0.9rem;
  padding-left: 0.9rem;
  border-left: 2px solid var(--star-500);
}

.other-field label {
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--text);
}

.field label {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text);
}

.field .hint {
  font-size: 0.86rem;
  color: var(--text-soft);
  font-weight: 400;
}

.field .req {
  color: #a3341f;
  margin-left: 0.15rem;
}

.field input,
.field select,
.field textarea {
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--text);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.8rem 0.95rem;
  width: 100%;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

/* Dial code and number as one control. Without the code a number written in
   its local form cannot be dialled from here: an Australian mobile is
   0422 877 866 at home but +61 422 877 866 from the Philippines. */
.tel-combo {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
}

.tel-combo select {
  /* Narrow on purpose: closed, this shows only a dial code, never a country
     name. main.js puts the full names back while the list is open. Wide
     enough for the longest code (+971) plus the browser's own arrow. */
  flex: 0 0 5.75rem;
  width: auto;
  /* Without this the select refuses to go narrower than its widest option —
     "Saint Vincent and the Grenadines +1" — because a flex item's default
     min-width is auto, and it swallows the whole cell. */
  min-width: 0;
  padding-inline: 0.6rem;
}

.tel-combo input {
  /* min-width:0 or the input refuses to shrink below its content and pushes
     the pair wider than the cell. */
  flex: 1 1 auto;
  min-width: 0;
}

.field textarea {
  min-height: 150px;
  resize: vertical;
  line-height: 1.6;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--sea-600);
  box-shadow: 0 0 0 3px rgba(45, 122, 140, 0.18);
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: 3px solid var(--star-500);
  outline-offset: 2px;
}

.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"],
.field select[aria-invalid="true"] {
  border-color: #a3341f;
}

.field-error {
  font-size: 0.88rem;
  color: #a3341f;
  min-height: 0;
}

/* An error slot waiting for a message is still a grid row, and so still costs
   a gap under every field it sits in. */
.field-error:empty {
  display: none;
}

.honeypot {
  position: absolute;
  left: -9999px;
  opacity: 0;
  height: 0;
  overflow: hidden;
}

.form-status {
  border-radius: var(--radius);
  padding: 1.1rem 1.3rem;
  font-size: 0.98rem;
}

.form-status[data-state="success"] {
  background: #e8f4ee;
  border: 1px solid #2f7d55;
  color: #1d5637;
}

.form-status[data-state="error"] {
  background: #fdecea;
  border: 1px solid #a3341f;
  color: #7d2718;
}

.form-status p {
  margin: 0;
  max-width: none;
}

.form-status p + p {
  margin-top: 0.5rem;
}

.form-aside {
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 3px solid var(--sea-600);
  border-radius: var(--radius);
  padding: 1.5rem 1.6rem;
}

.form-aside h3 {
  margin-bottom: 0.6rem;
}

.form-aside p:last-child {
  margin-bottom: 0;
}

/* --- Prose ---------------------------------------------------------------- */

/* Reading column. Held to a comfortable measure but left-aligned with the rest
   of the page rather than centred, so headings and body share one left edge. */
/* The About copy runs the full width of the band with its headings at the
   left edge, like every other section, and the body text set in two columns
   underneath. One column at this width would run to roughly 140 characters a
   line; two keeps each line short while the band stays filled. */
.prose {
  max-width: none;
}

.prose h2 {
  margin-top: 2.9rem;
}

.prose h2:first-child {
  margin-top: 0;
}

.prose-cols {
  column-count: 2;
  column-gap: clamp(2rem, 5vw, 4.5rem);
  /* Keep at least two lines of a paragraph together when one is split across
     the column break, so no single line is stranded at the top or bottom. */
  orphans: 2;
  widows: 2;
}

/* The global paragraph measure is for a single column of text; inside these
   it would cap the lines twice over. */
.prose-cols p,
.prose-split p {
  max-width: none;
}

.prose-cols p:first-child {
  margin-top: 0;
}

.prose-cols p:last-child,
.prose-split p:last-child {
  margin-bottom: 0;
}

/* The closing line sits beside its paragraph rather than under it, on the
   same two-column rhythm. */
.prose-split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

.prose-split .pull {
  margin-top: 0;
}

/* Two columns stop being readable once each is narrower than about 300px. */
@media (max-width: 860px) {
  .prose-cols {
    column-count: 1;
  }

  .prose-split {
    grid-template-columns: 1fr;
  }

  .prose-split .pull {
    margin-top: 2.2rem;
  }
}

.prose a {
  color: var(--sea-700);
  text-underline-offset: 3px;
}

.pull {
  font-family: var(--font-display);
  font-size: clamp(1.12rem, 1.7vw, 1.38rem);
  line-height: 1.38;
  color: var(--ink-800);
  border-left: 2px solid var(--star-500);
  padding-left: clamp(1.1rem, 2.5vw, 1.8rem);
  margin: 2.6rem 0;
  max-width: 34ch;
}

/* --- Footer --------------------------------------------------------------- */

.site-footer {
  background: var(--ink-900);
  color: var(--text-on-night-soft);
  padding-block: clamp(2.2rem, 3.5vw, 2.8rem) 1.4rem;
  font-size: 0.9rem;
}

/* The link columns were removed at the client's request: the same contact
   details and social links already appear in the band directly above the
   footer, so repeating them here was duplication. The mark went too, since
   the header carries it on every page and the registration line below names
   the business anyway. What is left is the tagline, the registration details
   and the trading disclaimer, centred. */
.footer-top {
  display: grid;
  justify-items: center;
  text-align: center;
  padding-bottom: 1.1rem;
}

.footer-brand p {
  margin: 0;
  max-width: 46ch;
  font-size: 0.88rem;
  line-height: 1.55;
  text-wrap: pretty;
}

/* --- Registration line and disclaimer ------------------------------------- */

.footer-legal {
  text-align: center;
  padding-top: 1.2rem;
  border-top: 1px solid var(--line-night);
  display: grid;
  gap: 0.2rem;
  justify-items: center;
}

.footer-reg {
  margin: 0;
  max-width: none;
  font-size: 0.84rem;
  line-height: 1.6;
  color: var(--text-on-night);
}

.footer-reg strong {
  color: var(--white);
}

/* Each registration is one atomic unit, with its separator tucked inside it
   rather than sitting between units. A separator can then never be pushed to
   the start of a wrapped line, and a number never splits from its label. */
.footer-reg-item {
  display: inline-block;
  white-space: nowrap;
}

.footer-sep {
  color: var(--star-300);
  opacity: 0.5;
  padding-inline: 0.3rem;
}

/* Four registrations will not sit across a phone. Each takes its own line and
   the separators go, which is tidier than a wrapped run of pipes. */
@media (max-width: 620px) {
  .footer-reg-item {
    display: block;
    white-space: normal;
  }

  .footer-sep {
    display: none;
  }
}

/* The Australian registration sits on its own line under the Philippine
   address, so each country's number stays with the place it belongs to.
   Tighter above than the first line, since the two read as one block. */
.footer-reg--second {
  margin-top: 0.45rem;
}

.footer-place {
  margin: 0;
  max-width: none;
  font-size: 0.84rem;
  color: #8ea0b8;
}

.footer-disclaimer {
  margin: 0.35rem 0 0;
  max-width: 68ch;
  font-size: 0.78rem;
  line-height: 1.55;
  color: #7e8fa6;
  text-wrap: pretty; /* keeps a single word off the last line */
}

.footer-col h4 {
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--star-300);
  margin: 0 0 1rem;
}

.footer-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.65rem;
}

.footer-col a {
  color: var(--text-on-night);
  text-decoration: none;
  transition: color 0.18s ease;
}

.footer-col a:hover {
  color: var(--star-300);
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
  margin-top: 1.1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line-night);
  font-size: 0.8rem;
  color: #7e8fa6;
}

.footer-bottom p {
  margin: 0;
  max-width: none;
}

/* --- Scroll reveals ------------------------------------------------------- */
/* Applied by js/main.js, so the content is visible to crawlers and to anyone
   with JavaScript off. A fade with a short rise — not a slide. */

.js[data-reveal-armed] .will-reveal {
  opacity: 0;
  transform: translateY(14px);
}

.js[data-reveal-armed] .will-reveal.is-revealed {
  opacity: 1;
  transform: none;
  transition: opacity 0.42s ease-out,
    transform 0.42s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

/* --- Living star ---------------------------------------------------------- */
/* The star is the brand. It breathes, the compass ring turns, the sky twinkles
   — all slow enough to register as atmosphere rather than movement. */

@keyframes halo-breathe {
  0%,
  100% {
    opacity: 0.6;
  }
  50% {
    opacity: 1;
  }
}

@keyframes ray-shimmer {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.035);
  }
}

@keyframes orbit-turn {
  to {
    transform: rotate(360deg);
  }
}

@keyframes twinkle {
  0%,
  100% {
    opacity: var(--twinkle-low, 0.18);
  }
  50% {
    opacity: var(--twinkle-high, 0.65);
  }
}

/* The back facet counter-rotates against the front one, which is what makes
   the star read as a solid object catching light rather than a flat cut-out. */
@keyframes facet-turn {
  from {
    transform: rotate(45deg) scale(0.82);
  }
  to {
    transform: rotate(405deg) scale(0.82);
  }
}

@keyframes core-pulse {
  0%,
  100% {
    opacity: 0.85;
    transform: scale(1);
  }
  50% {
    opacity: 1;
    transform: scale(1.35);
  }
}

.star-orbit,
.star-shape,
.star-halo,
.star-core {
  transform-box: fill-box;
  transform-origin: center;
}

.js .hero-star .star-halo {
  animation: halo-breathe 7.5s ease-in-out 1.4s infinite;
}

/* The glow is a real light source, so it bleeds onto everything around it. */
.js .hero-star .star-shape {
  animation: star-bloom 1.5s cubic-bezier(0.16, 0.8, 0.28, 1) backwards,
    ray-shimmer 9s ease-in-out 1.6s infinite;
  filter: drop-shadow(0 0 14px rgba(232, 200, 126, 0.45))
    drop-shadow(0 0 34px rgba(200, 150, 62, 0.25));
}

.js .hero-star .star-shape--back {
  animation: facet-turn 48s linear infinite;
  filter: none;
}

.star-shape--back {
  transform: rotate(45deg) scale(0.82);
}

.js .hero-star .star-core {
  animation: core-pulse 4.5s ease-in-out 1.6s infinite;
  filter: drop-shadow(0 0 8px rgba(255, 248, 230, 0.9));
}

/* Two rings at different speeds and opposite directions: the parallax between
   them is what gives the star its sense of depth. */
.js .star-orbit {
  animation: orbit-turn 90s linear infinite;
}

.js .star-orbit--mid {
  animation-duration: 62s;
  animation-direction: reverse;
}

.js .page-head .star-orbit {
  animation-duration: 120s;
}

.js .hero-stars circle {
  animation: twinkle 5s ease-in-out infinite;
}

.js .hero-stars circle:nth-child(3n) {
  animation-duration: 7.5s;
  animation-delay: -2s;
}

.js .hero-stars circle:nth-child(3n + 1) {
  animation-duration: 6.2s;
  animation-delay: -4s;
}

.js .hero-stars circle:nth-child(4n) {
  animation-duration: 9s;
  animation-delay: -1s;
}

/* Decorative layers only — the headline never moves. */
.hero-star,
.hero-sky {
  will-change: transform;
}

.js .hero-star {
  transform: translate3d(0, var(--drift, 0px), 0);
}

/* --- Motion --------------------------------------------------------------- */
/* One orchestrated moment on the home page: the star blooms and the headline
   settles. Nothing else on the site animates on scroll. */

@keyframes star-bloom {
  from {
    opacity: 0;
    transform: scale(0.72) rotate(-18deg);
  }
  to {
    opacity: 1;
    transform: scale(1) rotate(0deg);
  }
}

@keyframes glow-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* NOTE: the star's own bloom/breathe/shimmer animations live entirely in the
   "Living star" section above — .star-shape, .star-halo and .star-ring are
   deliberately not re-touched here. (An earlier pass duplicated a plainer
   version of these same rules at this exact spot; because it came later in
   the cascade it silently won over the fancier "Living star" ones — the star
   never actually breathed. Fixed by deleting the duplicate rather than
   re-adding it.) */

/* fill-mode is "backwards", not "both", on purpose: a finished CSS animation
   with a "forwards"/"both" fill keeps holding its last keyframe at a cascade
   tier *above* inline styles, for good — which would block JavaScript from
   ever adjusting these same properties afterwards. "backwards" still shows
   the from-state during the delay (no flash before it starts) but lets the
   effect end cleanly once it has played. */
.js .hero-copy > * {
  animation: rise 0.85s cubic-bezier(0.2, 0.7, 0.25, 1) backwards;
}

.js .hero-copy > *:nth-child(1) {
  animation-delay: 0.1s;
}
.js .hero-copy > *:nth-child(2) {
  animation-delay: 0.22s;
}
.js .hero-copy > *:nth-child(3) {
  animation-delay: 0.34s;
}

.js .hero-tagline {
  animation: rise 0.85s cubic-bezier(0.2, 0.7, 0.25, 1) 0.46s backwards;
}

@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;
  }
}

/* --- Print ---------------------------------------------------------------- */

@media print {
  .site-header,
  .nav-toggle,
  .btn-row,
  .lightbox {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
  }
}
