/* Shared components — see docs/COMPONENTES_FRONTEND_BUENTAJO.md */

/* Header / navigation ------------------------------------------------- */
/* Full-bleed sticky bar whose content still lines up with .container: the
   padding trick (see .bleed in base.css) keeps this a single element, so no
   page's markup needs an extra wrapper for the header to become a real bar. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  padding-left: max(var(--layout-gutter), calc((100% - var(--layout-max)) / 2 + var(--layout-gutter)));
  padding-right: max(var(--layout-gutter), calc((100% - var(--layout-max)) / 2 + var(--layout-gutter)));
  height: var(--header-height);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-line);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-ink);
  text-decoration: none;
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.045em;
}

/* Decorative brand mark: a rounded accent tile before the wordmark. Kept as a
   pseudo-element so it appears on every page without touching 40+ headers,
   and stays invisible to assistive tech (the link already has its own label). */
.brand::before {
  content: "";
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  box-shadow: inset 0 0 0 3px rgba(255, 255, 255, 0.32);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.site-nav a {
  position: relative;
  color: var(--color-ink);
  text-decoration: none;
  font-size: 0.94rem;
  font-weight: 600;
  white-space: nowrap;
}

.site-nav a:not(.nav-cta):hover {
  color: var(--color-accent-dark);
}

/* Current-page indicator, set by js/nav.js. */
.site-nav a[aria-current="page"]:not(.nav-cta) {
  color: var(--color-accent-dark);
}

.site-nav a[aria-current="page"]:not(.nav-cta)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 2px;
  border-radius: 2px;
  background: var(--color-accent);
}

.site-nav .nav-cta {
  background: var(--color-ink);
  color: #fff;
  padding: 10px 18px;
  border-radius: var(--radius-pill);
  transition: background var(--duration-fast) var(--ease-standard);
}

.site-nav .nav-cta:hover {
  background: var(--color-accent-dark);
  color: #fff;
}

.nav-toggle {
  display: none;
  border: 1px solid var(--color-line);
  background: var(--color-white);
  border-radius: var(--radius-sm);
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.nav-toggle svg {
  width: 22px;
  height: 22px;
}

.nav-session {
  font-size: 0.9rem;
  color: var(--color-muted);
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.nav-notifications {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  color: var(--color-ink);
}

.nav-notifications svg {
  width: 20px;
  height: 20px;
}

.notif-badge {
  position: absolute;
  top: -4px;
  right: -6px;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--color-danger);
  color: var(--color-white);
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

.nav-session button {
  background: none;
  border: none;
  color: var(--color-ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  padding: var(--space-2);
}

@media (max-width: 960px) {
  .site-nav {
    gap: var(--space-4);
  }
}

@media (max-width: 860px) {
  .nav-toggle {
    display: inline-flex;
  }

  .site-nav {
    position: fixed;
    inset: var(--header-height) 0 0 0;
    background: var(--color-white);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--space-4);
    overflow-y: auto;
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration-base) var(--ease-standard), transform var(--duration-base) var(--ease-standard);
  }

  .site-nav[data-open="true"] {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }

  .site-nav a {
    padding: var(--space-4) var(--space-2);
    border-bottom: 1px solid var(--color-line);
    font-size: 1.02rem;
  }

  .site-nav a[aria-current="page"]:not(.nav-cta)::after {
    display: none;
  }

  .site-nav .nav-cta {
    text-align: center;
    border-bottom: 0;
    margin-top: var(--space-4);
  }

  .nav-session {
    flex-wrap: wrap;
    padding-top: var(--space-3);
  }
}

/* Buttons --------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  padding: 12px 20px;
  min-height: 44px;
  font: inherit;
  font-weight: 750;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard), transform var(--duration-fast) var(--ease-standard);
}

.btn-primary {
  background: var(--color-accent);
  color: #fff;
}

.btn-primary:hover:not(:disabled) {
  background: var(--color-accent-dark);
}

.btn-secondary {
  background: transparent;
  color: var(--color-ink);
  border: 1px solid var(--color-line);
}

.btn-secondary:hover:not(:disabled) {
  border-color: var(--color-ink);
}

.btn-text {
  background: none;
  color: var(--color-ink);
  text-decoration: underline;
  padding: var(--space-2);
  min-height: auto;
}

/* For CTAs sitting on --color-ink (dark hero band, footer, pro recruiting). */
.btn-inverse {
  background: var(--color-white);
  color: var(--color-ink);
}

.btn-inverse:hover:not(:disabled) {
  background: var(--color-accent-bright);
}

/* Secondary action on a dark band: outline only. */
.btn-ghost {
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.45);
}

