/* ==========================================================================
   Salt & Soul Support
   Hand written CSS. Mobile first.
   1. Tokens
   2. Reset & base
   3. Utilities
   4. Buttons
   5. Nav
   6. Wave dividers
   7. Hero
   8. About
   9. Services
   10. Experiences
   11. Real moments
   12. Team
   13. Happy clients
   14. Friendly Paws
   15. Testimonial
   16. FAQ
   17. Contact
   18. Footer
   19. Thank you page
   20. Reveal & reduced motion
   ========================================================================== */

/* 1. Tokens ================================================================ */

:root {
  /* palette */
  --teal:      #1B5A6B;
  --aqua:      #3FA9BE;
  --coral:     #E8836B;
  --sand:      #F7F3EC;
  --ink:       #2A3B40;

  /* derived tones, kept minimal */
  --sand-deep: #EFE9DE;   /* hero and team background */
  --sand-line: #E3DBCC;   /* hairlines on sand */
  --teal-deep: #164C5A;   /* contact section depth */
  --on-coral:  #223034;   /* readable text on the coral button */
  --ink-soft:  rgba(42, 59, 64, 0.74);
  --sand-soft: rgba(247, 243, 236, 0.78);

  /* type */
  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-body: "Nunito Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* rhythm */
  --gutter: clamp(1.25rem, 5vw, 2.5rem);
  --measure: 1140px;
  --section-y: clamp(4.5rem, 10vw, 7.5rem);

  /* shape */
  --radius-card: 18px;
  --radius-arch: 220px 220px 18px 18px;
  --shadow-soft: 0 2px 4px rgba(27, 90, 107, .04), 0 12px 28px rgba(27, 90, 107, .07);
  --shadow-lift: 0 4px 8px rgba(27, 90, 107, .06), 0 20px 44px rgba(27, 90, 107, .12);
}

/* 2. Reset & base ========================================================== */

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

html {
  scroll-behavior: smooth;
  /* clears the sticky nav so anchored sections do not land under it */
  scroll-padding-top: 6.25rem;
  -webkit-text-size-adjust: 100%;
}

@media (min-width: 62em) {
  html { scroll-padding-top: 7.25rem; }
}

body {
  margin: 0;
  background: var(--sand);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  font-weight: 400;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 300;
  color: var(--teal);
  line-height: 1.14;
  letter-spacing: -0.015em;
  margin: 0;
  text-wrap: balance;
}

h1 em, h2 em {
  font-style: italic;
  font-weight: 300;
  color: var(--coral);
}

p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

ul { margin: 0; padding: 0; list-style: none; }

a { color: inherit; }

/* visible keyboard focus, everywhere */
:focus-visible {
  outline: 3px solid var(--aqua);
  outline-offset: 3px;
  border-radius: 4px;
}

/* 3. Utilities ============================================================= */

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

.section {
  position: relative;
  padding-block: var(--section-y);
}

.section__head {
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
  margin-bottom: clamp(2.5rem, 5vw, 3.5rem);
}

.section__title {
  font-size: clamp(2rem, 1.35rem + 2.6vw, 3rem);
}

.section__lead {
  margin-top: 1.1rem;
  color: var(--ink-soft);
  font-size: 1.075rem;
  max-width: 38rem;
  margin-inline: auto;
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: .625rem;
  margin: 0 0 1rem;
  font-family: var(--font-body);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--teal);
}

.eyebrow::before {
  content: "";
  flex: none;
  width: 1.75rem;
  height: 2px;
  border-radius: 2px;
  background: var(--coral);
}

.section__head .eyebrow { justify-content: center; }

.eyebrow--light { color: var(--sand); }

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

.skip-link {
  position: absolute;
  left: 1rem;
  top: -4rem;
  z-index: 200;
  padding: .7rem 1.1rem;
  background: var(--coral);
  color: var(--on-coral);
  font-weight: 700;
  text-decoration: none;
  border-radius: 0 0 10px 10px;
  transition: top .2s ease;
}
.skip-link:focus { top: 0; }

