/* ==========================================================================
   Deely Creators — 2027 mockup
   Brand system: colours and typeface taken from the live site.
   Colours  #FCFAF5 / #E7E5E1 / #CDC6BD / #84837F / #46413E
   Typeface Inter (variable, self-hosted)
   ========================================================================== */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --------------------------------------------------------------- tokens -- */

:root {
  --cream: #fcfaf5;
  --bone: #e7e5e1;
  --taupe: #cdc6bd;
  --stone: #84837f;
  --ink: #46413e;
  --ink-deep: #33302d; /* tonal variation of --ink for full-bleed dark blocks */

  --bg: var(--cream);
  --fg: var(--ink);
  --muted: color-mix(in srgb, var(--stone) 72%, var(--ink)); /* 4.7:1 on cream */
  --rule: color-mix(in srgb, var(--taupe) 70%, transparent);

  --gutter: clamp(1.25rem, 1rem + 3.2vw, 5rem);
  --maxw: 1840px;

  --fs-xs: clamp(0.6875rem, 0.665rem + 0.1vw, 0.75rem);
  --fs-sm: clamp(0.8125rem, 0.79rem + 0.11vw, 0.875rem);
  --fs-base: clamp(0.9375rem, 0.9rem + 0.2vw, 1.0625rem);
  --fs-md: clamp(1.0625rem, 0.96rem + 0.45vw, 1.375rem);
  --fs-lg: clamp(1.375rem, 1.15rem + 0.95vw, 2.25rem);
  --fs-xl: clamp(1.875rem, 1.35rem + 2.3vw, 3.75rem);
  --fs-2xl: clamp(2.5rem, 1.35rem + 5vw, 6rem);
  --fs-3xl: clamp(3rem, 1.1rem + 8vw, 8.5rem);

  --section: clamp(4rem, 2.5rem + 7vw, 10.5rem);
  --flow: clamp(1rem, 0.8rem + 0.7vw, 1.6rem);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur: 0.5s;
}

/* ---------------------------------------------------------------- reset -- */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: var(--fs-base);
  font-weight: 400;
  line-height: 1.6;
  font-feature-settings: 'ss01', 'cv05';
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
  overflow-x: clip;
}

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

img { height: auto; }

h1, h2, h3, h4, p, figure, blockquote, dl, dd { margin: 0; }

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

a { color: inherit; text-decoration: none; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
  border-radius: 0;
}

/* iOS Safari zooms the whole page the moment a control under 16px takes
   focus, which throws the layout off-centre and only a pinch undoes it. Every
   text control on a phone therefore sits at 16px or above; desktop keeps the
   scale it was designed at. */
@media (max-width: 61.99rem) {
  input, textarea, select { font-size: max(1rem, 1em); }
}

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

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

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

/* ------------------------------------------------------------ utilities -- */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.wrap--narrow { max-width: 1180px; }

/* Single-column default for every grid block, so long words and large text
   can never force a track wider than its container. Multi-column variants are
   declared later in each component's own media query. */
.statement,
.page-head__grid,
.about-hero,
.duo,
.campaign,
.contact-grid,
.newsletter,
.legal,
.profile-body,
.profile-hero__grid,
.footer-top,
.section-head,
.field-row,
.faq-group,
.model-grid,
.feed,
.trio,
.paths,
.steps,
.pager,
.gallery,
.specs,
.checklist,
.path,
.step,
.footer-col,
.roster-note,
.field,
.contact-block,
.campaign__text { grid-template-columns: minmax(0, 1fr); }

.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;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--ink);
  color: var(--cream);
  transform: translateY(-160%);
  transition: transform 0.2s var(--ease);
}
.skip-link:focus { transform: none; }

.section { padding-block: var(--section); }
.section--tight { padding-block: clamp(3rem, 2rem + 4vw, 6.5rem); }

.dark {
  background: var(--ink-deep);
  color: var(--cream);
  --fg: var(--cream);
  --muted: color-mix(in srgb, var(--taupe) 78%, var(--ink));
  --rule: color-mix(in srgb, var(--cream) 22%, transparent);
}

.label {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
}

.rule {
  height: 1px;
  border: 0;
  background: var(--rule);
  margin: 0;
}

/* --------------------------------------------------------------- typography */

