/*
  Hooman & Hound Photo Co.

  Mobile first. Flat color only: no gradients, no shadows.
  Photos keep square corners; buttons and panels take the soft radius of the
  camera body in the logo.
*/

/* Fonts (self-hosted, SIL Open Font License; see ../fonts/*-OFL.txt) */

@font-face {
  font-family: "Fraunces";
  src: url("../fonts/fraunces-latin-opsz-normal.069cb90e11a3.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "DM Sans";
  src: url("../fonts/dm-sans-latin-wght-normal.7c87a648293f.woff2") format("woff2");
  font-weight: 100 1000;
  font-style: normal;
  font-display: swap;
}

/* Tokens */

:root {
  color-scheme: light;

  /* Palette, sampled from the logo */
  --cream: #F4EFE7;   /* page background */
  --ink: #29211D;     /* body text and headings */
  --sage: #616D55;    /* primary buttons and links (4.79:1 on cream) */
  --moss: #48523F;    /* dark sections and hover states */
  --tongue: #D78E8C;  /* decoration, or behind ink text. Never text on cream */
  --rose: #AC6361;    /* accent detail: large text and non-text only on cream */

  /* Two quiet tints of the palette for form fields and hairlines */
  --paper: #FBF8F3;
  --rule: #D3CCC2;

  /* Lighter tints, for the small drawing on the home page only */
  --tint-sage: #C3C9BA;
  --tint-fern: #A3AC97;
  --tint-blush: #EBCBC9;
  --tint-sand: #DDD5C8;

  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-body: "DM Sans", "Helvetica Neue", Arial, sans-serif;

  --radius-panel: clamp(1.5rem, 3.5vw, 2.5rem);
  --radius-button: 1.125rem;
  --radius-field: 0.75rem;

  --gutter: clamp(1rem, 5vw, 3.5rem);
  --section: clamp(3.5rem, 9vw, 7rem);
  --measure: 36rem;
  --page: 76rem;
}

/* Base */

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

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

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

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

img {
  height: auto;
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.012em;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.25rem, 1.4rem + 4.4vw, 4.5rem);
  line-height: 1.03;
}

h2 {
  font-size: clamp(1.75rem, 1.35rem + 1.9vw, 2.75rem);
  line-height: 1.1;
}

h3 {
  font-size: 1.375rem;
  line-height: 1.2;
}

p,
ul,
figure,
fieldset {
  margin: 0;
}

h2[id] {
  scroll-margin-top: 1.5rem;
}

p {
  text-wrap: pretty;
}

a {
  color: var(--sage);
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.2em;
}

a:hover {
  color: var(--moss);
}

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

main:focus {
  outline: none;
}

/* Layout helpers */

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

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

.section--flush-top {
  padding-top: 0;
}

.stack > * + * {
  margin-top: 1rem;
}

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

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

.eyebrow {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}

.lede {
  max-width: var(--measure);
  font-size: clamp(1.125rem, 1.05rem + 0.4vw, 1.3125rem);
  line-height: 1.5;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 0.875rem;
}

/* A row of text links only. Each is already 44px tall, so rows sit flush. */
.actions--links {
  gap: 0 1.5rem;
}

.text-link {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-weight: 600;
}

/* Skip link */

.skip-link {
  position: absolute;
  top: 0;
  left: var(--gutter);
  z-index: 10;
  padding: 0.75rem 1rem;
  border-radius: 0 0 var(--radius-field) var(--radius-field);
  background: var(--ink);
  color: var(--cream);
  font-weight: 600;
  transform: translateY(-120%);
}

.skip-link:hover {
  color: var(--cream);
}

.skip-link:focus {
  transform: none;
}

/* Buttons */

.button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3rem;
  padding: 0.625rem 1.375rem;
  border: 2px solid transparent;
  border-radius: var(--radius-button);
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.button--compact {
  min-height: 2.75rem;
  padding-inline: 0.75rem;
  font-size: 0.9375rem;
}

.button--primary {
  background: var(--sage);
  color: var(--cream);
}

.button--primary:hover {
  background: var(--moss);
  color: var(--cream);
}

.button--secondary {
  border-color: var(--ink);
  background: transparent;
  color: var(--ink);
}

.button--secondary:hover {
  background: var(--ink);
  color: var(--cream);
}

/* A button whose action is under way. Set by site.js while a request sends. */
.button[aria-disabled="true"],
.button[aria-disabled="true"]:hover {
  background: var(--moss);
  cursor: progress;
}

/* The tongue: a small pink tab that drops below the primary button. */
.button--primary::after {
  content: "";
  position: absolute;
  top: calc(100% + 2px);
  left: 1.5rem;
  width: 1.25rem;
  height: 1rem;
  border-radius: 0 0 1rem 1rem;
  background: var(--tongue);
  transform: scaleY(0);
  transform-origin: top center;
}

/* The ears and the tail. The tongue has ::after, so these share ::before: one
   box over the button, in the button's own color, cut down to three shapes.
   Two numbers move them. --perk runs from 0 (ears flat, tail tucked in) to 1
   (both out). --wag swings the tail about the point where it joins the
   button; it is an angle in radians, and positive is away from the button.
   They are registered so a browser can animate them. Where it cannot, the
   ears and tail still appear, without the easing. */