.btn-ghost:hover:not(:disabled) {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.1);
}

.btn-lg {
  padding: 15px 26px;
  min-height: 52px;
  font-size: 1.02rem;
}

/* Buttons used as links keep the same box but must not inherit underlines. */
a.btn {
  text-decoration: none;
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Warm commercial CTA. Secondary to .btn-primary by intent, not by weight:
   used where a second action has to be as clickable as the first (the pro
   recruiting band, the "empty directory" invitations). */
.btn-ember {
  background: var(--color-ember);
  color: #fff;
}

.btn-ember:hover:not(:disabled) {
  background: var(--color-ember-dark);
}

/* Press feedback: every button dips 1px while held. Cheap, universal, and
   neutralised by the reduced-motion rule in base.css. */
.btn:active:not(:disabled) {
  transform: translateY(1px);
}

/* Small uppercase kicker above a section title. Shared by every public page. */
.eyebrow {
  margin: 0 0 var(--space-3);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-accent);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 800;
  font-size: var(--font-caption);
}

/* A short accent rule before the kicker, so section heads read as a series
   instead of as loose paragraphs. */
.eyebrow::before {
  content: "";
  width: 22px;
  height: 3px;
  border-radius: 2px;
  background: currentColor;
  flex: none;
}

.eyebrow--ember {
  color: var(--color-ember);
}

.eyebrow--info {
  color: var(--color-info-dark);
}

/* Arrow link — a text-weight call to action. Lives here, not in the home
   page's styles.css, because profesional.html and the informational pages use
   it too (before this pass it rendered unstyled outside the home page). */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--color-accent-dark);
  font-weight: 700;
  text-decoration: none;
}

.link-arrow::after {
  content: "→";
  transition: transform var(--duration-fast) var(--ease-standard);
}

.link-arrow:hover {
  text-decoration: underline;
}

.link-arrow:hover::after {
  transform: translateX(3px);
}

.link-arrow--muted {
  color: var(--color-muted);
}

.link-arrow--ember {
  color: var(--color-ember);
}

/* Tinted icon tile -------------------------------------------------------
   One shape for every "icon in a coloured square" across the public pages
   (trust cards, steps, category tiles, the professional recruiting band).
   The tint is data-driven so a list can rotate colours from JavaScript
   without inventing a class per item. Default (no attribute) is the brand
   green; every pair below clears AA for the icon's 1.75px stroke. */
.icon-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex: none;
  border-radius: 14px;
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
}

.icon-tile svg {
  width: 24px;
  height: 24px;
}

.icon-tile--sm {
  width: 40px;
  height: 40px;
  border-radius: 12px;
}

.icon-tile--sm svg {
  width: 20px;
  height: 20px;
}

.icon-tile--lg {
  width: 60px;
  height: 60px;
  border-radius: 18px;
}

.icon-tile--lg svg {
  width: 30px;
  height: 30px;
}

.icon-tile[data-tint="ember"] {
  background: var(--color-ember-soft);
  color: var(--color-ember);
}

.icon-tile[data-tint="info"] {
  background: var(--color-info-soft);
  color: var(--color-info-dark);
}

.icon-tile[data-tint="neutral"] {
  background: var(--color-neutral-soft);
  color: var(--color-ink);
}

/* Form fields ------------------------------------------------------------ */
.field {
  display: grid;
  gap: 6px;
  color: var(--color-muted);
  font-size: 0.85rem;
  font-weight: 700;
}