.display {
  font-size: var(--fs-2xl);
  font-weight: 300;
  line-height: 0.92;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.display--xl { font-size: var(--fs-3xl); }

.display em {
  font-style: normal;
  font-weight: 200;
  color: var(--muted);
}

.heading {
  font-size: var(--fs-xl);
  font-weight: 300;
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.subheading {
  font-size: var(--fs-lg);
  font-weight: 300;
  line-height: 1.2;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.lede {
  font-size: var(--fs-md);
  font-weight: 300;
  line-height: 1.45;
  letter-spacing: -0.012em;
  max-width: 34ch;
}

.prose p { max-width: 68ch; }
.prose p + p { margin-top: var(--flow); }

/* ------------------------------------------------------------------ links */

.link {
  display: inline-flex;
  width: fit-content;
  align-items: baseline;
  gap: 0.6em;
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding-block: 0.6rem;
  position: relative;
}

.link::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: 0.2rem;
  height: 1px;
  background: currentColor;
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}

.link:hover::after,
.link:focus-visible::after { transform: scaleX(0.35); }

.link .arrow { transition: transform var(--dur) var(--ease); }
.link:hover .arrow { transform: translateX(0.35em); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.75em;
  min-height: 3rem;
  padding: 0.9rem 1.9rem;
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  cursor: pointer;
  max-width: 100%;
  overflow-wrap: anywhere;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.btn:hover,
.btn:focus-visible {
  background: var(--fg);
  color: var(--bg);
}

.btn--solid {
  background: var(--ink);
  color: var(--cream);
  border-color: var(--ink);
}
.btn--solid:hover,
.btn--solid:focus-visible {
  background: transparent;
  color: var(--ink);
}
.dark .btn--solid {
  background: var(--cream);
  color: var(--ink);
  border-color: var(--cream);
}
.dark .btn--solid:hover,
.dark .btn--solid:focus-visible {
  background: transparent;
  color: var(--cream);
}

/* A pair of calls to action reads as one decision, so on phones the two
   buttons stay on one line and share the width equally. The labels are
   longer than a 150px column, so they wrap inside the button rather than
   the row breaking apart: a stacked pair implies a hierarchy between two
   choices that are meant to be equal. Desktop keeps the original
   content-width, wrapping row. */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

@media (max-width: 47.99rem) {
  .btn-row {
    flex-wrap: nowrap;
    gap: 0.75rem;
    align-items: stretch;
  }

  .btn-row .btn {
    flex: 1 1 0;
    min-width: 0;
    /* two lines' worth, so a pair that wraps and a pair that does not still
       carry the same weight from one CTA block to the next */
    min-height: 4rem;
    padding-inline: clamp(0.75rem, 3vw, 1.9rem);
    text-align: center;
    text-wrap: balance;
    overflow-wrap: break-word;
    line-height: 1.3;
  }
}

/* --------------------------------------------------------------- header -- */

.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  padding-top: env(safe-area-inset-top);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
  border-bottom: 1px solid transparent;
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 3rem);
  min-height: clamp(4.25rem, 3.4rem + 2.4vw, 6rem);
}

.site-header.is-stuck,
.site-header.is-open {
  background: var(--cream);
  color: var(--ink);
  border-bottom-color: var(--rule);
}

.site-header.is-inverted:not(.is-stuck):not(.is-open) { color: var(--cream); }

.brand {
  display: block;
  flex: 0 1 auto;
  width: clamp(7.5rem, 5.5rem + 6vw, 12.5rem);
  max-width: 42vw;
  min-width: 0;
  margin-inline-end: auto;
}

.brand__mark {
  display: block;
  width: 100%;
  aspect-ratio: 580 / 96;
  background-color: currentColor;
  -webkit-mask: url('../img/site/wordmark.webp') center / contain no-repeat;
  mask: url('../img/site/wordmark.webp') center / contain no-repeat;
}

.nav {
  display: none;
  min-width: 0;
  flex-wrap: wrap;
  gap: clamp(1.1rem, 0.4rem + 1.6vw, 2.75rem);
  align-items: center;
}

.nav a {
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding-block: 0.75rem;
  position: relative;
}

.nav a::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: 0.4rem;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}

.nav a:hover::after,
.nav a:focus-visible::after,
.nav a[aria-current='page']::after { transform: scaleX(1); }

.nav a[aria-current='page'] { font-weight: 600; }

/* Below the desktop breakpoint the navigation lives behind the menu button,
   which is where a booking enquiry used to end up as well. The commercial
   action is too important to cost a tap, so it stays on the bar at every
   width — as a ruled micro-label on phones, so the header keeps its weight,
   and as the outline button from 62rem. */
.header-cta {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  min-height: 2.75rem;
  padding: 0.5rem 0;
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  border: 0;
  border-bottom: 1px solid currentColor;
  background: none;
}

.header-cta:hover,
.header-cta:focus-visible { background: none; color: inherit; }

/* "Book" on the bar, "Book now" once there is room for the whole phrase */
.header-cta__long { display: none; }

/* the drawer carries its own Book now, so the bar's copy steps aside */
.site-header.is-open .header-cta { display: none; }

.menu-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 3rem;
  height: 3rem;
  margin-inline-end: -0.75rem;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  align-items: flex-end;
}

.menu-toggle span {
  display: block;
  width: 26px;
  height: 1px;
  background: currentColor;
  transition: transform 0.35s var(--ease), opacity 0.2s var(--ease);
}

.site-header.is-open .menu-toggle span:first-child { transform: translateY(6px) rotate(45deg); }
.site-header.is-open .menu-toggle span:nth-child(2) { opacity: 0; }
.site-header.is-open .menu-toggle span:last-child { transform: translateY(-6px) rotate(-45deg); }

@media (min-width: 62rem) {
  .nav { display: flex; }
  .menu-toggle { display: none; }

  .header-cta {
    min-height: 3rem;
    padding: 0.9rem 1.9rem;
    font-size: var(--fs-sm);
    letter-spacing: 0.16em;
    border: 1px solid currentColor;
  }
  .header-cta:hover,
  .header-cta:focus-visible { background: var(--fg); color: var(--bg); }
  .header-cta__long { display: inline; }
}

/* mobile drawer */

.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;
  padding: calc(env(safe-area-inset-top) + clamp(5.5rem, 4.5rem + 4vw, 7rem)) var(--gutter)
    calc(env(safe-area-inset-bottom) + 2rem);
  background: var(--cream);
  color: var(--ink);
  max-width: 100vw;
  overflow-x: hidden;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.35s var(--ease), visibility 0.35s;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.mobile-nav[data-open='true'] {
  visibility: visible;
  opacity: 1;
}

.mobile-nav__list {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(0.1rem, 0.5vh, 0.6rem);
}

.mobile-nav__list a {
  display: block;
  overflow-wrap: anywhere;
  font-size: clamp(2rem, 1rem + 7vw, 3.75rem);
  font-weight: 300;
  letter-spacing: -0.035em;
  line-height: 1.15;
  padding-block: 0.15em;
}