@property --perk {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

@property --wag {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

.button--primary::before {
  /* How high an ear's tip stands: 0 at the top of the box, 1.125rem when flat. */
  --ear: calc(1.125rem - var(--perk) * 1.125rem);
  /* Where the tail joins the button: just inside the right-hand edge. */
  --tx: calc(100% - 1.0625rem);
  --ty: 2.25rem;
  /* The tail is plotted in sixteenths of a rem from that point. */
  --u: calc(var(--perk) * 0.0625rem);
  --w: var(--wag);
  content: "";
  position: absolute;
  /* 0.75rem above the button for the ears, 1rem to its right for the tail.
     No wider than that: 1rem is the narrowest page gutter, and a wider box
     would let the header button scroll a phone sideways. */
  top: calc(-2px - 0.75rem);
  right: calc(-2px - 1rem);
  left: -2px;
  height: 3rem;
  background-color: inherit;
  /* One outline. Each ear's base and the tail's root sit inside the button,
     so they run into its rounded corners with no gap. */
  clip-path: polygon(
    /* Left ear */
    0.5rem 1.125rem,
    0.9375rem var(--ear),
    1.96875rem 1.125rem,
    /* Right ear */
    calc(100% - 2.96875rem) 1.125rem,
    calc(100% - 1.9375rem) var(--ear),
    calc(100% - 1.5rem) 1.125rem,
    /* Tail: out along the underside, up the outer curve to the tip, and back
       down the inside. Each point is (x, y) from the joint, turned by --wag:
       x + wag * -y across, y + wag * x down. */
    calc(var(--tx) + var(--u) * (-3 + var(--w) * -5)) calc(var(--ty) + var(--u) * (5 + var(--w) * -3)),
    calc(var(--tx) + var(--u) * (2 + var(--w) * -4.5)) calc(var(--ty) + var(--u) * (4.5 + var(--w) * 2)),
    calc(var(--tx) + var(--u) * (6 + var(--w) * -2.7)) calc(var(--ty) + var(--u) * (2.7 + var(--w) * 6)),
    calc(var(--tx) + var(--u) * (8.8 + var(--w) * 0.5)) calc(var(--ty) + var(--u) * (-0.5 + var(--w) * 8.8)),
    calc(var(--tx) + var(--u) * (10.7 + var(--w) * 4.5)) calc(var(--ty) + var(--u) * (-4.5 + var(--w) * 10.7)),
    calc(var(--tx) + var(--u) * (11.7 + var(--w) * 8.7)) calc(var(--ty) + var(--u) * (-8.7 + var(--w) * 11.7)),
    calc(var(--tx) + var(--u) * (12 + var(--w) * 12.8)) calc(var(--ty) + var(--u) * (-12.8 + var(--w) * 12)),
    calc(var(--tx) + var(--u) * (11.7 + var(--w) * 16.8)) calc(var(--ty) + var(--u) * (-16.8 + var(--w) * 11.7)),
    calc(var(--tx) + var(--u) * (10.7 + var(--w) * 20.5)) calc(var(--ty) + var(--u) * (-20.5 + var(--w) * 10.7)),
    calc(var(--tx) + var(--u) * (9.6 + var(--w) * 23.8)) calc(var(--ty) + var(--u) * (-23.8 + var(--w) * 9.6)),
    calc(var(--tx) + var(--u) * (7.7 + var(--w) * 26.6)) calc(var(--ty) + var(--u) * (-26.6 + var(--w) * 7.7)),
    calc(var(--tx) + var(--u) * (5.4 + var(--w) * 28.9)) calc(var(--ty) + var(--u) * (-28.9 + var(--w) * 5.4)),
    calc(var(--tx) + var(--u) * (3.6 + var(--w) * 28.2)) calc(var(--ty) + var(--u) * (-28.2 + var(--w) * 3.6)),
    calc(var(--tx) + var(--u) * (3.6 + var(--w) * 25)) calc(var(--ty) + var(--u) * (-25 + var(--w) * 3.6)),
    calc(var(--tx) + var(--u) * (4.6 + var(--w) * 19.3)) calc(var(--ty) + var(--u) * (-19.3 + var(--w) * 4.6)),
    calc(var(--tx) + var(--u) * (4.4 + var(--w) * 13)) calc(var(--ty) + var(--u) * (-13 + var(--w) * 4.4)),
    calc(var(--tx) + var(--u) * (2.9 + var(--w) * 7.6)) calc(var(--ty) + var(--u) * (-7.6 + var(--w) * 2.9)),
    calc(var(--tx) + var(--u) * (1 + var(--w) * 4.7)) calc(var(--ty) + var(--u) * (-4.7 + var(--w) * 1)),
    calc(var(--tx) + var(--u) * (-3 + var(--w) * 5)) calc(var(--ty) + var(--u) * (-5 + var(--w) * -3)),
    /* Back to the right ear, so the outline closes along the ears' base. */
    calc(100% - 1.5rem) 1.125rem
  );
}

.button--primary:hover,
.button--primary:focus-visible {
  --perk: 1;
}

.button--primary:hover::after,
.button--primary:focus-visible::after {
  transform: scaleY(1);
}

/* Four wags, then the tail rests: nothing keeps moving while a button is
   focused. Each wag starts and ends with the tail straight. */
@keyframes wag {
  25% { --wag: 0.1; }
  75% { --wag: -0.22; }
}

@media (prefers-reduced-motion: no-preference) {
  .button--primary {
    transition: --perk 0.16s ease-out;
  }

  .button--primary:hover,
  .button--primary:focus-visible {
    animation: wag 0.5s ease-in-out 0.1s 4;
  }

  .button--primary::after {
    transition: transform 0.16s ease-out;
  }

  .skip-link {
    transition: transform 0.12s ease-out;
  }
}

/* The frame. The outlined button hangs like a portrait on the wall: a wire
   rises from its top edge to a nail, and it sways on the nail before it
   settles. The same drawing as the frame on the home page.
   The wire and the nail are one ink box, cut to shape. --perk, registered
   above with the ears, runs from 0 (wire flat along the top edge, no nail) to
   1 (wire up, nail full size). */
.button--secondary {
  /* Where the nail is: about 0.75rem above the middle of the top edge. The
     sway turns about this point, so the nail stays put. */
  transform-origin: 50% calc(0.5px - 0.75rem);
}

.button--secondary::before {
  /* A sixteenth of a rem, scaled by how far up the wire is. */
  --n: calc(var(--perk) * 0.0625rem);
  /* The line the wire lies along when flat: just inside the top border. With
     --perk at 0 every point below is on this line, so nothing is drawn and the
     button at rest is its plain outline. */
  --flat: calc(0.9375rem + 0.5px);
  content: "";
  position: absolute;
  right: -2px;
  /* The box stands on the inside of the button's top border. Its lowest 2px
     lie over that border, which is where the wire's ends join it. */
  bottom: 100%;
  left: -2px;
  height: calc(0.9375rem + 2px);
  /* Ink, like the border: the button is clear until it is pointed at. */
  background: var(--ink);
  clip-path: polygon(
    /* Up the left-hand wire, which leaves the top edge 1.75rem in */
    1.75rem var(--flat),
    /* Over the top of the nail */
    calc(50% - 2.5 * var(--n)) calc(var(--flat) - 12 * var(--n)),
    calc(50% - 2.02 * var(--n)) calc(var(--flat) - 13.47 * var(--n)),
    calc(50% - 0.77 * var(--n)) calc(var(--flat) - 14.38 * var(--n)),
    calc(50% + 0.77 * var(--n)) calc(var(--flat) - 14.38 * var(--n)),
    calc(50% + 2.02 * var(--n)) calc(var(--flat) - 13.47 * var(--n)),
    calc(50% + 2.5 * var(--n)) calc(var(--flat) - 12 * var(--n)),
    /* Down the right-hand wire and into the border */
    calc(100% - 1.75rem) var(--flat),
    calc(100% - 1.75rem) calc(var(--flat) + var(--perk) * 1.5px),
    /* Back along the underside of the wire, round the bottom of the nail */
    calc(50% + 2.02 * var(--n)) calc(var(--flat) - 10.53 * var(--n)),
    calc(50% + 0.77 * var(--n)) calc(var(--flat) - 9.62 * var(--n)),
    calc(50% - 0.77 * var(--n)) calc(var(--flat) - 9.62 * var(--n)),
    calc(50% - 2.02 * var(--n)) calc(var(--flat) - 10.53 * var(--n)),
    1.75rem calc(var(--flat) + var(--perk) * 1.5px)
  );
}

/* The sway moves the button's edges a little. A pointer resting on an edge
   would lose the button as it swung away, which stops the sway, which puts
   the button back under the pointer, which starts it again, and so on. This
   is an unseen sheet the size of the button that turns the opposite way, so
   it stays where the button was and keeps hold of the pointer. */
.button--secondary::after {
  content: "";
  position: absolute;
  inset: -2px;
  /* Rounded like the button, so its corners catch no extra clicks. */
  border-radius: inherit;
  transform-origin: 50% calc(0.5px - 0.75rem);
}

.button--secondary:hover,
.button--secondary:focus-visible {
  --perk: 1;
}

/* A picture finding its level: each swing smaller than the last, then still. */
@keyframes sway {
  18% { rotate: 2.4deg; }
  42% { rotate: -1.6deg; }
  64% { rotate: 0.9deg; }
  84% { rotate: -0.4deg; }
}

/* The same swings, the other way, for the sheet above. */
@keyframes sway-back {
  18% { rotate: -2.4deg; }
  42% { rotate: 1.6deg; }
  64% { rotate: -0.9deg; }
  84% { rotate: 0.4deg; }
}

@media (prefers-reduced-motion: no-preference) {
  .button--secondary {
    transition: --perk 0.18s ease-out;
  }

  .button--secondary:hover,
  .button--secondary:focus-visible {
    animation: sway 1.5s ease-in-out 0.08s;
  }

  .button--secondary:hover::after,
  .button--secondary:focus-visible::after {
    animation: sway-back 1.5s ease-in-out 0.08s;
  }
}

/* Header and navigation */

.site-header {
  padding-block: 0.875rem;
}

.site-nav {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "brand cta"
    "links links";
  align-items: center;
  gap: 0.25rem 0.75rem;
}

.brand {
  grid-area: brand;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  color: var(--ink);
  text-decoration: none;
}

.brand:hover {
  color: var(--ink);
}

/* The camera from the logo. It is a little taller than wide, ears to tongue. */
.brand__mark {
  flex: none;
  width: auto;
  height: 2.75rem;
}

.brand__text {
  display: flex;
  flex-direction: column;
  line-height: 1;
}

.brand__name {
  font-family: var(--font-display);
  /* Scales down a touch on narrow phones so it stays on one line. */
  font-size: clamp(0.875rem, 4vw, 1rem);
  /* The weight and cut of the typeface that the logo's lettering is drawn
     in, which also brings its looped ampersand. */
  font-weight: 600;
  font-variation-settings: "opsz" 48;
}

/* Sage, as in the logo. */
.brand__sub {
  margin-top: 0.3rem;
  color: var(--sage);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}

.site-nav__links {
  grid-area: links;
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.25rem;
  margin-inline: -0.5rem;
  padding: 0;
  list-style: none;
}

.site-nav__links a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding-inline: 0.5rem;
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
}

.site-nav__links a:hover {
  text-decoration: underline;
}

.site-nav__links a[aria-current="page"] {
  text-decoration: underline;
  text-decoration-color: var(--rose);
  text-decoration-thickness: 3px;
  text-underline-offset: 0.45em;
}

.site-nav__cta {
  grid-area: cta;
}

@media (min-width: 56rem) {
  .site-header {
    padding-block: 1.5rem;
  }

  /* The gaps tighten on the narrowest of these screens, so the four links
     stay on one row beside the logo and the button. */
  .site-nav {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "brand links cta";
    column-gap: clamp(1rem, 4vw - 1.25rem, 2rem);
  }

  .brand {
    gap: 0.75rem;
  }

  .brand__mark {
    height: 3.5rem;
  }

  .brand__name {
    font-size: 1.3125rem;
  }

  .button--compact {
    padding-inline: 1.125rem;
  }

  .site-nav__links {
    justify-content: flex-end;
    gap: 0 0.75rem;
    margin-inline: 0;
  }

  .site-nav__links a {
    font-size: 1rem;
  }
}

/* Home: intro and the two doors */

.hero {
  padding-top: clamp(2rem, 5vw, 3.5rem);
}

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

.hero__headline > * + * {
  margin-top: 1rem;
}

.hero__pitch > * + * {
  margin-top: 1.5rem;
}

@media (min-width: 75rem) {
  /* The headline sits over the first door and the intro over the second:
     the same two columns as the doors below. */
  .hero__intro {
    grid-template-columns: 7fr 5fr;
    align-items: end;
  }

  /* Sized so the headline sets in two lines within its column. */
  .hero__title {
    font-size: clamp(3.25rem, (100vw - 8.5rem) * 0.0504, 3.75rem);
  }
}

.doors {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 1rem;
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}

.door {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: clamp(13rem, 22vw, 17rem);
  padding: clamp(1.5rem, 4vw, 2.75rem);
  border-radius: var(--radius-panel);
}

.door > * + * {
  margin-top: 0.75rem;
}

.door--hoomans {
  background: var(--sage);
  color: var(--cream);
}

.door--hounds {
  background: var(--tongue);
  color: var(--ink);
}

.door__heading {
  font-size: clamp(1.625rem, 1.3rem + 1.5vw, 2.375rem);
}

.door .text-link {
  align-self: flex-start;
  margin-top: 0.5rem;
  color: inherit;
}

/* The link covers its whole door, so the photo and heading are tappable too. */
.door .text-link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-panel);
}

