/* ============================================================
   THE HUMAN ELEMENT — SHARED CHROME
   Nav, footer, buttons, section headers, CTA band, page header.
   Used by every page.
   ============================================================ */

/* Progressive-enhancement fade-in for images: only applies once the
   js-fade-images class (set by the inline script in <head>) is present, so
   a JS failure leaves images at their normal opacity instead of hiding them. */
html.js-fade-images img {
  opacity: 0;
  background-color: var(--he-grey-light);
  transition: opacity 0.4s ease;
}
html.js-fade-images img.is-loaded {
  opacity: 1;
  background-color: transparent;
}
/* .hero__sculpture already has its own entrance animation (heFadeUp, in
   tokens.css) that fades and slides it up in sync with the rest of the
   hero. Layering the generic fade-in on top made it play twice and look
   jerky, so let the existing animation own opacity for this element. */
html.js-fade-images img.hero__sculpture {
  opacity: 1;
  background-color: transparent;
  transition: none;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 24px;
  padding: 16px clamp(20px, 5vw, 40px);
  border-bottom: 1.5px solid var(--he-ink);
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--he-white);
}
.site-nav__logo { height: 40px; width: auto; }
/* margin-left:auto pulls the links off the logo and over to the right, so
   they sit as a group beside the language switch rather than centred. */
.site-nav__links {
  display: flex;
  flex-wrap: wrap;
  margin-left: auto;
  gap: clamp(18px, 2.4vw, 32px);
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 700;
}
.site-nav__links a {
  text-decoration: none;
  color: var(--he-ink);
  padding: 8px 0;
  transition: color var(--dur-base) var(--ease-standard);
}
.site-nav__links a:hover { color: var(--he-orange); }
.site-nav__links a.is-current { color: var(--he-orange); }
.site-nav__lang {
  display: inline-flex;
  border: 1.5px solid var(--he-ink);
  overflow: hidden;
  font-size: 11px;
  font-weight: 600;
}
.site-nav__lang a { padding: 5px 12px; cursor: pointer; text-decoration: none; color: var(--he-ink); }
.site-nav__lang a.is-active { background: var(--he-ink); color: var(--he-white); }
.site-nav__lang a.is-active:hover { color: var(--he-white); }

/* Mobile nav toggle — pure CSS "checkbox hack": the checkbox is invisible,
   its <label> is the visible hamburger button, and :checked reveals the
   links/lang siblings. No JS involved, so there's nothing here that can
   fail on load like a script-driven menu would. */
.site-nav__toggle-input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.site-nav__toggle { display: none; }

/* 860px, not 640: between ~640 and ~830 the full nav no longer fits on one
   line and wraps the language toggle onto a second row. Collapsing to the
   menu button across that whole band avoids the wrap. */
@media (max-width: 860px) {
  .site-nav__toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border: 1.5px solid var(--he-ink);
    border-radius: var(--radius-pill);
    cursor: pointer;
  }
  .site-nav__toggle span {
    position: relative;
    display: block;
    width: 16px;
    height: 1.5px;
    background: var(--he-ink);
  }
  .site-nav__toggle span::before,
  .site-nav__toggle span::after {
    content: '';
    position: absolute;
    left: 0;
    width: 16px;
    height: 1.5px;
    background: var(--he-ink);
    transition: transform var(--dur-fast) var(--ease-standard);
  }
  .site-nav__toggle span::before { top: -5px; }
  .site-nav__toggle span::after { top: 5px; }
  .site-nav__toggle-input:checked ~ .site-nav__toggle span { background: transparent; }
  .site-nav__toggle-input:checked ~ .site-nav__toggle span::before { top: 0; transform: rotate(45deg); }
  .site-nav__toggle-input:checked ~ .site-nav__toggle span::after { top: 0; transform: rotate(-45deg); }

  .site-nav__links,
  .site-nav__lang {
    display: none;
    width: 100%;
  }
  .site-nav__toggle-input:checked ~ .site-nav__links,
  .site-nav__toggle-input:checked ~ .site-nav__lang {
    display: flex;
  }
  .site-nav__links {
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
  }
  .site-nav__links a { padding: 10px 0; }

  /* The language switch drops its pill too, so every row in the open menu
     reads as the same plain right-aligned text rather than one lone button. */
  .site-nav__lang {
    width: auto;
    margin-left: auto;
    border: none;
    gap: 14px;
    padding: 10px 0;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
  }
  .site-nav__lang a { padding: 0; color: var(--he-ink-soft); }
  .site-nav__lang a.is-active { background: transparent; color: var(--he-orange); }
  .site-nav__lang a.is-active:hover { color: var(--he-orange); }
}

