/* components.css — reusable UI patterns.
   Sizing convention: rem for typography, spacing, dimensions, and layout —
   1rem = 16px (the browser default, never overridden on <html>). px is kept
   only for values where pixel precision matters: 1–2px borders/hairlines,
   sub-pixel micro-transforms (e.g. translateY(-1px)), the 999px pill idiom
   for fully-rounded corners, and box-shadow blur radii. */

/* Component-layer design tokens. tokens.css holds the brand tokens (colors,
   fonts, type scale) generated from brand-tokens.json. These additional
   tokens are the contract for atomic project-card / project-detail components
   migrated from the old susplify-projects library: a tighter spacing scale
   (--sp-N), per-axis typography (--t-display-*, --t-h1-*, etc.), pixel-precise
   sizes (--size-N), semantic color roles (--fg-*, --surface-*, --hairline,
   --accent), motion (--dur-*, --ease-out), and layout maxes (--layout-card-*,
   --layout-detail-*). Kept here, not in tokens.css, because they are not
   brand-owned and not regenerated from brand-tokens.json. */
:root {
  /* spacing scale (4px base) */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-8: 48px; --sp-10: 64px; --sp-14: 96px;

  /* typography (single body family; each axis addressable) */
  --t-display-size: 56px; --t-display-weight: 500; --t-display-lh: 1.05; --t-display-track: -0.02em;
  --t-h1-size: 32px;      --t-h1-weight: 500;      --t-h1-lh: 1.1;       --t-h1-track: -0.015em;
  --t-h2-size: 40px;      --t-h2-weight: 500;      --t-h2-lh: 1.0;       --t-h2-track: -0.02em;
  --t-h3-size: 24px;      --t-h3-weight: 500;      --t-h3-lh: 1.15;      --t-h3-track: -0.01em;
  --t-body-lg-size: 17px; --t-body-lg-weight: 400; --t-body-lg-lh: 1.55; --t-body-lg-track: 0;
  --t-body-size: 15px;    --t-body-weight: 400;    --t-body-lh: 1.5;     --t-body-track: 0;
  --t-caption-size: 13px; --t-caption-weight: 500; --t-caption-lh: 1.3;  --t-caption-track: 0;
  --t-eyebrow-size: 11px; --t-eyebrow-weight: 500; --t-eyebrow-lh: 1.2;  --t-eyebrow-track: 0.12em;

  /* pixel-precise sizes used by hairlines, dot indicators, and borders */
  --size-1: 1px; --size-2: 2px; --size-3: 3px; --size-4: 4px; --size-6: 6px;
  --size-8: 8px; --size-10: 10px; --size-12: 12px; --size-14: 14px;
  --size-16: 16px; --size-18: 18px; --size-20: 20px; --size-22: 22px;
  --size-24: 24px; --size-28: 28px; --size-32: 32px; --size-36: 36px;
  --size-44: 44px; --size-48: 48px; --size-56: 56px; --size-64: 64px;

  /* semantic color roles (map to brand tokens already in tokens.css) */
  --fg-strong:        var(--color-deep);
  --fg-default:       var(--color-deep);
  --fg-muted:         rgba(26, 58, 82, 0.72);
  --fg-faint:         rgba(26, 58, 82, 0.55);
  --fg-on-dark:       var(--color-sand);
  --fg-on-dark-muted: rgba(245, 240, 232, 0.72);
  --fg-data:          var(--color-forest);
  --accent:           var(--color-amber);
  --surface-page:     var(--color-sand);
  --surface-raised:   rgba(26, 58, 82, 0.03);
  --surface-cta:      var(--color-forest);
  --hairline:         var(--alpha-deep-16);

  /* radius extras (coexist with --radius-sm/md/lg from tokens.css) */
  --radius-sharp: 2px;
  --radius-card-tight: 4px;

  /* motion */
  --dur-fast: 160ms;
  --dur-base: 240ms;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);

  /* layout maxes for portfolio card + project detail */
  --layout-card-width: 980px;
  --layout-card-min-height: 340px;
  --layout-card-image-min: 320px;
  --layout-card-image-min-mobile: 240px;
  --layout-detail-hero-min-h: 520px;
}

/* Buttons ------------------------------------------------------------------ */
.sp-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-xs);
  padding: var(--spacing-sm) var(--spacing-lg);
  border: 1px solid transparent;
  border-radius: var(--radius-button);
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--size-15);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform var(--motion-duration-xs) var(--motion-ease-standard),
              box-shadow var(--motion-duration-xs) var(--motion-ease-standard),
              background-color var(--motion-duration-xs) var(--motion-ease-standard),
              color var(--motion-duration-xs) var(--motion-ease-standard),
              border-color var(--motion-duration-xs) var(--motion-ease-standard);
}
.sp-button:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); }
.sp-button:active:not(:disabled) {
  transform: translateY(0) scale(0.98);
  box-shadow: var(--shadow-sm);
  transition-duration: var(--motion-duration-xs);
  transition-timing-function: var(--motion-ease-accelerate);
}
.sp-button:disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }

.sp-button--amber {
  background: var(--color-white);
  color: var(--color-deep);
  border-color: var(--color-sand);
}
.sp-button--amber:hover { filter: brightness(0.85); }

/* True amber emphasis variant — solid brand amber with deep text. Used where
   we want the CTA to *pop* (hero primary, CTA strip primary). The legacy
   .sp-button--amber above is misnamed and renders white; preserved as-is for
   the contact form, 404 page, and other consumers that already read white. */
.sp-button--solid-amber {
  background: var(--color-amber);
  color: var(--color-deep);
  border-color: var(--color-amber);
}
.sp-button--solid-amber:hover { filter: brightness(0.92); }

.sp-button--outline {
  background: transparent;
  color: var(--color-sand);
  border-color: var(--color-sand);
}
.sp-button--outline:hover {
  background: var(--color-sand);
  color: var(--color-primary);
}

