/* Fly Black Girls Fly
   Design rules and tokens are documented in CLAUDE.md. Keep the two in sync. */

/* Fonts ----------------------------------------------------------------- */

/* Headings: Recoleta Alt Bold (Latinotype), one weight for every heading level.
   Use the vendor's woff2 as delivered: Latinotype's license forbids modifying it. */
@font-face {
  font-family: "Recoleta Alt";
  src: url("/fonts/RecoletaAlt-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Body and UI: GT Maru (Grilli Type) trial files, fine for mockups and Janay's
   review. Before launch, swap in the licensed web files and rename these paths
   to match. */
@font-face {
  font-family: "GT Maru";
  src: url("/fonts/GT-Maru-Regular-Trial.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "GT Maru";
  src: url("/fonts/GT-Maru-Medium-Trial.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "GT Maru";
  src: url("/fonts/GT-Maru-Bold-Trial.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "GT Maru";
  src: url("/fonts/GT-Maru-Regular-Oblique-Trial.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "GT Maru";
  src: url("/fonts/GT-Maru-Bold-Oblique-Trial.woff2") format("woff2");
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}

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

:root {
  /* Her picks */
  --teal: #01B79E;          /* Valspar Tantalizing Teal 5008-10B */
  --orange: #FC8901;        /* Valspar Orange Fruit 2011-1 */
  --fuchsia: #D64685;       /* Her circled swatch, Fuchsia Boho palette */

  /* Neutrals and text */
  --sand: #FFF7F0;          /* Base background, from her pink-sand beach photo */
  --ink: #2A2330;           /* Body and heading text, a deeper cut of her logo charcoal */
  --wine: #9A2252;          /* Links and small accent text, same palette as her fuchsia */
  --logo-charcoal: #544E5A; /* Ink color in her logo file, reference only */

  /* Tints and shades */
  --teal-mist: #E0F6F3;     /* Calm section background */
  --teal-strong: #017F6E;   /* Teal for small text, icons, and the focus ring */
  --teal-deep: #00564A;     /* Footer background */
  --peach: #FFEAD3;         /* Optional warm panel */
  --blush: #FBE5E5;         /* Testimonials background */
  --orange-hover: #E57C01;  /* Button hover */
  --sunset: linear-gradient(110deg, #D64685 0%, #FC8901 100%);

  /* Roles */
  --color-bg: var(--sand);
  --color-text: var(--ink);
  --color-link: var(--wine);
  --color-link-underline: var(--fuchsia);
  --color-cta-bg: var(--orange);
  --color-cta-bg-hover: var(--orange-hover);
  --color-cta-text: var(--ink);
  --color-focus: var(--teal-strong);
  --color-footer-bg: var(--teal-deep);
  --color-footer-text: var(--sand);

  /* Type */
  --font-sans: "GT Maru", ui-rounded, "Arial Rounded MT Bold", system-ui, sans-serif;
  --font-heading: "Recoleta Alt", ui-serif, "Iowan Old Style", Palatino, serif;

  --text-sm: 0.9375rem;                                  /* 15px: captions, meta */
  --text-base: 1.125rem;                                 /* 18px: body */
  --text-lg: 1.375rem;                                   /* 22px: lead paragraphs, H3 */
  --text-h2: clamp(1.75rem, 1.35rem + 1.6vw, 2.25rem);   /* 28px to 36px */
  --text-h1: clamp(2.5rem, 1.6rem + 3.6vw, 3.5rem);      /* 40px to 56px */
  --text-display: clamp(3rem, 1.4rem + 6.4vw, 5.5rem);   /* 48px to 88px, display moments only */

  --leading-body: 1.6;
  --leading-heading: 1.1;
  --leading-display: 1;
  --measure: 65ch;

  /* Layout */
  --gutter: clamp(1rem, 4vw, 2rem);
  --container: 72rem;
  --space-section: clamp(3.5rem, 8vw, 6.5rem);
  --edge-height: clamp(1.5rem, 4vw, 3.5rem);
  --radius: 1.5rem;
  --radius-sm: 0.75rem;
  --radius-pill: 999px;
}

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

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

[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: 400;
  line-height: var(--leading-body);
}

main {
  flex: 1;
}

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

svg {
  max-width: 100%;
}

/* Every heading is Recoleta Alt Bold. Hierarchy comes from size alone. */
h1,
h2,
h3 {
  margin: 0 0 0.5em;
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: var(--leading-heading);
  text-wrap: balance;
}

h1 {
  font-size: var(--text-h1);
  letter-spacing: -0.01em;
}

h2 {
  font-size: var(--text-h2);
}

h3 {
  font-size: var(--text-lg);
}

p,
ul,
ol,
dl {
  margin: 0 0 1em;
}

p {
  max-width: var(--measure);
  text-wrap: pretty;
}

/* Janay likes paragraphs justified, even on both ends. Hyphenation keeps narrow
   phone columns from opening wide gaps between words. */
main p {
  text-align: justify;
  -webkit-hyphens: auto;
  hyphens: auto;
}

/* Centered blocks, short labels, quotes, and the page intros keep their own
   alignment. The intros' few large-type lines open gaps no hyphenation fixes. */
.book-cta p,
.not-found p,
.booking-cta p,
.pull-quote p,
.quote blockquote p,
.hero-copy .lead,
.page-intro .lead,
.card-detail,
.trip-meta,
.meta,
.form-status,
.faq-item p {
  text-align: inherit;
  -webkit-hyphens: manual;
  hyphens: manual;
}

/* The four-column steps are too narrow to justify cleanly. */
@media (min-width: 64rem) {
  .step p {
    text-align: inherit;
    -webkit-hyphens: manual;
    hyphens: manual;
  }
}

strong {
  font-weight: 700;
}

a {
  color: var(--color-link);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-color: var(--color-link-underline);
  text-decoration-thickness: 2px;
}

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

::selection {
  background: var(--peach);
  color: var(--ink);
}

.lead {
  font-size: var(--text-lg);
  line-height: 1.5;
}

/* Display moments, at most two per page: the hero greeting and the booking prompt. */
.display {
  font-family: var(--font-heading);
  font-size: var(--text-display);
  font-weight: 700;
  line-height: var(--leading-display);
  letter-spacing: -0.01em;
}

/* The one place a headline can be set in fuchsia (display size, 48px and up). */
.display-fuchsia {
  color: var(--fuchsia);
}

.meta {
  font-size: var(--text-sm);
}

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

.skip-link {
  position: absolute;
  top: -10rem;
  left: 1rem;
  z-index: 100;
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  background: var(--ink);
  color: var(--sand);
  font-weight: 500;
}

.skip-link:focus {
  top: 1rem;
}

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

.container {
  width: min(100% - 2 * var(--gutter), var(--container));
  margin-inline: auto;
}

.section {
  --section-bg: var(--sand);
  position: relative;
  padding-block: var(--space-section);
  background: var(--section-bg);
}

.section-mist {
  --section-bg: var(--teal-mist);
}

/* The one full-teal band per page. Text on it is ink, and orange stays off it. */
.section-teal {
  --section-bg: var(--teal);
  --color-focus: var(--ink);
}

.section-teal a:not(.button) {
  color: var(--ink);
}

.section-blush {
  --section-bg: var(--blush);
}

/* For a section that continues straight on from the intro above it. */
.section-flush {
  padding-top: 0;
}

.section-header {
  max-width: 42rem;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.section-header > :last-child {
  margin-bottom: 0;
}

.section-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.5rem;
  margin-top: clamp(2rem, 4vw, 3rem);
}

/* Curved section edges. The SVG sits just outside its section and takes the
   section's own color, so it curves into whatever comes before or after. */
.edge {
  position: absolute;
  left: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: var(--edge-height);
  fill: var(--section-bg);
  pointer-events: none;
}

.edge-top {
  bottom: calc(100% - 1px);
}

.edge-bottom {
  top: calc(100% - 1px);
  transform: scale(-1, -1);
}

/* Buttons and links ----------------------------------------------------- */

/* Orange means action: every primary button, and nothing else. */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  min-height: 3rem;
  padding: calc(0.75rem - 2px) calc(1.5rem - 2px);
  /* Transparent, so buttons keep their shape in forced-colors mode at the same size. */
  border: 2px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--color-cta-bg);
  color: var(--color-cta-text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.button:hover {
  background: var(--color-cta-bg-hover);
  color: var(--color-cta-text);
  text-decoration: none;
}

.button:disabled,
.button[aria-disabled="true"] {
  cursor: progress;
  opacity: 0.7;
}

.button-plane {
  width: 1.25em;
  height: 1.1em;
  fill: currentColor;
  flex: none;
  transition: transform 0.25s ease;
}

.button:hover .button-plane,
.button:focus-visible .button-plane {
  transform: translate(3px, -3px) rotate(-8deg);
}

.text-link {
  font-weight: 500;
}

/* Read more ------------------------------------------------------------ */

/* On phones, long text marked data-readmore shows its opening lines, fades
   out, and gets a Read more button from main.js. Wider screens, and browsers
   without JavaScript, always show the full text. --readmore-height on each
   block sets how much shows while collapsed. */
@media (max-width: 47.99rem) {
  .js [data-readmore]:not(.is-open):not(.is-short) {
    max-height: var(--readmore-height, 14rem);
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 5rem), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 5rem), transparent);
  }
}

/* The buttons only make sense while the clamp is on; the no-JavaScript fallback hides them. */
:root:not(.js) .readmore-toggle {
  display: none;
}

/* Its own line, so it never runs into a link that follows the text. */
.readmore-toggle {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 0.375rem;
  min-height: 2.75rem;
  padding: 0.5rem 0;
  border: 0;
  background: none;
  color: var(--color-link);
  font: inherit;
  font-weight: 500;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  cursor: pointer;
}

.readmore-toggle:hover {
  text-decoration-color: var(--color-link-underline);
  text-decoration-thickness: 2px;
}

.readmore-toggle svg {
  width: 0.875em;
  height: 0.875em;
  flex: none;
  transition: transform 0.2s ease;
}

.readmore-toggle[aria-expanded="true"] svg {
  transform: rotate(180deg);
}

/* Wine is too dark on full teal, so the button goes ink there. */
.section-teal .readmore-toggle {
  color: var(--ink);
}

/* Header and nav -------------------------------------------------------- */

.site-header {
  position: relative;
  z-index: 10;
}

.header-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  min-height: 5rem;
  padding-block: 1rem;
}

/* Her logo, traced from her designer's PNGs. The header shows the color version
   (#logo). The footer uses the same shapes with no fill (#logo-mono), so they
   take the surrounding text color, sand. */
.logo {
  display: block;
  flex: none;
  color: var(--ink);
}

.logo svg {
  display: block;
  width: auto;
  height: clamp(6rem, 4.5rem + 4.5vw, 7.5rem);
  aspect-ratio: 764 / 927;
  fill: currentColor;
}

/* On wider screens the logo is bigger and sits well down from the top edge
   (Janay and Eugene, October 22). */
@media (min-width: 48rem) {
  .header-inner {
    padding-block: clamp(2rem, 4vw, 3.5rem) 1rem;
  }

  .logo svg {
    height: clamp(10rem, 5rem + 10vw, 16rem);
  }
}

/* A phone held sideways is wide enough for the desktop logo but only about
   400px tall, so it keeps a smaller one, closer to the top. */
@media (min-width: 48rem) and (max-height: 30rem) {
  .header-inner {
    padding-block: 1.25rem 1rem;
  }

  .logo svg {
    height: 7.5rem;
  }
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2rem;
}

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
  padding: 0;
  margin: 0;
  list-style: none;
}

.site-nav ul a {
  padding-block: 0.25rem;
  background: linear-gradient(var(--fuchsia), var(--fuchsia)) no-repeat 0 100% / 0 2px;
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
  transition: background-size 0.2s ease;
}

.site-nav ul a:hover,
.site-nav ul a[aria-current="page"] {
  background-size: 100% 2px;
}

.nav-toggle {
  display: none;
}

@media (max-width: 47.99rem) {
  .js .header-inner {
    flex-wrap: nowrap;
    column-gap: 1rem;
  }

  .js .nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex: none;
    min-height: 2.75rem;
    padding: 0.5rem 0.875rem;
    border: 2px solid var(--ink);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: var(--text-base);
    font-weight: 500;
    cursor: pointer;
  }

  .nav-toggle-icon {
    width: 1.125rem;
    height: 1.125rem;
  }

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

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

  .js .site-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 1.25rem;
    padding: 0.5rem var(--gutter) 2rem;
    background: var(--sand);
    box-shadow: 0 1.5rem 2rem -1.5rem rgb(42 35 48 / 0.25);
  }

  .js .site-nav.is-open {
    display: flex;
  }

  .js .site-nav ul {
    flex-direction: column;
    gap: 0;
  }

  .js .site-nav ul a {
    display: inline-block;
    padding-block: 0.625rem;
    font-size: var(--text-lg);
  }
}

