/* ==========================================================================
   Homepage.

   Original composition. Competitor sites informed WHAT patients need
   answered and in what order; nothing about how it looks is borrowed.

   The layout leans on asymmetry and generous type rather than the
   card-grid-then-carousel rhythm the market defaults to.
   ========================================================================== */

/* --- Section shells ------------------------------------------------------- */

.section-head {
  display: grid;
  gap: var(--space-3);
  max-width: 58ch;
}

.section--ink {
  background: var(--color-ink);
  color: var(--color-text-invert);
}

.section--ink h2,
.section--ink h3 {
  color: var(--color-text-invert);
}

.section--muted {
  background: var(--color-surface-muted);
}

.eyebrow--invert {
  color: var(--color-accent);
}

/* --- Hero ----------------------------------------------------------------- */
/* Asymmetric: the copy takes the wider column, the contact card sits beside
   it rather than a full-width form dominating the fold. */

.hero {
  position: relative;
  padding-block: clamp(48px, 7vw, 104px);
  background:
    radial-gradient(ellipse 80% 60% at 85% 0%, rgb(0 164 188 / 0.10), transparent 60%),
    var(--color-background);
  overflow: hidden;
}

.hero__inner {
  display: grid;
  gap: clamp(32px, 4vw, 56px);
  align-items: start;
}

@media (min-width: 900px) {
  .hero__inner {
    grid-template-columns: minmax(0, 1.35fr) minmax(300px, 0.85fr);
  }
}

.hero__copy {
  display: grid;
  gap: var(--space-5);
  align-content: start;
}

.hero__title {
  max-width: 18ch;
  font-size: var(--fs-display);
  line-height: var(--lh-display);
}

.hero__lead {
  max-width: 46ch;
  font-size: var(--fs-h4);
  line-height: var(--lh-subheading);
  color: var(--color-text-muted);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-block-start: var(--space-2);
}

.hero__proof {
  display: grid;
  gap: var(--space-3);
  padding: 0;
  margin-block-start: var(--space-4);
  list-style: none;
  font-size: var(--fs-small);
  color: var(--color-text-muted);
}

/* A checkmark drawn in CSS: no icon font, no extra request. */
.hero__proof li {
  position: relative;
  padding-inline-start: 30px;
}

.hero__proof li::before {
  position: absolute;
  content: "";
  inset-inline-start: 4px;
  inset-block-start: 0.45em;
  width: 11px;
  height: 6px;
  border-inline-start: 2px solid var(--color-accent-strong);
  border-block-end: 2px solid var(--color-accent-strong);
  rotate: -45deg;
}