/* Badges & tags ------------------------------------------------------------ */
/* Scoped to the web's own filter tabs + segment pickers so these rules do NOT
   bleed into the <span class="sp-tag"> that susplify-projects emits inside
   cards/details — that one stays styled purely by its inline <style> block. */
.sp-portfolio-filters .sp-tag,
.sp-contact__segments .sp-tag {
  display: inline-flex;
  align-items: center;
  padding: var(--spacing-sm) var(--spacing-md);
  min-height: 2.5rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: var(--color-background);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--size-14);
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--motion-duration-xs) var(--motion-ease-standard),
              color var(--motion-duration-xs) var(--motion-ease-standard),
              border-color var(--motion-duration-xs) var(--motion-ease-standard);
}
@media (max-width: 767px) {
  .sp-portfolio-filters .sp-tag,
  .sp-contact__segments .sp-tag { min-height: 2.75rem; }
}
.sp-portfolio-filters .sp-tag:hover,
.sp-contact__segments .sp-tag:hover { border-color: var(--color-deep-light); }
/* Active state = amber accent keeps brand spark alive (VIS-023). */
.sp-portfolio-filters .sp-tag.is-active,
.sp-contact__segments .sp-tag.is-active {
  background: var(--color-amber);
  color: var(--color-deep);
  border-color: var(--color-amber);
  font-weight: var(--weight-medium);
}

/* Hero metric ------------------------------------------------------------- */
/* Scoped to .sp-hero__metrics so these rules only touch the hero tiles. The
   .sp-metric elements emitted inside susplify-projects cards/details keep
   their own inline <style> and are NOT overridden from the web.
   Pill/glass styling removed per the new hero spec — metrics render as a
   3-column row separated by thin vertical dividers (rendered via ::before). */
.sp-hero__metrics .sp-metric {
  flex: 1 1 0;
  min-width: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0;
  background: transparent;
  border-radius: 0;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.sp-hero__metrics .sp-metric + .sp-metric::before {
  content: "";
  position: absolute;
  left: -0.75rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1px;
  height: 2rem;
  background: rgba(245, 240, 232, 0.4);
  pointer-events: none;
}
.sp-hero__metrics .sp-metric__value {
  display: inline-flex;
  align-items: baseline;
  gap: 0.25rem;
  font-family: var(--font-display);
  color: var(--sp-metric-value-color, var(--color-sand));
  line-height: 1.1;
}
.sp-hero__metrics .sp-metric__number {
  font-size: var(--sp-metric-value-size, 2.5rem);
  font-weight: 700;
  line-height: 1.1;
}
.sp-hero__metrics .sp-metric__unit {
  font-size: 0.6em;
  font-weight: var(--weight-medium);
  color: inherit;
}
.sp-hero__metrics .sp-metric__label {
  font-family: var(--font-body);
  font-size: var(--sp-metric-label-size, 1rem);
  font-weight: var(--weight-medium);
  color: var(--sp-metric-label-color, var(--color-sand));
  opacity: 0.8;
  margin-top: 0.5rem;
}
@media (min-width: 768px) {
  .sp-hero__metrics .sp-metric + .sp-metric::before { left: -1.5rem; }
}
@media (max-width: 767px) {
  .sp-hero__metrics .sp-metric__number { font-size: clamp(1.5rem, 6vw, 2.25rem); }
  .sp-hero__metrics .sp-metric__label { font-size: clamp(0.625rem, 2.5vw, 0.6875rem); }
  .sp-hero__metrics .sp-metric + .sp-metric::before { left: -0.5rem; }
}
@media (max-width: 360px) {
  .sp-hero__metrics .sp-metric + .sp-metric::before { left: -0.375rem; height: 1.5rem; }
}

/* Service card ------------------------------------------------------------- */
.sp-card-service {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
  padding: var(--spacing-lg);
  background: var(--color-background);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  color: var(--color-text);
  transition: transform var(--motion-duration-sm) var(--motion-ease-standard),
              box-shadow var(--motion-duration-sm) var(--motion-ease-standard);
}
.sp-card-service:hover,
.sp-card-service:focus-within {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}
.sp-card-service__icon {
  width: var(--size-32);
  height: var(--size-32);
  color: var(--color-deep);
}
.sp-card-service__title {
  font-family: var(--font-display);
  font-size: var(--size-24);
  font-weight: var(--weight-regular);
  color: var(--color-deep);
  margin: 0;
}
.sp-card-service__desc {
  flex: 1;
  font-family: var(--font-body);
  font-size: var(--size-15);
  color: var(--color-text-muted);
  margin: 0;
}

/* Partner logo ------------------------------------------------------------- */
.sp-partner-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-sm) var(--spacing-md);
  min-height: var(--size-64);
  background: transparent;
}
.sp-partner-logo img {
  max-width: 100%;
  max-height: var(--size-48);
  height: auto;
  width: auto;
  object-fit: contain;
}
.sp-partner-logo__name {
  font-family: var(--font-body);
  font-size: var(--size-14);
  color: var(--color-text-muted);
}

/* FAQ — card grid modelled on .sp-card-service (see components.css:236). Section
   bg flips between sand and white via the .sp-faqs--white modifier driven by
   the Jinja _faqs_white flag in templates/index.html. */
.sp-faqs--white {
  background: var(--color-white);
}
.sp-faqs__lede {
  margin: var(--spacing-sm) auto 0;
  max-width: 56ch;
  text-align: center;
  font-family: var(--font-body);
  font-size: var(--size-16);
  line-height: 1.5;
  color: var(--color-text-muted);
}

.sp-faqs__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--spacing-md);
  margin-top: var(--spacing-lg);
}