.btn {
  display: inline-block;
  padding: 16px 34px;
  border-radius: var(--radius-pill);
  font-size: 16px;
  text-decoration: none;
  transition: background var(--dur-base) var(--ease-standard), color var(--dur-base) var(--ease-standard), transform var(--dur-fast) var(--ease-standard);
  cursor: pointer;
  border: none;
  font-family: inherit;
}
.btn:active { transform: scale(0.97); }
.btn--filled {
  background: var(--he-ink);
  color: var(--he-white);
  font-weight: 600;
}
.btn--filled:hover { background: var(--he-orange); color: var(--he-white); }
.btn--teal.btn--filled:hover { background: var(--he-teal-deep); }
.btn--outline {
  border: 1.5px solid var(--he-ink);
  color: var(--he-ink);
  font-weight: 500;
  background: transparent;
}
.btn--outline:hover { background: var(--he-ink); color: var(--he-white); }
.btn--teal-fill {
  background: var(--he-teal);
  color: var(--he-white);
  font-weight: 600;
}
.btn--teal-fill:hover { background: var(--he-teal-deep); }
.btn--small { padding: 14px 30px; font-size: 15px; }

.section { border-bottom: 1.5px solid var(--he-ink); }
.section__eyebrow-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 40px 40px 0;
}
.section__eyebrow {
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--he-ink-soft);
}
.section__cta {
  font-size: 14px;
  font-weight: 600;
  color: var(--he-orange);
  text-decoration: none;
}

.section--clients {
  background: #000000;
}
.section--clients .section__eyebrow-row {
  padding-bottom: 24px;
}
.section--clients .section__eyebrow {
  color: var(--he-grey-3);
}

.clients-marquee {
  overflow: hidden;
}
.clients-marquee__track {
  display: flex;
  width: max-content;
}
.clients-marquee__group {
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 28px 14px;
}
/* Duplicate copy for the seamless loop below — hidden by default (and from
   assistive tech) so browsers without prefers-reduced-motion support, or
   users who asked for reduced motion, get one static, centered copy. */