.door--hoomans :focus-visible {
  outline-color: var(--cream);
}

.door__photo {
  margin-bottom: auto;
  padding-bottom: 1.25rem;
}

.door__photo img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: 35% 30%;
}

@media (min-width: 48rem) {
  .doors {
    grid-template-columns: 7fr 5fr;
    align-items: start;
    gap: 1.5rem;
  }

  /* The second door hangs lower and steps down into the Sunroom band. */
  .door--hounds {
    margin-top: 4.5rem;
  }
}

/* Bands: full-width flat color sections */

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

/* Each service has its own color, used for its band, the block behind its
   lead photo and its closing panel: sage for hoomans, pink for hounds, and
   for the Kennel the ink of the logo's lens, with pink for small accents.
   Moss is the studio's own color, for statements about the two owners. */

.band--moss {
  background: var(--moss);
  color: var(--cream);
}

.band--ink {
  background: var(--ink);
  color: var(--cream);
}

/* Links in a dark band are cream. A button there keeps its own colors. */
.band--moss a:not(.button),
.band--ink a:not(.button) {
  color: var(--cream);
}

.band--moss :focus-visible,
.band--ink :focus-visible {
  outline-color: var(--cream);
}

/* The small label above a heading, and the line that answers the problem,
   pick up the pink of the logo's tongue. */