.field input,
.field select,
.field textarea {
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  padding: 12px;
  color: var(--color-ink);
  font: inherit;
  background: var(--color-white);
  width: 100%;
}

.field[data-invalid="true"] input,
.field[data-invalid="true"] select,
.field[data-invalid="true"] textarea {
  border-color: var(--color-danger);
}

.field-error {
  color: var(--color-danger);
  font-size: 0.82rem;
  font-weight: 600;
}

/* Alerts (success / danger / warning / info) ----------------------------- */
.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  font-size: 0.9rem;
  font-weight: 600;
}

.alert svg {
  flex: none;
  width: 20px;
  height: 20px;
}

.alert--success {
  background: var(--color-accent-soft);
  color: var(--color-success);
}

.alert--danger {
  background: var(--color-danger-soft);
  color: var(--color-danger);
}

.alert--warning {
  background: var(--color-warning-soft);
  color: var(--color-warning);
}

.alert--info {
  background: var(--color-info-soft);
  color: var(--color-info-dark);
}

.alert:empty {
  display: none;
}

/* Company invitation banner (shown on any page for the invited user) ----- */
.invitation-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  background: var(--color-info-soft);
  color: var(--color-info-dark);
  padding: var(--space-3) 28px;
  font-size: 0.9rem;
  font-weight: 600;
}

.invitation-banner span {
  flex: 1;
  min-width: 200px;
}

/* Professional card -------------------------------------------------------*/
/* One card serves two layouts: the stacked, full-width list on buscar.html
   and the 3-column .results-grid on the SEO landing pages. Everything inside
   wraps, so the component itself needs no variant class; buscar.html's wide
   single-column list re-flows the same markup into two zones from
   css/pages/search.css, without touching this file or the renderer. */
.professional-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  transition: box-shadow var(--duration-base) var(--ease-standard),
    border-color var(--duration-base) var(--ease-standard),
    transform var(--duration-base) var(--ease-standard);
}

/* Accent rule that only draws itself on hover/focus, so a grid of cards is
   calm at rest and unmistakable once one is targeted. */
.professional-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, var(--color-accent), var(--color-accent-bright));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duration-base) var(--ease-standard);
}

.professional-card:hover,
.professional-card:focus-visible {
  box-shadow: var(--shadow-lift);
  border-color: var(--color-line-strong);
  transform: translateY(-3px);
}

.professional-card:hover::before,
.professional-card:focus-visible::before {
  transform: scaleX(1);
}

.professional-card:active {
  transform: translateY(-1px);
}

.professional-card__top {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}

.professional-card__id {
  min-width: 0;
  display: grid;
  gap: 6px;
}

.professional-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.professional-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
}

/* Pinned to the bottom so a row of cards lines its CTAs up even when the
   headline above wraps to a different number of lines. */
.professional-card__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: auto;
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-line);
}

.professional-card__where {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  color: var(--color-muted);
  font-size: var(--font-body-sm);
}

.professional-card__where svg {
  width: 16px;
  height: 16px;
  flex: none;
}

.professional-card__where span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Looks like a button, but the whole card is the single link (accessibility
   note in docs/COMPONENTES_FRONTEND_BUENTAJO.md §2.4) — so this is a span. */
.professional-card__cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
  font-size: var(--font-body-sm);
  font-weight: 700;
}

.professional-card__cta svg {
  width: 15px;
  height: 15px;
}

.professional-card:hover .professional-card__cta,
.professional-card:focus-visible .professional-card__cta {
  background: var(--color-accent);
  color: #fff;
}

/* Distance is the one fact that changes with *where the visitor is*, so it
   gets the warm accent instead of another green pill among green pills. */
.professional-card__distance {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  background: var(--color-ember-soft);
  color: var(--color-ember);
  font-size: 0.78rem;
  font-weight: 700;
}

.professional-card__distance svg {
  width: 12px;
  height: 12px;
}

/* The score reads as a badge, not as running text. */
.professional-card .rating {
  align-self: flex-start;
  padding: 3px 10px 3px 8px;
  border-radius: var(--radius-pill);
  background: var(--color-star-soft);
}