.clients-marquee__group[aria-hidden="true"] { display: none; }
.clients-marquee__tile {
  flex: 0 0 auto;
  width: 170px;
  height: 90px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.clients-marquee__tile img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

@media (prefers-reduced-motion: no-preference) {
  .clients-marquee__group[aria-hidden="true"] { display: flex; }
  .clients-marquee__track { animation: heClientsScroll 32s linear infinite; }
}

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

@media (max-width: 640px) {
  .clients-marquee__group { gap: 18px; padding: 20px 10px; }
  .clients-marquee__tile { width: 120px; height: 64px; }
}

/* ---- Generic two-column page header (left copy, right GeoMotif panel) ---- */
.page-header {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  border-bottom: 1.5px solid var(--he-ink);
}
.page-header__copy {
  padding: 72px 40px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}
.page-header__eyebrow {
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--he-ink-soft);
}
.page-header__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(36px, 6vw, 60px);
  line-height: 0.98;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  max-width: 640px;
}
.page-header__title em {
  font-family: var(--font-serif);
  font-style: italic;
  text-transform: lowercase;
  font-weight: 400;
  color: var(--he-orange);
}
.page-header__lead {
  margin: 0;
  max-width: 480px;
  font-size: 18px;
  line-height: 1.5;
  color: var(--he-ink-soft);
}
.page-header__lead--serif {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 20px;
}
.page-header__panel {
  background: var(--he-grey-light);
  border-left: 1.5px solid var(--he-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 320px;
  padding: 40px;
}

/* ---- CTA band ---- */
.cta {
  background: var(--he-orange);
  color: var(--he-ink);
  padding: 80px 40px;
  position: relative;
  overflow: hidden;
}
.cta--quiet { background: var(--he-grey-light); }
.cta--teal { background: var(--he-teal); }
.cta--ink { background: var(--he-ink); color: var(--he-white); }
.cta__bg {
  position: absolute;
  right: -110px;
  bottom: -150px;
  width: 380px;
  opacity: 0.35;
}
.cta__bg--motif {
  --he-ink: var(--he-white);
  width: auto;
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .cta__bg--motif .geo-motif {
    transform-origin: 50% 50%;
    animation: cta-bg-spin 40s linear infinite;
  }
  @keyframes cta-bg-spin {
    to { transform: rotate(360deg); }
  }
}
.cta__inner {
  display: flex;
  flex-direction: column;
  gap: 26px;
  position: relative;
  max-width: var(--container-max);
  margin: 0 auto;
}
.cta__eyebrow { font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; }
.cta__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(28px, 5vw, 56px);
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  max-width: 860px;
}
.cta__title em {
  font-family: var(--font-serif);
  font-style: italic;
  text-transform: lowercase;
  font-weight: 400;
  color: var(--he-white);
}
.cta--quiet .cta__title em { color: var(--he-orange); }
.cta__body { margin: 0; max-width: 560px; font-size: 16px; line-height: 1.55; }
.cta__actions { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; }
.cta__email {
  display: inline-block;
  padding: 14px 30px;
  border: 1.5px solid currentColor;
  border-radius: var(--radius-pill);
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  color: inherit;
}

/* ---- CTA band, split layout — headline+lead left, embedded form right (merges the old cta + footer-contact pair into one section) ---- */
.cta__inner--split {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(280px, 1fr);
  gap: 40px 56px;
  align-items: center;
}
.cta__inner--split .cta__copy { display: flex; flex-direction: column; gap: 18px; }
.cta__inner--split .contact-embed { justify-self: end; }
@media (max-width: 860px) {
  .cta__inner--split { grid-template-columns: 1fr; }
  .cta__inner--split .contact-embed { justify-self: stretch; }
}

/* ---- Contact form (used in the dedicated Contacto section and the footer) ---- */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 32px;
  background: var(--he-white);
  border: 1.5px solid var(--he-ink);
  border-radius: var(--radius-lg);
}
.contact-form__row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 18px; }
.contact-form__field { display: flex; flex-direction: column; gap: 6px; }
.contact-form__field label { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--he-ink-soft); }
.contact-form__field input,
.contact-form__field textarea {
  font-family: inherit;
  font-size: 15px;
  padding: 12px 14px;
  border: 1.5px solid var(--he-grey);
  border-radius: var(--radius-sm);
  background: var(--he-white);
  color: var(--he-ink);
  resize: vertical;
}
.contact-form__field input:focus,
.contact-form__field textarea:focus {
  outline: none;
  border-color: var(--he-orange);
}
.contact-form__submit { align-self: flex-start; }
.contact-form__note { margin: 0; font-size: 12px; color: var(--he-grey-dark); }