/* 4. Buttons =============================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .95rem 1.6rem;
  border: 2px solid transparent;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: transform .28s cubic-bezier(.2, .7, .3, 1),
              background-color .22s ease, border-color .22s ease, color .22s ease;
}

.btn--primary {
  background: var(--coral);
  color: var(--on-coral);
}
.btn--primary:hover { background: #e5734f; transform: translateY(-2px); }

.btn--ghost {
  background: transparent;
  color: var(--teal);
  border-color: var(--teal);
}
.btn--ghost:hover { background: var(--teal); color: var(--sand); transform: translateY(-2px); }

.btn--sm { padding: .65rem 1.25rem; font-size: .95rem; }
.btn--block { width: 100%; }

/* 5. Nav =================================================================== */

.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(247, 243, 236, .82);
  border-bottom: 1px solid var(--sand-line);
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav { background: var(--sand); }
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  /* sized off the logo so the bar keeps even air above and below it */
  min-height: 4.75rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

/* the svg carries the mark and the wordmark together, so it is the whole
   nav logo. height drives it; width follows the artwork's own ratio */
.brand__mark {
  flex: none;
  width: auto;
  height: 46px;
  max-width: none;
}

.nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.85rem;
  height: 2.85rem;
  padding: 0;
  border: 1px solid var(--sand-line);
  border-radius: 12px;
  background: transparent;
  color: var(--teal);
  cursor: pointer;
}

.nav__bars { display: block; width: 20px; }
.nav__bars span {
  display: block;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform .25s ease, opacity .2s ease;
}
.nav__bars span + span { margin-top: 5px; }

.nav__toggle[aria-expanded="true"] .nav__bars span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] .nav__bars span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] .nav__bars span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* mobile panel */
.nav__menu {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  display: none;
  background: var(--sand);
  border-bottom: 1px solid var(--sand-line);
  box-shadow: var(--shadow-soft);
}
.nav__menu.is-open { display: block; }

.nav__list {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  padding: 1rem var(--gutter) 1.5rem;
}

.nav__link {
  display: block;
  padding: .6rem 0;
  font-weight: 600;
  color: var(--teal);
  text-decoration: none;
  border-bottom: 1px solid var(--sand-line);
}
.nav__link:hover { color: var(--coral); }

.nav__list .btn { margin-top: .75rem; }

@media (min-width: 62em) {
  .nav__toggle { display: none; }

  .nav__inner { min-height: 5.75rem; }
  .brand__mark { height: 64px; }

  .nav__menu {
    position: static;
    display: block;
    background: transparent;
    border: 0;
    box-shadow: none;
  }

  .nav__list {
    flex-direction: row;
    align-items: center;
    gap: 2rem;
    padding: 0;
  }

  .nav__link {
    padding: .25rem 0;
    border-bottom: 2px solid transparent;
  }
  .nav__link:hover { border-bottom-color: var(--coral); color: var(--teal); }

  .nav__list .btn { margin-top: 0; }
}

/* 6. Wave dividers ========================================================= */
/* The brand mark is a heart made of a wave. The same curve carries the page
   from one section into the next. This is the only decorative element. */

.wave {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  line-height: 0;
  pointer-events: none;
  /* contains the oversize drifting svg below, so it cannot widen the page */
  overflow: hidden;
}

.wave svg {
  width: 100%;
  height: clamp(52px, 8vw, 118px);
}

.wave--up svg { transform: scaleX(-1); }

/* The hero wave drifts, very slowly, so the water reads as moving rather
   than frozen. Cut oversized and pulled back by half, so the ends never
   swing into view. The contact wave stays still, since it already carries
   a scaleX flip that an animation on the same property would overwrite. */
.wave--down svg {
  width: calc(100% + 48px);
  /* the reset caps every svg at max-width 100%, which would clamp the
     oversize back to flush and let the drift open a gap at the edge */
  max-width: none;
  margin-left: -24px;
  animation: wave-drift 22s ease-in-out infinite;
}

@keyframes wave-drift {
  0%, 100% { transform: translateX(-7px); }
  50%      { transform: translateX(7px); }
}

/* hero washes down into the sand page */
.wave--down .wave__front { fill: var(--sand); }
.wave--down .wave__back  { fill: var(--aqua); opacity: .16; }

/* team rises into the teal contact section */
.wave--up .wave__front { fill: var(--teal); }
.wave--up .wave__back  { fill: var(--aqua); opacity: .3; }

/* 7. Hero ================================================================== */