.professional-card .rating--none {
  padding: 0;
  background: none;
}

.professional-card__tags .chip {
  background: var(--color-accent-softer);
  color: var(--color-accent-dark);
  border: 1px solid var(--color-accent-soft);
  font-weight: 650;
  font-size: 0.8rem;
}

.avatar {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: linear-gradient(140deg, var(--color-accent), var(--color-accent-dark));
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: -0.02em;
  flex: none;
  object-fit: cover;
}

.avatar--lg {
  width: 104px;
  height: 104px;
  font-size: 1.9rem;
  box-shadow: 0 0 0 4px var(--color-surface), 0 0 0 5px var(--color-line);
}

.avatar--img {
  object-fit: cover;
}

.avatar--lg.avatar--img {
  width: 104px;
  height: 104px;
}

.professional-card__name {
  margin: 0;
  font-size: 1.12rem;
  font-weight: 750;
  letter-spacing: -0.02em;
  line-height: 1.25;
}

.professional-card__headline {
  margin: 0;
  color: var(--color-muted);
  font-size: 0.92rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Trust badges — always icon + text, never colour alone (Design System §4.2) */
.badge-verified {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
  font-size: 0.75rem;
  font-weight: 700;
}

.badge-verified svg {
  width: 13px;
  height: 13px;
}

.badge-company {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--color-info-soft);
  color: var(--color-info-dark);
  font-size: 0.75rem;
  font-weight: 700;
  border: 1px solid transparent;
  border-radius: var(--radius-pill, 999px);
  padding: 2px 8px;
}

.typeahead-results {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.typeahead-results:not(:empty) {
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  padding: var(--space-2);
  margin-top: 4px;
}

.checkbox-field {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 500;
  cursor: pointer;
}

.checkbox-field input[type="checkbox"] {
  width: 18px;
  height: 18px;
  flex: none;
}

.profile-completion {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-3) 0;
}

.profile-completion__bar {
  flex: 1;
  height: 8px;
  border-radius: var(--radius-pill, 999px);
  background: var(--color-line);
  overflow: hidden;
}

.profile-completion__fill {
  height: 100%;
  background: var(--color-success);
  border-radius: var(--radius-pill, 999px);
  transition: width 0.2s ease;
}

.profile-completion__label {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--color-muted);
  white-space: nowrap;
}

.gallery {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin: var(--space-3) 0;
}

.gallery__item {
  position: relative;
  width: 96px;
  height: 96px;
  border-radius: var(--radius-md, 8px);
  overflow: hidden;
  border: 1px solid var(--color-line);
}

.gallery__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.gallery__item button {
  position: absolute;
  top: 2px;
  right: 2px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  border: none;
  border-radius: 50%;
  width: 22px;
  height: 22px;
  cursor: pointer;
}

.wizard-steps {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  list-style: none;
  padding: 0;
}

.wizard-steps li {
  padding: 4px 12px;
  border-radius: var(--radius-pill, 999px);
  background: var(--color-cream);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-muted);
}

.wizard-steps li[data-active="true"] {
  background: var(--color-accent);
  color: #fff;
}

.wizard-steps li[data-done="true"] {
  background: var(--color-success);
  color: #fff;
}

.chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-2) 0;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--radius-pill, 999px);
  background: var(--color-cream);
  font-size: 0.85rem;
}

.chip button {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-muted);
  font-weight: 700;
  line-height: 1;
}

/* Rating ---------------------------------------------------------------- */
/* The stars are decorative; the numeric value is always present as text and
   the whole block carries an aria-label (Componentes §2.11). */
.rating {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.88rem;
  color: var(--color-muted);
}

.rating strong {
  color: var(--color-ink);
  font-size: 0.98rem;
}

.rating svg {
  width: 15px;
  height: 15px;
  color: var(--color-star);
}

.rating__stars {
  display: inline-flex;
  gap: 1px;
  flex: none;
}

.rating__stars svg {
  color: var(--color-line-strong);
}