.mobile-nav__list a[aria-current='page'] { color: var(--stone); }

.mobile-nav__foot {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem 1.5rem;
  align-items: center;
  padding-top: 2rem;
  border-top: 1px solid var(--rule);
}

.mobile-nav__foot a { font-size: var(--fs-sm); overflow-wrap: anywhere; }
.mobile-nav__foot .btn { flex: 1 1 100%; }

@media (min-width: 62rem) {
  .mobile-nav { display: none; }
}

body.is-locked { overflow: hidden; }

/* ----------------------------------------------------------------- hero -- */

/* The agency's header photograph is a diptych: a magazine spread on the studio
   floor (left) and a model on a sofa (right), split at 49.4% of the frame. Its
   left panel is bare wall from the top edge down to 31% — measured at 5.1:1
   against --ink — and that is the only part of the frame that will carry type.
   So the headline is set into it. Nothing is laid over the photograph that the
   photograph did not already leave empty: no scrim, no gradient, no panel.
   Landscape viewports get the whole spread; portrait viewports get the right
   panel alone, because a diptych cannot survive a phone and the face can. */

.hero {
  --hero-head: calc(clamp(4.25rem, 3.4rem + 2.4vw, 6rem) + env(safe-area-inset-top));
  --hero-gap: clamp(1rem, 0.6rem + 1.6vw, 2.25rem);
}

/* Portrait: the first screen is one composition, not a stack that happens to
   start at the top. Masthead, photograph and claim are measured against the
   fold — the photograph takes whatever the type does not need, so the frame is
   as tall as the device allows and the page below begins exactly where the
   screen ends. 17rem is the floor for very short screens, where the hero is
   allowed to exceed the viewport instead of squashing the photograph into a
   letterbox. */
.hero__first {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  min-block-size: calc(100svh - clamp(0.75rem, 2.5vw, 1.5rem));
  padding-top: calc(var(--hero-head) + var(--hero-gap));
}

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 2.5rem;
  align-items: baseline;
  padding-bottom: clamp(0.85rem, 1.5vw, 1.5rem);
}

/* Portrait: one mast line, not two, so the plate arrives sooner. The
   discipline list moves down to read as context for the promise instead of
   competing with the wordmark before the photograph has even appeared. */
.hero__meta .label:nth-of-type(2) { display: none; }

/* Portrait: frame, then claim at caption distance. The frame takes the free
   row, the type takes what it needs. */
.hero__stage {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  gap: clamp(1rem, 3.2vw, 1.75rem);
  overflow: hidden;
}

/* The service line holds one line down to 320px: at the label's own 0.22em it
   drops "Campaigns" onto a second line on every phone, and a three-word list
   broken after the second word reads as an accident. */
.hero__disciplines {
  margin-block: clamp(0.75rem, 2.6vw, 1.25rem) 0;
  letter-spacing: 0.15em;
  text-wrap: balance;
}

.hero__type { grid-row: 2; min-inline-size: 0; padding-inline: var(--gutter); }

/* display: contents makes the <img> itself the grid item, so its box is the
   grid area rather than a percentage of a track that is sized by its own
   content. object-fit then does the cropping instead of an overflow clip. */
.hero__stage picture { display: contents; }

/* On a phone the frame is the screen: edge to edge, no indent, no bleed to
   guess at. The crop is a 5:6 portrait taken tight on the model, so the face
   is large at the top of the frame and the photograph carries the screen
   rather than sitting in it. Past 34rem it stops growing and centres, so a
   portrait tablet gets a plate on a page instead of a stretched phone layout. */
.hero__stage img {
  grid-row: 1;
  justify-self: center;
  align-self: stretch;
  display: block;
  inline-size: min(100%, 34rem);
  /* Fill whatever the type leaves — but never go shallower than the crop's own
     5:6. On a tall phone that means the frame reaches the fold exactly; on a
     short one the hero runs past it rather than flattening the photograph into
     a letterbox, and the headline's first line becomes the scroll cue. */
  block-size: 100%;
  aspect-ratio: 5 / 6;
  object-fit: cover;
  object-position: 50% 32%;
  background: var(--bone);
}

.hero__title {
  margin: 0;
  font-size: clamp(2.125rem, 1.05rem + 5.3vw, 3.25rem);
  font-weight: 300;
  line-height: 0.95;
  letter-spacing: -0.04em;
  /* 14.5ch breaks the first clause after "the" at every width the headline is
     used at, so the two-line shape is the same on a phone and on a 5K display. */
  max-inline-size: 14.5ch;
}

/* One sentence, two voices — now separated by scale rather than by colour, so
   the second clause keeps its contrast where it sits on the photograph. */
.hero__title .em {
  display: block;
  max-inline-size: 26ch;
  margin-block-start: 0.7em;
  font-size: 0.44em;
  font-weight: 300;
  line-height: 1.3;
  letter-spacing: -0.008em;
  color: var(--ink);
}

/* Landscape: the whole spread. Capping the stage at the frame's own 16:9 keeps
   the seam at 49.4vw and the empty wall at its true size at every width, so the
   headline sits in the same place in the photograph on a laptop as on a 5K
   display. Vertical crop is taken off the bottom, never off the wall. */