/* Motifs ---------------------------------------------------------------- */

/* Dotted flight path with the paper airplane from her logo. */
.flight-path {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  color: var(--fuchsia);
}

.flight-path svg {
  display: block;
  width: min(100%, 34rem);
  height: auto;
  margin-inline: auto;
  overflow: visible;
}

/* The plane flies in along its trail, leaving the dots behind it, the first time
   each flight path comes into view (main.js adds is-flying). Everything else
   keeps the still version from the markup, plane at the end of a full trail:
   browsers without CSS motion paths, visitors who prefer reduced motion, and
   pages where main.js never starts (print hides the flight paths altogether).
   main.js also adds no-motion-path to <html> when a browser parses offset-path
   but doesn't move the plane with it. The path() values here must match the d
   of the trails in the markup. The trail is revealed by a mask whose round-capped
   stroke is drawn along the same path, so the dots appear right behind the plane
   and the end dots stay whole. */
@supports (offset-path: path("M0 0h1")) {
  @media screen and (prefers-reduced-motion: no-preference) {
    .js:not(.no-motion-path) .flight-reveal {
      stroke-dashoffset: 1;
      transition: stroke-dashoffset 2.4s cubic-bezier(0.45, 0.05, 0.35, 1) 0.2s;
    }

    .js:not(.no-motion-path) .flight-plane {
      offset-path: path("M10 96C120 120 200 30 320 62S500 96 560 36");
      offset-distance: 0%;
      offset-rotate: auto 45deg;
      transform: none;
      transition: offset-distance 2.4s cubic-bezier(0.45, 0.05, 0.35, 1) 0.2s;
    }

    .js:not(.no-motion-path) .hero-flight .flight-plane {
      offset-path: path("M14 214C90 222 150 170 230 168C320 166 330 92 280 96C236 100 250 160 320 150C400 138 470 92 540 56");
      offset-rotate: auto 27deg;
    }

    .js:not(.no-motion-path) .hero-flight .flight-reveal,
    .js:not(.no-motion-path) .hero-flight .flight-plane {
      transition-duration: 2.8s;
      transition-delay: 0.6s;
    }

    .js:not(.no-motion-path) .is-flying .flight-reveal {
      stroke-dashoffset: 0;
    }

    .js:not(.no-motion-path) .is-flying .flight-plane {
      offset-distance: 100%;
    }
  }
}