.rating__stars svg[data-filled="true"] {
  color: var(--color-star);
}

.rating--none {
  color: var(--color-muted);
  font-style: normal;
}

.rating--lg {
  font-size: 1rem;
}

.rating--lg svg {
  width: 18px;
  height: 18px;
}

.rating--lg strong {
  font-size: 1.25rem;
}

/* Grid of results ----------------------------------------------------------*/
.results-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-5);
}

@media (max-width: 960px) {
  .results-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 700px) {
  .results-grid {
    grid-template-columns: 1fr;
  }
}

/* Empty / loading / error / 404 states -------------------------------------*/
/* Rendered by js/ui-state.js so home, buscar and profesional all fail the
   same way: a real explanation, a suggestion and a way out — never a raw
   technical string on its own. */
.state-block {
  display: grid;
  justify-items: center;
  gap: var(--space-2);
  text-align: center;
  padding: var(--space-8) var(--space-5);
  color: var(--color-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
}

.state-block h2 {
  color: var(--color-ink);
  font-size: var(--font-heading-sm);
  margin: var(--space-3) 0 0;
}

.state-block p {
  margin: 0;
  max-width: 46ch;
}

.state-block__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--color-accent-softer);
  color: var(--color-accent-dark);
}

.state-block__icon svg {
  width: 30px;
  height: 30px;
}

.state-block--error .state-block__icon {
  background: var(--color-danger-soft);
  color: var(--color-danger);
}

/* "Esto existe, pero no en tu plan" — el muro de plan del CRM. Es una
   oferta, no un fallo, así que va en ember y no en rojo. */
.state-block--offer {
  background: linear-gradient(160deg, var(--color-ember-softer) 0%, var(--color-surface) 72%);
  border-color: var(--color-ember-soft);
}

/* "Nothing here yet, and that is expected" — the directory before its first
   professionals are published. Warm rather than apologetic, because it is the
   state most visitors see today. */
.state-block--invite {
  background: linear-gradient(160deg, var(--color-ember-softer) 0%, var(--color-surface) 70%);
  border-color: var(--color-ember-soft);
}

.state-block--invite .state-block__icon {
  background: var(--color-ember-soft);
  color: var(--color-ember);
}

.state-block__bullets {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
  text-align: left;
  font-size: var(--font-body-sm);
}

.state-block__bullets li {
  position: relative;
  padding-left: 26px;
}

.state-block__bullets li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 7px;
  width: 9px;
  height: 9px;
  border-radius: 3px;
  background: var(--color-accent);
}

.state-block--invite .state-block__bullets li::before {
  background: var(--color-ember);
}

.state-block__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

/* Technical cause, kept available but secondary to the human message. */
.state-block__detail {
  font-size: 0.82rem;
  color: var(--color-muted);
  margin-top: var(--space-2);
}

.skeleton-card {
  height: 168px;
  border-radius: var(--radius-md);
  background: linear-gradient(90deg, #eceae1 25%, #f6f4ed 37%, #eceae1 63%);
  background-size: 400% 100%;
  animation: skeleton-shimmer 1.4s ease infinite;
}

.skeleton-card--chip {
  height: 42px;
  width: 132px;
  border-radius: var(--radius-pill);
}

.skeleton-card--tile {
  height: 116px;
}

/* Shaped skeletons: the card outline is real, only the contents shimmer, so
   the placeholder occupies the same silhouette as the card that replaces it. */
.skeleton-card--pro,
.skeleton-card--review {
  height: auto;
  display: grid;
  gap: var(--space-3);
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  animation: none;
}

.skeleton-card--review {
  padding: var(--space-4) 0;
  border: 0;
  border-top: 1px solid var(--color-line);
  border-radius: 0;
  background: none;
}

.skeleton-card__row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.skeleton-bit {
  display: block;
  height: 12px;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, #eceae1 25%, #f6f4ed 37%, #eceae1 63%);
  background-size: 400% 100%;
  animation: skeleton-shimmer 1.4s ease infinite;
}

.skeleton-bit--avatar {
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 50%;
}

.skeleton-bit--title {
  height: 18px;
  flex: 1;
  max-width: 220px;
}

.skeleton-bit--line {
  width: 100%;
}

.skeleton-bit--short {
  width: 62%;
}

@keyframes skeleton-shimmer {
  0% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0 50%;
  }
}