.sp-faq-card {
  display: block;
  background: var(--color-background);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  color: var(--color-text);
  overflow: hidden;
  transition: transform   var(--motion-duration-sm) var(--motion-ease-standard),
              box-shadow  var(--motion-duration-sm) var(--motion-ease-standard);
}
.sp-faq-card:hover,
.sp-faq-card:focus-within {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}
.sp-faq-card[open] {
  box-shadow: inset 3px 0 0 0 var(--color-amber), var(--shadow-md);
}
.sp-faq-card__question {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--spacing-md);
  padding: var(--spacing-lg);
  font-family: var(--font-body);
  font-size: var(--size-16);
  font-weight: var(--weight-medium);
  line-height: 1.4;
  color: var(--color-deep);
}
.sp-faq-card__question::-webkit-details-marker { display: none; }
.sp-faq-card__question::after {
  content: "+";
  flex-shrink: 0;
  font-family: var(--font-display);
  font-size: var(--size-24);
  line-height: 1;
  color: var(--color-deep);
  transition: color var(--motion-duration-sm) var(--motion-ease-standard);
}
.sp-faq-card[open] > .sp-faq-card__question::after {
  content: "−";
  color: var(--color-amber);
}
.sp-faq-card__question:focus-visible {
  outline: 2px solid var(--color-amber);
  outline-offset: -4px;
  border-radius: var(--radius-card);
}
.sp-faq-card__answer {
  padding: 0 var(--spacing-lg) var(--spacing-lg);
  color: var(--color-text-muted);
}
.sp-faq-card__answer p {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--size-15);
  line-height: 1.6;
}

@media (min-width: 64rem) {
  .sp-faqs__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--spacing-lg);
  }
}

/* Team card ---------------------------------------------------------------- */
.sp-team-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--spacing-sm);
  padding: var(--spacing-lg);
  background: var(--color-background);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  transition: transform var(--motion-duration-sm) var(--motion-ease-standard),
              box-shadow var(--motion-duration-sm) var(--motion-ease-standard);
}
.sp-team-card:hover,
.sp-team-card:focus-within {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}
.sp-team-card__photo {
  width: var(--size-80);
  height: var(--size-80);
  border-radius: 50%;
  object-fit: cover;
}
.sp-team-avatar {
  width: var(--size-80);
  height: var(--size-80);
  border-radius: 50%;
  background: var(--color-deep);
  color: var(--color-sand);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: var(--size-32);
}
.sp-team-card__name {
  font-family: var(--font-display);
  font-size: var(--size-20);
  font-weight: var(--weight-regular);
  color: var(--color-deep);
  margin: 0;
}
.sp-team-card__role {
  font-family: var(--font-body);
  font-size: var(--size-13);
  color: var(--color-text-muted);
  margin: 0;
}
.sp-team-card__bio {
  font-family: var(--font-body);
  font-size: var(--size-15);
  color: var(--color-text);
  margin: 0;
}
.sp-team-card__linkedin {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-xs);
  font-family: var(--font-body);
  font-size: var(--size-14);
  font-weight: var(--weight-medium);
  color: var(--color-deep);
  text-decoration: none;
  transition: opacity var(--motion-duration-xs) var(--motion-ease-standard);
}
.sp-team-card__linkedin:hover { opacity: 0.7; color: var(--color-deep-light); }

/* Team carousel — each slide hosts a single card; cap its width so a lone
   member doesn't stretch edge-to-edge when perPage is 1. */
.sp-team-slide .sp-team-card {
  max-width: 35rem;
  margin: 0 auto;
}

/* Form fields -------------------------------------------------------------- */
.sp-form[hidden] { display: none !important; }
.sp-form {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
  max-width: 40rem;
}
.sp-form-field {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
}
/* Honeypot anti-spam field. Off-screen and excluded from the tab order so
   real users never see or focus it; bots that auto-fill named fields will
   populate it, and send.php silently drops those submissions. */