/* ---- Footer contact band — present on every page, just above the bottom bar ---- */
.footer-contact {
  background: var(--he-teal-tint);
  border-top: 1.5px solid var(--he-ink);
  padding: 64px clamp(20px, 5vw, 40px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 32px 48px;
  max-width: var(--container-max);
  margin: 0 auto;
}
.footer-contact__copy { display: flex; flex-direction: column; gap: 14px; max-width: 360px; }
.footer-contact__eyebrow { font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--he-teal-deep); font-weight: 700; }
.footer-contact__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(28px, 5vw, 40px);
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: -0.02em;
}
.footer-contact__title em { font-family: var(--font-serif); font-style: italic; text-transform: lowercase; font-weight: 400; color: var(--he-orange); }
.footer-contact__body { margin: 0; font-size: 15px; line-height: 1.5; color: var(--he-ink-soft); }
.footer-contact__email { font-size: 14px; color: var(--he-ink-soft); }

/* ---- Embedded (Tally) contact form — same ink-bordered card language as the old .contact-form ---- */
.contact-embed {
  max-width: 480px;
  width: 100%;
  background: var(--he-white);
  border: 1.5px solid var(--he-ink);
  border-radius: var(--radius-lg);
  padding: 10px;
  overflow: hidden;
}
.contact-embed iframe {
  display: block;
  width: 100%;
  border: none;
}

/* ---- Footer ---- */
.site-footer {
  background: var(--he-ink);
  color: var(--he-grey-dark);
  padding: 24px 40px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 10px 24px;
  font-size: 13px;
}
.site-footer__logo { height: 16px; width: auto; }
.site-footer a { color: var(--he-grey-dark); text-decoration: none; }
.site-footer a:hover { color: var(--he-orange); }

@media (max-width: 640px) {
  .cta { padding: 56px 24px; }
  .site-footer { justify-content: flex-start; }
  .page-header__copy { padding: 48px 24px; }
  .footer-contact { padding: 48px 24px; }
}

/* Loading skeletons ---------------------------------------------------- */
/* The list and detail regions are rendered client-side from /api, so they
   sit empty between first paint and the fetch resolving. These placeholders
   stand in at the same dimensions as the real content, so the page doesn't
   jump when it lands. Each skeleton is built from the same layout classes
   as the thing it replaces, which is what keeps the two in step. */
.skel {
  display: block;
  background: var(--he-grey-2);
  border-radius: 2px;
}
/* Sized in em so a line tracks the font-size of whatever it stands in for. */
.skel-line { height: 0.7em; }
.skel-line + .skel-line { margin-top: 0.5em; }
.skel-line--sm { height: 0.6em; }
.skel-block { width: 100%; height: 100%; }
/* Real headings size themselves from their text. A heading holding only
   skeleton bars has no text to measure, so as a centred flex item it
   collapses to zero width and the percentage bars inside collapse with it.
   This is on every wrapper that holds skel-lines in place of real copy. */
.skel-fill { width: 100%; }
/* The detail-page hero figures have no intrinsic height until their image
   loads, so the stand-in has to carry its own. */
.skel-hero { height: clamp(220px, 38vw, 480px); }

/* Widths are staggered so a stack of lines reads as prose rather than a
   solid slab — the last line of a paragraph is rarely full width. */
.skel-w-30 { width: 30%; }
.skel-w-40 { width: 40%; }
.skel-w-55 { width: 55%; }
.skel-w-70 { width: 70%; }
.skel-w-85 { width: 85%; }
.skel-w-100 { width: 100%; }

/* Matches the repo's existing treatment of decorative motion: the sweep is
   opt-in, so a static grey block is what anyone with reduced-motion set
   (and any browser that doesn't support the query) actually gets. */
@media (prefers-reduced-motion: no-preference) {
  .skel {
    background-image: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.75) 50%, transparent 100%);
    background-repeat: no-repeat;
    background-size: 200% 100%;
    animation: heSkelShimmer 1.5s ease-in-out infinite;
  }
  @keyframes heSkelShimmer {
    from { background-position: 150% 0; }
    to { background-position: -150% 0; }
  }
}

/* The shapes are decoration; the surrounding container carries role="status"
   and this label so assistive tech hears "Loading…" once rather than
   reading out a pile of empty divs. */
.skel-label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