.hero {
  position: relative;
  background: var(--sand-deep);
  padding-block: clamp(2.5rem, 7vw, 5rem) calc(var(--section-y) + clamp(52px, 8vw, 118px));
}

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

/* photo on top when stacked, as briefed */
.hero__figure {
  order: -1;
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius-arch);
  box-shadow: var(--shadow-soft);
}

.hero__figure img {
  width: 100%;
  aspect-ratio: 4 / 3.4;
  object-fit: cover;
  object-position: 50% 20%;
}

.hero__title {
  font-size: clamp(2.6rem, 1.5rem + 5vw, 4.5rem);
  margin-bottom: 1.4rem;
}

.hero__lead {
  max-width: 34rem;
  font-size: clamp(1.05rem, 1rem + .3vw, 1.175rem);
  color: var(--ink-soft);
  margin-bottom: 2rem;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: .85rem;
}

/* Hero load sequence.
   The copy rises in one line at a time; the photo takes noticeably longer
   and only settles a fraction of its scale, so the picture feels like it
   is coming to rest rather than arriving. Gated on .js so the hero is
   never stuck invisible if scripts do not run. */

.js .hero__copy > * {
  opacity: 0;
  animation: hero-rise .72s cubic-bezier(.2, .7, .3, 1) forwards;
}

.js .hero__copy .eyebrow      { animation-delay: .08s; }
.js .hero__copy .hero__title  { animation-delay: .20s; }
.js .hero__copy .hero__lead   { animation-delay: .32s; }
.js .hero__copy .hero__actions{ animation-delay: .44s; }

.js .hero__figure {
  opacity: 0;
  animation: hero-fade .9s cubic-bezier(.2, .7, .3, 1) .06s forwards;
}

.js .hero__figure img {
  animation: hero-settle 1.5s cubic-bezier(.2, .7, .3, 1) .06s both;
}

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

@keyframes hero-fade {
  to { opacity: 1; }
}

@keyframes hero-settle {
  from { transform: scale(1.04); }
  to   { transform: scale(1); }
}

@media (min-width: 52em) {
  .hero__inner {
    grid-template-columns: 1.05fr .95fr;
    gap: clamp(2.5rem, 5vw, 4.5rem);
  }
  .hero__figure { order: 0; }
  .hero__figure img { aspect-ratio: 4 / 5; }
}

/* 8. About ================================================================= */

.section--about { background: var(--sand); }

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

.about__copy .section__title { margin-bottom: 1.4rem; }
.about__copy p { color: var(--ink-soft); max-width: 36rem; }

.about__figure {
  order: -1;
  margin: 0;
  align-self: start;
}

.about__figure img {
  width: 100%;
  aspect-ratio: 4 / 4.2;
  object-fit: cover;
  object-position: 50% 16%;
  border-radius: 180px 180px 18px 18px;
  box-shadow: var(--shadow-soft);
}

.about__caption {
  margin-top: .9rem;
  text-align: center;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--aqua);
}

.values {
  display: grid;
  gap: 1.75rem;
  margin-top: .5rem;
  padding-top: 2.25rem;
  border-top: 1px solid var(--sand-line);
}

.values__item { padding-left: 1.15rem; border-left: 3px solid var(--aqua); }

.values__title {
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: .01em;
  color: var(--teal);
  margin-bottom: .2rem;
}

.values__text { margin: 0; color: var(--ink-soft); }

@media (min-width: 52em) {
  .about__inner {
    grid-template-columns: 1.12fr .88fr;
    row-gap: clamp(2.75rem, 4vw, 3.75rem);
  }
  .about__figure { order: 0; }
  /* the value points run the full width beneath both columns */
  .values {
    grid-column: 1 / -1;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(1.75rem, 3vw, 3rem);
    margin-top: 0;
  }
}

/* 9. Services ============================================================== */

.section--services { background: var(--sand); }

.cards {
  display: grid;
  gap: 1.25rem;
}

.card {
  padding: clamp(1.6rem, 3vw, 2.1rem);
  background: #fff;
  border: 1px solid var(--sand-line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
  transition: transform .32s cubic-bezier(.2, .7, .3, 1),
              box-shadow .32s cubic-bezier(.2, .7, .3, 1), border-color .28s ease;
}

.card:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-lift);
  border-color: rgba(63, 169, 190, .5);
}