.band--ink .eyebrow,
.band--ink .says__turn {
  color: var(--tongue);
}

.band--sage {
  background: var(--sage);
  color: var(--cream);
}

.band--tongue {
  background: var(--tongue);
  color: var(--ink);
}

.band__actions {
  align-items: center;
  margin-top: 1.5rem;
}

.band--under-doors {
  margin-top: -3.5rem;
  padding-top: calc(var(--section) + 3.5rem);
}

.band__inner {
  display: grid;
  gap: 2rem;
}

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

.band__text > * + * {
  margin-top: 1rem;
}

.band__photo img {
  width: 100%;
  aspect-ratio: 5 / 4;
  object-fit: cover;
  object-position: 60% 40%;
}

@media (min-width: 48rem) {
  .band__inner--split {
    grid-template-columns: 5fr 7fr;
    align-items: center;
    gap: 3.5rem;
  }
}

/* Page headers on the inner pages */

.page-header {
  padding-block: clamp(2.5rem, 7vw, 5rem) clamp(2.5rem, 6vw, 4rem);
}

.page-header > .wrap > * + * {
  margin-top: 1.5rem;
}

.page-header h1 {
  max-width: 16ch;
}

/* Page hero on the service pages: what the visitor gets, the button to get
   it, and a photo of it. The page's name is the first line of the heading. */

