/* Estilos de componentes compartidos por todas las páginas. Requiere css/tokens.css cargado antes. */

/* RESET */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
a { text-decoration: none; color: inherit; }
img { display: block; }
* { -webkit-tap-highlight-color: transparent; }

/* BASE */
/* scrollbar-gutter: reserva siempre el hueco de la barra vertical: sin él, al filtrar /news (o elegir
   Empresa/Particular en /workwithme) la página pasa de larga a corta, la barra desaparece y el
   contenido centrado se mueve ~7px. */
html { font-size: 16px; scroll-behavior: smooth; scrollbar-gutter: stable; }
/* Navegadores sin scrollbar-gutter (p. ej. Safari < 18.2): se fuerza siempre la barra */
@supports not (scrollbar-gutter: stable) { html { overflow-y: scroll; } }
body {
  font-family: var(--font);
  background-color: var(--bg);
  background-image: var(--noise);
  background-repeat: repeat;
  color: var(--text);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  transition: background-color .35s ease, color .35s ease, border-color .35s ease;
}

/* Reparto de líneas: títulos equilibrados y párrafos sin línea final huérfana (sin soporte, se ignora) */
h1, h2, h3 { text-wrap: balance; }
p, li { text-wrap: pretty; }

/* ICON COLORS */
.icon-on-light              { filter: invert(1); }
html.dark .icon-on-light    { filter: none; }
.icon-on-dark               { filter: none; }
html.dark .icon-on-dark     { filter: invert(1); }
@media (prefers-color-scheme: dark) {
  :root:not(.light) .icon-on-light { filter: none; }
  :root:not(.light) .icon-on-dark  { filter: invert(1); }
}
/* Always white — for icons on colored backgrounds (e.g. CTA accent button) */
.icon-always-white { filter: brightness(0) invert(1); }
.btn-icon img,
.social-btn img { transition: filter .35s ease; }
/* Fade del icono al teñirse el botón (mismo tiempo que la cara). Los filtros de
   estado sólido comparten forma con los del tema: ver setBrandFg() en shared.js. */
.link-btn[data-color] .btn-icon img,
.social-btn[data-color] img { transition: filter .18s cubic-bezier(0.2,0,0,1); }

/* LAYOUT */
.page {
  display: flex; flex-direction: column; align-items: center;
  padding: 4rem 1.25rem 5rem;
}
.stack {
  width: 100%; max-width: var(--max);
  display: flex; flex-direction: column; gap: 2.5rem;
}

/* FADE-IN STAGGER */
.fade-in {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .45s cubic-bezier(0.2,0,0,1), transform .45s cubic-bezier(0.2,0,0,1);
  /* Red lenta: el JS que añade .visible llega el último; si tarda > 0,6 s el CSS revela el contenido solo */
  animation: fade-failsafe .45s cubic-bezier(0.2,0,0,1) .6s forwards;
}
.fade-in.visible { opacity: 1; transform: translateY(0); }
@keyframes fade-failsafe { to { opacity: 1; transform: none; } }

/* SECTION */
/* gap 1rem: deja sitio al aro de foco/tap (≈9px arriba, 4px abajo) sin tocar al vecino */
.section { display: flex; flex-direction: column; gap: 1rem; }

/* SECTION LABEL */
.section-label {
  display: flex; align-items: center; gap: .5rem;
  font-size: .7rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-3);
  padding-bottom: .5rem; margin-bottom: .1rem;
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg, var(--border) 0%, var(--border) 55%, transparent 100%) 1;
}
html.dark .section-label {
  border-image: linear-gradient(90deg, #3a3a3a 0%, #3a3a3a 55%, transparent 100%) 1;
}
@media (prefers-color-scheme: dark) {
  :root:not(.light) .section-label {
    border-image: linear-gradient(90deg, #3a3a3a 0%, #3a3a3a 55%, transparent 100%) 1;
  }
}
.section-label svg { opacity: .55; flex-shrink: 0; }
html.dark .section-label svg { opacity: .50; }
.section-note {
  margin-left: auto; font-size: .65rem; font-weight: 400;
  text-transform: none; letter-spacing: 0; color: var(--text-3);
}

/* LINK BUTTON (3D pushable): ::before = canto fijo, .pb-front = cara (solo transform).
   --brand lo fija initLinkColors() desde data-color. */
.link-btn {
  position: relative; display: block; padding: 0;
  background: transparent; border: none; border-radius: var(--r);
  cursor: pointer; color: var(--text); outline-offset: 4px;
  -webkit-tap-highlight-color: transparent;
}
.link-btn::before, .social-btn::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--edge); box-shadow: 0 3px 6px var(--push-shadow);
}
/* Aro de foco/tap: envuelve cara + canto. Margen superior extra porque la cara
   sube hasta 6px (hover/tap) por encima de la caja del botón. */