.card__title {
  font-size: 1.3rem;
  margin-bottom: .9rem;
  padding-bottom: .9rem;
  border-bottom: 2px solid var(--coral);
  border-image: linear-gradient(90deg, var(--coral) 0 2.25rem, var(--sand-line) 2.25rem) 1;
}

.card__text { margin: 0; color: var(--ink-soft); font-size: 1rem; }

@media (min-width: 40em) {
  .cards { grid-template-columns: repeat(2, 1fr); gap: 1.5rem; }
}

@media (min-width: 60em) {
  .cards { grid-template-columns: repeat(3, 1fr); }
}

/* 10. Experiences ========================================================== */

.section--experiences {
  background: var(--teal);
  color: var(--sand);
  /* room for the wave that spills in from the services page above */
  padding-top: calc(var(--section-y) + clamp(52px, 8vw, 118px));
}

.section--experiences .section__title { color: var(--sand); }
.section--experiences .section__lead { color: var(--sand-soft); }

/* this band is entered from the plain sand page rather than the team tone,
   so the wave that spills in needs the lighter fill */
.wave--top.wave--from-sand .wave__front { fill: var(--sand); }

.things {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .75rem;
  max-width: 54rem;
  margin-inline: auto;
}

.thing {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: .75rem 1.35rem;
  background: var(--sand);
  border-radius: 999px;
  font-size: 1rem;
  font-weight: 700;
  color: var(--teal);
  box-shadow: var(--shadow-soft);
  transition: transform .28s cubic-bezier(.2, .7, .3, 1),
              box-shadow .28s cubic-bezier(.2, .7, .3, 1);
}

.thing::before {
  content: "";
  flex: none;
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background: var(--coral);
}

.thing:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(11, 44, 53, .28);
}

.things__note {
  max-width: 40rem;
  margin: clamp(2.25rem, 4vw, 3rem) auto 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(1.1rem, 1rem + .45vw, 1.35rem);
  line-height: 1.5;
  color: var(--sand);
  text-wrap: pretty;
}

/* 11. Real moments ========================================================= */

/* sand, so it separates from the teal band above and the sand-deep team below */
.section--moments { background: var(--sand); }

/* Masonry. These are real photos in every orientation, so they keep their own
   proportions rather than being cropped into a uniform box.

   Multicol is the no-script fallback. It balances only by choosing break
   points and must fill in source order, so with unbreakable items of very
   different heights it leaves one column hanging short. main.js upgrades this
   to real columns and drops each photo into whichever is shortest. */
.moments {
  columns: 1;
  column-gap: clamp(1rem, 2vw, 1.4rem);
}

@media (min-width: 40em) { .moments { columns: 2; } }
@media (min-width: 64em) { .moments { columns: 3; } }

/* enhanced: genuine shortest-column masonry */
.moments.is-masonry {
  columns: auto;
  display: flex;
  align-items: flex-start;
  gap: clamp(1rem, 2vw, 1.4rem);
}

.moments__col {
  flex: 1 1 0;
  min-width: 0;
}

/* no trailing space under the bottom photo of each column */
.moments__col .moment:last-child { margin-bottom: 0; }

.moment {
  break-inside: avoid;
  margin: 0 0 clamp(1.15rem, 2.2vw, 1.6rem);
  text-align: center;
}

.moment__frame {
  overflow: hidden;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

.moment__frame img {
  width: 100%;
  height: auto;
  transition: transform .5s ease;
}

.moment:hover .moment__frame img { transform: scale(1.03); }

.moment__caption {
  margin: .8rem 0 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-style: italic;
  font-size: 1rem;
  line-height: 1.35;
  color: var(--teal);
  text-wrap: balance;
}

/* 12. Team ================================================================= */

.section--team { background: var(--sand-deep); }

.team {
  display: grid;
  gap: clamp(1.75rem, 3vw, 2.5rem);
  max-width: 24rem;
  margin-inline: auto;
}

.team__figure {
  margin: 0 0 1.25rem;
  overflow: hidden;
  border-radius: 140px 140px 18px 18px;
  box-shadow: var(--shadow-soft);
}

.team__figure img {
  width: 100%;
  aspect-ratio: 4 / 4.6;
  object-fit: cover;
  object-position: 50% 18%;
  transition: transform .5s ease;
}

.team__member:hover .team__figure img { transform: scale(1.03); }

.team__member { text-align: center; }

.team__name { font-size: 1.45rem; margin-bottom: .2rem; }

.team__role {
  margin: 0;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--aqua);
  text-wrap: balance;
}

