/* =========================================================================
   rediseño v2 — capa sobre styles.css
   inspiración: opencode.ai · docker.com

   reglas de la casa, respetadas en todo el archivo:
     · nada de cajas ni botones: la estructura la dan líneas de 1px y aire
     · sólo blanco y negro: ni un tono de color, salvo la foto
     · mayúsculas sólo en los rótulos que nombran partes de la página
       (ver el bloque MAYÚSCULAS al final); el resto va en minúscula

   esta hoja se carga DESPUÉS de styles.css y la pisa. para volver al diseño
   anterior basta con borrar el <link> de styles-v2.css en el index.html.
   ========================================================================= */

/* ---------- tokens ----------
   sólo blanco y negro: ni un tono de color en toda la paleta. donde antes el
   acento era azul, ahora el acento ES el blanco puro (o el negro puro en tema
   claro), y la jerarquía la llevan los grises y el grosor de las líneas. */
:root{
    --bg:#0A0A0A;
    --panel:#141414;
    --panel-2:#1A1A1A;
    --text:#F5F5F5;
    --muted:#A1A1A1;
    --faint:#707070;
    --line:#242424;
    --line-2:#3A3A3A;
    --accent:#FFFFFF;
    --accent-soft:rgba(255,255,255,.14);
    --star:#F5F5F5;
    --frame:1088px;
    --gutter:44px;    /* aire contra los rieles del contenedor */
    --gutter-in:30px; /* aire a cada lado de las divisorias internas */
  }
  :root[data-theme="light"]{
    --bg:#FFFFFF;
    --panel:#FAFAFA;
    --panel-2:#F2F2F2;
    --text:#0A0A0A;
    --muted:#565656;
    --faint:#7A7A7A;
    --line:#E4E4E4;
    --line-2:#C8C8C8;
    --accent:#000000;
    --accent-soft:rgba(0,0,0,.10);
    --star:#0A0A0A;
  }

  /* ---------- rieles verticales del contenedor ----------
     dos líneas fijas que recorren toda la página: es lo único que "encuadra",
     y no encierra nada. */
  body{ position:relative }
  body::before{
    content:""; position:fixed; top:0; bottom:0; left:50%;
    width:var(--frame); transform:translateX(-50%);
    border-left:1px solid var(--line); border-right:1px solid var(--line);
    pointer-events:none; z-index:0;
  }
  @media (max-width:1140px){ body::before{ display:none } }
  body > *{ position:relative; z-index:1 }

  .wrap{ max-width:var(--frame); padding:0 var(--gutter) }

  /* ---------- barra superior ---------- */
  .controls{
    justify-content:space-between; gap:22px;
    padding:0 var(--gutter); height:54px; align-items:center;
    border-bottom:1px solid var(--line);
    background:color-mix(in srgb, var(--bg) 88%, transparent);
    backdrop-filter:saturate(140%) blur(8px);
    position:sticky; top:0; z-index:20;
  }
  /* el "~/nico" que iba aquí lo reemplazan el lugar y la hora, que ahora son
     un elemento real del html (esto era un ::before de puro adorno). */
  .controls::before{ content:none }
  .nav-loc{
    margin-right:auto; font-family:var(--mono); font-size:.78rem; color:var(--faint);
  }
  .nav-loc #clock{ color:var(--muted); font-variant-numeric:tabular-nums }
  .ctrl-theme svg{ width:17px; height:17px }
  .ctrl-theme:hover{ color:var(--accent) }
  .ctrl-blog{
    font-size:.8rem; padding:0 0 3px;
    border-bottom:1px solid transparent;
  }
  .ctrl-blog:hover{ color:var(--text); border-bottom-color:var(--line-2) }
  .ctrl-blog.is-active{ color:var(--accent); border-bottom-color:var(--accent) }

  /* ---------- una sola pantalla ----------
     la vista CV ocupa el alto de la ventana: el hero se centra en el espacio
     que sobra y educación/experiencia quedan ancladas abajo, sin scroll. */
  #cv{
    display:flex; flex-direction:column;
    min-height:calc(100dvh - 54px);
  }
  /* IMPORTANTE: el javascript esconde la portada con cv.hidden = true para
     mostrar el blog. una regla de autor (el display:flex de arriba) le gana
     siempre al display:none que el navegador aplica por el atributo hidden,
     así que sin esta línea la portada no se oculta nunca y el blog aparece
     pegado debajo de ella. lo mismo vale para cualquier elemento al que el
     css le fije un display y el js lo oculte con hidden. */
  #cv[hidden]{ display:none }
  /* mismo caso: los formularios de administración se ocultan con hidden y
     .pelis-form les fija display:flex */
  .pelis-form[hidden], .pelis-add[hidden], .pelis-admin[hidden]{ display:none }
  .top{ flex:1 1 auto; display:flex; align-items:center }
  .top > .wrap{ width:100% }
  .cols{ flex:0 0 auto }

  /* ---------- hero ---------- */
  .top{
    position:relative; overflow:hidden;
    padding:clamp(28px,5.5vh,72px) 0; border-bottom:1px solid var(--line);
  }
  /* trama de puntos en un pseudo-elemento, para que el degradado que la
     desvanece no afecte al texto */
  .top::before{
    content:""; position:absolute; inset:0; pointer-events:none;
    background-image:radial-gradient(var(--line) 1px, transparent 1px);
    background-size:26px 26px;
    -webkit-mask-image:linear-gradient(180deg, rgba(0,0,0,.55), transparent 68%);
    mask-image:linear-gradient(180deg, rgba(0,0,0,.55), transparent 68%);
  }
  /* el hero: una columna de texto a la izquierda y la foto a la derecha,
     ocupando todo el alto de esa columna.

       fila 1:  título        ┐
       fila 2:  descripción   ├── columna 1        foto  ── columna 2
       fila 3:  redes         ┘                   (filas 1 a 3)

     .intro no pinta nada por sí misma, así que con display:contents sus hijos
     entran directamente en esta retícula y se colocan fila por fila, sin
     necesidad de envolturas extra en el html. */
  .hero{
    position:relative; display:grid;
    grid-template-columns:1fr auto;
    gap:clamp(18px,3vh,30px) clamp(30px,5vw,64px);
    align-items:start;
  }
  .intro{ display:contents }
  h1{ grid-column:1; grid-row:1 }
  .presento{ grid-column:1; grid-row:2 }
  /* fila 3: las redes */
  .socials{ grid-column:1; grid-row:3 }
  /* la foto abarca las tres filas: su alto es el de toda la columna de texto */
  .photo-col{ grid-column:2; grid-row:1 / 4; align-self:stretch }

  /* el nombre a sangre, en dos líneas, cerrado por una regla de 1px */
  h1{
    font-size:clamp(2.6rem,8.4vw,6.6rem); letter-spacing:-.05em; line-height:.86; font-weight:700;
  }
  h1 .n{ color:var(--accent) }
  h1::after{
    content:""; display:block; height:1px; background:var(--line);
    margin-top:clamp(18px,3vh,34px);
  }


  /* el margen superior lo pone ahora el gap de la retícula del hero */
  .presento{ font-size:1rem; line-height:1.72; margin-top:0; max-width:58ch }
  .presento a{ color:var(--text); border-bottom:1px solid var(--line-2) }
  .presento a:hover{ color:var(--accent); border-color:var(--accent) }

  /* íconos: en fila, alineados a la izquierda bajo la descripción. el margen
     superior lo pone el gap de la retícula, como al resto de las filas. */
  .socials{ display:flex; align-items:center; gap:22px; margin-top:0 }
  .socials a{ color:var(--muted); transition:color .16s ease, transform .16s ease }
  .socials a:hover{ color:var(--accent); transform:translateY(-2px) }
  .socials svg{ width:21px; height:21px }

  /* el correo, como texto junto a los íconos */
  .socials a.mail{
    font-family:var(--mono); font-size:.82rem; color:var(--muted);
    border-bottom:1px solid var(--line-2); padding-bottom:2px;
    transition:color .16s ease, border-color .16s ease;
  }
  .socials a.mail:hover{ color:var(--accent); border-color:var(--accent); transform:none }

  /* la foto: una línea de 1px y ticks de esquina que aparecen al pasar el mouse.
     no tiene alto propio — lo recibe de la columna de texto que tiene al lado —,
     por eso pierde el aspect-ratio fijo. */
  .photo-col{
    display:flex; flex-direction:column; align-items:flex-start;
    align-self:stretch; position:relative;
  }
  .photo{
    position:relative; flex:1 1 auto; min-height:0; aspect-ratio:auto;
    width:clamp(200px,27vw,340px); border-radius:0;
    background:var(--panel); border:1px solid var(--line);
  }
  /* "click me" sale del flujo para no restarle alto a la foto: si contara,
     la foto quedaría más baja que el título por esos ~26px. */
  .click{
    position:absolute; top:100%; left:0; margin:10px 0 0;
    font-size:.74rem; color:var(--faint); white-space:nowrap;
  }
  /* la foto va a color: es el único punto de color de la página, y ese es
     justamente el efecto. */

  /* las fotos del array tienen proporciones distintas entre sí. anclada a los
     cuatro bordes, la imagen ya no puede imponerle su tamaño a la caja: la caja
     manda y la imagen se recorta para llenarla (cover, nunca deformada). así
     todas se ven exactamente del mismo tamaño al ir cambiándolas. */
  .photo img{
    position:absolute; inset:0;
    width:100%; height:100%; object-fit:cover; object-position:center;
    filter:none;
  }
  .photo::before, .photo::after{
    content:""; position:absolute; width:16px; height:16px; z-index:2; pointer-events:none;
    border-color:var(--accent); border-style:solid; opacity:0; transition:opacity .18s ease;
  }
  .photo::before{ top:-1px; left:-1px; border-width:1px 0 0 1px }
  .photo::after{ bottom:-1px; right:-1px; border-width:0 1px 1px 0 }
  .photo:hover{ border-color:var(--line-2) }
  .photo:hover::before, .photo:hover::after{ opacity:1 }

  /* ---------- secciones: grilla de líneas, no de cajas ---------- */
  .cols{
    counter-reset:sec; grid-template-columns:repeat(3,1fr);
    gap:0; margin-top:0; padding-bottom:0;
  }
  .cols > section{ counter-increment:sec; padding:clamp(24px,3.6vh,44px) 0 clamp(28px,4.4vh,52px) }
  /* divisorias verticales entre educación · experiencia · bitácora */
  .cols > section:nth-child(1),
  .cols > section:nth-child(2){ padding-right:var(--gutter-in); border-right:1px solid var(--line) }
  .cols > section:nth-child(2),
  .cols > section:nth-child(3){ padding-left:var(--gutter-in) }
  /* las secciones a todo el ancho se separan con una línea horizontal */
  .col-projects, .stk{ border-top:1px solid var(--line) }

  /* encabezado: 01 · educación ──────────────── */
  .cols h2, .col-projects h2{
    display:flex; align-items:center; gap:14px;
    font-family:var(--mono); font-weight:400; font-size:.82rem; letter-spacing:.02em;
    color:var(--muted); margin-bottom:clamp(16px,2.6vh,30px);
  }
  .cols h2::before{
    content:counter(sec,decimal-leading-zero); color:var(--accent); font-size:.78rem;
  }
  .cols h2::after{ content:""; flex:1; height:1px; background:var(--line) }

  /* riel de bitácora ---------------------------------------------------- */
  .rail{ border-left:1px dashed var(--line-2); gap:clamp(18px,2.8vh,30px) }
  .node::before{
    border-radius:1px; width:7px; height:7px; left:-32px; top:7px; background:var(--accent);
    box-shadow:0 0 0 3px var(--accent-soft);
  }
  .node-ghost::before{
    background:transparent; box-shadow:none; border:1px dashed var(--faint); width:7px; height:7px;
  }
  .ndate{ font-size:.74rem; color:var(--faint); margin-bottom:5px }
  .ehead h3{ font-size:1.08rem; letter-spacing:-.01em }
  .desc{ font-size:.94rem; line-height:1.65; margin-top:5px }
  .stack{ margin-top:8px; font-size:.76rem; color:var(--faint) }
  .desc a.link-emp:hover, .ehead a.link-emp:hover{ color:var(--accent); border-color:var(--accent) }

  /* proyectos: columnas separadas por aire y una línea superior fina */
  .proj-grid{ gap:34px 40px; grid-template-columns:repeat(3,1fr) }
  .proj-grid .entry{ padding-top:18px; border-top:1px solid var(--line); margin:0 }
  .proj-grid .entry:hover{ border-top-color:var(--accent) }
  .proj-grid .entry{ transition:border-color .18s ease }
  .gh:hover, .live:hover{ color:var(--accent) }

  /* ---------- bitácora: últimos posts en la portada ---------- */
  .ultimos{ display:flex; flex-direction:column }
  .ultimo{
    display:block; width:100%; text-align:left; cursor:pointer;
    background:none; border:none; border-bottom:1px solid var(--line);
    padding:0 0 12px; margin-bottom:12px;
    transition:border-color .16s ease;
  }
  .ultimo:last-of-type{ border-bottom:none }
  .ultimo-fecha{
    display:block; font-family:var(--mono); font-size:.72rem; color:var(--faint); margin-bottom:4px;
  }
  .ultimo-titulo{
    display:block; font-family:var(--display); font-weight:600; font-size:.98rem;
    line-height:1.3; color:var(--text); transition:color .16s ease;
  }
  .ultimo:hover{ border-bottom-color:var(--line-2) }
  .ultimo:hover .ultimo-titulo{ color:var(--accent) }
  .ultimos-todos{
    align-self:flex-start; margin-top:6px; padding:0 0 3px; cursor:pointer;
    background:none; border:none; border-bottom:1px solid transparent;
    font-family:var(--mono); font-size:.76rem; color:var(--muted);
    transition:color .16s ease, border-color .16s ease;
  }
  .ultimos-todos:hover{ color:var(--accent); border-bottom-color:var(--accent) }
  .ultimos-msg{ font-family:var(--mono); font-size:.78rem; color:var(--faint) }

  .stk{ padding-top:46px }
  .stk-row dt{ font-size:.78rem; color:var(--faint) }

  footer{ padding:22px 0 44px; font-size:.74rem; border-top:1px solid var(--line) }
  footer a{ border-bottom-color:var(--line-2) }
  footer a:hover{ color:var(--accent) }

  /* ---------- vista blog / listas ---------- */
  .listas, .blog{ padding-top:52px }
  .blog-head{ align-items:baseline; margin-bottom:32px }
  .blog-head h2, #listas-title{
    font-family:var(--display); font-weight:700; font-size:clamp(1.8rem,4vw,2.5rem);
    letter-spacing:-.03em;
  }
  .back:hover{ color:var(--accent) }

  /* pestañas: texto con subrayado, sin caja */
  .hub-tabs{ gap:22px; margin-bottom:30px }
  .hub-tab{ font-size:.84rem; border-bottom:1px solid transparent; padding:0 0 4px }
  .hub-tab:hover{ color:var(--text); border-bottom-color:var(--line-2) }
  .hub-tab.is-active{ color:var(--accent); border-bottom-color:var(--accent) }
  .sub-tab.is-active{ color:var(--accent); border-bottom-color:var(--accent) }
  .sub-tab .n{ color:var(--faint) }

  /* lista de posts: filas separadas por una línea, sin recuadro */
  .post-link{
    border:none; border-bottom:1px solid var(--line); border-radius:0;
    padding:20px 0; background:none;
    transition:border-color .16s ease;
  }
  .post-link:first-child{ border-top:1px solid var(--line) }
  .post-link:hover{ border-bottom-color:var(--accent) }
  .post-link:hover h3{ color:var(--accent) }
  .post-link .date{ font-size:.76rem; color:var(--faint) }

  /* post */
  .post h2{ font-size:1.95rem; letter-spacing:-.03em }
  .post .date{ font-size:.78rem }
  .post a{ color:var(--accent); border-bottom-color:var(--accent) }
  .post pre{ background:var(--panel); border-color:var(--line); padding:16px 18px }
  .post code{ background:var(--panel) }
  .post blockquote{ border-left:2px solid var(--accent); color:var(--muted) }

  /* ---------- listas (pelis / anime / manga) ---------- */
  .tl-rail{ border-left:1px dashed var(--line-2) }
  .tl-rail .tl-label::before{ border-radius:1px; border-color:var(--accent) }
  .tl-activo .tl-label b::before{ background:var(--accent); border-radius:1px }

  .prow{ padding:12px 0; border-bottom:1px solid var(--line) }
  .prow:hover{ border-bottom-color:var(--line-2) }
  .col-stars{ color:var(--star) }
  .col-stars .g.h::before{ color:var(--star) }
  .eps-resumen .col-stars{ color:var(--star) }

  /* controles de admin: texto, no botones */
  .prow-admin button, .post-admin button, .bf-tools button, .eps-todos{
    border:none; background:none; padding:5px 0; margin-left:14px; color:var(--faint);
    border-bottom:1px solid transparent;
  }
  .prow-admin button:hover, .post-admin button:hover, .bf-tools button:hover, .eps-todos:hover{
    color:var(--accent); border-bottom-color:var(--accent); background:none;
  }
  .bf-tools{ gap:0 }
  .bf-tools button{ margin:0 18px 0 0 }

  .hcard-cover{ border-radius:0 }
  .hcard-admin button{ border:none; background:rgba(0,0,0,.55) }
  /* con el acento en blanco, el texto del hover tiene que ser el fondo */
  .hcard-admin button:hover{ background:var(--accent); color:var(--bg) }

  /* ---------- los últimos restos de color ----------
     styles.css trae un rojo fijo para borrar y para el corazón de favoritos, y
     las listas usan emoji de color. aquí se neutraliza todo: la jerarquía la
     lleva el gris, no el matiz. */
  .back-logout{ color:var(--muted) }
  .back-logout:hover{ color:var(--text) }
  .pe-del{ color:var(--muted) }
  .pe-del:hover{ color:var(--text) }
  .pcard-fav{ color:var(--text) }
  /* 🍿 y 🔖 son emoji de color; el filtro los pasa a gris */
  .pcard-cine, .pa-check{ filter:grayscale(1) }

  /* ---------- formularios ----------
     los campos conservan su línea (un input necesita mostrar dónde se escribe),
     pero los botones pasan a ser texto con subrayado. */
  .pelis-admin{ border:none; border-left:1px solid var(--line); background:none; padding:4px 0 4px 26px }
  .pelis-form input, .pelis-form textarea, .pa-search,
  .pa-field input, .pa-field select, .pa-datos textarea, .eps-nota, .eps-fecha{
    background:var(--panel); transition:border-color .14s ease, box-shadow .14s ease;
  }
  .pelis-form input:focus, .pelis-form textarea:focus, .pa-search:focus,
  .pa-field input:focus, .pa-field select:focus, .pa-datos textarea:focus,
  .eps-nota:focus, .eps-fecha:focus{
    border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft);
  }
  .pelis-form button, .pa-datos button[type="submit"], .eps-actions button{
    background:none; color:var(--accent); border:none; border-bottom:1px solid var(--accent);
    border-radius:0; padding:4px 0; align-self:flex-start;
  }
  .pelis-form button:hover, .pa-datos button[type="submit"]:hover, .eps-actions button:hover{
    opacity:1; color:var(--text); border-bottom-color:var(--text);
  }
  .pelis-form button.blog-cancelar, .pelis-form button.bf-prev-btn{
    color:var(--muted); background:none; border:none; border-bottom:1px solid var(--line-2);
  }
  .pelis-form button.blog-cancelar:hover, .pelis-form button.bf-prev-btn:hover{
    color:var(--accent); border-bottom-color:var(--accent);
  }
  .pa-link{ color:var(--accent) }
  .pa-res:hover{ background:var(--panel) }
  .pm-opt:hover{ border-color:var(--accent) }
  .bf-preview{ border-color:var(--line-2) }
  .pa-radio input, .pa-check input, .eps-check input{ accent-color:var(--accent) }

  /* =========================================================================
     MAYÚSCULAS
     todo lo que se pasa a mayúsculas está agrupado aquí, para poder ajustarlo
     o quitarlo de una sola vez. dos cuidados tipográficos:
       · las mayúsculas necesitan MÁS espaciado entre letras que las minúsculas
         (una versal apretada se lee mal), así que cada bloque lleva el suyo;
       · los párrafos NO se tocan. un texto largo en mayúsculas es ilegible:
         se pierde la silueta de las palabras, que es de lo que se agarra el ojo.
     ========================================================================= */

  /* el criterio: van en versales las palabras que NOMBRAN una parte de la
     página, no las que dicen algo. son señales, no contenido — por eso pueden
     ir en mayúscula sin que nadie las "lea" de verdad, y así se distinguen a
     simple vista de lo que sí hay que leer.

     quedan fuera, a propósito: el nombre, los títulos de entradas y posts, las
     fechas, las redes, los tabs y todos los párrafos. */

  /* etiquetas de sección: 01 · EDUCACIÓN */
  .cols h2, .col-projects h2{ text-transform:uppercase; letter-spacing:.16em }

  /* el separador de las listas (el rótulo que parte "ahora" del historial) */
  .tl-sep span{ text-transform:uppercase; letter-spacing:.16em }

  /* encabezados de grupo de las listas: el mes en pelis, el estado en series
     y manga. no son contenido, dicen bajo qué criterio está agrupado lo de
     abajo — misma función que una etiqueta de sección. */
  .tl-label{ text-transform:uppercase; letter-spacing:.12em }

  /* sub-secciones (diario · en curso · archivo): nombran partes, no dicen nada */
  .sub-tab{ text-transform:uppercase; letter-spacing:.12em }

  /* etiquetas de los campos del formulario y de las filas de stack */
  .pa-field, .stk-row dt{ text-transform:uppercase; letter-spacing:.12em }

  /* los tabs principales (blog · pelis · series…) se quedan en minúscula a
     propósito: son la navegación primaria, se leen como contenido. */

  /* ---------- foco visible ---------- */
  a:focus-visible, .photo:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible{
    outline:2px solid var(--accent); outline-offset:3px; border-radius:0;
  }

  /* ---------- responsive ----------
     el encaje en una pantalla se suelta cuando ya no cabe de forma cómoda:
     pantallas bajas y móviles vuelven a flujo normal con scroll. */
  @media (max-height:620px), (max-width:900px){
    #cv{ min-height:0 }
    .top{ display:block }
  }
  @media (max-width:900px){
    .cols{ grid-template-columns:1fr }
    .cols > section{ padding:34px 0 36px; border-bottom:1px solid var(--line) }
    .cols > section:last-child{ border-bottom:none }
    .cols > section:nth-child(1),
    .cols > section:nth-child(2){ padding-right:0; border-right:none }
    .cols > section:nth-child(2),
    .cols > section:nth-child(3){ padding-left:0 }
    .proj-grid{ grid-template-columns:repeat(2,1fr); gap:28px 32px }
  }
  @media (max-width:640px){
    :root{ --gutter:22px }
    .top{ padding:52px 0 48px }
    /* en móvil las dos columnas se deshacen y todo cae en una, en el orden del
       html: nombre · descripción · redes · foto */
    .hero{ grid-template-columns:1fr; gap:26px }
    h1, .presento, .socials, .photo-col{ grid-column:1; grid-row:auto }
    /* sin columna de texto al lado, la foto necesita alto propio otra vez */
    .photo-col{ align-self:auto }
    .photo{ width:100%; max-width:260px; aspect-ratio:1/1; flex:none }
    .click{ position:static; margin-top:12px }
    /* con la url completa siguen apiladas: en fila no cabrían */
    .socials{ gap:16px }
    .proj-grid{ grid-template-columns:1fr }
    .controls{ height:50px }
  }