/* Sunset gradient, used at most twice per page: under the hero and atop the footer. */
.stop-fuchsia {
  stop-color: var(--fuchsia);
}

.stop-orange {
  stop-color: var(--orange);
}

.sunset-line {
  display: block;
  width: 100%;
  height: var(--edge-height);
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  overflow: visible;
}

/* Photos: arches for portraits, soft corners for everything else. */
.photo {
  position: relative;
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--teal-mist);
}

/* Set --focus on an image or video to keep its subject in frame when the shape crops it. */
.photo img,
.photo video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
}

/* Taller arch for full-length portraits and the About intro video. */
.photo-arch-tall {
  aspect-ratio: 2 / 3;
  border-radius: 50% 50% var(--radius) var(--radius) / 33.333% 33.333% var(--radius) var(--radius);
}

.photo-soft {
  aspect-ratio: 2 / 3;
  border-radius: var(--radius) 6rem var(--radius) var(--radius);
}

.photo-wide {
  aspect-ratio: 4 / 3;
}

/* Home: hero ------------------------------------------------------------ */

.hero {
  position: relative;
  padding-top: clamp(1rem, 3vw, 2.5rem);
}

.hero-inner {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.hero-copy {
  position: relative;
}

.hero-copy .display {
  margin-bottom: 0.35em;
}

/* Desktop only: her plane flies up from the greeting toward the nav, across the space under the header. */
.hero-flight {
  display: none;
}

/* On desktop the plane loops up from the greeting on Home, and from the About
   heading, toward the nav. --hero-flight-height is shared with the About intro's
   top padding, which makes room for the flight above its heading. */
@media (min-width: 56rem) {
  .hero,
  .page-intro.has-flight {
    --hero-flight-height: clamp(7rem, 37vw - 15.5rem, 14rem);
  }

  .hero-flight {
    position: absolute;
    bottom: calc(100% + 0.75rem);
    left: 0;
    display: block;
    width: auto;
    height: var(--hero-flight-height);
    aspect-ratio: 600 / 222;
    overflow: visible;
    color: var(--fuchsia);
    pointer-events: none;
  }

  /* About: room above the heading for most of the flight. The top of the loop may
     rise into the header's empty middle, left of the nav, as it does on Home. */
  .page-intro.has-flight {
    padding-top: calc(var(--hero-flight-height) - clamp(2.5rem, 9vw - 2.5rem, 5.5rem));
  }
}

.intro-copy {
  position: relative;
}

.hero-copy .lead {
  max-width: 30rem;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.5rem;
  margin-top: 2rem;
}

.hero-media {
  width: 100%;
}

@media (max-width: 55.99rem) {
  .hero-media {
    order: -1;
  }
}

@media (min-width: 56rem) {
  .hero-inner {
    grid-template-columns: 1fr minmax(0, 30rem);
  }

  /* The greeting sits near the top of the hero rather than centered beside
     the photos, which keeps it close to the logo. The flight above it then
     rises into the header's empty middle, left of the nav, and the plane
     lands just under the nav. */
  .hero-copy {
    align-self: start;
    margin-top: calc(var(--hero-flight-height) * 0.25);
  }
}

/* Hero slideshow */
.slideshow {
  position: relative;
}

.slides {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: 50% 50% var(--radius) var(--radius) / 50% 50% var(--radius) var(--radius);
  background: var(--teal-mist);
}

@media (min-width: 56rem) {
  .slides {
    aspect-ratio: 4 / 5;
    border-radius: 50% 50% var(--radius) var(--radius) / 40% 40% var(--radius) var(--radius);
  }
}

.slide {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.9s ease, visibility 0s linear 0.9s;
}

.slide.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.9s ease, visibility 0s;
}

.slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
}

.slideshow-controls {
  position: absolute;
  bottom: 1rem;
  left: 50%;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem;
  border-radius: var(--radius-pill);
  background: var(--sand);
  transform: translateX(-50%);
}

/* On phones the controls would cover half the photo's bottom edge, so they sit under it. */
@media (max-width: 47.99rem) {
  .slideshow-controls {
    position: static;
    width: fit-content;
    margin: 0.5rem auto 0;
    transform: none;
  }
}

.slideshow-dots {
  display: flex;
  padding: 0;
  margin: 0;
  list-style: none;
}

/* Taller hit areas for the dots and pause button, without changing how they look. */
.slideshow-dot::after,
.slideshow-toggle::after {
  content: "";
  position: absolute;
  inset: -0.375rem 0;
}

.slideshow-dot,
.slideshow-toggle {
  position: relative;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}

.slideshow-dot::before {
  content: "";
  width: 0.625rem;
  height: 0.625rem;
  border: 2px solid var(--ink);
  border-radius: var(--radius-pill);
  transition: width 0.3s ease, background-color 0.3s ease;
}

.slideshow-dot[aria-current="true"]::before {
  width: 1.25rem;
  background: var(--ink);
}

.slideshow-toggle svg,
.video-toggle svg {
  width: 1rem;
  height: 1rem;
}