/* four members, so two up on tablet and four across on desktop.
   Both stages divide evenly, which keeps the row from orphaning a card. */
@media (min-width: 34em) {
  .team {
    grid-template-columns: repeat(2, 1fr);
    max-width: none;
  }
}

@media (min-width: 64em) {
  .team { grid-template-columns: repeat(4, 1fr); }
}

/* 13. Happy clients ======================================================== */

/* Shares the team tone on purpose. The testimonial band below is entered by a
   wave filled with --sand-deep, so whatever sits directly above it has to be
   that colour or the wave spills the wrong shade. */
.section--clients { background: var(--sand-deep); }

.clients {
  display: grid;
  gap: clamp(1.35rem, 2.5vw, 1.85rem);
}

@media (min-width: 34em) { .clients { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64em) { .clients { grid-template-columns: repeat(4, 1fr); } }

.client { text-align: center; }

.client__figure {
  margin: 0 0 1.1rem;
  overflow: hidden;
  border-radius: 140px 140px 18px 18px;
  box-shadow: var(--shadow-soft);
}

.client__figure img {
  width: 100%;
  /* matches the crop the files ship at, so nothing gets cut a second time */
  aspect-ratio: 3 / 4;
  object-fit: cover;
  transition: transform .5s ease;
}

.client:hover .client__figure img { transform: scale(1.03); }

.client__name {
  margin: 0;
  font-size: 1.3rem;
}

/* 14. Friendly Paws ======================================================== */

/* Sand rather than sand-deep, so it reads apart from the clients band above.
   The testimonial wave below is switched to .wave--from-sand to match. */
.section--paws { background: var(--sand); }

.paws {
  display: grid;
  gap: clamp(1.35rem, 2.5vw, 1.85rem);
  max-width: 26rem;
  margin-inline: auto;
}

/* four cards now, so two up then four across. Both stages divide evenly,
   which is what stops a card being orphaned on a row of its own. */
@media (min-width: 34em) {
  .paws {
    grid-template-columns: repeat(2, 1fr);
    max-width: none;
  }
}

@media (min-width: 64em) {
  .paws { grid-template-columns: repeat(4, 1fr); }
}

.paw { text-align: center; }

.paw__figure {
  margin: 0 0 1.1rem;
  overflow: hidden;
  border-radius: 140px 140px 18px 18px;
  box-shadow: var(--shadow-soft);
}

.paw__figure img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  transition: transform .5s ease;
}

.paw:hover .paw__figure img { transform: scale(1.03); }

/* a caption about the moment rather than a name label, so it is set a touch
   smaller and in the italic the brand uses for its warmer lines */
.paw__caption {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-style: italic;
  font-size: 1.12rem;
  line-height: 1.35;
  letter-spacing: -0.005em;
  color: var(--teal);
  text-wrap: balance;
}

/* 15. Testimonial ========================================================== */

.section--quote {
  background: var(--teal);
  color: var(--sand);
  /* room for the wave that spills in from the team section above */
  padding-top: calc(var(--section-y) + clamp(52px, 8vw, 118px));
}

.section--quote .section__title { color: var(--sand); }

.quotes {
  display: grid;
  gap: clamp(1.25rem, 2.5vw, 1.75rem);
}

@media (min-width: 54em) {
  .quotes { grid-template-columns: repeat(2, 1fr); }
}

/* sand cards on teal, the same pairing the contact form already uses */
.quote__card {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: clamp(1.75rem, 3.5vw, 2.5rem);
  background: var(--sand);
  border: 1px solid var(--sand-line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
  transition: transform .32s cubic-bezier(.2, .7, .3, 1),
              box-shadow .32s cubic-bezier(.2, .7, .3, 1);
}

.quote__card:hover {
  transform: translateY(-5px);
  box-shadow: 0 22px 54px rgba(11, 44, 53, .3);
}

/* drawn rather than typed: a text quote glyph carries only about a fifth of
   its font size in actual ink, so it will not hold up at display size */
.quote__mark {
  display: block;
  width: clamp(38px, 4.5vw, 50px);
  margin-bottom: 1.35rem;
  color: var(--coral);
}

.quote__mark svg { width: 100%; height: auto; fill: currentColor; }

.quote__text {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.05rem, .98rem + .35vw, 1.22rem);
  line-height: 1.55;
  color: var(--ink);
  text-wrap: pretty;
}