@media (min-width: 34rem) and (min-aspect-ratio: 5 / 4) {
  /* the spread is measured against the frame, not against the fold */
  .hero__first { display: block; min-block-size: 0; }

  .hero__stage {
    grid-template-rows: auto;
    gap: 0;
    block-size: min(56.25vw, calc(100svh - var(--hero-head) - var(--hero-gap)
                           - clamp(3.25rem, 2rem + 3.2vh, 5.5rem)));
  }
  /* the masthead splits where the photograph splits */
  .hero__meta { display: grid; grid-template-columns: 49.4% minmax(0, 1fr); gap: 0; }
  .hero__meta .label:nth-of-type(2) { display: block; }
  .hero__disciplines { display: none; }

  /* The frame is laid in at its own ratio, full width, anchored to the top of
     the stage; the stage's height is what crops it, always off the bottom. The
     wall the headline sits in is therefore never cropped at any viewport. */
  .hero__stage img {
    grid-area: 1 / 1;
    justify-self: stretch;
    align-self: start;
    inline-size: 100%;
    block-size: auto;
    min-block-size: 0;
    max-block-size: none;
    object-position: 50% 50%;
    /* stated, not inherited from the width/height attributes, which describe
       the portrait crop: the box is the spread's ratio from the first paint */
    aspect-ratio: 16 / 9;
    transform-origin: 50% 0;
  }

  .hero__type {
    grid-area: 1 / 1;
    z-index: 1;
    display: grid;
    align-content: end;
    align-self: start;
    inline-size: 49.4%;
    block-size: 17.1vw;
    padding-block-end: 1.7vw;
    padding-inline: var(--gutter) 3vw;
  }

  .hero__title {
    font-size: min(5vw, 6.5rem);
    line-height: 0.92;
    letter-spacing: -0.045em;
  }

  /* on the photograph the small clause carries a little more weight: same
     colour, same size, but 400 holds up against a textured wall */
  .hero__title .em { font-size: 0.375em; font-weight: 400; margin-block-start: 0.5em; }

}

/* A single, slow settle on the one photograph that is already on screen: no
   entrance, no delay, nothing hidden — the frame simply comes to rest. */
@media (prefers-reduced-motion: no-preference) {
  .hero__stage img { animation: hero-settle 1.8s var(--ease) both; }
}

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

.hero__caption {
  margin-top: 0.7rem;
  font-size: var(--fs-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ----------------------------------------------------------------- trio -- */

.trio {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.75rem, 0.4rem + 1.4vw, 1.75rem);
  align-items: start;
}

.trio figure { margin: 0; min-width: 0; }

.trio img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  object-position: center 18%;
  background: var(--bone);
}

.trio figure:nth-child(3) { grid-column: span 2; }
.trio figure:nth-child(3) img { aspect-ratio: 3 / 2; object-position: center 22%; }

@media (min-width: 48rem) {
  .trio { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .trio figure:nth-child(3) { grid-column: auto; }
  .trio figure:nth-child(3) img { aspect-ratio: 2 / 3; object-position: center 18%; }
  .trio figure:nth-child(2) { margin-top: clamp(2rem, 6vw, 5rem); }
}

/* ------------------------------------------------------------- statement -- */

.statement {
  display: grid;
  gap: clamp(1.5rem, 1rem + 2vw, 3rem);
}

.statement__body {
  font-size: var(--fs-lg);
  font-weight: 300;
  line-height: 1.32;
  letter-spacing: -0.022em;
  max-width: 24ch;
}

.statement__note {
  color: var(--muted);
  max-width: 44ch;
}

@media (min-width: 55rem) {
  .statement {
    grid-template-columns: minmax(0, 0.32fr) minmax(0, 1fr);
    gap: clamp(2rem, 6vw, 7rem);
  }
  .statement__body { max-width: 28ch; }
}

/* --------------------------------------------------------------- clients -- */

.clients {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(1.75rem, 1rem + 4vw, 5rem);
  padding-block: clamp(2rem, 1.5rem + 2vw, 3.5rem);
}

.clients img {
  width: auto;
  max-width: clamp(5.5rem, 4rem + 6vw, 9rem);
  max-height: clamp(1.5rem, 1.1rem + 1.4vw, 2.5rem);
  object-fit: contain;
  /* 0.75 put the lightest mark in the row at 2.2:1 on cream, which is below
     the 3:1 non-text minimum and effectively invisible on a phone screen in
     daylight. The grayscale filter already does the muting. */
  opacity: 0.9;
  filter: grayscale(1);
  transition: opacity var(--dur) var(--ease);
}

.clients a:hover img,
.clients a:focus-visible img { opacity: 1; }

/* ---------------------------------------------------------------- roster -- */

.section-head {
  display: grid;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  margin-bottom: clamp(2rem, 1.5rem + 3vw, 4.5rem);
}

.section-head__row {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: 1rem 2rem;
}

.model-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(2rem, 1.2rem + 3vw, 4rem) clamp(1rem, 0.5rem + 2vw, 2.5rem);
}