.page-hero {
  padding-block: clamp(2rem, 6vw, 4rem) clamp(3rem, 7vw, 5.5rem);
}

.page-hero__inner {
  display: grid;
  gap: 2.5rem;
}

.page-hero__text > * + * {
  margin-top: 1.5rem;
}

.page-hero h1 {
  max-width: 15ch;
}

.page-hero__name {
  display: block;
  margin-bottom: 1rem;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}

/* A photo standing on a block of the page's color. The photo keeps its square
   corners; the block behind it takes the soft radius. */
.plate {
  position: relative;
  padding: 0 0 1rem 1rem;
}

.plate::before {
  content: "";
  position: absolute;
  inset: 2.5rem 2.5rem 0 0;
  border-radius: var(--radius-panel);
  background: var(--sage);
}

.plate--tongue::before {
  background: var(--tongue);
}

.plate--ink::before {
  background: var(--ink);
}

/* The photo opens at full size, like the gallery photos. */
.plate__link {
  position: relative;
  display: block;
}

/* It keeps its own shape. Only a very tall one is trimmed, to stay on screen. */
.plate img {
  width: 100%;
  max-height: 34rem;
  object-fit: cover;
  object-position: 50% 30%;
}

@media (min-width: 56rem) {
  .page-hero__inner--split {
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    align-items: center;
    gap: clamp(2.5rem, 6vw, 5rem);
  }

  /* With no photo, the headline and the intro share the row instead. */
  .page-hero__inner--wide {
    grid-template-columns: 7fr 5fr;
    align-items: end;
    gap: 3.5rem;
  }

  .plate {
    padding: 0 0 1.75rem 1.75rem;
  }

  .plate::before {
    inset: 4rem 4rem 0 0;
  }
}

/* The problem, said once per page in large type, with the answer beside it. */

.statement {
  max-width: 17ch;
  font-size: clamp(2rem, 1.3rem + 3.3vw, 3.75rem);
  line-height: 1.04;
}

/* A statement of two sentences starts each on its own line. */
.statement span {
  display: block;
}

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

.says__body {
  max-width: 30rem;
  font-size: 1.125rem;
}

.says__body > * + * {
  margin-top: 1rem;
}

.says__turn,
.stakes__turn {
  font-weight: 600;
}

@media (min-width: 56rem) {
  .says {
    grid-template-columns: 7fr 5fr;
    align-items: end;
    gap: 3.5rem;
  }
}

/* A side note, marked with a tongue-pink rule. Not a pill: it must not look
   like the button that follows it. */
.note {
  display: inline-block;
  max-width: var(--measure);
  padding: 0.25rem 0 0.25rem 1rem;
  border-left: 0.3125rem solid var(--tongue);
  color: var(--ink);
  font-weight: 500;
}

/* Section headings on the inner pages */

.section__label {
  /* Leaves air above the label when a "See sessions" link jumps to it. */
  scroll-margin-top: 1.5rem;
  margin-bottom: 1.5rem;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}

/* Gallery */

.gallery {
  columns: 2;
  column-gap: 0.75rem;
}

.gallery__item {
  margin-bottom: 0.75rem;
  break-inside: avoid;
}

/* Each photo opens at full size. */
.gallery__link {
  display: block;
}

.gallery__item img {
  width: 100%;
}

@media (min-width: 48rem) {
  .gallery {
    columns: 3;
    column-gap: 1.25rem;
  }

  .gallery__item {
    margin-bottom: 1.25rem;
  }
}

/* Empty states: a flat color panel stands in until photos arrive */

.panel {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 1rem;
  min-height: clamp(11rem, 24vw, 17rem);
  max-width: 48rem;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border-radius: var(--radius-panel);
  font-size: 1.125rem;
  font-weight: 500;
}

.panel--sage {
  background: var(--sage);
  color: var(--cream);
}

.panel--tongue {
  background: var(--tongue);
  color: var(--ink);
}

.panel--ink {
  background: var(--ink);
  color: var(--cream);
}

.panel .text-link {
  color: inherit;
}

.panel--sage :focus-visible,
.panel--ink :focus-visible {
  outline-color: var(--cream);
}

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

.empty > * + * {
  margin-top: 1.25rem;
}

/* Session list */

/* The list, or the message that stands in for it, under its heading. */
h2 + .sessions,
h2 + .empty {
  margin-top: 2rem;
}

.sessions {
  padding: 0;
  border-top: 1px solid var(--rule);
  list-style: none;
}

.sessions__item {
  display: grid;
  gap: 1rem 2.5rem;
  padding-block: 1.5rem;
  border-bottom: 1px solid var(--rule);
}