.quote__text p { margin: 0; }

/* auto margin pins both attributions to the bottom, so the pair still
   lines up when one quote runs much longer than the other */
.quote__cite {
  margin-top: auto;
  padding-top: 1.4rem;
  border-top: 1px solid var(--sand-line);
  font-family: var(--font-body);
  font-size: .95rem;
  font-weight: 800;
  color: var(--teal);
}

/* wave sitting at the top of a section rather than the bottom, so the
   previous section's colour spills down into this one */
.wave--top { top: -1px; bottom: auto; }
.wave--top svg { transform: scaleY(-1); }
.wave--top .wave__front { fill: var(--sand-deep); }
.wave--top .wave__back  { fill: var(--aqua); opacity: .22; }

/* 16. FAQ ================================================================== */

.section--faq {
  background: var(--sand);
  /* room for the wave that carries the page into the contact section */
  padding-bottom: calc(var(--section-y) + clamp(52px, 8vw, 118px));
}

.faq {
  max-width: 50rem;
  margin-inline: auto;
  background: #fff;
  border: 1px solid var(--sand-line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

.faq__item + .faq__item { border-top: 1px solid var(--sand-line); }

.faq__q { margin: 0; font: inherit; }

.faq__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  width: 100%;
  padding: clamp(1.15rem, 2.5vw, 1.5rem) clamp(1.25rem, 3vw, 1.9rem);
  background: none;
  border: 0;
  font-family: var(--font-display);
  font-size: clamp(1.075rem, 1rem + .4vw, 1.24rem);
  font-weight: 300;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--teal);
  text-align: left;
  cursor: pointer;
  transition: color .2s ease;
}

.faq__text { text-wrap: balance; }

.faq__trigger:hover { color: var(--coral); }
.faq__item.is-open .faq__trigger { color: var(--coral); }

/* plus that spins into a minus */
.faq__icon {
  position: relative;
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  transition: transform .35s cubic-bezier(.2, .7, .3, 1);
}

.faq__icon::before,
.faq__icon::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  background: var(--coral);
  border-radius: 2px;
  transform: translate(-50%, -50%);
  transition: opacity .25s ease;
}

.faq__icon::before { width: 100%; height: 2px; }
.faq__icon::after { width: 2px; height: 100%; }

.faq__item.is-open .faq__icon { transform: rotate(90deg); }
/* after the quarter turn the upright bar is horizontal, so drop the other one */
.faq__item.is-open .faq__icon::before { opacity: 0; }

/* the panel animates on grid rows, which gives a real height transition
   without hard coding a max-height */
.faq__panel {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition: grid-template-rows .38s cubic-bezier(.2, .7, .3, 1), visibility 0s linear .38s;
}

.faq__item.is-open .faq__panel {
  grid-template-rows: 1fr;
  visibility: visible;
  transition: grid-template-rows .38s cubic-bezier(.2, .7, .3, 1), visibility 0s;
}

.faq__inner {
  overflow: hidden;
  opacity: 0;
  transition: opacity .25s ease;
}

.faq__item.is-open .faq__inner { opacity: 1; transition: opacity .35s ease .1s; }

.faq__inner p {
  margin: 0;
  padding: 0 clamp(1.25rem, 3vw, 1.9rem) clamp(1.35rem, 3vw, 1.75rem);
  max-width: 44rem;
  color: var(--ink-soft);
  font-size: 1rem;
}

/* 17. Contact ============================================================== */

.section--contact {
  background: var(--teal);
  color: var(--sand);
}

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

.section--contact .section__title { color: var(--sand); }
.section--contact .section__title em { color: var(--coral); }

.contact__lead {
  margin-top: 1.35rem;
  max-width: 34rem;
  color: var(--sand-soft);
  font-size: 1.075rem;
}

.section--contact :focus-visible {
  outline-color: var(--coral);
}