/* Category chips -------------------------------------------------------- */
.category-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 10px 16px;
  min-height: 44px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-line);
  background: var(--color-white);
  color: var(--color-ink);
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  transition: border-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard), background var(--duration-fast) var(--ease-standard);
}

.category-chip svg {
  width: 17px;
  height: 17px;
  flex: none;
  color: var(--color-accent);
}

.category-chip:hover {
  border-color: var(--color-accent);
  color: var(--color-accent-dark);
  background: var(--color-accent-softer);
}

/* Category tile — the richer, icon-led card used in the home category grid.
   The soft background tint and the colour strip rotate over four tones of the
   extended palette (set as data-tint by js/pages/home.js, by position in the
   catalog — never a colour hardcoded per category name). Text is always the
   ink over a very light tint, so every rotation clears AA by a wide margin
   (14.3:1 on the weakest of the four). */
.category-tile {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5) var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-line);
  background: var(--color-accent-softer);
  color: var(--color-ink);
  text-decoration: none;
  font-weight: 650;
  min-height: 88px;
  overflow: hidden;
  transition: border-color var(--duration-base) var(--ease-standard),
    box-shadow var(--duration-base) var(--ease-standard), transform var(--duration-base) var(--ease-standard);
}

/* Colour strip down the leading edge — the small graphic detail that makes a
   grid of tiles read as a set instead of a list of boxes. */
.category-tile::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 5px;
  background: var(--color-accent);
}

.category-tile:hover,
.category-tile:focus-visible {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-lift);
  transform: translateY(-3px);
}

.category-tile__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  flex: none;
  border-radius: 14px;
  background: var(--color-surface);
  color: var(--color-accent-dark);
  box-shadow: var(--shadow-sm);
}

.category-tile__icon svg {
  width: 23px;
  height: 23px;
}

/* Quiet affordance that only commits to being visible on hover/focus. */
.category-tile__go {
  color: var(--color-accent-dark);
  font-size: 1.05rem;
  opacity: 0.45;
  transition: opacity var(--duration-base) var(--ease-standard),
    transform var(--duration-base) var(--ease-standard);
}

.category-tile:hover .category-tile__go,
.category-tile:focus-visible .category-tile__go {
  opacity: 1;
  transform: translateX(3px);
}

.category-tile[data-tint="ember"] {
  background: var(--color-ember-softer);
}

.category-tile[data-tint="ember"]::before {
  background: var(--color-ember);
}

.category-tile[data-tint="ember"] .category-tile__icon,
.category-tile[data-tint="ember"] .category-tile__go {
  color: var(--color-ember);
}

.category-tile[data-tint="ember"]:hover,
.category-tile[data-tint="ember"]:focus-visible {
  border-color: var(--color-ember);
}

.category-tile[data-tint="info"] {
  background: var(--color-info-softer);
}

.category-tile[data-tint="info"]::before {
  background: var(--color-info-dark);
}

.category-tile[data-tint="info"] .category-tile__icon,
.category-tile[data-tint="info"] .category-tile__go {
  color: var(--color-info-dark);
}

.category-tile[data-tint="info"]:hover,
.category-tile[data-tint="info"]:focus-visible {
  border-color: var(--color-info-dark);
}

.category-tile[data-tint="neutral"] {
  background: var(--color-neutral-softer);
}

.category-tile[data-tint="neutral"]::before {
  background: var(--color-ink);
}

.category-tile[data-tint="neutral"] .category-tile__icon,
.category-tile[data-tint="neutral"] .category-tile__go {
  color: var(--color-ink);
}

.category-tile[data-tint="neutral"]:hover,
.category-tile[data-tint="neutral"]:focus-visible {
  border-color: var(--color-ink);
}

.category-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: var(--space-4);
}