@media (min-width: 23rem) {
  .model-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* On phones the first card runs full width: the roster opens on one face
   rather than a uniform stack. */
@media (min-width: 23rem) and (max-width: 55.99rem) {
  .model-grid--wide > .model-card:first-child { grid-column: span 2; }
  .model-grid--wide > .model-card:first-child .model-card__media { aspect-ratio: 4 / 5; }
}

@media (min-width: 56rem) {
  .model-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .model-grid--offset > :nth-child(3n + 2) { margin-top: clamp(2rem, 6vw, 6rem); }
  .model-grid--offset > :nth-child(3n + 3) { margin-top: clamp(1rem, 3vw, 3rem); }
}

@media (min-width: 90rem) {
  .model-grid--wide { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .model-grid--wide.model-grid--offset > :nth-child(3n + 2) { margin-top: 0; }
  .model-grid--wide.model-grid--offset > :nth-child(3n + 3) { margin-top: 0; }
  .model-grid--wide.model-grid--offset > :nth-child(4n + 2) { margin-top: clamp(2rem, 5vw, 6rem); }
  .model-grid--wide.model-grid--offset > :nth-child(4n + 4) { margin-top: clamp(2rem, 5vw, 6rem); }
}

.model-card { position: relative; min-width: 0; }

.model-card__media {
  position: relative;
  overflow: hidden;
  background: var(--bone);
  aspect-ratio: 2 / 3;
}

.model-card__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 20%;
  transition: opacity 0.6s var(--ease), transform 1.2s var(--ease);
}

/* The second frame is never rendered on a touch device, so it is never
   fetched there either: `display: none` keeps the background image out of the
   network entirely, which halves the imagery a phone downloads for the
   roster. The card's information never depended on it. */
.model-card__hover { display: none; }

@media (hover: hover) {
  .model-card__hover {
    display: block;
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center 20%;
    opacity: 0;
    transition: opacity 0.6s var(--ease), transform 1.2s var(--ease);
  }

  .model-card:hover .model-card__media img,
  .model-card:focus-within .model-card__media img,
  .model-card:hover .model-card__hover,
  .model-card:focus-within .model-card__hover { transform: scale(1.03); }

  .model-card:hover .model-card__hover,
  .model-card:focus-within .model-card__hover { opacity: 1; }
}

/* Name and status share a line only where a card is wide enough to hold both.
   Below that they are always stacked, never left to flex-wrap: a card with a
   long status would otherwise wrap while its neighbour did not, and the two
   would stop sharing a baseline. */
.model-card__body {
  display: grid;
  gap: 0.2rem;
  margin-top: 0.9rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule);
}

@media (min-width: 56rem) {
  .model-card__body {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.25rem 1rem;
  }
}

.model-card__name {
  font-size: var(--fs-lg);
  font-weight: 300;
  letter-spacing: -0.03em;
  line-height: 1.05;
}

.model-card__status {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  min-width: 0;
}

@media (min-width: 56rem) {
  .model-card__status { text-align: right; }
}

.model-card a::after {
  content: '';
  position: absolute;
  inset: 0;
}

.roster-note {
  display: grid;
  gap: 1rem;
  align-content: center;
  padding: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
  border: 1px solid var(--rule);
  min-height: 60%;
}

.roster-note h3 {
  font-size: var(--fs-md);
  font-weight: 300;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.roster-note p { color: var(--muted); font-size: var(--fs-sm); }

/* -------------------------------------------------------------- campaign -- */

.campaign {
  display: grid;
  gap: clamp(1.5rem, 1rem + 3vw, 3.5rem);
  align-items: center;
}

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

.campaign__text { display: grid; gap: var(--flow); }

@media (min-width: 55rem) {
  .campaign {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 4.5rem);
  }
  .campaign__a { align-self: start; }
  .campaign__b { align-self: end; padding-bottom: clamp(1rem, 4vw, 4rem); }
  .campaign__text { align-self: center; }
}

/* ----------------------------------------------------------------- paths -- */

.paths {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  background: var(--rule);
  border-block: 1px solid var(--rule);
}

.path {
  display: grid;
  min-width: 0;
  gap: var(--flow);
  align-content: start;
  padding: clamp(2rem, 1.5rem + 3vw, 4.5rem) 0;
  background: var(--bg);
}

.path__title {
  font-size: var(--fs-xl);
  font-weight: 300;
  letter-spacing: -0.03em;
  line-height: 1.02;
}

.path p {
  color: var(--muted);
  max-width: 42ch;
}

@media (min-width: 48rem) {
  .paths { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .path { padding-inline: clamp(1.5rem, 4vw, 4.5rem); }
  .path:first-child { padding-inline-start: 0; }
  .path:last-child { padding-inline-end: 0; }
}

/* ------------------------------------------------------------------ feed -- */

.feed {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(62vw, 22rem);
  max-width: 100%;
  min-width: 0;
  gap: clamp(0.75rem, 0.4rem + 1.2vw, 1.5rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: 1rem;
  scrollbar-width: thin;
}

.feed > * { scroll-snap-align: start; }

.feed img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

/* ------------------------------------------------------------ newsletter -- */

.newsletter {
  display: grid;
  gap: clamp(1.5rem, 1rem + 2.5vw, 3.5rem);
}

.field-row {
  display: grid;
  gap: 1rem;
}

@media (min-width: 40rem) {
  .field-row { grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr)); }
}

@media (min-width: 60rem) {
  .newsletter { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); align-items: end; }
}

/* ----------------------------------------------------------------- forms -- */

.field {
  display: grid;
  gap: 0.4rem;
}

.field label {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}

.field input,
.field textarea,
.field select {
  width: 100%;
  min-height: 3rem;
  padding: 0.75rem 0;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-base);
  transition: border-color var(--dur) var(--ease);
}

.field textarea {
  min-height: 8rem;
  resize: vertical;
  line-height: 1.5;
}

.field input:focus,
.field textarea:focus,
.field select:focus {
  outline: none;
  border-bottom-color: var(--fg);
}

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

.choice-set {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.choice-set legend {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0;
  margin-bottom: 0.75rem;
}

.choice {
  display: inline-flex;
  max-width: 100%;
  align-items: center;
  gap: 0.6rem;
  min-height: 3rem;
  padding: 0.5rem 1.25rem;
  border: 1px solid var(--rule);
  font-size: var(--fs-sm);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}

.choice input { accent-color: var(--ink); width: 1rem; height: 1rem; }
.choice:has(input:checked) { border-color: var(--fg); background: var(--bone); }
.choice:has(input:focus-visible) { outline: 2px solid var(--fg); outline-offset: 3px; }

.form-note {
  font-size: var(--fs-sm);
  color: var(--muted);
  max-width: 46ch;
}

/* ------------------------------------------------------------------- faq -- */

.faq-group {
  display: grid;
  gap: 1rem;
}

@media (min-width: 62rem) {
  .faq-group {
    grid-template-columns: minmax(0, 0.28fr) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 5rem);
  }
}