.sessions__body > * + * {
  margin-top: 0.5rem;
}

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

/* The length and price, when given, then the button to ask about this one. */
.sessions__side {
  display: grid;
  justify-items: start;
  gap: 0.875rem;
}

.sessions__meta {
  font-weight: 600;
}

.sessions__meta span {
  display: block;
}

/* With room for two columns, that side moves to the right of the row. The
   button lines up with the middle of the text when it stands alone. */
@media (min-width: 48rem) {
  .sessions__item {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
  }

  .sessions__side {
    justify-items: end;
  }

  .sessions__meta {
    text-align: right;
  }
}

/* The Sunroom's current season */

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

.season__text > * + * {
  margin-top: 1rem;
}

.season__photos {
  margin-top: 2.5rem;
}

/* Paw print divider */

.paw-divider {
  display: flex;
  align-items: center;
  gap: 1rem;
  color: var(--rose);
}

.paw-divider svg {
  flex: none;
  width: 2rem;
  height: 2rem;
  fill: currentColor;
  transform: rotate(-14deg);
}

.paw-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--rule);
}

/* About: the two owners, framed like lenses */

.owners {
  display: grid;
  gap: 3.5rem;
}

.owner > * + * {
  margin-top: 1.25rem;
}

.owner p {
  max-width: 30rem;
}

.lens {
  width: min(15rem, 68vw);
  aspect-ratio: 1;
  padding: 0.5rem;
  border: 0.625rem solid var(--sage);
  border-radius: 50%;
}

.lens--tongue {
  border-color: var(--tongue);
}

.lens img,
.lens__blank {
  width: 100%;
  height: 100%;
  border-radius: 50%;
}

.lens img {
  object-fit: cover;
}

.lens__blank {
  background: var(--sage);
}

.lens--tongue .lens__blank {
  background: var(--tongue);
}

@media (min-width: 48rem) {
  .owners {
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
  }

  .owner:nth-child(2) {
    margin-top: 6rem;
  }

  .lens {
    width: 18rem;
  }
}

/* Forms */

.form {
  display: grid;
  gap: 1.75rem;
  max-width: var(--measure);
}

.field {
  display: grid;
  gap: 0.375rem;
  min-width: 0;
  padding: 0;
  border: 0;
}

.field__label {
  padding: 0;
  font-weight: 600;
}

.field__help {
  font-size: 0.9375rem;
}

.field__input {
  width: 100%;
  min-height: 3rem;
  padding: 0.625rem 0.875rem;
  border: 1.5px solid var(--sage);
  border-radius: var(--radius-field);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
}

textarea.field__input {
  min-height: 8rem;
  resize: vertical;
}

.field--error {
  padding-left: 1rem;
  border-left: 0.3125rem solid var(--rose);
}

.field--error .field__input {
  border-color: var(--ink);
  border-width: 2px;
}

.field__error {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-weight: 600;
}

.field__error::before {
  content: "!";
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 50%;
  background: var(--tongue);
  color: var(--ink);
  font-size: 0.875rem;
  line-height: 1;
}

.choices {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.25rem;
}

.choice {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 3rem;
  padding: 0.5rem 0.875rem;
  border: 1.5px solid var(--sage);
  border-radius: var(--radius-field);
  background: var(--paper);
  cursor: pointer;
}

.choice input {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  margin: 0;
  accent-color: var(--sage);
}

@supports selector(:has(*)) {
  .choice:has(input:checked) {
    border-color: var(--ink);
    box-shadow: inset 0 0 0 1px var(--ink);
  }

  .choice:has(input:focus-visible) {
    outline: 3px solid var(--ink);
    outline-offset: 3px;
  }

  .choice input:focus-visible {
    outline: none;
  }

  /* The animal question belongs to hound sessions only. */
  .form:not(:has(input[name="service"][value="hounds"]:checked)) .field--animal {
    display: none;
  }

  /* A Kennel rental needs its date, so the label stops calling it optional. */
  .form:has(input[name="service"][value="sunroom"]:checked) .field--date .field__optional {
    display: none;
  }
}

/* Set by site.js in browsers without :has() */
.field--animal[hidden],
.field__optional[hidden] {
  display: none;
}

/* Spam trap: kept out of sight and out of the tab order */
.form__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.error-summary {
  padding: 1rem 1.25rem;
  border: 2px solid var(--ink);
  border-left: 0.5rem solid var(--rose);
  border-radius: var(--radius-field);
  background: var(--paper);
  font-weight: 600;
}

.error-summary ul {
  margin-top: 0.5rem;
  padding-left: 1.25rem;
  font-weight: 400;
}

.error-summary a {
  color: var(--ink);
}

/* Footer */

.site-footer {
  padding-block: 2.5rem;
  border-top: 1px solid var(--rule);
  font-size: 0.9375rem;
}

.site-footer__inner {
  display: grid;
  gap: 1.25rem;
}

/* The copyright line closes the page, centered. */
.site-footer__copyright {
  text-align: center;
}

/* The whole logo signs the page off, with the summary and contact beside it. */
.site-footer__about {
  display: grid;
  gap: 1.25rem;
  justify-items: start;
}

.site-footer__logo {
  display: block;
}

.site-footer__logo img {
  width: 9rem;
}

.site-footer__text > * + * {
  margin-top: 0.375rem;
}