.hero__card {
  display: grid;
  gap: var(--space-4);
  padding: clamp(24px, 3vw, 34px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
}

.hero__card-title {
  font-size: var(--fs-h3);
}

.hero__card-hint {
  color: var(--color-accent-strong);
  font-size: var(--fs-small);
  font-weight: 600;
}

.hero__contact {
  display: grid;
  gap: var(--space-4);
  margin: 0;
  padding-block: var(--space-4);
  border-block: 1px solid var(--color-border);
}

.hero__contact dt {
  color: var(--color-text-muted);
  font-size: var(--fs-caption);
}

.hero__contact dd {
  margin: 0;
  font-size: var(--fs-h4);
  font-weight: 600;
}

.hero__contact a {
  text-decoration: none;
}

.hero__card-note {
  color: var(--color-text-muted);
  font-size: var(--fs-caption);
}

/* --- Cards ---------------------------------------------------------------- */

.card {
  display: grid;
  gap: var(--space-3);
  align-content: start;
  padding: clamp(20px, 2vw, 28px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  transition: border-color var(--transition-fast), transform var(--transition-fast),
    box-shadow var(--transition-fast);
}

.card:hover {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.card__title {
  font-size: var(--fs-h4);
}

.card__body {
  color: var(--color-text-muted);
  font-size: var(--fs-small);
}

.card--quiet {
  background: var(--color-surface-muted);
  border-color: transparent;
}

.card--quiet:hover {
  background: var(--color-surface);
}

/* --- Journey -------------------------------------------------------------- */
/* A connecting rule between the steps, drawn on the container so it cannot
   trail past the last item. */

.journey {
  display: grid;
  gap: var(--stack);
  padding: 0;
  margin: 0;
  list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
}

.journey__step {
  position: relative;
  display: grid;
  gap: var(--space-3);
  align-content: start;
  padding-block-start: var(--space-6);
  border-block-start: 2px solid rgb(255 255 255 / 0.16);
}

.journey__number {
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-ink);
  font-size: var(--fs-small);
  font-weight: 700;
}

.journey__title {
  font-size: var(--fs-h4);
}

.journey__body {
  color: rgb(255 255 255 / 0.74);
  font-size: var(--fs-small);
}

/* --- Closing CTA ---------------------------------------------------------- */

.cta {
  padding-block: var(--section-y);
  background: var(--color-ink);
  color: var(--color-text-invert);
}

.cta__inner {
  display: grid;
  gap: var(--space-4);
  justify-items: center;
  max-width: 54ch;
  text-align: center;
}

.cta__title {
  font-size: var(--fs-h1);
  color: var(--color-text-invert);
}

.cta__lead {
  color: rgb(255 255 255 / 0.74);
}

.cta__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-block-start: var(--space-3);
}

.cta .btn--secondary {
  border-color: rgb(255 255 255 / 0.3);
  background: transparent;
  color: var(--color-text-invert);
}

.cta .btn--secondary:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

/* --- Scroll reveal -------------------------------------------------------- */
/* Transform and opacity only. Delay is a custom property so the stagger is
   data-driven rather than a class per position. */

.reveal {
  opacity: 0;
  translate: 0 14px;
  transition:
    opacity var(--transition-slow) calc(var(--reveal-delay, 0) * 70ms),
    translate var(--transition-slow) calc(var(--reveal-delay, 0) * 70ms);
}

.reveal.is-revealed {
  opacity: 1;
  translate: none;
}

/* Without JavaScript nothing may stay invisible. */
.no-js .reveal {
  opacity: 1;
  translate: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    translate: none;
    transition: none;
  }
}

/* --- Hero decorative layer (animated via --depth in animation.css) -------- */

.hero__aura {
  position: absolute;
  z-index: 0;
  inset-block-start: -22%;
  inset-inline-end: -12%;
  width: min(760px, 78vw);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgb(0 164 188 / 0.16), transparent 66%);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 1;
}

/* The rule each journey step draws in. */
.journey__rule {
  display: block;
  height: 2px;
  background: var(--color-accent);
  border-radius: 2px;
}

.journey__step {
  border-block-start: 0;
}


/* ==========================================================================
   Section compositions

   Three sections, three different forms. The page previously ran specialties,
   services and destinations through the same `.card-grid`, which is what made
   it read as a directory listing rather than a designed page: identical
   rhythm three times over. Each now has its own geometry, so scrolling the
   homepage feels composed instead of repeated.
   ========================================================================== */

/* --- Specialties: feature grid -------------------------------------------- */
/* Uniform tiles with one double-width lead, so the block has a focal point. */

.feature-grid {
  display: grid;
  gap: var(--stack);
  padding: 0;
  margin: 0;
  list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}

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

  /* The lead tile spans two columns and two rows: a real focal point rather
     than a slightly larger card. */
  .feature-tile--lead {
    grid-column: span 2;
    grid-row: span 2;
  }
}

.feature-tile {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr;
  overflow: hidden;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast),
    transform var(--transition-fast);
}