.faq {
  border-top: 1px solid var(--rule);
  min-width: 0;
}

.faq details {
  border-bottom: 1px solid var(--rule);
}

.faq summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: clamp(1.1rem, 0.9rem + 0.8vw, 1.85rem);
  font-size: var(--fs-md);
  font-weight: 300;
  letter-spacing: -0.015em;
  line-height: 1.3;
  cursor: pointer;
  list-style: none;
}

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

.faq summary::after {
  content: '';
  flex: 0 0 auto;
  width: 0.85rem;
  height: 0.85rem;
  margin-top: 0.4em;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M7.3 0h1.4v16H7.3z'/%3E%3Cpath d='M0 7.3h16v1.4H0z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M7.3 0h1.4v16H7.3z'/%3E%3Cpath d='M0 7.3h16v1.4H0z'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 0.35s var(--ease);
}

.faq details[open] summary::after { transform: rotate(135deg); }

.faq__answer {
  padding-bottom: clamp(1.25rem, 1rem + 1vw, 2rem);
  color: var(--muted);
  max-width: 56ch;
}

.faq__answer a { text-decoration: underline; text-underline-offset: 0.2em; }

/* ------------------------------------------------------------ page heads -- */

.page-head {
  padding-top: clamp(7rem, 5rem + 9vw, 12rem);
  padding-bottom: clamp(2rem, 1.5rem + 3vw, 4.5rem);
}

.page-head__grid {
  display: grid;
  gap: clamp(1.25rem, 1rem + 2vw, 2.5rem);
}

@media (min-width: 48rem) {
  .page-head__grid {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    align-items: end;
    gap: clamp(2rem, 6vw, 6rem);
  }
}

/* ------------------------------------------------------------- about page */

.about-hero {
  display: grid;
  gap: clamp(1.5rem, 1rem + 3vw, 3.5rem);
  align-items: end;
}

.about-hero img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  object-position: center 15%;
}

@media (min-width: 55rem) {
  /* Equal columns, both starting at the same baseline. The story carries the
     column at lede scale on a short measure, so its height answers the
     portrait instead of leaving a hole between label and text. */
  .about-hero { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); align-items: start; gap: clamp(2rem, 6vw, 6rem); }
  .about-hero__text { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); }
}

.about-hero img { max-height: min(92svh, 62rem); max-width: calc(min(92svh, 62rem) * 2 / 3); }

.prose--story p {
  font-size: var(--fs-md);
  font-weight: 300;
  line-height: 1.5;
  letter-spacing: -0.01em;
  max-width: 40ch;
}

.duo {
  display: grid;
  gap: clamp(1.5rem, 1rem + 3vw, 4rem);
}

@media (min-width: 55rem) {
  .duo { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
  .duo--offset > :last-child { margin-top: clamp(2rem, 6vw, 6rem); }
}

/* ----------------------------------------------------------- become page -- */

.steps {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  background: var(--rule);
  border-block: 1px solid var(--rule);
}

.step {
  display: grid;
  min-width: 0;
  gap: 0.75rem;
  align-content: start;
  padding: clamp(1.75rem, 1.2rem + 2.5vw, 3.5rem) 0;
  background: var(--bg);
}

.step__n {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.22em;
  color: var(--muted);
}

.step h3 {
  font-size: var(--fs-md);
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.25;
}

.step p { color: var(--muted); max-width: 38ch; }

@media (min-width: 48rem) {
  .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .step { padding-inline: clamp(1.25rem, 3vw, 3rem); }
  .step:first-child { padding-inline-start: 0; }
  .step:last-child { padding-inline-end: 0; }
}

.checklist {
  display: grid;
  gap: 0.85rem;
  max-width: 46ch;
}

.checklist li {
  display: grid;
  grid-template-columns: 1.6rem minmax(0, 1fr);
  gap: 0.5rem;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--rule);
}

.checklist li::before {
  content: '—';
  color: var(--muted);
}

/* ---------------------------------------------------------- contact page -- */

.contact-grid {
  display: grid;
  gap: clamp(2.5rem, 2rem + 4vw, 6rem);
}

@media (min-width: 60rem) {
  .contact-grid { grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); }
}

/* The portrait opens the enquiry column: what a client is actually booking,
   sitting above the addresses rather than trailing off the end of the page. */
.contact-portrait img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center 12%;
  background: var(--bone);
}

.contact-portrait { margin-bottom: clamp(1.5rem, 1rem + 2vw, 3rem); }

/* On a phone the column is the page, so a 4:5 portrait above the addresses
   costs a whole screen before the visitor can see an email address. Below the
   two-column breakpoint the answers come first and the portrait closes the
   column instead of opening it. Order only — desktop is untouched. */
@media (max-width: 59.99rem) {
  .contact-aside { display: flex; flex-direction: column; }
  .contact-follow { order: 1; }
  .contact-portrait {
    order: 2;
    margin-block: clamp(1.75rem, 1rem + 3vw, 3rem) 0;
  }
}

.contact-block {
  display: grid;
  gap: 0.35rem;
  padding-block: clamp(1.25rem, 1rem + 1vw, 2rem);
  border-bottom: 1px solid var(--rule);
}