.sp-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.sp-form-label {
  font-family: var(--font-body);
  font-size: var(--size-15);
  color: var(--color-deep);
  font-weight: var(--weight-medium);
}
.sp-form-field input,
.sp-form-field textarea,
.sp-form-field select {
  font-family: var(--font-body);
  font-size: var(--size-15);
  color: var(--color-text);
  padding: var(--spacing-sm);
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-button);
  transition: box-shadow var(--motion-duration-xs) var(--motion-ease-standard),
              border-color var(--motion-duration-xs) var(--motion-ease-standard);
}
.sp-form-field input:focus-visible,
.sp-form-field textarea:focus-visible,
.sp-form-field select:focus-visible {
  outline: none;
  border-color: var(--color-deep);
  box-shadow: 0 0 0 2px var(--color-deep);
}
.sp-form-field input[aria-invalid="true"],
.sp-form-field textarea[aria-invalid="true"],
.sp-form-field select[aria-invalid="true"] {
  border-color: var(--color-error, #b00020);
}
.sp-form-field input[aria-invalid="true"]:focus-visible,
.sp-form-field textarea[aria-invalid="true"]:focus-visible,
.sp-form-field select[aria-invalid="true"]:focus-visible {
  box-shadow: 0 0 0 2px var(--color-error, #b00020);
}
.sp-form-error {
  font-family: var(--font-body);
  font-size: 0.8125rem;
  color: var(--color-error, #b00020);
}
.sp-form__status {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  color: var(--color-text);
}
.sp-form__status[data-status="error"] { color: var(--color-error, #b00020); }
.sp-form__status[data-status="success"] { color: var(--color-deep); }

/* Portfolio card + grid pagination + modal -------------------------------- */
/* The grid lives in #sp-portfolio-grid. Each <li> contains the library's
   <a class="sp-card" href="/proyectos/<id>/"> directly — no wrapping
   button (<a> inside <button> is invalid HTML and the inner anchor would
   intercept the click). Default click is intercepted by JS and opens the
   modal; modifier-clicks (Cmd/Ctrl/middle) navigate to the per-project page
   so right-click → open in new tab keeps working. */

/* Focus ring on the card anchor — emitted by the library, so we scope the
   override under .sp-portfolio-item to avoid bleeding into the rendered
   pages the library can produce on its own. */
.sp-portfolio-item .sp-card:focus-visible {
  outline: 2px solid var(--color-amber);
  outline-offset: 3px;
}

/* Pagination row — sits below the grid; counter centered between two
   circular chip buttons that mirror the previous Splide arrow visuals. */
.sp-portfolio-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-md);
  margin-top: 2rem;
}
.sp-portfolio-pagination__btn {
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: var(--color-sand);
  border: 1px solid var(--color-border);
  color: var(--color-deep);
  font-size: 1.125rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color var(--motion-duration-xs) var(--motion-ease-standard),
              opacity var(--motion-duration-xs) var(--motion-ease-standard);
}
.sp-portfolio-pagination__btn:hover:not(:disabled) { background: var(--alpha-deep-04); }
.sp-portfolio-pagination__btn:focus-visible {
  outline: 2px solid var(--color-amber);
  outline-offset: 3px;
}
.sp-portfolio-pagination__btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.sp-portfolio-pagination__counter {
  font-family: var(--font-body);
  font-size: var(--size-15);
  font-weight: var(--weight-medium);
  color: var(--color-text);
  min-width: 4rem;
  text-align: center;
  letter-spacing: 0.04em;
}

/* Modal dialog — native <dialog>. ::backdrop handles the dim + blur; the
   .sp-portfolio-modal element is the centered surface. body.is-modal-open
   is a defense-in-depth scroll lock atop the browser's default modal behavior.
   Width is near-fullscreen (96vw) so the library detail's grid/flex content
   has room to breathe; the previous narrower modal made multi-column sections
   wrap into a long markdown-like column. */
.sp-portfolio-modal {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: 96vw;
  width: 96vw;
  max-height: 92vh;
  color: var(--color-text);
}
.sp-portfolio-modal::backdrop {
  background: rgba(20, 20, 19, 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.sp-portfolio-modal__inner {
  position: relative;
  background: var(--color-background);
  border-radius: var(--radius-card);
  max-height: 92vh;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
/* Header row — sticks to the top of the modal, hosts the close button
   (the "Ver página completa" CTA is overlaid on the project hero by
   project-detail.html when context='modal'). Sits outside the scrollable
   body so the close control stays reachable while the user reads. */
.sp-portfolio-modal__header {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--spacing-md);
  padding: var(--spacing-md) var(--spacing-lg);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-background);
  flex-shrink: 0;
}
.sp-portfolio-modal__close {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--color-sand);
  border: 1px solid var(--color-border);
  color: var(--color-deep);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background-color var(--motion-duration-xs) var(--motion-ease-standard);
}
.sp-portfolio-modal__close:hover { background: var(--alpha-deep-04); }
.sp-portfolio-modal__close:focus-visible {
  outline: 2px solid var(--color-amber);
  outline-offset: 3px;
}
/* Body — only this region scrolls. Padding sits inside so the header's
   bottom border lines up edge to edge. */
.sp-portfolio-modal__body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: var(--spacing-lg);
}
.sp-portfolio-modal__slot[hidden] { display: none !important; }

body.is-modal-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .sp-portfolio-item__card-button,
  .sp-project-hero__view-full { transition: none; }
  .sp-portfolio-item__card-button:hover,
  .sp-project-hero__view-full:hover { transform: none; }
}

/* Portfolio empty state --------------------------------------------------- */
.sp-portfolio-empty {
  padding: var(--spacing-xl) var(--spacing-md);
  text-align: center;
  color: var(--color-text-muted);
  font-family: var(--font-body);
}

/* Nav hamburger ------------------------------------------------------------ */
.sp-nav__hamburger {
  background: transparent;
  border: 0;
  padding: var(--spacing-xs);
  display: inline-flex;
  flex-direction: column;
  gap: 0.25rem;
  cursor: pointer;
}
.sp-nav__hamburger span {
  display: block;
  width: 1.5rem;
  height: 2px;
  background: var(--color-sand);
  border-radius: var(--radius-sm);
  transform-origin: center;
  transition: transform var(--motion-duration-sm) var(--motion-ease-standard),
              opacity var(--motion-duration-xs) var(--motion-ease-standard);
}
/* Hamburger → X morph when the drawer is open. The middle bar fades; the top
   and bottom rotate ±45° and translate to meet at the center. The 6px y-shift
   cancels the 4px gap (var(--spacing) scale: gap=4, bar height=2). */
body[data-nav-open] .sp-nav__hamburger span:nth-child(1) {
  transform: translateY(0.375rem) rotate(45deg);
}
body[data-nav-open] .sp-nav__hamburger span:nth-child(2) {
  opacity: 0;
}
body[data-nav-open] .sp-nav__hamburger span:nth-child(3) {
  transform: translateY(-0.375rem) rotate(-45deg);
}

/* Language toggle ---------------------------------------------------------- */
.sp-lang-toggle {
  display: inline-flex;
  gap: 0.125rem;
  border-radius: var(--radius-full);
  padding: var(--spacing-xs);
  background: var(--alpha-sand-10);
  border: 1px solid var(--alpha-sand-20);
}
.sp-lang-toggle__btn {
  background: transparent;
  color: var(--color-sand);
  border: none;
  border-radius: var(--radius-full);
  padding: var(--spacing-xs) var(--spacing-sm);
  font-family: var(--font-body);
  font-size: var(--size-12);
  font-weight: var(--weight-medium);
  letter-spacing: 0.08em;
  cursor: pointer;
  transition: background-color var(--motion-duration-xs) var(--motion-ease-standard),
              color var(--motion-duration-xs) var(--motion-ease-standard);
}
.sp-lang-toggle__btn.is-active {
  background: var(--color-amber);
  color: var(--color-deep);
}
.sp-lang-toggle__btn:hover:not(.is-active) {
  background: var(--alpha-sand-20);
}

/* Nav link hover uses Deep Light so the token earns its keep (VIS-022). */
.sp-nav__links a:hover,
.sp-nav__links a:focus-visible { opacity: 1; color: var(--color-amber); }
.sp-nav__links a.is-active { color: var(--color-amber); }

/* Initial nav state has the dark --color-deep surface, so the existing
   sand defaults (links, hamburger, lang toggle, outline CTA) already render
   correctly. On `.is-scrolled` the surface flips to --color-sand, so
   foreground controls flip to deep navy. The hamburger lives in the top bar
   at every viewport width and tracks the nav state directly; links / lang
   toggle / outline CTA flip only on desktop where they live in the nav bar
   (on mobile they're inside the always-dark drawer and stay sand). */
.sp-nav.is-scrolled .sp-nav__hamburger span { background: var(--color-deep); }

@media (min-width: 1024px) {
  .sp-nav.is-scrolled .sp-nav__links a { color: var(--color-deep); }
  .sp-nav.is-scrolled .sp-lang-toggle {
    background: var(--alpha-deep-08);
    border-color: var(--alpha-deep-16);
  }
  .sp-nav.is-scrolled .sp-lang-toggle__btn { color: var(--color-deep); }
  .sp-nav.is-scrolled .sp-nav__cta.sp-button--outline {
    color: var(--color-deep);
    border-color: var(--color-deep);
  }
  .sp-nav.is-scrolled .sp-nav__cta.sp-button--outline:hover {
    background: var(--color-deep);
    color: var(--color-sand);
  }
}

/* Splide overrides -------------------------------------------------------- */
/* Library defaults leak near-black (rgb(20,20,19)) and default gray into
   pagination bullets and arrows. Re-skin with brand tokens. */
.splide__arrow {
  background: var(--alpha-deep-08);
  color: var(--color-deep);
  opacity: 0.85;
}
.splide__arrow:hover:not(:disabled) {
  background: var(--alpha-deep-16);
  opacity: 1;
}
.splide__arrow svg { fill: currentColor; }
.splide__pagination__page {
  background: var(--alpha-deep-16);
  opacity: 1;
}
.splide__pagination__page.is-active {
  background: var(--color-amber);
  transform: scale(1.2);
}

/* Footer social — icon-only row (VIS-024) ---------------------------------- */
.sp-footer__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--size-36);
  height: var(--size-36);
  border-radius: var(--radius-full);
  color: var(--color-text-inverse);
  transition: color var(--motion-duration-xs) var(--motion-ease-standard),
              background-color var(--motion-duration-xs) var(--motion-ease-standard);
}
.sp-footer__social a:hover {
  color: var(--color-amber);
  background: var(--alpha-sand-10);
}
.sp-footer__social .sp-social__label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.sp-footer__social svg {
  width: var(--size-20);
  height: var(--size-20);
}