.slideshow-toggle .icon-play,
.slideshow-toggle[data-playing="false"] .icon-pause,
.video-toggle .icon-play,
.video-toggle[data-playing="false"] .icon-pause {
  display: none;
}

.slideshow-toggle[data-playing="false"] .icon-play,
.video-toggle[data-playing="false"] .icon-play {
  display: block;
}

/* Pause and play for an autoplaying video, in a sand circle over the frame. */
.video-toggle::after {
  content: "";
  position: absolute;
  inset: -0.125rem;
}

.video-toggle {
  position: absolute;
  right: 1rem;
  bottom: 1rem;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--sand);
  color: var(--ink);
  cursor: pointer;
}

/* Home: hello, services, steps, book ------------------------------------ */

.hello-inner {
  display: grid;
  gap: 1rem clamp(2rem, 6vw, 5rem);
}

/* Her photo sits under the heading, level with the end of the text. */
.hello-media {
  width: 100%;
  max-width: 28rem;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius) 6rem var(--radius) var(--radius);
}

@media (min-width: 56rem) {
  .hello-inner {
    grid-template-columns: minmax(0, 20rem) 1fr;
  }

  .hello-media {
    grid-column: 1;
    grid-row: 2;
    align-self: end;
  }

  .hello-text {
    grid-column: 2;
    grid-row: 1 / span 2;
  }
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 1.5rem;
}

.card-grid-wide {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
}

.card {
  padding: clamp(1.5rem, 3vw, 2rem);
  border-radius: var(--radius);
  background: var(--sand);
}

.card > :last-child {
  margin-bottom: 0;
}

.card-detail {
  color: var(--teal-strong);
  font-size: var(--text-sm);
  font-weight: 500;
}

.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 2rem clamp(1.5rem, 4vw, 3rem);
  padding: 0;
  margin: 0;
  list-style: none;
  counter-reset: step;
}