.feature-tile:hover {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.feature-tile__media {
  border-radius: 0;
}

/* The lead tile's image fills the taller cell instead of keeping the 3:2 of
   the small tiles. */
.feature-tile--lead .feature-tile__media .record-image__img {
  aspect-ratio: 16 / 10;
}

.feature-tile__text {
  display: grid;
  gap: var(--space-2);
  align-content: start;
  padding: clamp(18px, 2vw, 26px);
}

.feature-tile__title {
  font-size: var(--fs-h4);
}

.feature-tile--lead .feature-tile__title {
  font-size: var(--fs-h3);
}

.feature-tile__body {
  color: var(--color-text-muted);
  font-size: var(--fs-small);
}

.feature-tile:hover .record-image__img {
  transform: scale(1.05);
}

/* --- Services: alternating editorial rows --------------------------------- */

.service-list {
  display: grid;
  gap: clamp(28px, 5vw, 64px);
  padding: 0;
  margin: 0;
  list-style: none;
}

.service-row {
  display: grid;
  gap: var(--space-5);
  align-items: center;
}

@media (min-width: 820px) {
  .service-row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }

  /* Odd rows put the image on the opposite side. `order` rather than
     direction, so the reading order in the markup is untouched. */
  .service-row--flip .service-row__media {
    order: 2;
  }
}

.service-row__media {
  border-radius: var(--radius-lg);
}

.service-row__media .record-image__img {
  aspect-ratio: 4 / 3;
}

.service-row:hover .record-image__img {
  transform: scale(1.04);
}

.service-row__text {
  display: grid;
  gap: var(--space-2);
  align-content: center;
  max-width: var(--measure);
}

.service-row__index {
  color: var(--color-accent-strong);
  font-size: var(--fs-caption);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
}

.service-row__title {
  font-size: var(--fs-h3);
}

.service-row__body {
  color: var(--color-text-muted);
}

/* --- Destinations: image mosaic ------------------------------------------- */
/* Label sits on the photograph, so the section is image-led rather than
   another run of text cards. */

.destination-mosaic {
  display: grid;
  gap: var(--space-4);
  padding: 0;
  margin: 0;
  list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
}

@media (min-width: 900px) {
  .destination-mosaic {
    grid-template-columns: repeat(4, 1fr);
  }

  .destination-tile--wide {
    grid-column: span 2;
  }
}

.destination-tile {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  isolation: isolate;
}

.destination-tile__media {
  border-radius: 0;
}

.destination-tile__media .record-image__img {
  aspect-ratio: 3 / 4;
}

@media (min-width: 900px) {
  .destination-tile--wide .destination-tile__media .record-image__img {
    aspect-ratio: 3 / 2;
  }
}

/* Scrim carries the text contrast. Without it the label depends on whatever
   the photograph happens to look like, which is not a contrast guarantee. */
.destination-tile__text {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  display: grid;
  gap: var(--space-1);
  padding: clamp(16px, 2vw, 24px);
  color: var(--color-text-invert);
  background: linear-gradient(to top, rgb(11 22 33 / 0.88), rgb(11 22 33 / 0.55) 45%, transparent);
}

.destination-tile__title {
  color: var(--color-text-invert);
  font-size: var(--fs-h4);
}

.destination-tile__body {
  color: rgb(255 255 255 / 0.82);
  font-size: var(--fs-small);
}

.destination-tile:hover .record-image__img {
  transform: scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
  .feature-tile:hover .record-image__img,
  .service-row:hover .record-image__img,
  .destination-tile:hover .record-image__img {
    transform: none;
  }
}


/* ==========================================================================
   Cinematic hero

   Applied only when an administrator has set a background (`.hero--cinematic`).
   With no media the original light hero is untouched, so the page never
   depends on an upload existing.
   ========================================================================== */

.hero--cinematic {
  color: var(--color-text-invert);
  background: var(--color-ink);
  min-block-size: min(88svh, 780px);
  display: grid;
  align-items: center;
}

.hero__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
}

.hero__video,
.hero__still {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* Drifts a few pixels with scroll via --depth, set by reveal.js. Transform
     only, so it costs no layout. */
  transform: translate3d(0, calc(var(--depth, 0) * 0.06px), 0) scale(1.06);
  will-change: transform;
}