/* Forest emphasis --------------------------------------------------------- */
/* Inline keyword highlight used inside headings + body copy. Authors wrap
   meaningful words with <span class="sp-emph"> in strings.{es,en}.json, and
   the template renders those fields via |safe (server-side) and innerHTML
   (lang.js swap). Forest is otherwise unused in the system — this is its
   single, editorial role. */
.sp-emph {
  color: var(--color-forest);
  font-weight: var(--weight-medium);
}

/* About pillars — Mision / Vision / Testimonios ---------------------------- */
/* Three-card grid inside Nosotros. Cards emulate .sp-card-service: white
   background, card radius, small shadow, hover lift. Left-aligned content
   for a clean reading rhythm; the Testimonios card houses an auto-scrolling
   quote carousel. */
.sp-about-pillars {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--spacing-lg);
  max-width: var(--sp-content-max);
  margin: 0 auto;
}
@media (min-width: 768px) {
  .sp-about-pillars { grid-template-columns: repeat(3, 1fr); }
}

.sp-pillar {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--spacing-sm);
  padding: var(--spacing-lg);
  background: var(--color-background);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  color: var(--color-text);
  transition: transform var(--motion-duration-sm) var(--motion-ease-standard),
              box-shadow var(--motion-duration-sm) var(--motion-ease-standard);
}
.sp-pillar:hover,
.sp-pillar:focus-within {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}
.sp-pillar__icon {
  width: var(--size-32);
  height: var(--size-32);
  color: var(--color-deep);
}
/* Pillar title mirrors .sp-card-service__title exactly: display font,
   size-24, weight-regular, deep. Matches the "Qué hacemos" card hierarchy
   so Misión/Visión/Lo-que-dicen read at the same visual weight. */
.sp-pillar__title {
  font-family: var(--font-display);
  font-size: var(--size-24);
  font-weight: var(--weight-regular);
  color: var(--color-deep);
  margin: 0;
}
/* Body mirrors .sp-card-service__desc. */
.sp-pillar__body {
  flex: 1;
  font-family: var(--font-body);
  font-size: var(--size-15);
  color: var(--color-text-muted);
  margin: 0;
}

/* Testimonios pillar — same card chrome, but hosts a quote carousel. The
   carousel autoplays slowly and has no manual controls. The custom flex
   stack lives on .sp-testimonio-content (not .splide__slide directly) so
   Splide's own slide sizing/visibility logic is left alone. */
.sp-pillar--testimonios .sp-testimonios-carousel {
  width: 100%;
  margin-top: var(--spacing-xs);
}
.sp-testimonio-content {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}
/* Testimonial quote adopts the same body style as pillar + service card:
   body font, size-15, muted. Only difference vs Misión/Visión body: the
   text rotates via the Splide autoplay inside this card. */
.sp-testimonio-quote {
  font-family: var(--font-body);
  font-size: var(--size-15);
  color: var(--color-text-muted);
  margin: 0;
  flex: 1;
}
.sp-testimonio-attrib {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-sm);
  margin-top: auto;
}
.sp-testimonio-logo {
  max-height: var(--size-22);
  max-width: var(--size-56);
  width: auto;
  height: auto;
  object-fit: contain;
  opacity: 0.7;
  filter: grayscale(100%);
}
.sp-testimonio-name {
  font-family: var(--font-body);
  font-size: var(--size-13);
  font-weight: var(--weight-medium);
  color: var(--color-text-muted);
  letter-spacing: 0.04em;
}
/* Autoplay-only carousel: arrows and pagination are hidden at the config
   level, but defend here too in case a breakpoint override enables them. */