@media (max-width: 480px) {
  .category-grid {
    grid-template-columns: 1fr;
  }
}

/* Footer ------------------------------------------------------------------*/
/* Two shapes share these styles: the full public footer (.site-footer__inner
   present) and the compact one still used by the private panels, which is
   just the brand line plus the legal links. */
.site-footer {
  margin-top: var(--space-8);
  padding: var(--space-7) max(var(--layout-gutter), calc((100% - var(--layout-max)) / 2 + var(--layout-gutter)))
    var(--space-6);
  background: var(--color-ink);
  color: var(--color-ink-on-dark);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
}

.site-footer .brand {
  color: #fff;
}

.site-footer .brand::before {
  box-shadow: inset 0 0 0 3px rgba(20, 34, 30, 0.4);
}

.site-footer p {
  margin: 0;
}

.site-footer a {
  color: var(--color-ink-on-dark);
  text-decoration: none;
}

.site-footer a:hover {
  color: #fff;
  text-decoration: underline;
}

.site-footer .footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4);
  font-size: var(--font-body-sm);
}

/* Full public footer ------------------------------------------------------*/
.site-footer--full {
  display: block;
}

/* Compact footer de las páginas privadas: la misma fila legal del pie
   público (términos, privacidad, cookies, preferencias de cookies) sin las
   columnas comerciales, que dentro de un panel de trabajo solo son ruido.
   Antes estas páginas terminaban en el wordmark a secas, sin ninguna vía
   hacia los documentos legales ni hacia el consentimiento de cookies. */
.site-footer--slim {
  display: block;
  padding-top: var(--space-6);
  padding-bottom: var(--space-6);
}

.site-footer--slim .site-footer__bottom {
  padding-top: 0;
  border-top: none;
}

.site-footer__inner {
  display: grid;
  grid-template-columns: minmax(240px, 1.4fr) repeat(3, minmax(150px, 1fr));
  gap: var(--space-6);
  padding-bottom: var(--space-6);
}

.site-footer__about {
  display: grid;
  gap: var(--space-3);
  align-content: start;
  max-width: 34ch;
}

.site-footer__about p {
  font-size: var(--font-body-sm);
  line-height: 1.6;
}

.site-footer__col h2 {
  margin: 0 0 var(--space-3);
  font-size: 0.78rem;
  font-weight: 750;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-accent-bright);
}

.site-footer__col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
  font-size: var(--font-body-sm);
}

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-top: var(--space-5);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  font-size: var(--font-body-sm);
}

@media (max-width: 960px) {
  .site-footer__inner {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 560px) {
  .site-footer__inner {
    grid-template-columns: 1fr;
    gap: var(--space-5);
  }

  .site-footer {
    align-items: flex-start;
  }
}

/* Report modal (reusable — see js/report-modal.js) */
.report-modal {
  border: none;
  border-radius: var(--radius-md);
  padding: 0;
  max-width: 440px;
  width: calc(100% - var(--space-6));
}

.report-modal::backdrop {
  background: rgba(15, 23, 20, 0.55);
}

.report-modal__inner {
  padding: var(--space-5);
  display: grid;
  gap: var(--space-3);
}

.report-modal__header {
  display: flex;
  justify-content: space-between;
  align-items: start;
  gap: var(--space-3);
}

.report-modal__close {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--color-muted);
}

.report-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}

/* Breadcrumbs — reused across legal.html, categoria/servicio/provincia/
   municipio.html and the informational pages. */
.breadcrumbs {
  font-size: var(--font-body-sm);
  color: var(--color-muted);
  margin: var(--space-4) 0;
}

.breadcrumbs a {
  color: var(--color-muted);
}

.breadcrumbs span[aria-hidden] {
  margin: 0 var(--space-2);
}

.legal-index {
  margin-top: var(--space-7);
  border-top: 1px solid var(--color-line);
  padding-top: var(--space-4);
}

.legal-index ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-2);
}

/* Legal document acceptance (registration form, legal-gate modal). Checkbox
   labels wrap to two lines often, so align to the top of the box instead of
   centering (unlike the shorter single-line .checkbox-field elsewhere). */