.site-footer__blurb {
  max-width: 26rem;
}

.site-footer__contact,
.site-footer__nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.5rem;
  padding: 0;
  list-style: none;
}

.site-footer__contact li {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
}

.site-footer__contact a,
.site-footer__nav a {
  display: inline-flex;
  align-items: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
}

.site-footer__nav a {
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
}

.site-footer__nav a:hover {
  text-decoration: underline;
}

@media (min-width: 40rem) {
  .site-footer__about {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: 2rem;
  }
}

@media (min-width: 56rem) {
  .site-footer__inner {
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 3rem;
  }

  .site-footer__nav ul {
    justify-content: flex-end;
  }

  .site-footer__copyright {
    grid-column: 1 / -1;
  }
}

/* Small pieces used by the inner pages */

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

.band__statement {
  max-width: 24ch;
  text-wrap: balance;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.35rem + 1.9vw, 2.75rem);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.012em;
}

.owner__caption {
  font-size: 1.625rem;
}

.band__now {
  font-weight: 500;
}

.band__link {
  margin-top: 0.75rem;
}

/* Home: the problem, with a small drawing of it: a phone full of photos
   beside an empty frame. */

.stakes {
  display: grid;
  gap: 2.5rem;
}

.stakes__text > * + * {
  margin-top: 1.25rem;
}

.stakes__text p {
  max-width: 32rem;
  font-size: 1.125rem;
}

.roll {
  width: min(100%, 19rem);
  height: auto;
}

.roll__phone {
  fill: var(--paper);
  stroke: var(--ink);
  stroke-width: 5;
}

.roll__ink {
  fill: var(--ink);
}

.roll__wire {
  fill: none;
  stroke: var(--ink);
  stroke-width: 2;
  stroke-linejoin: round;
}

.roll__frame {
  fill: var(--paper);
  stroke: var(--rose);
  stroke-width: 5;
}

.roll__mat {
  fill: none;
  stroke: var(--rule);
  stroke-width: 2;
  stroke-dasharray: 6 6;
}

.roll__tile--a { fill: var(--tint-sage); }
.roll__tile--b { fill: var(--tint-blush); }
.roll__tile--c { fill: var(--tint-sand); }
.roll__tile--d { fill: var(--tint-fern); }
.roll__tile--e { fill: var(--tongue); }

@media (min-width: 56rem) {
  .stakes {
    grid-template-columns: 7fr 5fr;
    align-items: center;
    gap: 3.5rem;
  }

  .roll {
    width: min(100%, 24rem);
    margin-left: auto;
  }
}

/* Home: what a session gets you. Three short promises under a pink rule. */

.benefits {
  display: grid;
  gap: 2rem;
  margin: 2.5rem 0 0;
  padding: 0;
  list-style: none;
}

.benefits__item {
  padding-top: 1.25rem;
  border-top: 0.3125rem solid var(--tongue);
}

.benefits__item > * + * {
  margin-top: 0.5rem;
}

.benefits__item p {
  max-width: 24rem;
}

.benefits__actions {
  margin-top: 2.5rem;
}

@media (min-width: 48rem) {
  .benefits {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2.5rem;
  }
}

/* Home: a few favorites. Each photo is cropped to its row and opens whole.
   A wide photo takes more of the row than a tall one, so little is cut off. */

.favorites {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 2rem 0 1rem;
  padding: 0;
  list-style: none;
}

/* A basis just over a third: two to a row. */
.favorites__item {
  flex: 3 1 34%;
  height: clamp(9rem, 42vw, 15rem);
}

.favorites__item--wide {
  flex-grow: 6;
}

.favorites__item--tall {
  flex-grow: 1;
}

.favorites__link {
  display: block;
  height: 100%;
}

.favorites__link img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (min-width: 48rem) {
  .favorites {
    gap: 1.25rem;
    margin-top: 2.5rem;
  }

  /* A basis just over a quarter: three to a row. */
  .favorites__item {
    flex-basis: 26%;
    height: clamp(15rem, 27vw, 22rem);
  }
}

/* Home: the two owners, in the same lens frames as the About page */

.meet {
  display: grid;
  gap: 2.5rem;
}