.sp-testimonios-carousel .splide__arrows,
.sp-testimonios-carousel .splide__pagination { display: none; }

/* ========================================================================== */
/* Project portfolio card                                                     */
/* Migrated from the susplify-projects library so card rendering happens in   */
/* this repo via templates/_partials/project-card.html.                       */
/* ========================================================================== */
/* Full-bleed photo card with peek-on-hover. The whole <a> is the click target.
   Layers (back to front): .sp-card__media (absolute photo, blurred + dim by
   default), .sp-card__grid-badge (top-left, z-index 3, stays during peek),
   .sp-card__overlay (gradient scrim + content, fades to 0 on hover/focus). */
.sp-card {
  position: relative;
  display: block;
  aspect-ratio: 4 / 5;
  width: 100%;
  max-width: var(--layout-card-width);
  margin: 0 auto;
  border-radius: var(--radius-card-tight);
  border: var(--size-1) solid var(--hairline);
  background: var(--color-deep);
  overflow: hidden;
  isolation: isolate;
  font-family: var(--font-body);
  color: var(--fg-on-dark);
  text-decoration: none;
  transition: transform var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.sp-card:focus-visible {
  outline: var(--size-2) solid var(--color-amber);
  outline-offset: var(--size-3);
}

.sp-card__media {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  z-index: 0;
}

.sp-card__overlay {
  position: absolute; inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  z-index: 2;
  transition: opacity var(--dur-base) var(--ease-out);
}
/* Gradient scrim: transparent at top so the photo shows through cleanly,
   ramping up sharply through the text band and going fully solid under the
   footer so the segment tag and title stay legible against any photo. */
.sp-card__overlay::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(
    180deg,
    transparent 0%,
    transparent 20%,
    var(--alpha-deep-12) 35%,
    var(--alpha-deep-50) 55%,
    var(--alpha-deep-75) 72%,
    var(--color-deep) 88%
  );
  z-index: -1;
}
.sp-card__content {
  position: relative;
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.sp-card__grid-badge {
  position: absolute;
  top: var(--sp-3); left: var(--sp-3);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--t-eyebrow-size);
  font-weight: var(--t-eyebrow-weight);
  line-height: var(--t-eyebrow-lh);
  letter-spacing: var(--t-eyebrow-track);
  text-transform: uppercase;
  color: var(--fg-on-dark);
  background: var(--alpha-deep-65);
  padding: var(--size-6) var(--size-10);
  border-radius: var(--radius-sharp);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.sp-card__grid-badge::before {
  content: "";
  width: var(--size-6); height: var(--size-6);
  border-radius: 50%;
  background: var(--color-amber);
}

.sp-card__subline {
  font-size: var(--t-caption-size);
  font-weight: var(--t-caption-weight);
  line-height: var(--t-caption-lh);
  letter-spacing: var(--t-eyebrow-track);
  text-transform: uppercase;
  color: var(--fg-on-dark-muted);
}
.sp-card__title {
  font-family: var(--font-body);
  font-size: var(--t-h1-size);
  font-weight: var(--t-h1-weight);
  line-height: var(--t-h1-lh);
  letter-spacing: var(--t-h1-track);
  color: var(--fg-on-dark);
  margin: 0;
}

.sp-card__metric {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-1);
}
.sp-card__metric-value {
  font-size: var(--t-h3-size);
  font-weight: var(--t-h3-weight);
  line-height: var(--t-h3-lh);
  letter-spacing: var(--t-h3-track);
  color: var(--fg-on-dark);
  font-variant-numeric: tabular-nums;
}
.sp-card__metric-unit {
  font-size: var(--t-caption-size);
  font-weight: var(--t-caption-weight);
  color: var(--fg-on-dark-muted);
}
.sp-card__metric-label {
  font-size: var(--t-eyebrow-size);
  font-weight: var(--t-eyebrow-weight);
  line-height: var(--t-eyebrow-lh);
  letter-spacing: var(--t-eyebrow-track);
  text-transform: uppercase;
  color: var(--fg-on-dark-muted);
  margin-left: var(--sp-2);
}

.sp-card__footer {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
}
.sp-card .sp-tag {
  font-size: var(--t-eyebrow-size);
  font-weight: var(--t-eyebrow-weight);
  line-height: var(--t-eyebrow-lh);
  letter-spacing: var(--t-eyebrow-track);
  text-transform: uppercase;
  padding: var(--size-4) var(--size-10);
  border-radius: var(--radius-sharp);
  background: transparent;
  border: var(--size-1) solid var(--alpha-sand-30);
  color: var(--fg-on-dark);
}

/* Hover: subtle lift + border deepen. Overlay stays put so the card reads
   consistently whether or not the user is hovering. */