/* The scrim is what guarantees the headline stays readable over ANY frame of
   ANY video the client uploads. Text contrast cannot depend on the footage. */
.hero__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right, rgb(9 18 28 / 0.90) 0%, rgb(9 18 28 / 0.72) 45%, rgb(9 18 28 / 0.42) 100%),
    linear-gradient(to top, rgb(9 18 28 / 0.75), transparent 55%);
}

.hero--cinematic .hero__inner {
  position: relative;
  z-index: 1;
}

.hero--cinematic .hero__title,
.hero--cinematic .hero__card-title {
  color: var(--color-text-invert);
}

.hero--cinematic .hero__lead,
.hero--cinematic .hero__proof {
  color: rgb(255 255 255 / 0.82);
}

/* The contact card becomes glass over the footage rather than a white slab
   punched out of it. */
.hero--cinematic .hero__card {
  border-color: rgb(255 255 255 / 0.16);
  background: rgb(12 22 32 / 0.58);
  backdrop-filter: blur(14px) saturate(120%);
  color: var(--color-text-invert);
}

.hero--cinematic .hero__card-hint,
.hero--cinematic .hero__contact dt,
.hero--cinematic .hero__card-note {
  color: rgb(255 255 255 / 0.72);
}

.hero--cinematic .hero__contact a,
.hero--cinematic .hero__contact dd {
  color: var(--color-text-invert);
}

.hero--cinematic .hero__contact div + div {
  border-block-start-color: rgb(255 255 255 / 0.14);
}

@media (prefers-reduced-motion: reduce) {
  .hero__video,
  .hero__still {
    transform: none;
  }
}

/* --- Carousel tiles ------------------------------------------------------- */
/* The feature tile and destination tile are reused inside a carousel track,
   where the slide owns the width. They must not also try to size themselves. */

.carousel__slide.feature-tile,
.carousel__slide.destination-tile {
  block-size: 100%;
}

.carousel--portrait .destination-tile__media .record-image__img {
  aspect-ratio: 3 / 4;
}


/* --- Services: numbered index --------------------------------------------- */
/* Dense by design. The previous alternating image rows left roughly half of
   each row empty and put the whole burden on the photograph; this carries
   itself on number, rule and type. */