.link-btn::after, .social-btn::after {
  content: ""; position: absolute; inset: -9px -4px -4px; pointer-events: none;
  border: 2.5px solid var(--accent); border-radius: calc(var(--r) + 4px);
  /* Salida: solo se desvanece (no se encoge sobre el botón). La entrada es el keyframe ring-in */
  opacity: 0; transform-origin: 50% 60%;
  transition: opacity .18s ease, border-color .15s ease;
}
.social-btn::after { border-radius: calc(var(--r-lg) + 4px); }
.link-btn.tap-active::after, .link-btn:focus-visible::after,
.social-btn.tap-active::after, .social-btn:focus-visible::after {
  animation: ring-in .4s cubic-bezier(.2,.9,.3,1.35);
}
/* Pulso de entrada: nace pequeño, dentro del botón, y se expande con un leve rebote */
@keyframes ring-in { from { transform: scale(.88); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .link-btn::after, .social-btn::after { animation: none !important; }
}
.pb-front {
  position: relative; display: flex; align-items: center; gap: .9rem;
  padding: .85rem 1rem; background: var(--surface);
  border: 1px solid var(--border); border-radius: inherit;
  transform: translateY(-4px);
  transition:
    transform 600ms cubic-bezier(.3,.7,.4,1),
    background .18s cubic-bezier(0.2,0,0,1),
    border-color .18s cubic-bezier(0.2,0,0,1);
}
.link-btn:hover .pb-front, .social-btn:hover .pb-front {
  transform: translateY(-6px);
  transition:
    transform 250ms cubic-bezier(.3,.7,.4,1.5),
    background .18s cubic-bezier(0.2,0,0,1),
    border-color .18s cubic-bezier(0.2,0,0,1);
}
.link-btn:active .pb-front, .social-btn:active .pb-front {
  transform: translateY(-2px); transition: transform 34ms;
}

/* Color de marca: hover (puntero) y tap-to-confirm (táctil) */
/* Color de marca sólido (sin translucidez) al pasar el ratón / tocar. El canto 3D se oscurece.
   .is-featured = el mismo aspecto de forma PERMANENTE (acción recomendada de un panel). */
.link-btn[data-color]:hover .pb-front,
.link-btn[data-color].is-featured .pb-front,
.link-btn[data-color].tap-active .pb-front,
.social-btn[data-color]:hover .pb-front,
.social-btn[data-color].tap-active .pb-front {
  background: var(--brand); border-color: var(--brand); color: var(--brand-fg, #fff);
}
.link-btn[data-color]:hover::before, .link-btn[data-color].tap-active::before, .link-btn[data-color].is-featured::before,
.social-btn[data-color]:hover::before, .social-btn[data-color].tap-active::before {
  background: color-mix(in srgb, var(--brand) 62%, #000);
}
.link-btn[data-color]:hover .btn-arrow,
.link-btn[data-color].is-featured .btn-arrow,
.link-btn[data-color].tap-active .btn-arrow { color: var(--brand-fg, #fff); }
.link-btn[data-color]:hover .btn-icon,
.link-btn[data-color].is-featured .btn-icon,
.link-btn[data-color].tap-active .btn-icon { background: rgba(255,255,255,.22); }
.link-btn[data-color]:hover .btn-sup, .link-btn[data-color].is-featured .btn-sup { opacity: .85; }
.link-btn[data-color].is-featured .btn-arrow { opacity: 1; }
/* Glifos monocromos: se repintan con el mismo color que el texto (--brand-fg),
   así siempre contrastan con el fondo de marca, sea cual sea el color. */
.link-btn[data-color]:hover .icon-on-light,    .link-btn[data-color].tap-active .icon-on-light, .link-btn[data-color].is-featured .icon-on-light,
.social-btn[data-color]:hover .icon-on-light,  .social-btn[data-color].tap-active .icon-on-light  { filter: var(--icon-f-light, none); }
.link-btn[data-color]:hover .icon-on-dark,     .link-btn[data-color].tap-active .icon-on-dark, .link-btn[data-color].is-featured .icon-on-dark,
.social-btn[data-color]:hover .icon-on-dark,   .social-btn[data-color].tap-active .icon-on-dark   { filter: var(--icon-f-dark, none); }
.link-btn[data-color]:hover .icon-always-white,.link-btn[data-color].tap-active .icon-always-white, .link-btn[data-color].is-featured .icon-always-white,
.social-btn[data-color]:hover .icon-always-white,.social-btn[data-color].tap-active .icon-always-white { filter: var(--icon-f-white, none); }

/* CTA button — color sólido, sin degradado (contraste AA) */
.link-btn.cta::before { background: var(--edge-accent); }
.link-btn.cta .pb-front {
  background: var(--accent-solid); border-color: var(--accent-solid); color: var(--accent-fg);
}

.cta-badge {
  font-size: .55rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; background: rgba(255,255,255,.22);
  padding: 2px 6px; border-radius: var(--r-xs); white-space: nowrap;
  flex-shrink: 0; align-self: center;
}
.btn-icon {
  width: 32px; height: 32px; border-radius: var(--r-sm); overflow: hidden;
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); transition: background .2s ease;
}
.link-btn.cta .btn-icon { background: rgba(255,255,255,.18); }
.btn-icon img { width: 20px; height: 20px; object-fit: contain; }
.btn-text { flex: 1; font-size: .9rem; font-weight: 500; letter-spacing: -.01em; }
.link-btn.cta .btn-text { font-weight: 600; }
.btn-sup {
  display: block; font-size: .65rem; font-weight: 400; opacity: .65; margin-bottom: 1px;
}
.btn-arrow {
  display: flex; align-items: center; opacity: .3; flex-shrink: 0; line-height: 1;
  transition: transform .14s cubic-bezier(0.34,1.56,0.64,1), opacity .14s cubic-bezier(0.2,0,0,1), color .18s ease;
}
.link-btn:hover .btn-arrow { transform: translateX(4px); opacity: 1; }
.link-btn.cta .btn-arrow   { opacity: .65; color: var(--accent-fg); }
.link-btn.cta:hover .btn-arrow { opacity: 1; }

/* SOCIAL STRIP (dock destacado con discos 3D) */
.social-strip {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-4); flex-wrap: wrap; width: fit-content; max-width: 100%;
  margin: var(--space-5) auto 0; padding: var(--space-4) var(--space-5);
  background: var(--accent-tint); border: 1px solid var(--accent-tint-border);
  border-radius: var(--r-xl);
}
.social-btn {
  position: relative; display: block; width: 52px; height: 52px; padding: 0;
  background: transparent; border: none; border-radius: var(--r-lg); cursor: pointer;
  outline-offset: 4px; -webkit-tap-highlight-color: transparent;
}
.social-btn .pb-front {
  display: flex; align-items: center; justify-content: center;
  padding: 0; width: 100%; height: 100%;
}
.social-btn .pb-front img { width: 22px; height: 22px; object-fit: contain; }
/* «Toca de nuevo» (solo táctil) en .pb-front::after (sube con la cara); .social-btn::after queda para el aro.
   Sin etiqueta con el nombre de la red al pasar el ratón: los iconos son conocidos y el aria-label la nombra. */
.social-btn .pb-front::after {
  content: var(--tap-again, ""); position: absolute; bottom: calc(100% + 10px); left: 50%;
  transform: translateX(-50%) translateY(4px);
  background: var(--text); color: var(--bg); font-size: .62rem; font-weight: 600;
  letter-spacing: .03em; white-space: nowrap; padding: 3px 8px; border-radius: 5px;
  opacity: 0; pointer-events: none; z-index: 10;
  transition: opacity .15s ease, transform .15s ease;
}

/* Botón 3D compacto (en línea) para tarjetas y acciones: reutiliza el relieve de .link-btn/.pb-front */
.link-btn.btn-sm { display: inline-block; width: auto; }
.link-btn.btn-sm .pb-front { padding: .55rem .9rem; gap: .5rem; }
.link-btn.btn-sm .btn-text { flex: none; font-size: .82rem; font-weight: 600; }
.link-btn.btn-sm .btn-arrow { opacity: .55; }
.link-btn.btn-sm:hover .btn-arrow { opacity: 1; }

/* Chips 3D (filtros): mismo relieve que .nav-btn. Activo = tinte de acento OPACO (color-mix sobre
   --surface; con una tinta translúcida se vería el canto 3D a través) + cara hundida. */
.chip {
  position: relative; display: inline-block; min-height: var(--tap-target); padding: 0;
  border: none; background: transparent; border-radius: var(--r-sm);
  color: var(--text-2); font-family: inherit; font-size: .82rem; font-weight: 600; line-height: 1;
  cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent; outline-offset: 4px;
}
.chip::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--edge); box-shadow: 0 2px 4px var(--push-shadow);
}
.chip .pb-front {
  display: flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: var(--tap-target); padding: 0 var(--space-4);
  background: var(--surface); border: 1px solid var(--border); border-radius: inherit;
  transform: translateY(-4px);
  transition: transform 600ms cubic-bezier(.3,.7,.4,1), background .15s, border-color .15s, color .15s;
}
.chip:hover { color: var(--text); }
.chip:hover .pb-front { transform: translateY(-6px); transition: transform 250ms cubic-bezier(.3,.7,.4,1.5); }
.chip:active .pb-front, .chip[aria-pressed="true"] .pb-front { transform: translateY(-2px); transition: transform 34ms; }
.chip[aria-pressed="true"] { color: var(--text); }
.chip[aria-pressed="true"] .pb-front {
  background: color-mix(in srgb, var(--accent) 12%, var(--surface)); border-color: var(--accent);
}
@media (prefers-reduced-motion: reduce) { .chip .pb-front { transition: none; } }

/* Texto solo para lectores de pantalla (regiones aria-live) */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ENLACE DE TARJETA (news + proyectos de /workwithme)
   El título lleva el único <a class="card-stretch">, cuyo ::after cubre la tarjeta; .card-go (pie) es decorativo (aria-hidden)
   y «se abre en una pestaña nueva» va por aria-describedby="link-new-tab". */
.has-link { position: relative; cursor: pointer; transition: border-color .15s ease; }
.has-link:hover { border-color: var(--accent); }
.has-link:has(.card-stretch:focus-visible) { outline: 2.5px solid var(--accent); outline-offset: 3px; }
.card-stretch { color: inherit; text-decoration: none; outline: none; }
.card-stretch::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.card-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.card-foot-left { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; min-width: 0; font-size: .74rem; color: var(--text-3); font-variant-numeric: tabular-nums; }
.card-go {
  margin-left: auto; display: inline-flex; align-items: center; gap: .3rem; min-height: 24px;
  font-size: .82rem; font-weight: 600; color: var(--text-2);
}
.card-go span { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.card-go svg { display: block; transition: transform .15s cubic-bezier(.2,0,0,1); }
.has-link:hover .card-go { color: var(--accent); }
.has-link:hover .card-go svg { transform: translate(2px, -2px); }
@media (prefers-reduced-motion: reduce) { .card-go svg, .has-link { transition: none; } }

/* FOOTER */
footer {
  display: flex; flex-direction: column; align-items: center; gap: .75rem;
  padding-top: 1.25rem;
  border-top: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, var(--border) 30%, var(--border) 70%, transparent) 1;
}
footer p { font-size: .72rem; color: var(--text-3); text-align: center; line-height: 1.9; }
footer a { color: var(--text-2); text-decoration: underline; text-underline-offset: 3px; }
footer a:hover { color: var(--text); }
#copy-year { font-variant-numeric: tabular-nums; }
.wwm-step-num, .wwm-project-meta, .news-item-meta, #update-date, .update-date { font-variant-numeric: tabular-nums; }

/* SAFE AREA */
.page { padding-bottom: calc(2.5rem + env(safe-area-inset-bottom)); }
footer { padding-bottom: env(safe-area-inset-bottom); }

/* MOBILE TOUCH FIXES */
a, button, .link-btn, .social-btn, .nav-btn {
  touch-action: manipulation;
}

/* TAP HINT / TAP-TO-CONFIRM */
.link-btn .tap-hint {
  font-size: .62rem; font-weight: 600; letter-spacing: .03em;
  white-space: nowrap; opacity: 0; max-width: 0; overflow: hidden;
  transition: opacity .2s ease, color .2s ease;
  flex-shrink: 0;
}
.link-btn.tap-active .tap-hint { opacity: 1; max-width: 120px; }
.link-btn.tap-active .pb-front,
.social-btn.tap-active .pb-front {
  background: color-mix(in srgb, var(--brand, var(--accent)) var(--brand-tap), var(--surface));
  border-color: var(--brand, var(--accent));
  transform: translateY(-6px);
}
.link-btn.tap-active::after { opacity: 1; border-color: var(--brand, var(--accent)); }
.social-btn.tap-active::after { opacity: 1; border-color: var(--brand, var(--accent)); }
.link-btn.tap-active .btn-arrow { transform: translateX(5px); opacity: 1; color: var(--brand, var(--accent)); }
.social-btn.tap-active .pb-front::after {
  content: var(--tap-again, "");
  opacity: 1; transform: translateX(-50%) translateY(0);
  background: var(--brand, var(--accent)); color: #fff;
}

/* NAVBAR MÓVIL (inyectada por controls.js) */
/* Flex + space-between: con 4 botones la rejilla desbordaba a 360px.
   Cada botón vive en un .nav-slot, ancla de su menú desplegable. */
.navbar-mobile {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 50; container-type: inline-size;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  height: calc(68px + env(safe-area-inset-bottom));
  padding: 6px var(--space-4) env(safe-area-inset-bottom);
  background: var(--bg);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-top: 1px solid var(--border);
}
.navbar-actions { display: flex; align-items: center; gap: var(--space-3); }
.nav-slot { position: relative; display: flex; }
.nav-index-target { scroll-margin-top: var(--space-4); }
.nav-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-width: var(--tap-target); height: var(--tap-target); padding: 0 .75rem;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface); color: var(--text);
  font-family: inherit; font-size: .82rem; font-weight: 600;
  cursor: pointer; touch-action: manipulation;
  transition: transform .12s ease, background .15s ease;
}
.nav-btn:active { transform: scale(.96); }
.nav-btn:hover { background: var(--surface-2); }
.nav-btn:focus-visible { border-radius: var(--r-sm); }