.contact-block:first-of-type { border-top: 1px solid var(--rule); }

.contact-block__value {
  font-size: var(--fs-md);
  font-weight: 300;
  letter-spacing: -0.015em;
  word-break: break-word;
}

.contact-block__value a { text-decoration: underline; text-underline-offset: 0.25em; text-decoration-thickness: 1px; }
.contact-block__value a:hover { text-decoration-color: var(--stone); }

/* Social and legal/company facts already live in the footer below, so this
   stays a quiet aside rather than a third bordered block competing with the
   two addresses that actually matter on a contact page. */
.contact-follow {
  margin-top: clamp(1.5rem, 1rem + 1.5vw, 2.25rem);
  font-size: var(--fs-sm);
  color: var(--muted);
}
.contact-follow a { color: inherit; text-decoration: underline; text-underline-offset: 0.25em; }
.contact-follow a:hover { text-decoration-color: var(--stone); }

/* ---------------------------------------------------------- model profile */

.profile-crumb { padding-top: clamp(5.5rem, 4.5rem + 5vw, 8rem); }

.profile-hero {
  padding-top: clamp(1.5rem, 1rem + 2vw, 3rem);
}

.profile-hero__grid {
  display: grid;
  gap: clamp(1.25rem, 1rem + 2.5vw, 3rem);
  align-items: end;
}

.profile-name {
  font-size: var(--fs-3xl);
  font-weight: 250;
  line-height: 0.85;
  letter-spacing: -0.045em;
  margin-top: 0.75rem;
}

.profile-hero__avail {
  margin-top: 1.5rem;
  color: var(--muted);
  max-width: 30ch;
}

.profile-hero__book { margin-top: 1.5rem; }

.profile-hero__media img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  object-position: center 18%;
}

/* A profile is a portfolio, so the portrait belongs in the first screen. On a
   phone the single column put the whole booking block above it and pushed the
   photograph off the fold. The text box dissolves into the grid below the
   two-column breakpoint so the order can become status, name, portrait, then
   the booking action, and the portrait is capped to leave room for it. */
@media (max-width: 47.99rem) {
  .profile-hero__grid { gap: clamp(1rem, 0.8rem + 1.6vw, 1.75rem); }
  .profile-hero__text { display: contents; }
  .profile-hero__media { order: 3; }
  .profile-hero__avail { order: 4; margin-top: 0; }
  .profile-hero__book { order: 5; margin-top: 0; justify-self: start; }
  .profile-name { margin-top: 0; }
  .profile-hero__media img { max-height: min(56svh, 30rem); }
}

/* Keep the name and the booking action inside the first screen on laptops. */
@media (min-width: 48rem) {
  .profile-hero__media img { max-height: min(74svh, 44rem); }
}

@media (min-width: 48rem) {
  .profile-hero__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
    gap: clamp(2rem, 5vw, 5rem);
  }
}

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

@media (min-width: 62rem) {
  .profile-body { grid-template-columns: minmax(16rem, 0.36fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 6rem); }
  .profile-aside { position: sticky; top: clamp(6rem, 5rem + 3vw, 8.5rem); }
}

.specs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--rule);
}

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

.specs div {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.15rem 1rem;
  min-width: 0;
  padding-block: 0.8rem;
  border-bottom: 1px solid var(--rule);
}

@media (max-width: 61.99rem) {
  .specs div:nth-child(odd) { padding-inline-end: 1rem; }
  .specs div:nth-child(even) { padding-inline-start: 1rem; }
}

.specs dt {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}

.specs dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: var(--fs-base);
  font-variant-numeric: tabular-nums;
}

.gallery {
  display: grid;
  gap: clamp(0.75rem, 0.5rem + 1.4vw, 1.75rem);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.gallery figure { margin: 0; }

.gallery img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  background: var(--bone);
}

.gallery .span-2 { grid-column: span 2; }

.gallery .span-2 img {
  aspect-ratio: 5 / 6;
  object-position: center 12%;
}

.gallery .offset { margin-top: clamp(1rem, 4vw, 4rem); }

@media (max-width: 34.99rem) {
  .gallery .offset { margin-top: 0; }
}

.pager {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  background: var(--rule);
  border-block: 1px solid var(--rule);
}

.pager a {
  display: grid;
  gap: 0.35rem;
  padding: clamp(1.5rem, 1.2rem + 2vw, 3rem) 0;
  background: var(--bg);
  transition: background var(--dur) var(--ease);
}

.pager a:hover { background: var(--bone); }

.pager__name {
  font-size: var(--fs-lg);
  font-weight: 300;
  letter-spacing: -0.03em;
}

@media (min-width: 48rem) {
  .pager { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pager a { padding-inline: clamp(1.25rem, 3vw, 3rem); }
  .pager a:first-child { padding-inline-start: 0; }
  .pager a:last-child { padding-inline-end: 0; text-align: right; justify-items: end; }
}

/* ------------------------------------------------------------ search bar -- */

.roster-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-block: 1rem;
  border-block: 1px solid var(--rule);
  margin-bottom: clamp(2rem, 1.5rem + 3vw, 4rem);
}

.roster-search {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex: 1 1 0;
  min-width: min(11rem, 100%);
  max-width: 22rem;
}

.roster-search input {
  flex: 1 1 0;
  min-width: 0;
  min-height: 2.75rem;
  padding: 0.5rem 0;
  background: transparent;
  border: 0;
  /* a resting hairline, because a touch device has no hover to reveal that
     this is a field rather than a caption */
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-sm);
  letter-spacing: 0.08em;
}

.roster-search input:focus {
  outline: none;
  border-bottom-color: var(--fg);
}