.service-index {
  display: grid;
  gap: 1px;
  padding: 0;
  margin: 0;
  list-style: none;
  /* The 1px gap over a border-coloured ground draws every divider in one
     go — no per-item borders to double up at the seams. */
  background: var(--color-border);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

@media (min-width: 680px) {
  .service-index {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1120px) {
  .service-index {
    grid-template-columns: repeat(4, 1fr);
  }
}

.service-item {
  position: relative;
  display: grid;
  gap: var(--space-2);
  align-content: start;
  padding: clamp(22px, 2.4vw, 32px);
  background: var(--color-surface);
  transition: background var(--transition-fast);
}

.service-item:hover {
  background: var(--color-surface-muted);
}

/* Accent rule that grows out of the top-left on hover. Transform only. */
.service-item__rule {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: 2px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--transition-slow);
}

.service-item:hover .service-item__rule {
  transform: scaleX(1);
}

.service-item__index {
  color: var(--color-accent-strong);
  font-size: var(--fs-caption);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  transition: transform var(--transition-fast);
}

.service-item:hover .service-item__index {
  transform: translateX(3px);
}

.service-item__title {
  font-size: var(--fs-h4);
  text-wrap: balance;
}

.service-item__body {
  color: var(--color-text-muted);
  font-size: var(--fs-small);
}

@media (prefers-reduced-motion: reduce) {
  .service-item__rule,
  .service-item__index {
    transition: none;
  }
}

/* The eyebrow and proof ticks are accent-green, which is a light-background
   colour. Over the hero photograph they fall below contrast, so both lift to
   the light end of the brand ramp. */
.hero--cinematic .eyebrow {
  color: var(--color-accent);
}

.hero--cinematic .hero__proof li::before {
  border-color: var(--color-accent);
}

/* --- Scrolling strip under the banner (§54.21) ---------------------------
   Admin-managed content, so the strip must survive six short items or ten
   long ones without being re-tuned. It scrolls the track rather than each
   item, and the track holds the list twice, so -50% lands exactly where 0
   started and the loop has no seam.

   THREE THINGS THAT ARE NOT DECORATION:

   1. `prefers-reduced-motion` stops it dead. Continuous horizontal motion is
      a documented trigger for vestibular disorders, and a strip a reader
      cannot stop is a strip they cannot read. Stopped, it still shows the
      first items and still scrolls by hand.
   2. It pauses on hover AND on keyboard focus. Focus matters more than
      hover: a keyboard user tabbing past must be able to hold it still.
   3. RTL reverses the direction. Arabic reads right to left, and a strip
      travelling the wrong way past the text fights the page.
   ------------------------------------------------------------------------ */

.marquee {
  --marquee-duration: 45s;

  overflow: hidden;
  background: var(--color-ink);
  color: var(--color-text-invert);
  border-block: 1px solid rgb(255 255 255 / 8%);
}

.marquee__track {
  display: flex;
  inline-size: max-content;
  animation: marquee-scroll var(--marquee-duration) linear infinite;
}

[dir="rtl"] .marquee__track {
  animation-name: marquee-scroll-rtl;
}

.marquee:hover .marquee__track,
.marquee:focus-within .marquee__track {
  animation-play-state: paused;
}

.marquee__list {
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.marquee__item {
  display: flex;
  align-items: center;
  padding-block: var(--space-3);
  padding-inline: var(--space-5);
  font-size: var(--font-size-sm);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* The dot lives here so no screen reader ever announces it. */
.marquee__item::after {
  content: "";
  inline-size: 0.375rem;
  block-size: 0.375rem;
  margin-inline-start: var(--space-5);
  border-radius: 50%;
  background: var(--color-accent);
  opacity: 0.9;
}

@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@keyframes marquee-scroll-rtl {
  from { transform: translateX(0); }
  to   { transform: translateX(50%); }
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track {
    animation: none;
  }

  /* Without motion the strip becomes a plain, scrollable row. */
  .marquee {
    overflow-x: auto;
  }
}

/* --- Home map (§54.21) --------------------------------------------------- */

.home-map {
  overflow: hidden;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg, 0.75rem);
  aspect-ratio: 16 / 9;
}

/* The iframe carries Google's own width/height attributes so the box has a
   ratio before the frame loads; these override them for the real layout
   without leaving a gap while it does. */
.home-map__frame {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  border: 0;
}

@media (max-width: 48rem) {
  .home-map {
    aspect-ratio: 4 / 3;
  }
}

/* --- Adjacent surfaces (§54.21) ------------------------------------------
   Two neighbouring sections on the same surface read as one long block with
   no boundary — the client reported exactly that between the questions and
   the enquiry form.

   Fixing that one pair by hand is not enough any more. Now that every
   section can be switched off independently, WHICH two end up adjacent is
   not known when the page is written: turn off the gallery and two light
   sections meet; turn off the enquiry form and two muted ones do. So the
   rule is expressed as adjacency rather than as a class on each section, and
   it holds for every combination of switches.

   The ink case gets a hairline rather than a new colour on purpose. Changing
   a dark background under text that is already set to the invert colour is
   how a contrast failure gets shipped; a divider separates the blocks
   without touching the contrast at all.
   ------------------------------------------------------------------------ */

.section--muted + .section--muted {
  background: var(--color-background);
}

.section:not(.section--muted):not(.section--ink)
  + .section:not(.section--muted):not(.section--ink) {
  background: var(--color-surface-muted);
}

.section--ink + .section--ink {
  border-block-start: 1px solid rgb(255 255 255 / 12%);
}