@media (hover: hover) {
  .sp-card:hover {
    transform: translateY(-2px);
    border-color: var(--alpha-deep-50);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sp-card { transition: none; }
  .sp-card:hover { transform: none; }
}

/* Skeleton when an <img> errors or its source is missing. The img removes
   itself on error and adds .sp-card--missing on the card root, leaving the
   deep background plus a soft diagonal shimmer in place of the photo. */
.sp-card--missing::after {
  content: "";
  position: absolute; inset: 0;
  z-index: 1;
  background: linear-gradient(135deg, transparent 30%, var(--alpha-sand-10) 50%, transparent 70%);
}

/* Coverage progress bar — used by templates/_partials/project-detail.html on
   the modal/per-project page (not the home card). Kept here so the detail
   view still picks up the same component styling. */
.sp-cov__head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3); }
.sp-cov__eyebrow {
  font-size: var(--t-eyebrow-size);
  font-weight: var(--t-eyebrow-weight);
  line-height: var(--t-eyebrow-lh);
  letter-spacing: var(--t-eyebrow-track);
  text-transform: uppercase;
  color: var(--fg-faint);
}
.sp-cov__label {
  font-size: var(--t-caption-size);
  font-weight: var(--t-caption-weight);
  color: var(--fg-data);
  white-space: nowrap;
}
.sp-cov__track {
  flex: none;
  height: var(--size-12);
  background: var(--hairline);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.sp-cov__track--lg { height: var(--size-16); }
.sp-cov__track--inline {
  height: var(--size-6);
  margin-top: var(--sp-2);
  width: 100%;
}
.sp-cov__fill {
  height: 100%;
  border-radius: var(--radius-full);
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--color-forest) 88%, black) 0%,
    var(--color-forest) 38%,
    color-mix(in srgb, var(--color-forest) 70%, white) 100%
  );
}
@keyframes sp-cov-fill { from { width: 0; } }
.sp-cov__fill { animation: sp-cov-fill 700ms var(--ease-out) both; }
@media print { .sp-cov__fill { animation: none; } }
@media (prefers-reduced-motion: reduce) { .sp-cov__fill { animation: none; } }

/* ========================================================================== */
/* Project detail — atomic components (fact pill, large metric, spec row,     */
/* coverage suffix, story block, gallery cell). Page-level layout for the     */
/* sections that wrap these lives in layout.css.                              */
/* ========================================================================== */
.sp-fact-pill {
  display: inline-flex;
  flex-direction: column;
  gap: var(--size-2);
  padding: var(--size-8) var(--size-14);
  border: var(--size-1) solid var(--alpha-sand-32);
  border-radius: var(--radius-sharp);
  background: var(--alpha-sand-50);
  color: var(--color-deep);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.sp-fact-pill__label {
  font-size: var(--t-eyebrow-size);
  font-weight: var(--t-eyebrow-weight);
  letter-spacing: var(--t-eyebrow-track);
  text-transform: uppercase;
  color: var(--alpha-deep-65);
}
.sp-fact-pill__value {
  font-size: var(--t-body-size);
  font-weight: var(--t-caption-weight);
  color: var(--color-deep);
}

.sp-section-label {
  display: block;
  font-size: var(--t-eyebrow-size);
  font-weight: var(--t-eyebrow-weight);
  line-height: var(--t-eyebrow-lh);
  letter-spacing: var(--t-eyebrow-track);
  text-transform: uppercase;
  color: var(--fg-muted);
  margin-bottom: var(--sp-4);
}

.sp-metric-lg {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  background-image: linear-gradient(
    to bottom,
    transparent 0%,
    var(--alpha-deep-16) 18%,
    var(--alpha-deep-16) 82%,
    transparent 100%
  );
  background-size: var(--size-1) 100%;
  background-repeat: no-repeat;
  background-position: left center;
  padding-left: var(--sp-5);
}
.sp-metric-lg:first-child,
.sp-metrics-grid[data-count="1"] .sp-metric-lg {
  background-image: none;
  padding-left: 0;
}
.sp-metric-lg__top { display: flex; align-items: baseline; gap: var(--sp-2); }
.sp-metric-lg__value {
  font-size: var(--t-h2-size);
  font-weight: var(--t-h2-weight);
  line-height: var(--t-h2-lh);
  letter-spacing: var(--t-h2-track);
  color: var(--fg-data);
  font-variant-numeric: tabular-nums;
}
.sp-metric-lg__unit {
  font-size: var(--t-body-size);
  font-weight: var(--t-body-weight);
  color: var(--fg-muted);
}
.sp-metric-lg__label {
  font-size: var(--t-eyebrow-size);
  font-weight: var(--t-eyebrow-weight);
  letter-spacing: var(--t-eyebrow-track);
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-top: var(--sp-3);
}

.sp-coverage__copy {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  margin-bottom: var(--sp-5);
}
.sp-coverage__pct {
  font-family: var(--font-body);
  font-size: var(--t-display-size);
  font-weight: var(--t-display-weight);
  line-height: var(--t-display-lh);
  letter-spacing: var(--t-display-track);
  color: var(--fg-data);
  font-variant-numeric: tabular-nums;
}
.sp-coverage__suffix {
  font-size: var(--t-body-lg-size);
  color: var(--fg-muted);
}

.sp-story-block {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding-top: var(--sp-4);
  border-top: var(--size-1) solid var(--hairline);
}
.sp-story-block__num {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--t-eyebrow-size);
  font-weight: var(--t-eyebrow-weight);
  letter-spacing: var(--t-eyebrow-track);
  text-transform: uppercase;
  color: var(--fg-faint);
}
.sp-story-block__sep { color: var(--accent); }
.sp-story-block__label { color: var(--fg-muted); }
.sp-story-block__p {
  font-size: var(--t-body-lg-size);
  line-height: var(--t-body-lg-lh);
  color: var(--fg-default);
  margin: 0;
}
/* Aliados (partner) names highlighted inline within the story block — bold +
   brand deep so the company names visually pop out of the surrounding copy. */
.sp-partner-name {
  font-weight: var(--weight-bold, 700);
  color: var(--color-deep);
}

.sp-spec-row {
  display: grid;
  grid-template-columns: minmax(180px, 30%) 1fr;
  align-items: baseline;
  gap: var(--sp-4);
  padding: var(--sp-3) 0;
  border-bottom: var(--size-1) solid var(--hairline);
}
.sp-spec-row__k {
  font-size: var(--t-eyebrow-size);
  font-weight: var(--t-eyebrow-weight);
  letter-spacing: var(--t-eyebrow-track);
  text-transform: uppercase;
  color: var(--fg-faint);
  margin: 0;
}
.sp-spec-row__v {
  font-size: var(--t-body-size);
  color: var(--fg-strong);
  margin: 0;
}

