/* =========================================================================
   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. 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 (se encoge con
                         el ancho: ver el bloque responsive del final) */
    --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;
  }

  /* ---------- el salto de 15px al cambiar de pestaña ----------
     Blog mide 613px de alto y cabe en la pantalla, así que no hay barra de
     scroll. Pelis mide 1753px, aparece la barra, y el ancho útil pasa de 1100
     a 1085: la página entera se corre 15px a la izquierda de golpe. Con los
     rieles verticales de más abajo se nota todavía más, porque el marco
     también se mueve.

     scrollbar-gutter:stable reserva el canal siempre, haya barra o no, así que
     el ancho no cambia nunca y no hay salto. Se pone en <html>, no en body:
     el que hace scroll es el elemento raíz.

     En un navegador que no lo soporte simplemente no pasa nada y vuelve el
     salto — no rompe nada. Se descartó overflow-y:scroll (el otro arreglo
     típico) porque deja el riel de la barra a la vista todo el tiempo, y en un
     diseño de líneas de 1px eso mete una franja gris que no pinta nada. */
  html{ scrollbar-gutter:stable }

  /* ---------- 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;
  }
  /* anula el adorno de la hoja base: el lugar y la hora son html real */
  .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.

     line-height por debajo de 1 aprieta las dos líneas a propósito, pero no
     puede bajar de ~.94: la cola de la coma de "Hola," cae justo encima de la
     "N" de "Nico" y a este tamaño se rozan. */
  h1{
    font-size:clamp(2.4rem,7.6vw,6.6rem); letter-spacing:-.05em; line-height:.96; font-weight:700;
    text-wrap:balance;
  }
  h1 .n{ color:var(--accent) }
  /* sin la regla de 1px que cerraba el nombre, el aire que la separaba del
     párrafo pasa a ser margen inferior del título */
  h1::after{ content:none }
  h1{ margin-bottom:clamp(18px,3vh,34px) }


  /* el margen superior lo pone 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 */
  .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; min-width:0;
    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;
  }
  /* sin filete a la derecha del título: el número y el aire de la izquierda ya
     marcan dónde empieza cada columna */
  .cols h2::after{ content:none }

  /* 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) }

  /* ---------- stack: rótulo, y bajo él cada tecnología con su logo ----------
     los logos son de Simple Icons (CC0): un solo path, silueta, sin color de
     marca. Embebidos y con fill:currentColor, como los de github y linkedin,
     así que siguen el blanco y negro y cambian solos con el tema. */
  .stk{
    border-top:1px solid var(--line);
    padding:clamp(24px,3.6vh,44px) 0 clamp(28px,4.4vh,52px);
  }
  /* tres celdas en los mismos ejes que educación · experiencia · bitácora, con
     la misma divisoria vertical: la columna se prolonga hacia abajo en vez de
     abrir una retícula nueva a media página. */
  .stk-list{ display:grid; grid-template-columns:repeat(3,1fr); gap:0; max-width:none }
  .stk-row{ display:block; padding-right:var(--gutter-in) }
  .stk-row + .stk-row{ padding-left:var(--gutter-in) }
  .stk-row:not(:last-child){ border-right:1px solid var(--line) }
  .stk-row dt{ margin-bottom:11px }
  .lg-list{ display:flex; flex-direction:column; gap:10px; margin:0 }
  .lg{
    display:inline-flex; align-items:center; gap:9px;
    font-size:.92rem; color:var(--muted); transition:color .16s ease;
  }
  .lg:hover{ color:var(--text) }
  .lg svg{ flex:0 0 auto; width:15px; height:15px }

  /* 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 ----------
     el rojo de borrar y del corazón, y los emoji de las listas: 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
     agrupadas aquí para poder ajustarlas o quitarlas de una sola vez.

     el criterio: van en versales las palabras que NOMBRAN una parte de la
     página, no las que dicen algo. 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: un texto largo en mayúsculas es ilegible, se pierde la silueta
     de las palabras. cada bloque lleva su espaciado entre letras, porque una
     versal apretada se lee mal.
     ========================================================================= */

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

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

  /* encabezados de grupo: el mes en pelis, el estado en series y manga */
  .tl-label{ text-transform:uppercase; letter-spacing:.12em }

  /* sub-secciones: diario · por ver · archivo */
  .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 }

  /* nombres de sección del hub: Blog · Pelis · Series · Manga · Juegos.
     Llevan su inicial porque son nombres, y porque sin ella la jerarquía
     quedaba al revés: los rótulos CHICOS gritaban en versales (DIARIO,
     JULIO 2026, VIENDO AHORA) mientras el nombre de la sección, que es lo
     más grande de la pantalla, iba en minúscula.

     El texto va con mayúscula en el html y en TITULOS de js/hub.js; esto sólo
     desactiva el text-transform:lowercase que .pelis (styles.css) le impone al
     título. Sin esta línea el html dice "Blog" y la pantalla muestra "blog".

     Las pestañas son <button> y el navegador no les hereda text-transform, así
     que hoy no necesitarían la regla — van igual, porque depender de ese
     detalle del user-agent es justo lo que ya nos falló una vez. */
  #listas-title, .hub-tab{ text-transform:none }

  /* el blog escribe con sus mayúsculas de verdad.
     styles.css trae .pelis{ text-transform:lowercase } y eso cubre TODO el
     #listas, el blog incluido.

     Lo raro era que no cubría el blog COMPLETO, sino a medias, y por un
     detalle del navegador: input, textarea y button no heredan
     text-transform. Los títulos de la lista de posts viven dentro de un
     <button class="post-link">, así que salvaban sus mayúsculas; el post
     abierto es un <article> pelado y las perdía. Resultado: la lista decía
     "Cómo quedé con el CSS", hacías clic, y el post decía "cómo quedé con el
     css". El mismo título escrito de dos formas.

     Y en el cuerpo del post no era sólo estética: el código dejaba de ser
     código. getElementById se veía "getelementbyid" y SELECT * FROM posts
     "select * from posts". Eso nadie lo puede copiar y que le funcione.
     También aplastaba los nombres propios — CSS, INACAP, Cloudflare Pages.

     La vista previa del editor (#bf-preview, un div) tenía el mismo problema.

     Ojo con el alcance: esto es SOLO #tab-blog. Las listas de pelis, series,
     manga y juegos siguen en minúscula, tal como estaban.

     No cambia nada del resto de la pestaña: los botones, los avisos y los
     placeholders ya venían escritos en minúscula en el html y en el js, así
     que quitar el transform los deja igual. Si algún día quieres un rótulo en
     versales aquí, va arriba con los otros, no se toca esta regla. */
  #tab-blog{ text-transform:none }

  /* ---------- 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. */
  /* nada de saltos bruscos donde se puede evitar: el aire lateral se encoge de
     forma continua con el ancho, en vez de cambiar de golpe en un breakpoint. */
  :root{ --gutter:clamp(20px,4.4vw,44px) }

  /* ningún hijo de una retícula puede ser más angosto que su contenido a menos
     que se le diga: sin esto, el correo o un título largo desbordan la columna
     en vez de acomodarse dentro. */
  .hero > *, .intro > *, .cols > section{ min-width:0 }
  .socials{ flex-wrap:wrap; row-gap:12px }
  .nav-loc{ white-space:nowrap }

  @media (max-height:620px), (max-width:900px){
    #cv{ min-height:0 }
    .top{ display:block }
  }

  /* el corte real: por debajo de ~880px la foto ya le quita demasiado ancho a
     la columna de texto (queda un sliver alto y angosto), así que las dos
     columnas del hero y las tres de abajo caen juntas a una sola. */
  @media (max-width:880px){
    .top{ padding:clamp(36px,7vw,56px) 0 }
    /* todo en una columna, en el orden del html:
       nombre · descripción · redes · foto */
    .hero{ grid-template-columns:1fr; gap:clamp(20px,4.5vw,30px) }
    h1, .presento, .socials, .photo-col{ grid-column:1; grid-row:auto }
    /* OJO: styles.css trae .photo-col{ justify-self:end } para pegarla al borde
       derecho en la versión de dos columnas. Apilada, eso la encoge al ancho de
       su contenido más angosto ("click me"), y como la foto mide width:100% de
       ese ancho, terminaba de 55px arrinconada a la derecha. Aquí manda al
       revés: la columna ocupa todo el ancho y la foto se alinea a la izquierda,
       como el resto del bloque. */
    .photo-col{ justify-self:stretch; text-align:left; align-self:auto; width:100% }
    /* sin columna de texto al lado, la foto necesita alto propio otra vez */
    .photo{ width:100%; max-width:clamp(200px,44vw,280px); aspect-ratio:1/1; flex:none }
    .click{ position:static; margin-top:12px; text-align:left }

    /* apiladas, la divisoria deja de ser vertical y pasa a ser horizontal, y va
       de sangre a sangre como la que cierra el hero.

       El truco: la sección se sale del padding lateral del .wrap con un margen
       negativo del mismo tamaño y lo repone como padding propio. El texto no se
       mueve ni un píxel, pero la caja —y con ella el borde— llega a los dos
       bordes de la pantalla. */
    .cols{ grid-template-columns:1fr; gap:0 }
    .cols > section{
      padding:30px var(--gutter) 32px;
      margin-inline:calc(-1 * var(--gutter));
      border-bottom:1px solid var(--line);
    }
    .cols > section:last-child{ border-bottom:none }
    /* hay que repetir el padding aquí: los selectores :nth-child de la versión
       de tres columnas tienen más especificidad que el .cols > section de
       arriba, así que su padding de --gutter-in (30px) le ganaba y dejaba a 02
       y 03 diez píxeles más adentro que 01. */
    .cols > section:nth-child(1),
    .cols > section:nth-child(2){ padding-right:var(--gutter); border-right:none }
    .cols > section:nth-child(2),
    .cols > section:nth-child(3){ padding-left:var(--gutter) }

    /* el stack apila igual que el resto: la divisoria pasa de vertical a
       horizontal. Los selectores repiten la forma de los de arriba
       (`.stk-row + .stk-row`) porque si no, su especificidad mayor le ganaría
       al padding de aquí. */
    .stk-list{ grid-template-columns:1fr }
    .stk-row, .stk-row + .stk-row{ padding:14px 0 }
    .stk-row:not(:last-child){ border-right:none; border-bottom:1px solid var(--line) }
    .stk-row:last-child{ border-right:none }
    .proj-grid{ grid-template-columns:repeat(2,1fr); gap:28px 32px }
  }

  @media (max-width:560px){
    /* en teléfono la foto se va: apilada ya no acompaña al título, sólo empuja
       educación/experiencia media pantalla más abajo. El botón sigue en el html
       (el js que cambia la imagen no se entera), simplemente no se pinta. */
    .photo-col{ display:none }

    /* el hero se queda con el aire que soltaron la foto y las líneas de párrafo
       que sobraban, en vez de que lo herede el bloque de secciones: nombre y
       descripción son lo primero que se lee y necesitan respirar. */
    .top{ padding:clamp(60px,17vw,92px) 0 clamp(52px,14vw,76px) }
    .hero{ gap:clamp(28px,7.5vw,38px) }
    h1{ margin-bottom:clamp(24px,7vw,34px) }
    /* un punto más grande y con más interlínea: en teléfono se lee de cerca y
       en diagonal, no palabra por palabra */
    .presento{ font-size:1.06rem; line-height:1.78 }

    /* el hero va centrado: apilado y sin la foto que hacía de contrapeso a la
       derecha, alineado a la izquierda quedaba todo volcado a un lado.
       text-align se hereda hasta h1, .presento y .socials aunque .intro sea
       display:contents, porque la herencia sigue el html, no la retícula. */
    .hero{ text-align:center }
    /* .socials es flex: text-align no le mueve los ítems, hay que centrarlos
       por el eje principal */
    .socials{ justify-content:center }
    /* el nombre en una sola línea: a este tamaño "Hola, soy Nico" cabe entero y
       partirlo en dos sólo gastaba alto. En una línea sobra ancho, así que aquí
       el tamaño vuelve a atarse al viewport para que ocupe el renglón completo
       en vez de quedarse chico contra el mínimo de 2.4rem. */
    h1{ font-size:clamp(2.2rem,12.5vw,3.4rem) }
    h1 br{ display:none }
    .proj-grid{ grid-template-columns:1fr }
    .controls{ height:50px; gap:14px }
    /* NO tocar aquí las retículas de carátulas (.pcard-grid, .pm-grid). Se probó
       subir el mínimo de 96px a 132px para que en el teléfono cayeran a dos
       columnas en vez de tres; Nico prefiere las tres como estaban. Las listas
       de pelis, series, manga y juegos se quedan con lo que trae styles.css. */
  }

  /* bajo 640px styles.css angosta el riel (padding-left 28px → 22px) pero deja
     el punto donde estaba. Como esta hoja se carga después, su left:-32px le
     gana al -27px de allá y el punto quedaba flotando 10px fuera de la línea.
     Aquí se recoloca sobre el riel angosto: -26 + la mitad del punto (3.5) cae
     justo encima del borde, que está a -23. */
  @media (max-width:640px){
    .node::before{ left:-26px }
  }

  /* teléfonos angostos: el reloj se queda (es el dato que cambia), el lugar se
     va porque es lo primero que empuja la barra fuera de la pantalla. */
  @media (max-width:400px){
    .nav-loc{ font-size:.72rem }
    .nav-loc .loc-city{ display:none }
    .socials a.mail{ font-size:.76rem }
  }