.details {
  margin: 2.5rem 0 0;
  padding-top: 2rem;
  border-top: 1px solid rgba(247, 243, 236, .22);
  display: grid;
  gap: 1.15rem;
}

.details__row { display: grid; gap: .1rem; }

.details__label {
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--sand-soft);
}

.details__value {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 300;
  color: var(--sand);
  overflow-wrap: anywhere;
}

.details__value a {
  /* inline-block so the lift applies; the long email still breaks
     internally because overflow-wrap is inherited from the parent */
  display: inline-block;
  text-decoration: none;
  border-bottom: 1px solid rgba(247, 243, 236, .35);
  padding-bottom: 2px;
  transition: color .2s ease, border-color .2s ease,
              transform .28s cubic-bezier(.2, .7, .3, 1);
}
.details__value a:hover {
  color: var(--coral);
  border-bottom-color: var(--coral);
  transform: translateY(-2px);
}

/* form card */
.contact__card {
  padding: clamp(1.6rem, 4vw, 2.5rem);
  background: var(--sand);
  border-radius: var(--radius-card);
  box-shadow: 0 24px 60px rgba(11, 44, 53, .28);
}

.form__field { margin-bottom: 1.15rem; }

.form__label {
  display: block;
  margin-bottom: .4rem;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--teal);
}

.form__input {
  width: 100%;
  padding: .8rem .95rem;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--sand-line);
  border-radius: 10px;
  transition: border-color .2s ease, box-shadow .2s ease;
}

.form__input:hover { border-color: rgba(63, 169, 190, .6); }

.form__input:focus {
  outline: none;
  border-color: var(--aqua);
  box-shadow: 0 0 0 3px rgba(63, 169, 190, .28);
}

.form__input--area { resize: vertical; min-height: 8rem; line-height: 1.6; }

/* honeypot, hidden from people but present for Netlify */
.form__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form__note {
  margin: 1rem 0 0;
  font-size: .88rem;
  color: var(--ink-soft);
  text-align: center;
}

@media (min-width: 56em) {
  .contact__inner { grid-template-columns: 1fr 1fr; gap: clamp(3rem, 6vw, 5rem); }
}

/* 18. Footer =============================================================== */

.footer {
  background: var(--ink);
  color: var(--sand);
  padding-block: clamp(3.25rem, 6vw, 4.5rem);
  text-align: center;
}

.footer__cols {
  display: grid;
  gap: clamp(2.25rem, 5vw, 3.5rem);
}

@media (min-width: 52em) {
  .footer__cols {
    grid-template-columns: 1.45fr 1fr 1.25fr;
    gap: clamp(2rem, 5vw, 4rem);
    align-items: start;
    text-align: left;
  }
}

/* white artwork, so it needs no disc behind it on the ink background */
.footer__mark {
  width: auto;
  height: 84px;
  margin: 0 auto 1.25rem;
}

@media (min-width: 52em) {
  .footer__mark { margin-left: 0; }
}

.footer__tagline {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.35rem, 1.1rem + 1vw, 1.75rem);
  line-height: 1.25;
  color: var(--sand);
  text-wrap: balance;
}
.footer__tagline em { font-style: italic; color: var(--coral); }

.footer__heading {
  margin: 0 0 1.15rem;
  font-family: var(--font-body);
  font-size: .78rem;
  font-weight: 800;
  letter-spacing: .16em;
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--sand);
}

.footer__links,
.footer__contact {
  display: grid;
  gap: .65rem;
  font-size: .95rem;
  color: var(--sand-soft);
}

.footer__contact { overflow-wrap: anywhere; }

.footer__links a,
.footer__contact a {
  color: var(--sand-soft);
  text-decoration: none;
  transition: color .2s ease;
}

.footer__links a:hover,
.footer__contact a:hover { color: var(--coral); }

.footer__bottom {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: 1.75rem;
  border-top: 1px solid rgba(247, 243, 236, .16);
  text-align: center;
}

.footer__meta {
  font-size: .9rem;
  color: var(--sand-soft);
  margin-bottom: .35rem;
}

.footer__abn {
  font-size: .9rem;
  color: var(--sand-soft);
  letter-spacing: .02em;
  margin-bottom: .9rem;
}

.footer__credit {
  margin: 0;
  font-size: .85rem;
  color: var(--sand-soft);
}