.roster-count { font-size: var(--fs-xs); letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); }

.model-card[hidden] { display: none; }

/* ---------------------------------------------------- touch targets -- */

/* Every standalone destination and address on the site — footer navigation,
   booking addresses, the profile breadcrumb, the drawer's contacts — was a
   text-height box between 13px and 27px tall. That is fine for a cursor and
   wrong for a thumb. These are lists of links, not links inside running
   prose, so the box can grow to 44px without touching the type: the padding
   takes over the spacing the gap used to provide. Scoped to touch and to the
   widths where the phone layouts run, so the desktop composition is untouched.
   Model cards are absent because the whole card is already the target. */
@media (max-width: 61.99rem), (pointer: coarse) {
  .brand { padding-block: 0.75rem; }

  .footer-col a,
  .footer-legal a,
  .contact-block__value a,
  .contact-follow a,
  .mobile-nav__foot a,
  .breadcrumb {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
  }

  .footer-col { gap: 0.1rem; }
  .footer-legal { gap: 0 1.5rem; }
  .link { padding-block: 0.75rem; }
}

.empty-state {
  padding-block: clamp(3rem, 8vw, 6rem);
  color: var(--muted);
}

/* ---------------------------------------------------------------- footer -- */

.site-footer {
  background: var(--ink-deep);
  color: var(--cream);
  --fg: var(--cream);
  --muted: color-mix(in srgb, var(--taupe) 80%, var(--ink));
  --rule: color-mix(in srgb, var(--cream) 20%, transparent);
  padding-top: clamp(3.5rem, 2.5rem + 5vw, 7rem);
  padding-bottom: calc(env(safe-area-inset-bottom) + clamp(1.75rem, 1.5rem + 1.5vw, 2.75rem));
}

.footer-top {
  display: grid;
  gap: clamp(2rem, 1.5rem + 3vw, 4rem);
  padding-bottom: clamp(2.5rem, 2rem + 3vw, 4.5rem);
}

@media (min-width: 55rem) {
  .footer-top { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr); }
}

/* Below the three-column footer, the same links would be one 1100px thumb
   scroll. Each group becomes a two-column block under its own hairline, so
   the footer reads as three labelled blocks instead of one list. The
   addresses keep the full width — they do not survive a 150px column — and
   the two social links pair up beneath them. */
@media (max-width: 54.99rem) {
  .footer-top { gap: clamp(1.75rem, 1.25rem + 2vw, 2.5rem); }

  .footer-col--nav,
  .footer-col--contact {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 1.5rem;
    border-top: 1px solid var(--rule);
    padding-top: 1.25rem;
  }

  .footer-col--nav h2,
  .footer-col--contact h2,
  .footer-col--contact a[href^="mailto:"] { grid-column: 1 / -1; }
}

.footer-brand {
  display: block;
  width: clamp(9rem, 7rem + 8vw, 16rem);
  max-width: 100%;
  aspect-ratio: 580 / 96;
  background-color: currentColor;
  -webkit-mask: url('../img/site/wordmark.webp') left center / contain no-repeat;
  mask: url('../img/site/wordmark.webp') left center / contain no-repeat;
}

.footer-col { display: grid; gap: 0.85rem; align-content: start; }

.footer-col h2 {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.4rem;
}

.footer-col a {
  font-size: var(--fs-base);
  font-weight: 300;
  position: relative;
  width: fit-content;
  word-break: break-word;
}

.footer-col a::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: -2px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}

.footer-col a:hover::after,
.footer-col a:focus-visible::after { transform: scaleX(1); }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.75rem;
  align-items: center;
  justify-content: space-between;
  padding-top: clamp(1.5rem, 1.2rem + 1.5vw, 2.5rem);
  border-top: 1px solid var(--rule);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
}

.footer-legal a:hover { color: var(--cream); }

.footer-credit a { color: var(--muted); }
.footer-credit a:hover { color: var(--cream); }

/* ----------------------------------------------------------------- prose -- */

.legal {
  display: grid;
  gap: clamp(2rem, 1.5rem + 3vw, 4rem);
}

@media (min-width: 60rem) {
  .legal { grid-template-columns: minmax(0, 0.3fr) minmax(0, 1fr); gap: clamp(2rem, 6vw, 6rem); }
  .legal__meta { position: sticky; top: clamp(6rem, 5rem + 3vw, 8.5rem); align-self: start; }
}

.legal__body h2 {
  font-size: var(--fs-lg);
  font-weight: 300;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin-top: clamp(2rem, 1.5rem + 2vw, 3.5rem);
  margin-bottom: 0.9rem;
}

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

.legal__body h3 {
  font-size: var(--fs-base);
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-top: 1.75rem;
  margin-bottom: 0.5rem;
}

.legal__body p,
.legal__body li { color: color-mix(in srgb, var(--fg) 82%, var(--stone)); max-width: 68ch; }

.legal__body p + p { margin-top: var(--flow); }

.legal__body ul {
  display: grid;
  gap: 0.6rem;
  margin-top: var(--flow);
  max-width: 68ch;
}

.legal__body li {
  display: grid;
  grid-template-columns: 1.5rem minmax(0, 1fr);
}

.legal__body li::before { content: '—'; color: var(--stone); }

.legal__body a { text-decoration: underline; text-underline-offset: 0.2em; }

.legal__body .clause {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr);
  gap: 0.5rem;
  margin-top: 0.9rem;
}

.legal__body .clause span { color: var(--stone); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------- animation -- */

.js [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}

.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
}

@media print {
  .site-header, .mobile-nav, .site-footer { display: none; }
}