/* Botones 3D de la navbar móvil y del carril de escritorio (mismo relieve que .link-btn: 4 / 6 / 2px) */
:is(.navbar-mobile, .controls-rail) .nav-btn {
  position: relative; display: inline-block; min-width: var(--tap-target); height: var(--tap-target);
  padding: 0; border: none; background: transparent; border-radius: var(--r-sm);
  color: var(--text); font-family: inherit; font-size: .82rem; font-weight: 600; line-height: 1;
  cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  outline-offset: 4px; text-decoration: none; transition: none;
}
:is(.navbar-mobile, .controls-rail) .nav-btn:hover { background: transparent; }
:is(.navbar-mobile, .controls-rail) .nav-btn:active { transform: none; }
:is(.navbar-mobile, .controls-rail) .nav-btn::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--edge); box-shadow: 0 2px 4px var(--push-shadow);
}
:is(.navbar-mobile, .controls-rail) .nav-btn .pb-front {
  display: flex; align-items: center; justify-content: center; gap: .4rem;
  height: 100%; padding: 0 .8rem; background: var(--surface);
  border: 1px solid var(--border); border-radius: inherit; transform: translateY(-4px);
  transition: transform 600ms cubic-bezier(.3,.7,.4,1), background .15s, border-color .15s;
}
:is(.navbar-mobile, .controls-rail) .nav-btn:hover .pb-front { transform: translateY(-6px); transition: transform 250ms cubic-bezier(.3,.7,.4,1.5); }
:is(.navbar-mobile, .controls-rail) .nav-btn:active .pb-front,
:is(.navbar-mobile, .controls-rail) .nav-btn[aria-expanded="true"] .pb-front { transform: translateY(-2px); transition: transform 34ms; }
/* Fondo opaco (color-mix sobre --surface): con una tinta translúcida se vería el canto 3D a través */
:is(.navbar-mobile, .controls-rail) .nav-btn[aria-expanded="true"] .pb-front,
:is(.navbar-mobile, .controls-rail) .nav-btn[aria-current="true"] .pb-front {
  background: color-mix(in srgb, var(--accent) 12%, var(--surface)); border-color: var(--accent);
}
.nav-caret { opacity: .55; transition: transform .2s cubic-bezier(.2,0,0,1); }
.nav-btn[aria-expanded="true"] .nav-caret { transform: rotate(180deg); opacity: 1; }
@container (max-width: 339px) { .nav-label { display: none; } }