.sp-gallery-cell {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.sp-gallery-cell.is-feat { grid-column: span 2; }
.sp-gallery-cell__ph {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-card-tight);
  overflow: hidden;
  background: var(--color-deep);
}
.sp-gallery-cell.tone-deep   .sp-gallery-cell__ph { background: var(--color-deep); }
.sp-gallery-cell.tone-sand   .sp-gallery-cell__ph { background: var(--color-sand); }
.sp-gallery-cell.tone-amber  .sp-gallery-cell__ph { background: var(--color-amber); }
.sp-gallery-cell.tone-forest .sp-gallery-cell__ph { background: var(--color-forest); }
.sp-gallery-cell__ph img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  filter: saturate(1.05) contrast(1.02);
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  pointer-events: none;
}
/* Hero cover is rendered as background-image so right-click → save image is
   already off the table; reinforce with the same selection/touch-callout
   posture in case any future change introduces an <img> here. */
.sp-project-hero__bg {
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}
/* Image fallback when src 404s or is missing — keeps the dark tile visible
   as a skeleton instead of a layout-shifting blank. */
.sp-gallery-cell__ph--missing { background: var(--color-deep); }
.sp-gallery-cell__ph--missing::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(135deg, transparent 30%, var(--alpha-sand-16) 50%, transparent 70%);
}

/* ========================================================================== */
/* "Ver página completa" CTA — overlaid bottom-right on the project hero      */
/* by templates/_partials/project-detail.html when context='modal'. Mirrors  */
/* the close button's spacing scale; arrow lives in ::after so lang.js can    */
/* swap textContent without losing the chrome.                                 */
/* ========================================================================== */
.sp-project-hero__view-full {
  position: absolute;
  bottom: var(--spacing-md, 1rem);
  right: var(--spacing-md, 1rem);
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-xs);
  padding: 0.625rem 1.25rem;
  background: var(--color-amber);
  color: var(--color-deep);
  border: 1px solid var(--color-amber);
  border-radius: var(--radius-button);
  font-family: var(--font-body);
  font-size: var(--size-14);
  font-weight: var(--weight-medium);
  text-decoration: none;
  cursor: pointer;
  transition: filter var(--motion-duration-xs) var(--motion-ease-standard),
              transform var(--motion-duration-xs) var(--motion-ease-standard);
}
.sp-project-hero__view-full:hover {
  filter: brightness(0.92);
  transform: translateY(-1px);
}
.sp-project-hero__view-full:focus-visible {
  outline: 2px solid var(--color-amber);
  outline-offset: 3px;
}
.sp-project-hero__view-full::after {
  content: " \2192";
  display: inline-block;
  margin-left: var(--sp-1, 4px);
  transition: transform var(--dur-fast) var(--ease-out);
}
.sp-project-hero__view-full:hover::after { transform: translateX(2px); }
@media (max-width: 639px) {
  .sp-project-hero__view-full {
    bottom: var(--spacing-sm, 0.75rem);
    right: var(--spacing-sm, 0.75rem);
    padding: 0.5rem 1rem;
    font-size: var(--size-13, 0.8125rem);
  }
}

/* ========================================================================== */
/* Contact form card + side panel ("¿Qué pasa después?")                      */
/* Brand identity: white surface elevated above the sand page background,     */
/* susplify amber accent on the step number badge.                            */
/* ========================================================================== */
.sp-contact-card {
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: clamp(1.5rem, 3vw, 2.5rem);
}
.sp-contact-card .sp-form { max-width: none; }

.sp-contact-side {
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: clamp(1.5rem, 3vw, 2.5rem);
  position: sticky;
  top: calc(var(--sp-nav-height-mobile) + var(--spacing-md));
}
@media (min-width: 1024px) {
  .sp-contact-side { top: calc(var(--sp-nav-height) + var(--spacing-md)); }
}
@media (max-width: 1023px) {
  .sp-contact-side { position: static; }
}

.sp-contact-side__head { display: flex; flex-direction: column; gap: var(--spacing-xs); }
.sp-contact-side__title {
  font-family: var(--font-display);
  font-size: var(--size-24);
  color: var(--color-deep);
  margin: 0;
  line-height: 1.2;
}
.sp-contact-side__lede {
  font-family: var(--font-body);
  font-size: var(--size-15);
  color: var(--color-text-muted);
  margin: 0;
}

.sp-steps {
  list-style: none;
  padding: 0;
  margin: var(--spacing-lg) 0 0;
  display: grid;
  gap: var(--spacing-md);
}
.sp-step {
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr);
  gap: var(--spacing-sm);
  align-items: start;
}
.sp-step__num {
  inline-size: 2.25rem;
  block-size: 2.25rem;
  display: inline-grid;
  place-items: center;
  border-radius: 999px;
  background: var(--color-amber);
  color: var(--color-deep);
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: var(--size-13);
  font-variant-numeric: tabular-nums;
}
.sp-step__body { display: flex; flex-direction: column; gap: 4px; }
.sp-step__title {
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  color: var(--color-deep);
  font-size: var(--size-15);
}
.sp-step__desc {
  font-family: var(--font-body);
  font-size: var(--size-14);
  color: var(--color-text-muted);
  margin: 0;
  line-height: 1.45;
}

.sp-contact-side__divider {
  border: 0;
  border-top: 1px solid var(--color-border);
  margin: var(--spacing-lg) 0;
}

.sp-reassure { display: flex; flex-direction: column; gap: 4px; }
.sp-reassure__title {
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  color: var(--color-deep);
  font-size: var(--size-15);
  margin: 0;
}
.sp-reassure__body {
  font-family: var(--font-body);
  font-size: var(--size-14);
  color: var(--color-text-muted);
  margin: 0;
  line-height: 1.45;
}

.sp-contact-side__fallback {
  margin: var(--spacing-md) 0 0;
  font-family: var(--font-body);
  font-size: var(--size-14);
  color: var(--color-text-muted);
}
.sp-contact-side__fallback a { color: var(--color-deep); }
.sp-contact-side__fallback a:hover { color: var(--color-amber); }