.meet__faces {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

/* The second lens hangs lower, like the second door. */
.meet__face + .meet__face {
  margin-top: 2.5rem;
}

.meet__face .lens {
  width: min(13rem, 38vw);
  padding: 0.375rem;
  border-width: 0.5rem;
}

.meet__face figcaption {
  margin-top: 0.75rem;
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 600;
  text-align: center;
}

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

.meet__text > * + * {
  margin-top: 1rem;
}

@media (min-width: 48rem) {
  .meet {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: clamp(2.5rem, 6vw, 5rem);
  }

  .meet__face .lens {
    width: clamp(8.5rem, 17vw, 13rem);
  }
}

/* The plan: how booking works. Numbered because it is a sequence. Each
   number sits in a ring, all in rose: sage, pink and ink already mean Gabi,
   Shayla and the Kennel everywhere else. */

.steps {
  display: grid;
  gap: 2rem;
  margin: 2.5rem 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

/* On a phone the ring sits beside its step. */
.steps__item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 1rem;
  counter-increment: step;
}

/* The step's name lines up with the middle of its ring. */
.steps__item h3 {
  display: flex;
  align-items: center;
  min-height: 3.5rem;
}

.steps__item p {
  grid-column: 2;
  max-width: 24rem;
}

.steps__item::before {
  content: counter(step);
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  border: 0.3125rem solid var(--rose);
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1;
}

@media (min-width: 48rem) {
  .steps {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2.5rem;
  }

  /* With room for three across, the ring sits above its step. */
  .steps__item {
    display: block;
  }

  .steps__item h3 {
    display: block;
    min-height: 0;
    margin-top: 1rem;
  }

  .steps__item p {
    margin-top: 0.5rem;
  }
}

/* Closing panel: each page ends in its own color with one next step */

.closing {
  padding-bottom: var(--section);
}

.band + .closing {
  padding-top: var(--section);
}

.closing__panel {
  display: grid;
  gap: 1.5rem;
  padding: clamp(2rem, 6vw, 4.5rem);
  border-radius: var(--radius-panel);
  background: var(--sage);
  color: var(--cream);
}

.closing--ink .closing__panel {
  background: var(--ink);
}

.closing--tongue .closing__panel {
  background: var(--tongue);
  color: var(--ink);
}

.closing__body > * + * {
  margin-top: 1.5rem;
}

.closing__body p {
  max-width: 30rem;
  font-size: 1.125rem;
}

.closing__panel :focus-visible {
  outline-color: var(--cream);
}

.closing--tongue .closing__panel :focus-visible {
  outline-color: var(--ink);
}

/* A button for use on a color panel, where the sage one would disappear. */
.button--on-panel {
  background: var(--cream);
  color: var(--ink);
}

.button--on-panel:hover {
  background: var(--ink);
  color: var(--cream);
}

.closing--tongue .button--on-panel {
  background: var(--ink);
  color: var(--cream);
}

.closing--tongue .button--on-panel:hover {
  background: var(--moss);
}

/* On ink the cream button cannot darken when pointed at, so it turns pink. */
.band--ink .button--on-panel:hover,
.closing--ink .button--on-panel:hover {
  background: var(--tongue);
  color: var(--ink);
}

/* The wave. The primary button is the hound: ears, tongue and tail. This one
   is the hooman: a hand comes up from behind its top edge and waves.
   The hand is the button's own color, cut to shape by the drawing below. It
   waits inside the button, behind the label, where it cannot be seen. */
.button--on-panel {
  /* Lets the hand sit above the button's color but below its label. */
  isolation: isolate;
}

.button--on-panel::before {
  content: "";
  position: absolute;
  z-index: -1;
  right: 0.875rem;
  /* The wrist stays 0.25rem inside the button, so no gap opens as it waves. */
  bottom: calc(100% + 2px - 0.25rem);
  width: 1.375rem;
  height: 1.65rem;
  background-color: inherit;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-width='2.8' d='M4.9 12V4.5M8.3 12V2.5M11.7 12V3.2M15.1 12V6'/%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-width='3.2' d='M5 15.5 2 10.4'/%3E%3Cpath d='M3.5 9.5h13V15a6.5 6.5 0 0 1-13 0zM6.5 18h7v6h-7z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-width='2.8' d='M4.9 12V4.5M8.3 12V2.5M11.7 12V3.2M15.1 12V6'/%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-width='3.2' d='M5 15.5 2 10.4'/%3E%3Cpath d='M3.5 9.5h13V15a6.5 6.5 0 0 1-13 0zM6.5 18h7v6h-7z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  pointer-events: none;
  /* Down inside the button until wanted. It turns about the wrist. */
  translate: 0 100%;
  transform-origin: 50% 100%;
}

.button--on-panel:hover::before,
.button--on-panel:focus-visible::before {
  translate: 0 0;
}

/* Three waves, then the hand holds still: nothing keeps moving while a button
   is focused. Each wave starts and ends upright. */
@keyframes wave {
  30% { rotate: 18deg; }
  70% { rotate: -12deg; }
}

@media (prefers-reduced-motion: no-preference) {
  .button--on-panel::before {
    /* A little past the top and back, like a hand popping up. */
    transition: translate 0.22s cubic-bezier(0.34, 1.4, 0.64, 1);
  }

  .button--on-panel:hover::before,
  .button--on-panel:focus-visible::before {
    animation: wave 0.56s ease-in-out 0.18s 3;
  }
}

@media (min-width: 56rem) {
  .closing__panel {
    grid-template-columns: 6fr 5fr;
    align-items: center;
    gap: 3rem;
  }
}

/* Booking page: the form, with what happens next beside it */

.book {
  display: grid;
  gap: 3rem;
}

.next {
  max-width: var(--measure);
  padding: clamp(1.5rem, 4vw, 2.25rem);
  border: 1.5px solid var(--rule);
  border-radius: var(--radius-panel);
  background: var(--paper);
}

.next__heading {
  font-size: 1.375rem;
  line-height: 1.2;
}

.next__steps {
  margin: 1rem 0 0;
  padding-left: 1.25rem;
}

.next__steps li + li {
  margin-top: 0.75rem;
}

.next__steps li::marker {
  font-weight: 600;
}

@media (min-width: 60rem) {
  .book {
    grid-template-columns: minmax(0, 36rem) minmax(0, 22rem);
    justify-content: space-between;
    align-items: start;
  }

  .next {
    position: sticky;
    top: 2rem;
  }
}