/* Menú desplegable (Índice, Idioma): se abre hacia arriba, con cola */
.nav-menu {
  position: absolute; bottom: calc(100% + 16px); width: max-content; min-width: 176px;
  max-width: min(300px, calc(100vw - 32px)); padding: var(--space-3);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: 0 10px 30px var(--push-shadow); z-index: 60;
  animation: nav-menu-in .18s cubic-bezier(.2,0,0,1);
}
.nav-menu[hidden] { display: none; }
.nav-menu-list {
  display: flex; flex-direction: column; gap: var(--space-3);
  max-height: min(60vh, 420px); overflow-y: auto; padding: 8px 4px 4px; margin: -4px -4px -4px;
}
.nav-menu.align-right  { right: -4px; }
.nav-menu.align-left   { left: -4px; }
.nav-menu.align-center { left: 50%; transform: translateX(-50%); animation-name: nav-menu-in-c; }
.nav-menu-tail {
  position: absolute; bottom: -6px; width: 10px; height: 10px; background: var(--surface);
  border-right: 1px solid var(--border); border-bottom: 1px solid var(--border);
  border-bottom-right-radius: 3px; transform: rotate(45deg);
}
.nav-menu.align-right .nav-menu-tail  { right: 30px; }
.nav-menu.align-left .nav-menu-tail   { left: 30px; }
.nav-menu.align-center .nav-menu-tail { left: 50%; margin-left: -5px; }
/* Carril de escritorio: el menú se abre hacia el margen (derecha del botón) y, si no cabe,
   controls.js añade .flip y pasa a la IZQUIERDA, sobre la columna. */