@media (min-width: 64rem) {
  .steps {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.step {
  counter-increment: step;
}

.step::before {
  content: counter(step);
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  margin-bottom: 1rem;
  border-radius: 50%;
  background: var(--sand);
  color: var(--ink);
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 700;
}

.step p {
  margin-bottom: 0;
}

.book-cta {
  text-align: center;
}

.book-cta .display {
  margin-bottom: 0.3em;
}

.book-cta p {
  margin-inline: auto;
}

.book-cta .section-actions {
  justify-content: center;
}

.book-cta .meta {
  margin-top: 1rem;
}

/* Testimonials ---------------------------------------------------------- */

.quote-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: clamp(2rem, 4vw, 3rem);
}

.quote {
  margin: 0;
}

.quote blockquote {
  margin: 0 0 1rem;
  font-size: var(--text-lg);
  line-height: 1.5;
}

/* Both quote marks sit on the line with the words, in fuchsia, larger than the
   text (Janay, October 22: no mark hovering above). line-height 0 keeps the big
   glyphs from pushing the lines apart. */
.quote blockquote p:first-child::before,
.pull-quote p:first-child::before,
.quote blockquote p:last-child::after,
.pull-quote p:last-child::after {
  color: var(--fuchsia);
  font-family: var(--font-heading);
  font-style: normal;
  font-size: 2.2em;
  line-height: 0;
  vertical-align: -0.32em;
}

.quote blockquote p:first-child::before,
.pull-quote p:first-child::before {
  content: "\201C";
  margin-right: 0.08em;
}

.quote blockquote p:last-child::after,
.pull-quote p:last-child::after {
  content: "\201D";
  margin-left: 0.08em;
}

.quote figcaption {
  font-weight: 500;
}

.quote figcaption span {
  display: block;
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 400;
}

/* Interior pages -------------------------------------------------------- */

/* Bottom padding leaves room for a curved edge on the section that follows. */
.page-intro {
  padding-block: clamp(2rem, 6vw, 4rem) calc(var(--edge-height) + 1.5rem);
}

.page-intro-inner {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

@media (min-width: 56rem) {
  .page-intro-inner {
    grid-template-columns: 1fr minmax(0, 24rem);
  }
}

.page-intro .lead {
  max-width: 34rem;
}

/* About: story rows, mission band, trip notes */
.story {
  display: grid;
  gap: 2rem clamp(2rem, 6vw, 5rem);
  align-items: center;
}

.story + .story {
  margin-top: var(--space-section);
}

@media (min-width: 56rem) {
  .story {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }

  .story-reverse .story-media {
    order: 2;
  }

  .story-media {
    position: sticky;
    top: 2rem;
  }
}

.story-media {
  max-width: 28rem;
}

/* Mission text beside her Singapore photo; on phones the photo follows the text. */
.mission {
  display: grid;
  gap: 2.5rem clamp(2rem, 6vw, 5rem);
  align-items: center;
}

.mission-text {
  max-width: 48rem;
}

.mission-media {
  width: 100%;
  max-width: 22rem;
}

@media (min-width: 56rem) {
  .mission {
    grid-template-columns: 1fr minmax(0, 22rem);
  }
}

.mission h2 {
  font-size: var(--text-h1);
  letter-spacing: -0.01em;
}

/* Where I've been: her countries in columns, two on phones up to four on desktop. */
.been-list {
  padding: 0;
  margin: 0;
  list-style: none;
  columns: 2;
  column-gap: 2rem;
}

@media (min-width: 40rem) {
  .been-list {
    columns: 3;
  }
}

@media (min-width: 64rem) {
  .been-list {
    columns: 4;
  }
}

/* On the narrowest phones, slightly smaller type and tighter columns so long names fit. */
@media (max-width: 23.99rem) {
  .been-list {
    column-gap: 1rem;
    font-size: var(--text-sm);
  }

  .been-list li {
    gap: 0.5rem;
  }
}

.been-list li {
  display: flex;
  align-items: baseline;
  gap: 0.625rem;
  padding-block: 0.3rem;
  break-inside: avoid;
}

.been-list li::before {
  content: "";
  flex: none;
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
  background: var(--fuchsia);
  transform: translateY(-0.15em);
}

.trip-list {
  display: grid;
  gap: clamp(3rem, 6vw, 4.5rem);
}

.trip {
  display: grid;
  gap: 1.5rem clamp(2rem, 5vw, 4rem);
  align-items: start;
}

@media (min-width: 56rem) {
  .trip {
    grid-template-columns: minmax(0, 26rem) 1fr;
  }
}

.trip-body > :last-child {
  margin-bottom: 0;
}

.trip h3 {
  margin-bottom: 0.25em;
}

.trip-meta {
  margin-bottom: 0.75rem;
  color: var(--teal-strong);
  font-size: var(--text-sm);
  font-weight: 500;
}

/* Italic, as in Janay's copy. The quote marks stay upright. */
.pull-quote {
  max-width: 40rem;
  margin: 0 auto;
  font-size: var(--text-h2);
  font-style: italic;
  font-weight: 700;
  line-height: 1.3;
  text-wrap: balance;
}

/* A portrait beside the pull quote. */
.quote-feature {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.quote-feature-media {
  width: 100%;
  max-width: 22rem;
}

.quote-feature-copy {
  min-width: 0;
  container-type: inline-size;
}

/* The quote stays on one line: it scales with its column, up to the H2 size,
   never below 1rem (the largest floor that still fits a 320px phone). Browsers
   without container units skip this and keep the wrapped H2-size quote. */
.quote-feature .pull-quote {
  margin: 0;
}

@supports (font-size: 1cqw) {
  .quote-feature .pull-quote {
    max-width: none; /* the inherited 40rem is a hair narrower than the line at the H2 size */
    font-size: clamp(1rem, 5.4cqw, var(--text-h2)); /* the line is just over 18em wide, quote marks included */
    text-wrap: initial;
  }

  .quote-feature .pull-quote p {
    white-space: nowrap;
  }
}

.quote-feature-text {
  margin: 1.5rem 0 0;
}

/* Two columns only once the copy column can carry the quote near H2 size. */
@media (min-width: 64rem) {
  .quote-feature {
    grid-template-columns: minmax(0, 18rem) 1fr;
  }
}

@media (min-width: 72rem) {
  .quote-feature {
    grid-template-columns: minmax(0, 22rem) 1fr;
  }
}

/* FAQ: one reading-width column. Each question is a collapsed <details>, the
   question its summary, with a chevron that turns when it opens. */
.faq {
  max-width: var(--measure);
  border-top: 1px solid rgb(42 35 48 / 0.18);
}

.faq-item {
  border-bottom: 1px solid rgb(42 35 48 / 0.18);
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 0.25rem 1rem 0;
  cursor: pointer;
  list-style: none;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary h3 {
  margin: 0;
  font-size: var(--text-lg);
}

.faq-item summary::after {
  content: "";
  flex: none;
  width: 0.65rem;
  height: 0.65rem;
  margin: 0 0.4rem 0.3rem 0;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
}

.faq-item[open] summary::after {
  margin: 0.3rem 0.4rem 0 0;
  transform: rotate(-135deg);
}

@media (prefers-reduced-motion: no-preference) {
  .faq-item summary::after {
    transition: transform 0.2s ease, margin 0.2s ease;
  }
}

.faq-item p {
  margin: 0 0 1.25rem;
}

/* Book */
.booking-layout {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

@media (min-width: 56rem) {
  .booking-layout {
    grid-template-columns: minmax(0, 22rem) 1fr;
  }
}

.details {
  display: grid;
  gap: 1.25rem;
  margin: 0;
}

.details div {
  padding-bottom: 1.25rem;
  border-bottom: 1px solid rgb(42 35 48 / 0.15);
}

.details dt {
  color: var(--teal-strong);
  font-size: var(--text-sm);
  font-weight: 500;
}

.details dd {
  margin: 0;
}

.booking-widget {
  min-height: 24rem;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border-radius: var(--radius);
  background: #fff;
}

/* The booking panel: the site's own button to Janay's Square booking page (or to
   the contact form until Square approves her account). Square's embedded calendar
   can replace it after launch (README, Square booking widget). */
.booking-cta {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 1rem;
  min-height: 20rem;
  padding: 1rem;
  text-align: center;
}

.booking-cta p {
  max-width: 26rem;
  margin: 0;
}

.booking-cta .button {
  margin-top: 0.5rem;
}

.booking-cta-plane {
  width: 3rem;
  height: 2.625rem;
  fill: var(--fuchsia);
}

.policy {
  max-width: var(--measure);
}

/* Space above each section of a longer policy, like the privacy page. */
.policy > * + h2 {
  margin-top: 2.5rem;
}

.policy > p + h3 {
  margin-top: 1.75rem;
}

/* Contact */
.contact-layout {
  display: grid;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}

@media (min-width: 56rem) {
  .contact-layout {
    grid-template-columns: minmax(0, 36rem) minmax(0, 22rem);
    justify-content: space-between;
  }
}

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

.field label {
  display: block;
  margin-bottom: 0.375rem;
  font-weight: 500;
}

.field input,
.field textarea {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 2px solid var(--ink);
  border-radius: var(--radius-sm);
  background: #fff;
  color: var(--ink);
  font: inherit;
}

.field textarea {
  min-height: 11rem;
  resize: vertical;
}

.field input:focus-visible,
.field textarea:focus-visible {
  outline-offset: 2px;
}

/* Bots fill this field in. People never see it. */
.field-trap {
  position: absolute;
  left: -100vw;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-status {
  padding: 1rem 1.25rem;
  border-radius: var(--radius-sm);
  margin: 0;
}

/* Out of the flow while empty, but still rendered so screen readers hear updates. */
.form-status:empty {
  position: absolute;
  padding: 0;
}

.form-status[data-state="success"] {
  background: var(--teal-mist);
}

.form-status[data-state="error"] {
  background: var(--blush);
  color: var(--wine);
}

/* Without JavaScript the form posts and the server redirects back to one of these. */
.form-notice {
  display: none;
}

.form-notice:target {
  display: block;
}

.panel {
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border-radius: var(--radius);
  background: var(--teal-mist);
}

.panel > :last-child {
  margin-bottom: 0;
}

/* 404 */
.not-found {
  text-align: center;
}

.not-found p {
  margin-inline: auto;
}

.not-found .section-actions {
  justify-content: center;
}

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

.site-footer {
  --section-bg: var(--color-footer-bg);
  --color-focus: var(--sand);
  position: relative;
  margin-top: var(--edge-height);
  padding-block: clamp(2.5rem, 6vw, 4rem) 2rem;
  background: var(--color-footer-bg);
  color: var(--color-footer-text);
}

.site-footer a {
  color: var(--color-footer-text);
}

.site-footer a:hover {
  text-decoration-color: var(--color-footer-text);
}

.site-footer .logo {
  color: var(--color-footer-text);
}

.site-footer .logo svg {
  height: 7rem;
}

/* The links sit beside the brand when the tagline still fits on one line, and wrap under it when it doesn't. */
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 2rem 3rem;
}

.footer-brand p {
  margin: 1.25rem 0 0;
  text-wrap: balance;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
  padding: 0;
  margin: 0;
  list-style: none;
  font-weight: 500;
}

/* Her social links, stacked under the page links, each with its icon. */
.footer-social {
  display: grid;
  gap: 0.75rem;
  padding: 0;
  margin: 1.5rem 0 0;
  list-style: none;
  font-weight: 500;
}

.footer-social a {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}

.footer-social svg {
  width: 1.375rem;
  height: 1.375rem;
  flex: none;
}

/* From tablet up the footer nav sits at the right edge, the page links ending at
   Contact and the social stack right-aligned under it. Phones keep everything left. */
@media (min-width: 48rem) {
  .footer-inner > nav {
    margin-left: auto;
  }

  .footer-links {
    justify-content: flex-end;
  }

  .footer-social {
    justify-items: end;
  }
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 2rem;
  padding-top: 1.5rem;
  margin-top: 2.5rem;
  border-top: 1px solid rgb(255 247 240 / 0.25);
  font-size: var(--text-sm);
}

/* Taller tap areas on the footer links, without moving the layout or the focus ring. */
.footer-links a,
.footer-social a,
.footer-bottom a {
  position: relative;
}

.footer-links a::after,
.footer-social a::after,
.footer-bottom a::after {
  content: "";
  position: absolute;
  inset: -0.5rem 0;
}

/* Copyright and the legal links wrap as two pieces, never mid-phrase or indented. */
.footer-copy {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
}

.footer-legal {
  display: inline-flex;
  gap: 1.25rem;
}

.footer-bottom p {
  margin: 0;
}

/* Forced colors: the current page keeps a marker the system colors can show. */
@media (forced-colors: active) {
  .site-nav ul a[aria-current="page"] {
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 0.3em;
  }
}

/* Print: the whole text, no interface, and a footer that prints on white. */
@media print {
  [data-readmore] {
    max-height: none !important;
    -webkit-mask-image: none !important;
    mask-image: none !important;
  }

  .readmore-toggle,
  .nav-toggle,
  .site-nav,
  .slideshow-controls,
  .video-toggle,
  .skip-link,
  .edge,
  .sunset-line,
  .flight-path,
  .hero-flight {
    display: none !important;
  }

  .site-footer,
  .site-footer a,
  .site-footer .logo {
    background: none;
    color: var(--ink);
  }

  figure,
  .card,
  .step,
  .trip {
    break-inside: avoid;
  }

  h2,
  h3 {
    break-after: avoid;
  }
}

/* Motion ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}