.footer__credit a {
  color: var(--sand);
  text-decoration: none;
  border-bottom: 1px solid var(--coral);
  padding-bottom: 2px;
}
.footer__credit a:hover { color: var(--coral); }

.footer :focus-visible { outline-color: var(--coral); }

/* 19. Thank you page ======================================================= */

.section--thanks {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 68vh;
  background: var(--sand-deep);
  text-align: center;
  /* room for the wave that carries the block into the footer */
  padding-bottom: calc(var(--section-y) + clamp(52px, 8vw, 118px));
}

.thanks__inner { max-width: 40rem; margin-inline: auto; }

.thanks__inner .eyebrow { justify-content: center; }

/* the heart mark on its own, not the full lockup, so it does not read as a
   second copy of the logo sitting just below the one in the nav */
.thanks__mark {
  width: clamp(62px, 11vw, 78px);
  height: auto;
  margin: 0 auto 1.6rem;
}

.thanks__title {
  font-size: clamp(2.1rem, 1.4rem + 3vw, 3.35rem);
  margin-bottom: 1.35rem;
}

.thanks__lead {
  max-width: 34rem;
  margin-inline: auto;
  margin-bottom: 2.25rem;
  color: var(--ink-soft);
  font-size: clamp(1.05rem, 1rem + .3vw, 1.15rem);
}

.thanks__lead a {
  color: var(--teal);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 2px solid var(--coral);
  padding-bottom: 1px;
  transition: color .2s ease;
}

.thanks__lead a:hover { color: var(--coral); }

/* the wave here empties into the ink footer rather than the sand page */
.wave--ink svg { transform: scaleX(-1); }
.wave--ink .wave__front { fill: var(--ink); }
.wave--ink .wave__back  { fill: var(--aqua); opacity: .28; }

/* 20. Reveal & reduced motion ============================================== */

.js .reveal {
  transition: opacity .75s ease, transform .75s cubic-bezier(.2, .7, .3, 1);
}

/* The offset is scoped to the pre-reveal state on purpose. A `transform: none`
   left sitting on .is-visible outranks .card:hover and .quote__card:hover on
   specificity, which silently kills their lift. Once revealed, the element
   carries no transform declaration at all, so hover is free to apply. */
.js .reveal:not(.is-visible) {
  opacity: 0;
  transform: translateY(26px);
}

/* stagger the grids a touch */
.js .cards .reveal:nth-child(2),
.js .quotes .reveal:nth-child(2),
.js .clients .reveal:nth-child(2),
.js .paws .reveal:nth-child(2),
.js .team .reveal:nth-child(2) { transition-delay: .09s; }
.js .cards .reveal:nth-child(3),
.js .clients .reveal:nth-child(3),
.js .paws .reveal:nth-child(3),
.js .team .reveal:nth-child(3) { transition-delay: .18s; }
.js .clients .reveal:nth-child(4),
.js .paws .reveal:nth-child(4) { transition-delay: .27s; }
.js .cards .reveal:nth-child(4) { transition-delay: .09s; }
.js .cards .reveal:nth-child(5) { transition-delay: .18s; }
.js .cards .reveal:nth-child(6) { transition-delay: .27s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* matches the :not(.is-visible) specificity above, so content is never
     left stranded at opacity 0 if the observer never runs */
  .js .reveal,
  .js .reveal:not(.is-visible) {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }

  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }

  .btn:hover,
  .card:hover,
  .quote__card:hover,
  .thing:hover,
  .details__value a:hover,
  .client:hover .client__figure img,
  .moment:hover .moment__frame img,
  .paw:hover .paw__figure img,
  .team__member:hover .team__figure img { transform: none; }

  /* Hero arrives finished, and the water holds still. Stated outright
     rather than leaning on the blanket duration override above, so the
     hero can never be left mid keyframe at opacity 0. */
  .js .hero__copy > *,
  .js .hero__figure {
    opacity: 1;
    transform: none;
    animation: none;
  }

  .js .hero__figure img,
  .wave--down svg {
    transform: none;
    animation: none;
  }

  /* the panel carries a visibility delay, which the blanket duration
     override above does not reach, so clear it explicitly */
  .faq__panel,
  .faq__item.is-open .faq__panel,
  .faq__inner,
  .faq__item.is-open .faq__inner,
  .faq__icon { transition: none; }
}