.nav-menu.align-side { bottom: -4px; left: calc(100% + 16px); animation-name: nav-menu-in-s; }
.nav-menu.align-side .nav-menu-tail { bottom: 21px; left: -6px; transform: rotate(135deg); }
.nav-menu.align-side.flip { left: auto; right: calc(100% + 16px); animation-name: nav-menu-in-sf; }
.nav-menu.align-side.flip .nav-menu-tail { left: auto; right: -6px; transform: rotate(-45deg); }
@keyframes nav-menu-in-s  { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
@keyframes nav-menu-in-sf { from { opacity: 0; transform: translateX(6px); }  to { opacity: 1; transform: none; } }
.nav-menu .nav-btn { display: block; width: 100%; text-align: left; }
.nav-menu .nav-btn .pb-front { justify-content: space-between; gap: var(--space-3); padding: 0 .9rem; }
.nav-item-label { font-size: .85rem; font-weight: 600; }
.nav-item-hint { font-size: .7rem; font-weight: 500; color: var(--text-3); margin-left: .5rem; }
.nav-check { color: var(--accent); flex-shrink: 0; }
@keyframes nav-menu-in   { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes nav-menu-in-c { from { opacity: 0; transform: translateX(-50%) translateY(6px); } to { opacity: 1; transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .nav-menu { animation: none; }
  .navbar-mobile .nav-btn .pb-front, .nav-caret { transition: none; }
}
/* CARRIL LATERAL DE CONTROLES (escritorio ≥ 800px, inyectado por controls.js)
   Junto a la columna: --max es el ancho de columna de cada página. */
.controls-rail {
  position: fixed; z-index: 50; display: flex; flex-direction: column; gap: var(--space-3);
  left: calc(50% + var(--max, 520px) / 2 + var(--space-4));
  bottom: calc(var(--space-6) + env(safe-area-inset-bottom));
}
.controls-rail .nav-btn { padding: 0; }
/* Rail de 44px: sin caret ni relleno lateral (el menú ya lo indica aria-haspopup) */
.controls-rail > .nav-btn .pb-front,
.controls-rail > .nav-slot > .nav-btn .pb-front { padding: 0; }
.controls-rail .nav-caret { display: none; }
.controls-rail .nav-btn[hidden] { display: none; }

/* Etiqueta de los botones del carril (solo icono): ratón (con retardo, para no parpadear al cruzar el carril)
   o foco de teclado. Mismo aspecto que .bubble. Sale hacia el margen (derecha) y, si ahí no cabe, hacia la
   izquierda sobre la columna (.tip-flip, lo pone controls.js midiendo el ancho real), igual que sus menús y los
   .tip-auto. El texto es el aria-label, así que sigue al idioma y al estado (sol/luna, Inicio/Subir). Se oculta
   con el menú abierto. */
.controls-rail > .nav-btn::after,
.controls-rail > .nav-slot > .nav-btn::after {
  content: attr(aria-label); position: absolute; left: calc(100% + 12px); top: 50%;
  transform: translateY(-50%) translateX(-4px);
  width: max-content; max-width: 160px; text-align: left; white-space: normal;
  background: var(--text); color: var(--bg);
  font-size: .68rem; font-weight: 600; letter-spacing: .02em; line-height: 1.3;
  padding: 5px 9px; border-radius: var(--r-sm);
  opacity: 0; pointer-events: none; z-index: 10; transition: opacity .15s, transform .15s;
}
.controls-rail > .nav-btn.tip-flip::after,
.controls-rail > .nav-slot > .nav-btn.tip-flip::after {
  left: auto; right: calc(100% + 12px); transform: translateY(-50%) translateX(4px);
}
.controls-rail .nav-lang-btn[data-tip]::after { content: attr(data-tip); }   /* sin el «ES,» del aria-label */
.controls-rail .nav-btn[aria-expanded="true"]::after,
.controls-rail .nav-btn.tip-off::after { display: none; }   /* menú abierto · descartada con Esc (controls.js) */
.controls-rail > .nav-btn:focus-visible::after,
.controls-rail > .nav-slot > .nav-btn:focus-visible::after { opacity: 1; transform: translateY(-50%); }
@media (hover: hover) {
  .controls-rail > .nav-btn:hover::after,
  .controls-rail > .nav-slot > .nav-btn:hover::after {
    opacity: 1; transform: translateY(-50%); transition-delay: .35s;
  }
}
@media (prefers-reduced-motion: reduce) {
  .controls-rail > .nav-btn::after, .controls-rail > .nav-slot > .nav-btn::after { transition: none; }
}

/* Punto de corte único: < 800px navbar inferior, ≥ 800px carril.
   `body .page` gana a los padding-bottom propios de cada página (privacy, news…) */
@media (min-width: 800px) { .navbar-mobile { display: none; } }
@media (max-width: 799px) {
  .controls-rail { display: none; }
  body .page { padding-bottom: calc(68px + env(safe-area-inset-bottom) + 2rem); }
}

/* BOCADILLO INFORMATIVO LATERAL (punto de estado, verificado)
   A la derecha por defecto; .tip-left a la izquierda. ::before amplía el área táctil; controls.js añade .tip-active al tocar. */
.tip { position: relative; display: inline-flex; cursor: default; }
.tip::before { content: ""; position: absolute; inset: -12px; }
.bubble {
  position: absolute; left: calc(100% + 12px); top: 50%;
  transform: translateY(-50%) translateX(-4px);
  width: max-content; max-width: 132px;
  background: var(--text); color: var(--bg);
  font-size: .68rem; font-weight: 600; letter-spacing: .02em; line-height: 1.3;
  padding: 5px 9px; border-radius: var(--r-sm);
  opacity: 0; pointer-events: none; transition: opacity .15s, transform .15s; z-index: 10;
}
.bubble::before {
  content: ""; position: absolute; right: 100%; top: 50%; margin-top: -5px;
  border: 5px solid transparent; border-right-color: var(--text);
}
/* A la izquierda: .tip-left (siempre) o .tip-flip (lo añade controls.js a los .tip-auto cuando a la
   derecha no cabría; antes se volteaba por media query aunque hubiera sitio). */
.tip.tip-left .bubble, .tip.tip-flip .bubble { left: auto; right: calc(100% + 12px); transform: translateY(-50%) translateX(4px); }
.tip.tip-left .bubble::before, .tip.tip-flip .bubble::before { right: auto; left: 100%; border-right-color: transparent; border-left-color: var(--text); }
.tip:hover .bubble, .tip:focus-visible .bubble, .tip.tip-active .bubble {
  opacity: 1; transform: translateY(-50%) translateX(0);
}

/* AVATAR + PUNTO DE ESTADO (inicio, workwithme)
   Circular, sin 3D. Anillo gris → azul al pasar el ratón. El punto es un .tip con bocadillo. */
.avatar-wrap { position: relative; display: inline-block; }
.avatar {
  width: 96px; height: 96px; border-radius: 50%; overflow: hidden;
  outline: 2.5px solid var(--border); outline-offset: 3px;
  background: var(--surface-2);
  transition: outline-color .35s ease;
}
.avatar-wrap:hover .avatar { outline-color: var(--accent); }
.avatar img { width: 100%; height: 100%; object-fit: cover; }
/* Punto verde con pulso (mismo que sticky-dot de la barra superior) */
.status-dot {
  position: absolute; bottom: 3px; right: 3px;
  width: 13px; height: 13px; border-radius: 50%;
  background: #22c55e; border: 2.5px solid var(--bg);
  transition: border-color .35s ease;
}
.status-dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: #22c55e; pointer-events: none;
  animation: pulse-ring 2.4s ease infinite;
}
@media (prefers-reduced-motion: reduce) { .status-dot::after { animation: none; } }

/* INSIGNIA DE VERIFICADO (propia) */
.verified { width: 22px; height: 22px; color: var(--accent); flex-shrink: 0; }

/* ACCESSIBILITY */
.skip-link {
  position: fixed; top: 0; left: 50%; transform: translate(-50%, -100%);
  z-index: 999; background: var(--accent); color: var(--accent-fg);
  font-size: .85rem; font-weight: 700; padding: .6rem 1.4rem;
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  text-decoration: none; transition: transform .2s ease; white-space: nowrap;
}
.skip-link:focus { transform: translate(-50%, 0); }
:focus-visible { outline: 2.5px solid var(--accent); outline-offset: 3px; border-radius: var(--r-xs); }
/* La regla genérica cambia border-radius: los botones 3D lo heredan en ::before */
.link-btn:focus-visible { outline: none; border-radius: var(--r); }
.link-btn:focus-visible::after { opacity: 1; }
.social-btn:focus-visible { outline: none; border-radius: var(--r-lg); }
.social-btn:focus-visible::after { opacity: 1; }

/* AVISO BREVE (dirección de correo copiada) */
.copy-toast {
  position: fixed; left: 50%; bottom: calc(var(--space-6) + env(safe-area-inset-bottom)); z-index: 80;
  transform: translate(-50%, 8px); opacity: 0; pointer-events: none;
  max-width: calc(100vw - 2 * var(--space-4)); padding: .55rem .9rem;
  background: var(--text); color: var(--bg); border-radius: var(--r-sm);
  font-size: .8rem; font-weight: 600; text-align: center;
  transition: opacity .2s ease, transform .2s ease;
}
.copy-toast.show { opacity: 1; transform: translate(-50%, 0); }
@media (max-width: 799px) { .copy-toast { bottom: calc(68px + var(--space-4) + env(safe-area-inset-bottom)); } }
@media (prefers-reduced-motion: reduce) { .copy-toast { transition: opacity .01s; transform: translate(-50%, 0); } }

/* @KEYFRAMES */
/* Composited pulse — only transform + opacity (no box-shadow) */
@keyframes pulse-ring {
  0%   { transform: scale(.6);  opacity: .7; }
  70%  { transform: scale(2.2); opacity: 0;  }
  100% { transform: scale(.6);  opacity: 0;  }
}

/* Brillo con transform (compuesto): el ::after es 4× el ancho, con teselas de 2×; desplazarlo 50 % = una tesela, bucle sin salto */
@keyframes sk-shimmer { to { transform: translateX(50%); } }

/* SKELETON LOADER */
.skeleton-section { display: flex; flex-direction: column; gap: 1rem; }
.skeleton-label {
  height: 11px; width: 88px; border-radius: 20px;
  background: var(--surface-2); margin-bottom: .35rem;
}
.skeleton-card, .wwm-project-sk {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--surface-2);
}
.skeleton-card::after, .wwm-project-sk::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -200%; width: 400%; z-index: -1; will-change: transform;
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--border) 50%, var(--surface-2) 75%);
  background-size: 50% 100%; animation: sk-shimmer 1.4s linear infinite;
}

/* REDUCED MOTION */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .fade-in { opacity: 1; transform: none; }
  .skeleton-card::after, .wwm-project-sk::after { animation: none; }
}
