  /* ===================== RUEDA 3D DE SERVICIOS =====================
     Portada del "Works Wheel" (21st.dev). Es un anillo que se abre en un
     tambor 3D al girar. Todo el CSS es presentacional; la geometria y las
     transforms las escribe rueda-servicios.js en un solo paso de rAF. */
  /* El contenedor que el HTML declara. El motor le añade .rueda, así que aquí
     solo se declara que ocupa la pantalla: el resto lo pone la clase .rueda.
     Sin esta regla, el verificador avisa de una clase usada en el HTML que no
     tiene estilo — y con razón: así fue como "netia" salió naranja (§ hallazgo
     de la Fase 1: nunca dejes una clase del HTML sin regla). */
  .rueda-host{
    position:relative;
    block-size:100%;
    inline-size:100%;
  }
  .rueda{
    position:fixed; inset:0;
    /* z-index de la ESCALERA (§6), no el 6 suelto de ds-v2. La portada vive en
       --z-contenido, así que la rueda empata a ese nivel y gana por ir DESPUÉS
       en el DOM. No se usa --z-cabecera: la cabecera (logo + tema) tiene que
       quedar encima para poder cambiar de tema y volver. */
    z-index:var(--z-contenido);
    background:transparent;             /* deja ver el fondo neuronal */
    overflow:hidden; user-select:none;
    opacity:0; pointer-events:none;      /* oculta hasta que INICIAR la abre */
    /* visibility se hereda SIEMPRE, a diferencia de opacity: las .rueda-cara
       viven en un contexto 3D propio (preserve-3d + backface-visibility) y
       seguian pintando su fondo/borde/sombra a traves de la pagina. Era el
       recuadro tenue que asomaba bajo el boton Volver al pasar los reflejos.
       visibility:hidden las saca del pintado sin tocar su geometria 3D. */
    visibility:hidden;
    transition:opacity .6s ease, visibility 0s linear .6s;
  }
  .rueda.abierta{opacity:1; pointer-events:auto; visibility:visible;
    transition:opacity .6s ease, visibility 0s linear 0s}
  /* Con el overlay abierto se oculta de inmediato, sin esperar el fundido. */
  /* Sin !important: `body.overlay-abierto #ruedaServicios` (id + clase padre)
     ya gana a `.rueda.abierta` (dos clases) por especificidad. Los !important
     venian de ds-v2, donde el selector era mas debil. */
  body.overlay-abierto #ruedaServicios{
    opacity:0; visibility:hidden; transition:none}

  /* AVISO QUE LLAMA AL SCROLL: abajo, donde estaba antes. Color --boton
     (NARANJA en tema oscuro / AZUL en tema claro). Se oculta al pasar los
     100vh de scroll que "abren" el tambor. */
  .aviso-scroll-rueda{
    position:absolute; left:0; right:0; bottom:5.5vh; margin:0;
    display:flex; align-items:center; justify-content:center; gap:8px;
    font-size:1rem; font-weight:600; letter-spacing:.02em;
    color:var(--boton);
    text-shadow:0 2px 12px color-mix(in srgb, var(--boton) 45%, transparent);
    opacity:1; transition:opacity .5s ease, transform .5s ease;
    pointer-events:none;
  }
  .aviso-scroll-rueda svg{width:20px;height:20px;animation:latidoScroll 1.6s ease-in-out infinite}
  @keyframes latidoScroll{
    0%,100%{transform:translateY(0)}
    50%{transform:translateY(4px)}
  }
  .aviso-scroll-rueda.oculto{opacity:0; transform:translateY(12px)}

  .rueda-stage{
    position:absolute; inset:0; outline:none;
    /* TOUCH: la rueda gira en VERTICAL, pero touch-action:pan-x decia al
       navegador "aqui solo se desliza en horizontal". Resultado: en tablet y
       telefono el gesto vertical se peleaba con el navegador y costaba
       arrastrar (Oz: "el touch no es muy amigable, es dificil"). Con `none`
       el navegador entrega TODOS los gestos a la rueda.
       OJO: `none` bloquea el scroll de la pagina sobre el escenario, que es
       justo lo que se quiere: ahi manda la rueda. */
    cursor:grab; touch-action:none;
    perspective:800px;                  /* la ajusta el JS a la medida real */
  }
  .rueda-stage:active{cursor:grabbing}
  .rueda-stage:focus-visible{outline:2px solid var(--boton); outline-offset:-6px}

  .rueda-drum{
    position:absolute; top:50%; left:50%;
    transform-style:preserve-3d;
  }

  .rueda-tarjeta{
    position:absolute; display:block; text-decoration:none;
    backface-visibility:hidden;
    transition:opacity .3s ease;
    /* width/height los fija el JS en px (M.cardW/M.cardH). Se declaran aqui
       para que el hijo con height:100%/inset:0 resuelva SIEMPRE al mismo
       alto: sin esto, .rueda-cara colapsaba a la altura intrinseca del
       <video> y el fondo #0A0E14 asomaba por debajo (la "banda" de 65px). */
  }
  .rueda-cara{
    /* inset:0 en vez de 100%: no depende de que el padre tenga alto resuelto,
       clava las 4 esquinas al marco de la tarjeta. */
    position:absolute; inset:0;
    display:block;
    /* El video/imagen de dentro NO debe capturar el puntero: si lo captura, el
       clic cae en el <video> y no en la tarjeta, y la tarjeta no se abre. El
       clic tiene que llegar SIEMPRE a .rueda-tarjeta. */
    pointer-events:none;
    /* isolation:isolate + overflow:hidden = recorte REAL a ras del marco.
       Sin isolate el navegador puede crear un contexto de apilado que deja
       asomar el hijo escalado por las esquinas del border-radius. */
    overflow:hidden; isolation:isolate;
    border-radius:14px;
    background:var(--superficie); border:1px solid var(--borde);
    box-shadow:0 18px 40px -18px rgba(0,0,0,.55);
    transform-origin:center;
  }
  /* El video/imagen LLENA el marco con object-fit:cover. SIN transform:scale:
     escalar el hijo lo sacaba 0.5-1.2px por los 4 lados y el fondo #0A0E14
     asomaba por las esquinas del border-radius (la "banda" que se veia).
     El cover ya llena el marco: la diferencia de ratio es 0.1% (<1px). */
  .rueda-cara img{width:100%; height:100%; object-fit:cover; display:block}
  .rueda-cara video{width:100%; height:100%; object-fit:cover; display:block}

  /* Tarjeta SIN imagen (provisional): numero grande + nombre, en la paleta */
  .rueda-cara-texto{
    display:flex; flex-direction:column; justify-content:space-between; gap:2px;
    padding:14px 16px;
    background:
      radial-gradient(120% 90% at 12% 8%, rgba(255,153,0,.22), transparent 58%),
      radial-gradient(120% 90% at 88% 92%, rgba(30,111,235,.22), transparent 58%),
      var(--superficie);
  }
  .rueda-num{
    position:absolute; top:12px; left:14px;
    font-size:.72rem; letter-spacing:.18em; font-weight:500;
    /* numeros de tarjeta: naranja en tema oscuro, azul en tema claro */
    color:var(--boton);
  }
  .rueda-nombre-cara{
    font-size:clamp(.9rem,1.5vw,1.15rem); font-weight:600; line-height:1.15;
    color:var(--fg); letter-spacing:-.01em;
    margin-top:auto;          /* empuja el titulo ABAJO (alineado al fondo) */
  }

  /* titulo del anillo (centro) y BLOQUE de texto de la izquierda (titulo del
     servicio del frente + boton "Ver mas"). El boton NO va en la tarjeta. */
  .rueda-titulo-anillo,
  .rueda-titulo-frente{
    position:absolute; letter-spacing:-.02em;
    color:var(--fg);
  }
  .rueda-titulo-anillo{
    inset:0; display:grid; place-items:center;
    /* NEGRITA pedida por Oz (antes 300: era un trazo muy fino). */
    font-weight:700; pointer-events:none;
    /* "Servicios" del centro: naranja en tema oscuro, azul en tema claro */
    color:var(--boton);
  }
  .rueda-titulo-frente{
    top:50%; left:7%; transform:translateY(-50%);
    display:flex; flex-direction:column; align-items:flex-start; gap:18px;
    max-width:34%;
    font-weight:600; opacity:0;
    transition:opacity .3s ease;
    /* El BLOQUE no captura el puntero: la rueda sigue girando por debajo. */
    pointer-events:none;
    /* Y por encima del escenario: el stage es `inset:0` y, sin z-index, el
       orden del DOM decide. Con un nivel de la ESCALERA (§6) no depende de eso.
       --z-contenido es el nivel de contenido sobre el fondo; el stage no
       declara z-index, así que con esto el bloque queda encima. */
    z-index:var(--z-contenido);
  }
  .rueda-titulo-frente.abierto{pointer-events:auto}

  /* ==========================================================================
     EL BOTÓN SÍ RECIBE EL PUNTERO — LA TRAMPA QUE COSTÓ ESTA VUELTA
     --------------------------------------------------------------------------
     `pointer-events: none` en el padre SE HEREDA: los hijos también lo tienen,
     aunque pongan `pointer-events: auto` no basta si no se declara.

     Aquí faltaba esta regla. El comentario del bloque decía "solo el botón
     recibe el puntero", pero NADIE devolvía el puntero al botón. Resultado:
     Oz pulsaba "Ver más" y no pasaba nada, porque el gesto se lo quedaba la
     rueda (`touch-action: none` + `setPointerCapture` en `.rueda-stage`).

     Se devuelve SOLO al botón, no al bloque: el título debe seguir dejando
     arrastrar la rueda por debajo.
     ========================================================================== */
  .rueda-titulo-frente .rueda-ver{
    pointer-events:auto;
  }
  .rueda-nombre-frente{
    font-size:clamp(1.4rem, 2.6vw, 2.6rem); line-height:1.06;
    font-weight:600;
    /* texto sobre el boton: naranja en tema oscuro, azul en tema claro
       (mismo criterio de "detalles" que el resto de la pantalla) */
    color:var(--boton);
  }

  /* Boton "Ver mas" del TEXTO DE LA IZQUIERDA: MISMO estilo que el boton de
     entrar (.btn-metal): transparente, borde+texto en --boton (naranja oscuro /
     azul claro) y relleno con banda de brillo al pasar el raton. */
  .rueda-ver{
    position:relative; overflow:hidden; isolation:isolate;
    display:inline-flex; align-items:center; gap:8px;
    padding:12px 26px; border-radius:100px;
    font:inherit; font-size:clamp(.82rem,1.4vw,.95rem); font-weight:500;
    letter-spacing:.06em; text-transform:uppercase;
    color:var(--boton);
    background:transparent;
    border:1.5px solid var(--boton);
    box-shadow:0 0 0 rgba(var(--boton-rgb),0);
    cursor:pointer;
    transition:
      color        .30s cubic-bezier(.4,0,.2,1),
      border-color .30s cubic-bezier(.4,0,.2,1),
      box-shadow   .34s cubic-bezier(.4,0,.2,1),
      transform    .30s cubic-bezier(.4,0,.2,1);
  }
  .rueda-ver::before{
    /* z-index LOCAL, no de la escalera §6: .rueda-ver tiene isolation:isolate,
       así que estos -1/2 viven SOLO dentro de su propio contexto y no compiten
       con la página. El -1 pone el relleno detrás del texto y el 2 pone el
       brillo delante: son capas del botón, no de la página. */
    content:''; position:absolute; inset:0; z-index:-1; border-radius:inherit;
    background:linear-gradient(180deg,
      color-mix(in srgb, var(--boton) 55%, var(--blanco)) 0%,
      var(--boton) 42%,
      color-mix(in srgb, var(--boton) 80%, var(--negro)) 100%);
    opacity:0;
    transition:opacity .30s cubic-bezier(.4,0,.2,1);
  }
  .rueda-ver:hover{
    color:var(--negro);
    box-shadow:
      0 1px 0 rgba(255,255,255,.5) inset,
      0 -8px 22px rgba(0,0,0,.28) inset,
      0 12px 34px rgba(var(--boton-rgb),.32);
    transform:translateY(-2px);
  }
  .rueda-ver:hover::before{opacity:1}
  .rueda-ver:active{transform:translateY(0) scale(.985); transition:transform .08s ease}
  .rueda-ver::after{
    content:''; position:absolute; top:0; bottom:0; width:38%;
    left:-45%; opacity:0;
    background:linear-gradient(100deg, transparent, rgba(255,255,255,.85), transparent);
    transform:skewX(-18deg);
    animation:brillo 3.6s cubic-bezier(.4,0,.2,1) infinite;
    z-index:2; pointer-events:none;
    transition:opacity .3s;
  }
  .rueda-ver:hover::after{opacity:1; animation-duration:1.6s}
  .rueda-ver svg{width:13px;height:13px}

  /* ==========================================================================
     EQUIPOS TÁCTILES: EL BOTÓN FANTASMA SE VUELVE PRINCIPAL (§3.0j)
     --------------------------------------------------------------------------
     Regla de contrato: en táctil no hay hover, así que un "fantasma" (borde +
     texto de color, sin relleno) se ve apagado y no invita a tocarlo. Tiene
     que ser BOTÓN PRINCIPAL: relleno sólido y texto encima.

     POR QUÉ SE REPITE AQUÍ SI YA ESTÁ EN 04-componentes.css
     04-componentes.css TIENE su `@media (hover:none) .boton.boton--fantasma`,
     pero `05-rueda.css` se carga DESPUÉS y `.rueda-ver` (0,1,0) declara
     `background:transparent` y `border:1.5px solid var(--boton)` con esa misma
     especificidad: por orden de archivo, GANA `.rueda-ver` y el botón seguiría
     fantasma en el móvil.

     Se sube la especificidad a `.rueda-ver.boton--fantasma` (0,2,0) para que
     no dependa del orden de los archivos. No se usa `!important`.
     ========================================================================== */
  @media (hover: none) {
    .rueda-ver.boton--fantasma {
      color: var(--boton-fg);
      background-color: var(--boton);
      border-color: var(--boton);
      box-shadow: none;
    }
    /* Sin hover no hay brillo de barrido ni elevación: se apagan. */
    .rueda-ver::before,
    .rueda-ver::after {
      display: none;
    }
    .rueda-ver:hover {
      color: var(--boton-fg);
      transform: none;
      box-shadow: none;
    }
    /* El feedback pasa a ser `:active`, que sí existe en táctil. */
    .rueda-ver:active {
      transform: scale(0.97);
    }
  }

  /* indice de la derecha: texto mas grande y separado del boton de tema.
     top:14% lo baja lo bastante para no pisar el sol/luna (arriba a la dcha). */
  .rueda-indice{
    position:absolute; top:14%; right:2.8%; margin:0; padding:0;
    list-style:none; text-align:right; line-height:2.35;
    font-size:1.02rem;
    color:var(--mut);
  }
  .rueda-indice button{
    font:inherit; color:inherit; background:none; border:0; cursor:pointer;
    transition:color .2s ease, opacity .2s ease;
  }
  .rueda-indice button:hover{color:var(--boton)}
  /* ACTIVO: naranja en tema oscuro, azul en tema claro. --boton YA vale
     #FF9900 en oscuro y #1E6FEB en claro (html[data-theme="light"]). */
  .rueda-indice button.activo{
    color:var(--boton); font-weight:700;
  }

  /* ==========================================================================
     TABLET (720-1023px): la rueda se corre un 10% a la DERECHA
     --------------------------------------------------------------------------
     Orden de Oz: *"tablet: mover la rueda 10% a la derecha"*.

     POR QUE SE MUEVE EL ESCENARIO Y NO EL TAMBOR
     `.rueda-drum` tiene `left:50%` y el motor le reescribe el `transform` en
     cada frame (rotateX/rotateY). Un translate puesto en CSS lo borraria el
     primer frame de animacion. El escenario (`.rueda-stage`) es un contenedor
     estable que el motor NO toca, asi que se desplaza ese.

     10% del ANCHO de la ventana (`10vw`), no del contenedor: es lo que se lee
     como "un 10% a la derecha" mirando la pantalla.

     Se declara en su propio rango y NO toca el movil: alli el bloque de
     `max-width:720px` pone su propio `translateY`.
     ========================================================================== */
  @media (min-width: 721px) and (max-width: 1023px) {
    .rueda-stage{
      /* El desplazamiento es PROPORCIONAL al armado (§3.0k).
         `--m` lo publica el motor en cada frame: 0 = anillo, 1 = cilindro
         formado. Así la rueda se arma CENTRADA y se corre sola a la derecha
         mientras el cilindro se forma, hasta el 10% al terminar.

         Sin `var(--m)` esto seria un translate fijo y la rueda nacería ya
         desplazada, que es justo lo que Oz no quiere.
         El respaldo `1` es para el primer frame, antes de que el motor
         publique el valor: si faltara, el calc sería invalido y el
         desplazamiento se quedaria en 0. */
      transform: translateX(calc(10vw * var(--m, 1)));
    }
  }

  /* MOVIL: la rueda tambien funciona, pero el indice pasa a la esquina
     inferior izquierda para no chocar con el boton hamburguesa/tema.
     El tamano de TARJETA lo manda el motor (constantes CARD_*); aqui solo
     ajustamos el texto para que se lea bien en pantalla estrecha. */
  @media (max-width:720px){
    .rueda-indice{
      /* LADO DERECHO (orden de Oz). Antes estaba a la IZQUIERDA
         (`left:14px; right:auto; text-align:left`). Se ancla a la derecha con
         el mismo margen de borde que usa la cabecera, y el texto se alinea a
         la derecha. La Y la calcula el script (centrado entre rueda y pie),
         por eso `top:auto; bottom:auto`. */
      top:auto; bottom:auto; left:auto; right:var(--margen-borde); text-align:right;
      /* OJO: `!important` impedia que el script encogiera la letra cuando el
         hueco no daba (en 375x667 y menores el menu se salia 25-54px). El
         tamano lo gobierna centrarIndice; aqui solo se deja el de partida. */
      font-size:.88rem; line-height:1.7;
      max-width:56vw;
      /* MENU DE SERVICIOS: el desplazamiento lo CALCULA el script en cada
         arranque desde la posicion real de la rueda y del aviso (funcion
         centrarIndice). Aqui NO va un translate fijo: un valor en vh solo
         cuadraba en una pantalla concreta (390x844) y en pantallas mas bajas
         el menu se subia encima de la rueda (medido en 360x640 y 375x667). */
    }
    /* LA RUEDA (tambor de tarjetas): sube un 25% de la altura de pantalla.
       OJO: el tambor ya va posicionado en top:50%/left:50% y sus transforms
       los reescribe el motor en cada frame de rAF (rotateX/rotateY...). Un
       translateY aqui lo pisaria el JS. Por eso se desplaza el ESCENARIO
       entero, que es un contenedor estable que el motor no toca. */
    .rueda-stage{
      /* RUEDA CENTRADA EN PANTALLA (orden de Oz, paso 1 del telefono).
         Antes: translateY(-19vh). Ahora 0 -> el stage es `inset:0`, asi que su
         centro cae en el de la ventana. Sin tocar nada mas: si algo se pisa,
         se resuelve despues. */
      transform:translateY(0);
    }
    /* "Servicios" del centro: debe quedar DENTRO de la rueda.
       El titulo vive en .rueda (pantalla completa) con inset:0, asi que se
       centraba en el centro de la PANTALLA (y=422) mientras la rueda se
       movio a y=303: quedaba 119px por debajo, fuera del anillo.
       Se le aplica el MISMO desplazamiento que al escenario para que siga
       a la rueda. */
    .rueda-titulo-anillo{
      /* Igual que .rueda-stage: si uno se mueve y el otro no, "Servicios" se
         descuelga del centro del anillo. */
      transform:translateY(0);
    }
    /* TITULO DEL SERVICIO + "Ver mas" BAJO LA RUEDA (Oz, solo telefono).
       Antes iba a la izquierda, a media altura, y se montaba ENCIMA de la
       rueda (medido en 390x844: bloque 384..460 con la rueda 120..487).
       Ahora va debajo, centrado, y el menu de servicios se reparte el hueco
       restante con el (ver centrarIndice en el script).
       NO se le pone `top` fijo: la posicion la calcula centrarIndice para
       que funcione en cualquier alto de pantalla. Aqui solo se deja
       preparado el flujo y la alineacion. */
    .rueda-titulo-frente{
      left:0; right:0; max-width:none;
      top:auto; bottom:auto;
      transform:none;
      /* ===== TÍTULO Y BOTÓN EN UNA SOLA LÍNEA (orden de Oz) =====
         Título anclado a la IZQUIERDA, botón anclado a la DERECHA.
         `space-between` deja los dos extremos fijos: ninguno de los dos se
         mueve según lo largo que sea el texto del servicio. */
      display:flex;
      flex-direction:row;
      flex-wrap:nowrap;
      align-items:center;
      justify-content:space-between;
      text-align:left;
      gap:10px;
      /* AIRE LATERAL (orden de Oz): el título y el botón no deben quedar
         pegados a los bordes de la pantalla. Se usa el token de margen de
         borde del contrato (--margen-borde), el mismo de la cabecera y el pie,
         para que los tres guarden la misma línea vertical. */
      padding-inline:var(--margen-borde);
    }
    /* El título puede encogerse si es muy largo, pero nunca empuja al botón
       fuera de su sitio (el botón es `flex:0 0 auto`). */
    .rueda-nombre-frente{
      min-width:0;
      text-align:left;
    }
    /* El botón hereda `align-items:center` del bloque, pero medía 11px
       desplazado a la derecha: su `padding-inline` asimétrico (26px dcha por
       18px izq en el tamaño de teléfono) lo descentraba dentro de la columna.
       Se centra explícitamente y se iguala el padding lateral. */
    .rueda-ver{
      /* Antes `align-self:center` (era una columna). Ahora el bloque es fila:
         el botón se ancla al extremo DERECHO y no se desplaza con el texto. */
      align-self:center;
      margin-inline-start:auto;
      flex:0 0 auto;
      /* Padding lateral IGUAL a los dos lados: el 26/18 asimétrico del tamaño
         grande descentraba el botón dentro de la columna centrada (11px
         medidos a la derecha). */
      padding-inline: var(--e-3);
    }
    /* Una sola regla. Antes habia dos (clamp + 1.5rem !important) porque la
       segunda solo servia para pisar a la primera. Es la misma propiedad:
       se queda el valor fijo que Oz aprobo para telefono. */
    /* 2 PUNTOS MENOS (orden de Oz): 1.5rem = 24px -> 1.375rem = 22px. */
    .rueda-nombre-frente{font-size:1.375rem}
    .rueda-nombre-cara{font-size:.82rem}
    .rueda-num{font-size:.62rem}
    .rueda-ver{font-size:.85rem; padding:9px 18px}
  }