.legal-acceptance {
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  display: grid;
  gap: var(--space-3);
}

.legal-acceptance legend {
  font-weight: 600;
  padding: 0 var(--space-2);
}

.legal-acceptance .checkbox-field {
  align-items: flex-start;
}

.legal-acceptance .checkbox-field input {
  margin-top: 3px;
}

/* Long-form legal/informational content (legal.html, contacto.html, FAQ…) */
.prose {
  max-width: 72ch;
  margin: 0 auto;
  display: grid;
  gap: var(--space-4);
}

.prose h2 {
  margin-top: var(--space-5);
}

.prose ul,
.prose ol {
  padding-left: 1.4em;
  display: grid;
  gap: var(--space-2);
}

.draft-notice {
  border: 2px dashed var(--color-warning);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  /* --color-warning-bg never existed; this was falling back to a hardcoded
     amber that belonged to no token. */
  background: var(--color-warning-soft);
}

.legal-meta {
  color: var(--color-muted);
  font-size: 0.9rem;
}

/* Reusable modal chrome, shared by the legal acceptance gate and the cookie
   banner's "customize" dialog (report-modal.js/.report-modal covers the
   report flow specifically; this is the generic version). */
.modal {
  border: none;
  border-radius: var(--radius-md);
  padding: 0;
  max-width: 520px;
  width: calc(100% - var(--space-6));
}

.modal::backdrop {
  background: rgba(15, 23, 20, 0.55);
}

.modal__inner {
  padding: var(--space-5);
  display: grid;
  gap: var(--space-3);
  max-height: 80vh;
  overflow-y: auto;
}

.modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* Cookie consent banner: fixed, low z-index conflict with modals, dismissed
   only by an explicit choice (never auto-hides), respects reduced motion
   via the global rule in base.css. */
.cookie-banner {
  position: fixed;
  left: var(--space-4);
  right: var(--space-4);
  bottom: var(--space-4);
  z-index: 90;
  background: var(--color-ink);
  color: var(--color-white);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}

.cookie-banner p {
  margin: 0;
  flex: 1 1 320px;
}

.cookie-banner a {
  color: inherit;
  text-decoration: underline;
}

.cookie-banner__actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

@media (max-width: 480px) {
  .cookie-banner {
    left: var(--space-2);
    right: var(--space-2);
    bottom: var(--space-2);
  }
}

/* Panel de preferencias de cookies (mismo patrón de <dialog> nativo que
   .report-modal: foco atrapado y cierre con Escape los da el navegador). */
.cookie-dialog {
  border: none;
  border-radius: var(--radius-md);
  padding: 0;
  max-width: 520px;
  width: calc(100% - var(--space-6));
  color: var(--color-ink);
  background: var(--color-surface);
}

.cookie-dialog::backdrop {
  background: rgba(15, 23, 20, 0.55);
}

.cookie-dialog__inner {
  padding: var(--space-5);
  display: grid;
  gap: var(--space-4);
}

.cookie-dialog__inner h2 {
  margin: 0;
  font-size: var(--font-heading-sm);
}

.cookie-dialog__group {
  display: grid;
  gap: var(--space-3);
}

.cookie-dialog__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* Casilla + texto explicativo alineados, con área táctil cómoda. */
.field--check {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-3);
  align-items: start;
  font-size: var(--font-body-sm);
  font-weight: 400;
  padding: var(--space-3);
  border: var(--border-width-sm) solid var(--color-line);
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
}

.field--check input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin-top: 2px;
  accent-color: var(--color-accent);
}

.field--check input[type="checkbox"]:disabled + span {
  color: var(--color-muted);
}

.field--check .badge {
  display: inline-block;
  font-size: var(--font-caption);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--color-neutral-soft);
  color: var(--color-muted);
  vertical-align: middle;
}

/* Botón que vive dentro de una fila de enlaces del pie: tiene que leerse
   como un enlace más, no como un botón suelto. */
.footer-links__button {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-decoration: underline;
}
