/* ============================================================
   Sahuquillo de Arriba — tokens
   Fuente de verdad: Design System "Sahuquillo de Arriba"
   (https://claude.ai/artifact/BkE9DSu8oUuND7nyNSd7BQ)
   No añadir colores, familias o tamaños sin confirmarlo ahí.
   ============================================================ */

/* Fuentes servidas desde la propia web (no desde Google): no se envía
   la IP del visitante a terceros y cargan antes. Solo el subconjunto
   latino, que cubre castellano y valenciano. */
@font-face {
  font-family: "Hind";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/hind-400.woff2") format("woff2");
}
@font-face {
  font-family: "Hind";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/hind-700.woff2") format("woff2");
}
@font-face {
  font-family: "Courier Prime";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/courier-prime-400.woff2") format("woff2");
}
@font-face {
  font-family: "Courier Prime";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/courier-prime-400-italic.woff2") format("woff2");
}
@font-face {
  font-family: "Courier Prime";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/courier-prime-700.woff2") format("woff2");
}

:root {
  /* Color — 5 tokens confirmados, un solo tema */
  --color-brand-blue: #191970;
  --color-surface: #e7e8e3;
  --color-text-paragraph: #363636;
  --color-blue-secondary: #6f81a6;
  --color-accent: #db3700;

  /* Tipografía — dos familias confirmadas */
  --font-sans: "Hind", ui-sans-serif, sans-serif; /* titulares */
  --font-mono: "Courier Prime", ui-monospace, monospace; /* cuerpo */

  /*
   * Escala tipográfica WEB — provisional.
   * El sistema de diseño solo confirma tamaños calibrados para el
   * documento Word de referencia del estudio, y señala explícitamente
   * que la web necesita su propia escala, "aún sin definir". Esta
   * escala se acerca a la densidad tipográfica de la web actual
   * (texto pequeño, informativo, tipo ficha técnica) sin bajar de un
   * tamaño legible en pantalla. Pendiente de confirmar con el estudio.
   */
  --text-h1: clamp(1.75rem, 1.3rem + 2vw, 2.75rem);
  --text-h2: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
  --text-h3: clamp(0.95rem, 0.9rem + 0.2vw, 1.05rem);
  --text-body: 0.95rem;
  --text-small: 0.8125rem;
  --text-caption: 0.8125rem;
  --text-tag: 0.8125rem;

  --space-xs: 0.5rem;
  --space-sm: 1rem;
  --space-md: 2rem;
  --space-lg: 3.5rem;
  --space-xl: 6rem;

  --sidebar-width: 21rem;
  --content-narrow: 38rem;

  /* Alto fijo de la cabecera móvil (logo + "+"), ver .mobile-bar: con
     un valor fijo en vez de intrínseco se puede restar con calc() en
     .shell--inicio para que la composición de una sola pantalla siga
     cuadrando exactamente. */
  --mobile-bar-height: 7rem;
}

/* ============================================================
   Reset base
   ============================================================ */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  /* Reserva siempre el hueco de la barra de scroll, esté o no esté
     presente, para que el ancho disponible (y por tanto todo el layout
     calculado en vw) no cambie entre páginas con scroll (fichas de
     proyecto) y páginas sin scroll (Inicio, Proyectos, Estudio). El
     hueco se mantiene, pero la barra en sí queda oculta (ver abajo). */
  overflow-y: scroll;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

html::-webkit-scrollbar {
  display: none;
}

body {
  margin: 0;
  background: var(--color-surface);
  color: var(--color-text-paragraph);
  font-family: var(--font-mono);
  font-size: var(--text-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Las fotos llevan <picture> para ofrecer versiones WebP (shortcode
   "foto"); display: contents hace que la maquetación trate la <img>
   como si estuviera directamente en su <figure>, igual que antes. */
picture {
  display: contents;
}

/* "Reducir movimiento" del sistema: sin transiciones ni scroll animado
   por CSS (las marcas a mano ya se dibujan quietas desde su JS). */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

a {
  color: inherit;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

h1,
h2,
h3,
p,
figure,
dl,
dd,
address {
  margin: 0;
}

:focus-visible {
  outline: 2px solid var(--color-brand-blue);
  outline-offset: 3px;
}

/* ============================================================
   Tipografía
   ============================================================ */

.h1 {
  font-family: var(--font-sans);
  font-size: var(--text-h1);
  font-weight: 700;
  line-height: 1.05;
  text-transform: uppercase;
  color: var(--color-brand-blue);
  letter-spacing: -0.01em;
}

.h2 {
  font-family: var(--font-mono);
  font-size: var(--text-h2);
  font-weight: 700;
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--color-brand-blue);
}

.h3 {
  font-family: var(--font-mono);
  font-size: var(--text-h3);
  font-weight: 700;
  line-height: 1.4;
  color: var(--color-text-paragraph);
}

.body-lead {
  font-size: 1rem;
  line-height: 1.7;
}

.caption {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-style: italic;
  color: var(--color-blue-secondary);
  line-height: 1.5;
}

.tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-tag);
  letter-spacing: 0.05em;
  color: var(--color-blue-secondary);
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-tag);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.skip-link {
  position: absolute;
  left: -999px;
  top: auto;
  background: var(--color-brand-blue);
  color: var(--color-surface);
  padding: var(--space-xs) var(--space-sm);
  z-index: 100;
}

.skip-link:focus {
  left: var(--space-sm);
  top: var(--space-sm);
}

/* Texto solo para lectores de pantalla y buscadores (p. ej. el <h1> de
   páginas cuyo título ya se ve de otra forma en la maquetación). */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Los encabezados de la barra lateral son <h1>/<h2> por semántica, pero
   se ven como el texto que los rodea. */
.sidebar-heading {
  font-size: inherit;
  font-weight: inherit;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: var(--text-tag);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-decoration: none;
  padding: 0.75rem 1.25rem;
  border: 1px solid var(--color-brand-blue);
  color: var(--color-brand-blue);
  transition: background-color 0.15s ease, color 0.15s ease;
}

.btn:hover {
  background: var(--color-brand-blue);
  color: var(--color-surface);
}

.btn--solid {
  background: var(--color-brand-blue);
  color: var(--color-surface);
}

.btn--solid:hover {
  background: var(--color-text-paragraph);
  border-color: var(--color-text-paragraph);
}

.prose {
  max-width: var(--content-narrow);
  position: relative;
}

.prose p + p {
  margin-top: var(--space-sm);
}

/* ============================================================
   "Marca a mano" — subrayado irregular en brand-blue.
   Uso puntual: nunca como recurso repetido. Tiene que tener acabado
   de bolígrafo real (grosor variable, bordes irregulares, grano de
   tinta): escaneado o generado por código con esa textura, nunca una
   fuente manuscrita ni una línea vectorial limpia. Referencia: el
   tachón de proyectos visitados (assets/js/project-strike.js).
   ============================================================ */

.mark-underline {
  position: relative;
  display: inline-block;
}

/* ============================================================
   Shell — estructura clonada de la web actual: sidebar fija
   (identidad + contacto + contenido variable) + panel de
   contenido a la derecha con su propia navegación.
   ============================================================ */

.shell {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "sidebar nav"
    "sidebar main";
  align-items: start;
  min-height: 100vh;
}

.content-nav {
  grid-area: nav;
}

.sidebar {
  grid-area: sidebar;
  padding: var(--space-md) var(--space-md) var(--space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  position: sticky;
  top: 0;
  /* min-height (not a fixed height) so a short sidebar still sticks for
     a full viewport, matching the photo's sticky release point, but a
     long project list simply grows the row instead of clipping into its
     own inner scrollbar. */
  min-height: 100vh;
  overflow-y: visible;
}

.sidebar__body {
  font-size: var(--text-small);
  line-height: 1.6;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  flex: 1;
  min-height: 0;
}

.content-pane {
  grid-area: main;
  min-width: 0;
  padding: 0 var(--space-md) var(--space-xl);
}

/* ---------------- Inicio: split 50/50 + nav superpuesto ----------------
   Provisional según el mockup de Inicio: composición fija de un solo
   viewport, columna izquierda igual de ancha que la foto. El nav vive
   sobre la foto hasta que se diseñe un header definitivo. ---------------- */

/* En el body (no en .shell) para que también alcance el contenido de
   {% block after %}, que vive fuera de .shell como hermano suyo. */
body.shell--split {
  --text-small: 0.6875rem;
  --text-tag: 0.6875rem;
}

.shell--split {
  grid-template-columns: 1fr 1fr;
  grid-template-areas: "sidebar main";
}

/* Medido por muestreo de píxeles directo de dos fuentes (el PNG del
   mockup a 5692px y una captura tuya a 1530px, resultados consistentes
   entre ambas): margen izquierdo ~6.9% del viewport, logo ~6.3% del
   viewport (antes salía la mitad de grande porque no escalaba con
   ventanas anchas), listado indentado ~3% extra, firma ~11.3% extra.
   Uso vw/vh en vez de rem para que la proporción se mantenga sea cual
   sea el ancho real de la ventana, ya que esto es una composición fija
   de un solo viewport, no contenido que fluye. */

.shell--split .sidebar {
  padding-top: 5.4vh;
  padding-left: 6.9vw;
  color: var(--color-brand-blue);
  gap: var(--space-sm);
}

.shell--split .identity {
  line-height: 1.4;
  gap: 0;
}

.shell--split .identity__logo {
  width: 8.5rem;
}

.shell--split .identity__date {
  margin-bottom: 0.6rem;
}

/* Segundo nivel tipográfico: la identidad (nombre/contacto) va en
   --text-small, pero "Bienvenidos", su párrafo, "Nuestros proyectos",
   el listado y la firma van en un cuerpo visiblemente mayor — medido
   por comparación directa de ancho de carácter contra la identidad. */
.shell--split .sidebar-measure,
.shell--split .sidebar-signoff {
  font-size: var(--text-small);
}

.shell--split .sidebar-measure {
  max-width: 24vw;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  line-height: 1.24;
}

.shell--split .sidebar-heading {
  font-weight: 400;
  font-size: inherit;
  color: inherit;
  text-transform: none;
}

/* Indentación extra del listado de proyectos y la firma, medida en el
   mockup: el listado empieza ~3vw más adentro que el margen general, y
   la firma ~11.3vw más adentro. */
/* Gap más ajustado que el 0.4rem base: con 13+ proyectos en la lista,
   el gap por defecto hacía que el sidebar midiera más que la pantalla
   en ventanas no muy altas, forzando scroll en páginas que deben ser
   de un solo viewport (Inicio, Proyectos, fichas). */
.shell--split .project-list {
  margin-left: 3vw;
  gap: 0.15rem;
  /* Cada proyecto en una sola línea siempre que quepa: el listado toma
     su ancho natural, hasta el respiro antes de la foto (la columna
     termina en el 50% de la pantalla). Antes se limitaba a 24vw y en
     ventanas medias se partía en 2-3 líneas. */
  width: max-content;
  max-width: calc(50vw - 6.9vw - 3vw - var(--space-lg));
}

.shell--split .sidebar-signoff {
  align-self: flex-start;
  width: 24vw;
  text-align: right;
  margin-top: auto;
  padding-top: var(--space-md);
}

/* Enlace al aviso legal, bajo la firma de Estudio (solo ahí, no en Inicio). */
.sidebar-legal {
  align-self: flex-start;
  width: 24vw;
  margin: 0;
  text-align: right;
  /* Mismo estilo que la línea del pie de las fichas (.site-footer p). */
  font-family: var(--font-mono);
  font-size: var(--text-tag);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-blue-secondary);
}

.sidebar-legal a:hover {
  color: var(--color-brand-blue);
}

/* Aviso legal: el texto ocupa toda la columna izquierda, hasta la mitad
   de la pantalla (menos un respiro antes de la foto/centro). */
.aviso-page .sidebar-measure {
  max-width: calc(50vw - 6.9vw - var(--space-md));
}

/* Proyectos: a diferencia de Inicio y de las fichas (donde el listado
   se recorta con un "…" si crece demasiado, ver
   assets/js/project-list-fit.js), aquí el listado tiene que verse
   siempre completo — así que en vez de recortar, es el propio listado
   el que gana scroll interno, con la firma siempre visible debajo. */
.shell--proyectos .sidebar {
  height: 100vh;
}

.shell--proyectos .sidebar-measure,
.shell--proyectos .sidebar-measure > div {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.shell--proyectos .project-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Se desplaza con la rueda o el gesto, pero sin barra visible: una
     flecha hacia abajo avisa de que hay más (ver project-list-scroll.js). */
  scrollbar-width: none;
}

.shell--proyectos .project-list::-webkit-scrollbar {
  display: none;
}

.project-scroll {
  flex: none;
  align-self: flex-start;
  margin-left: 3vw;
  padding: 0.2rem 0;
  width: 1.6rem;
  height: 1.4rem;
  background: none;
  border: 0;
  color: var(--color-blue-secondary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  transition: opacity 0.2s, color 0.15s;
}

.project-scroll:hover {
  color: var(--color-brand-blue);
}

.project-scroll svg {
  width: 0.9rem;
  height: 0.9rem;
}

.project-scroll[hidden] {
  display: flex;
  visibility: hidden;
  opacity: 0;
}

.shell--split .content-pane {
  padding: 0;
  height: 100vh;
  overflow: hidden;
  position: sticky;
  top: 0;
  align-self: start;
}

/* Prensa: ocupa todo el ancho (no solo la columna de texto) y reparte
   el listado en columnas en paralelo — como las separatas de
   proyectos de Plantea — en vez de una lista con scroll interno. El
   alto disponible lo fija .sidebar (100vh menos la identidad y el
   título); "columns" calcula sola cuántas columnas caben y las va
   llenando de arriba abajo, así que nunca hace falta scroll. La firma
   cierra la composición abajo a la derecha. */
.shell--prensa .sidebar {
  height: 100vh;
  /* A diferencia del resto de páginas --split (sidebar al 50%, foto en
     el otro 50%), Prensa no tiene foto: la columna de texto ocupa
     todo el ancho para que quepan las columnas en paralelo. */
  grid-column: 1 / -1;
  /* Mismo margen derecho que el nav (ver .content-nav--overlay,
     right:6.9vw), para que la firma quede alineada con "Prensa" en vez
     del padding de --space-md de cualquier barra lateral normal. */
  padding-right: 6.9vw;
}

.shell--prensa .sidebar,
.shell--prensa .sidebar__body {
  gap: var(--space-md);
}

/* El panel de contenido (vacío en Prensa) quedaba encima de las
   columnas de la derecha y se tragaba los clics de sus enlaces. */
.shell--prensa .content-pane {
  pointer-events: none;
}

.shell--prensa .sidebar-measure {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  max-width: none;
  gap: 0;
}

.press-columns {
  display: flex;
  align-items: flex-end;
  gap: var(--space-xl);
  flex: 1 1 auto;
  min-height: 0;
  /* Mismo espacio que separa la identidad de "Prensa," (ver
     .shell--prensa .sidebar), para que los dos saltos de párrafo
     pesen igual en vez de uno mucho más ajustado que el otro. */
  margin-top: var(--space-md);
}

.press-list__items {
  columns: 12rem;
  column-gap: var(--space-lg);
  flex: 1 1 auto;
  max-height: 100%;
  overflow: hidden;
  /* .press-columns alinea sus hijos abajo (align-items:flex-end) para
     que la firma quede siempre al pie; sin esto el listado, más corto
     que la fila, se pegaba también abajo, abriendo un hueco enorme
     debajo del título. */
  align-self: flex-start;
}

.press-columns__signoff {
  flex: 0 0 auto;
  white-space: nowrap;
}

.press-list__group {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  break-inside: avoid;
  margin-bottom: var(--space-sm);
}

.press-list__group-title {
  font-weight: 700;
}

.press-list__group-title a {
  color: inherit;
  text-decoration: none;
}

.press-list__group-title a:hover {
  color: var(--color-brand-blue);
  text-decoration: underline;
}

.press-list__group-items {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.press-list__medio {
  text-transform: uppercase;
}

.press-list__item a {
  color: var(--color-blue-secondary);
  text-decoration: none;
}

.press-list__item a:hover {
  color: var(--color-brand-blue);
  text-decoration: underline;
}

.press-list__empty {
  color: var(--color-blue-secondary);
  margin-top: var(--space-sm);
}

.shell--split .content-photo,
.shell--split .content-photo img {
  height: 100vh;
  max-width: none;
}

.shell--split .content-photo img {
  width: 100%;
  object-fit: cover;
}

.content-photo--carousel {
  position: relative;
  overflow: hidden;
}

.content-photo__slide {
  position: absolute;
  inset: 0;
  display: block;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.2s ease;
}

.content-photo__slide.is-active {
  opacity: 1;
  pointer-events: auto;
}

/* Ancla al mismo "alineación derecha" (6.9vw) que el resto de la web,
   así su posición es siempre la misma en cualquier página. */
.content-nav--overlay {
  grid-area: main;
  position: absolute;
  top: var(--space-lg);
  right: 6.9vw;
  z-index: 2;
}

/* Sin el padding-right que trae .content-nav de base (definida más
   abajo, misma especificidad): aquí la posición ya la fija "right",
   así que ese padding solo separaba el texto del borde real de
   alineación derecha. Selector compuesto para ganar por especificidad,
   no por orden de aparición. */
.content-nav.content-nav--overlay {
  padding: 0;
}

/* El menú sobre las fotos va siempre en el azul de marca y en negrita, sea
   cual sea la foto (decisión del estudio, 28/10/2026). El color automático
   según la foto se probó y se retiró: _Archivo/menu-color-automatico. */
.content-nav--overlay .content-nav__link,
.content-nav--overlay .content-nav__link:hover,
.content-nav--overlay .content-nav__link[aria-current="page"] {
  color: var(--color-brand-blue);
  font-weight: 700;
}

/* ---------------- Identidad ---------------- */

.identity {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.identity__logo {
  display: inline-block;
  width: 4.5rem;
}

.identity__logo-mark {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  /* El trazo del sello dentro del SVG deja ~14.65% de margen interno
     (medido por muestreo de píxeles del archivo); se compensa aquí para
     que el trazo visible, no la caja, quede a ras del texto de abajo. */
  margin-left: -14.65%;
  background-color: var(--color-brand-blue);
  -webkit-mask-image: url("/assets/img/logo/logo.svg");
  mask-image: url("/assets/img/logo/logo.svg");
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}

.identity__name {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--color-brand-blue);
  font-size: var(--text-small);
}

.identity__tagline {
  font-size: var(--text-small);
}

.identity__contact {
  display: block;
  font-style: normal;
  font-size: var(--text-small);
  margin-top: 0.25rem;
}

.identity__contact a {
  text-decoration: none;
}

.identity__contact a:hover {
  color: var(--color-brand-blue);
}

.identity__date {
  font-size: var(--text-small);
  color: inherit;
}

.sidebar-signoff {
  align-self: flex-end;
  color: var(--color-brand-blue);
  font-weight: 700;
  font-size: var(--text-small);
}

.identity__social {
  display: inline;
}

/* ---------------- Navegación del panel ---------------- */

.content-nav {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-md) 0 0;
  margin-bottom: var(--space-lg);
}

.content-nav__link {
  font-family: var(--font-mono);
  font-size: var(--text-tag);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-text-paragraph);
  padding-block: 0.25rem;
  border-bottom: 2px solid transparent;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.content-nav__link:hover,
.content-nav__link[aria-current="page"] {
  color: var(--color-brand-blue);
}

/* Subrayado solo como respaldo sin JS para la sección activa; con JS la
   marca el círculo a bolígrafo. Al pasar el cursor solo cambia el color. */
.content-nav__link[aria-current="page"] {
  border-color: var(--color-brand-blue);
}

/* Círculo a bolígrafo en el menú (ver assets/js/nav-circle.js). Con JS
   activo sustituye al subrayado de la sección activa; sin JS se ve el
   subrayado de siempre. */
.content-nav__link {
  position: relative;
}

.js-pen .content-nav__link[aria-current="page"],
.js-pen .content-nav__link.is-circled {
  border-color: transparent;
}

.nav-circle {
  position: absolute;
  overflow: visible;
  pointer-events: none;
  mix-blend-mode: multiply;
  transition: opacity 0.25s ease;
}

.nav-circle.is-leaving {
  opacity: 0;
}

/* ---------------- Intro (Inicio) ---------------- */

.intro-text p + p {
  margin-top: var(--space-sm);
}

/* Estudio: con las bios de Adrián y Guillermo añadidas al párrafo de la
   izquierda, el gap y el interlineado por defecto hacían que la página
   necesitara scroll en una composición pensada para una sola pantalla
   (igual que ocurrió con el listado de proyectos en Inicio). */
.estudio-page .intro-text {
  line-height: 1.1;
}

.estudio-page .intro-text p + p {
  margin-top: 0.375rem;
}

.estudio-page .sidebar {
  gap: var(--space-sm);
}

.estudio-page .sidebar__body {
  gap: var(--space-sm);
}

.estudio-page .sidebar-measure {
  max-width: 36vw;
}

/* La firma y el aviso legal terminan en el mismo borde derecho que los
   párrafos de arriba (el bloque de texto mide 36vw, no los 24vw del
   resto de páginas); el aviso legal, además, algo más abajo. */
@media (min-width: 861px) {
  .estudio-page .sidebar-signoff,
  .estudio-page .sidebar-legal {
    width: 36vw;
  }

  .estudio-page .sidebar-legal {
    margin-top: var(--space-md);
  }
}

/* ---------------- Listado de proyectos (sidebar) ---------------- */

.project-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.project-list a {
  display: block;
  text-decoration: none;
  color: var(--color-blue-secondary);
}

.project-list a:hover,
.project-list a[aria-current="page"] {
  color: var(--color-brand-blue);
}

/* Proyectos visitados: tachón a bolígrafo (ver assets/js/project-strike.js) */
.project-list__title {
  position: relative;
  display: inline-block;
}

.project-list__strike {
  position: absolute;
  left: -3px;
  top: 52%;
  width: calc(100% + 6px);
  height: 0.95em;
  transform: translateY(-50%);
  overflow: visible;
  pointer-events: none;
  mix-blend-mode: multiply;
}

.project-list__strike g > path,
.project-list__strike g > ellipse,
.nav-circle g > path,
.scroll-hint g > path,
.scroll-hint g > ellipse,
.pen-underline g > path,
.pen-underline g > ellipse {
  fill: var(--color-brand-blue);
}

.project-list__strike .is-dense,
.nav-circle .is-dense,
.scroll-hint .is-dense,
.pen-underline .is-dense {
  opacity: 0.45;
}

/* Ficha de proyecto: flecha a bolígrafo que invita a bajar (ver
   assets/js/scroll-hint.js). Junto a la firma de la barra lateral. */
.scroll-hint {
  position: absolute;
  left: 40vw;
  bottom: var(--space-lg);
  width: 2.9rem;
  height: 7rem;
  display: block;
  transition: opacity 0.3s ease;
}

.scroll-hint svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  mix-blend-mode: multiply;
}

.scroll-hint.is-hidden {
  opacity: 0;
  pointer-events: none;
}

@media (max-width: 860px) {
  .scroll-hint {
    display: none;
  }
}

.project-list__strike .is-tail {
  fill: none;
  stroke: var(--color-brand-blue);
  stroke-linecap: round;
  opacity: 0.6;
}

.project-list__pending {
  display: block;
  color: var(--color-blue-secondary);
  opacity: 0.7;
}

/* ---------------- Letra a mano SdA ----------------
   Textos escritos con la letra del estudio (ver assets/js/letra-a-mano.js).
   Uso: <h1 data-letra-a-mano>Casa Kiwi</h1>. El texto real sigue dentro,
   oculto solo a la vista; sin JavaScript se ve el texto normal. */
[data-letra-a-mano] {
  color: var(--color-brand-blue);
}

/* .is-escrito sola (no solo [data-letra-a-mano]): el carrusel escribe
   sus títulos llamando a SdaLetraAMano.write() directamente (ver
   assets/js/carousel.js), sin ese atributo, para no pasar por el
   descubrimiento automático y escribirse todos a la vez. */
.is-escrito .letra-a-mano__texto {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.letra-a-mano__trazo {
  display: block;
  max-width: 100%;
  height: auto;
  overflow: visible;
  mix-blend-mode: multiply;
}

/* ---------------- Placeholder de fotografía ---------------- */

.photo-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-sm);
  background: repeating-linear-gradient(
    135deg,
    rgba(25, 25, 112, 0.08),
    rgba(25, 25, 112, 0.08) 10px,
    transparent 10px,
    transparent 20px
  );
  color: var(--color-blue-secondary);
  font-family: var(--font-mono);
  font-size: var(--text-tag);
  font-style: italic;
}

/* ---------------- Foto principal del panel (Inicio, Contacto, ficha) ---------------- */

.content-photo {
  max-width: 42rem;
}

.content-photo img {
  width: 100%;
  height: auto;
}

.content-photo figcaption {
  margin-top: var(--space-xs);
}

/* ---------------- Ficha de proyecto (detalle) ---------------- */

.content-header {
  margin-bottom: var(--space-md);
}

.meta-list {
  display: flex;
  gap: var(--space-md);
  flex-wrap: wrap;
  margin-top: var(--space-sm);
}

.meta-list dt {
  font-family: var(--font-mono);
  font-size: var(--text-tag);
  color: var(--color-blue-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.meta-list dd {
  font-weight: 700;
  font-size: var(--text-small);
}

/* Pie compartido: solo en páginas que ya tienen scroll (fichas de
   proyecto, Contacto), nunca en Inicio/Estudio/Proyectos, que son de
   un solo viewport. Estilo "membrete" — todo seguido en una línea,
   mayúsculas, con tracking, como una cabecera de papel antigua. */
.site-footer {
  margin-top: calc(var(--space-lg) / 2);
}

.site-footer__bottom {
  /* Simétrico: el mismo espacio entre la línea y el texto que entre el
     texto y el final de la página. */
  padding-block: var(--space-sm);
  border-top: 1px solid rgba(25, 25, 112, 0.15);
  text-align: center;
}

.site-footer p {
  font-family: var(--font-mono);
  font-size: var(--text-tag);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-blue-secondary);
}

.site-footer a {
  color: var(--color-blue-secondary);
  text-decoration: none;
}

.site-footer a:hover {
  color: var(--color-brand-blue);
  text-decoration: underline;
}

.back-to-top {
  position: relative;
  /* El texto no puede partirse en dos líneas: el círculo se calcula a
     partir de su caja, y un enlace partido da una caja falseada (todo el
     ancho de línea del footer) y un círculo enorme mal colocado. */
  white-space: nowrap;
}

/* El círculo de "Volver arriba," un poco más arriba del centro exacto
   del enlace (que además ahora tiene más padding-bottom que arriba,
   así que su centro real ya cae más bajo que el texto). */
.back-to-top .nav-circle {
  transform: translateY(-8px);
}

/* Separado del resto del pie, con el mismo tratamiento que la firma
   "Estudio Sahuquillo de Arriba," de Inicio: negrita, azul principal,
   sin mayúsculas. Centrado en la página (no a la derecha, como la
   firma). */
.site-footer a.site-footer__top {
  /* Ancho ajustado al texto (no display:block a ancho completo): el
     círculo a bolígrafo de back-to-top-hint.js/back-to-top.js se
     calcula a partir de esta caja, y una caja de todo el ancho del
     footer da un círculo enorme y mal colocado. */
  display: block;
  width: fit-content;
  margin-inline: auto;
  font-weight: 700;
  font-size: var(--text-small);
  color: var(--color-brand-blue);
  text-transform: none;
  letter-spacing: normal;
  text-decoration: none;
  /* 50% más separado de la línea que antes (var(--space-sm) base). */
  padding-bottom: calc(var(--space-sm) * 1.5);
}

.js-pen .back-to-top:hover {
  text-decoration: none;
}

/* ---------------- Ficha de proyecto: hero + editorial ---------------- */

/* Margen estándar entre secciones de la ficha de proyecto, usado
   consistentemente en todos los saltos entre bloques (ficha, foto
   breakout, secciones de texto, galería, footer): el doble del hueco
   ajustado (2.625rem) que hubo brevemente, para recuperar la
   separación más generosa. */
:root {
  --space-section: 5.25rem;
}

.container {
  max-width: 84rem;
  margin-inline: auto;
  padding-inline: var(--space-md);
}

/* El Cierre de la ficha (.project-editorial__section--cierre) combina
   .container y .prose: sin esta regla, el max-width de .container
   (84rem) gana por orden de aparición sobre el de .prose (38rem, la
   columna de lectura estrecha que sí se respeta en Ficha/Detalle), y
   el párrafo final se estira a todo el ancho de la página. */
.prose.container {
  max-width: var(--content-narrow);
}

.project-editorial {
  /* Sin max-width ni centrado propio: hereda el ancho completo del body
     (igual que la cabecera de Inicio), para que el 50% de la fila
     coincida exactamente con el centro real de la pantalla, no con el
     centro de un contenedor de 84rem. */
  padding-block: var(--space-xl) var(--space-section);
}

/* Solo margen inferior (no padding-block simétrico): el espacio de
   "antes" ya lo aporta el margin-bottom del elemento anterior
   (breakout, u otra .project-editorial__section), evitando que ambos
   lados se sumen y el hueco de arriba quede el doble que el de abajo. */
.project-editorial__section {
  padding-bottom: var(--space-section);
}

/* Cierre: la mitad de espacio antes del pie que entre el resto de
   secciones. */
.project-editorial__section--cierre {
  padding-bottom: calc(var(--space-section) / 2);
}

/* Foto "formato detalle" anclada a la alineación izquierda de página
   (6.9vw, no al borde del contenedor centrado de 84rem) y el texto
   centrado en el centro real de la pantalla: columnas 1fr a cada lado
   del texto (la de la izquierda aloja la foto, la de la derecha va
   vacía) para que la columna central quede exactamente centrada,
   sin depender de dónde termina la foto. */
.project-editorial__section-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: var(--space-md);
  align-items: flex-start;
  padding-left: 6.9vw;
  padding-right: 6.9vw;
}

.project-editorial__section-row .prose {
  max-width: var(--content-narrow);
  margin-inline: auto;
}

/* "Detalle 2": misma fila de 3 columnas, pero la foto pasa a la
   columna derecha (alineación derecha) en vez de la izquierda; el
   texto se queda en el centro real, igual que en la fila normal. */
.project-editorial__section-row--reverse .project-editorial__detail {
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
}

.project-editorial__section-row--reverse .prose {
  grid-row: 1;
  grid-column: 2;
}

/* Fila sin foto (la foto no se ha puesto): el texto se queda en su columna. */
.project-editorial__section-row--sinfoto .prose {
  grid-column: 2;
}

/* Cierre: misma fila de tres columnas que "Detalle 2" (foto a la
   derecha). En el lugar de la foto lleva un hueco invisible de su mismo
   ancho (340px), para que la columna del texto se calcule igual y su
   margen izquierdo quede alineado con el del texto de arriba a
   cualquier ancho de pantalla. */
.project-editorial__section-row--cierre .prose {
  grid-row: 1;
  grid-column: 2;
}

.project-editorial__section-row--cierre::after {
  content: "";
  grid-row: 1;
  grid-column: 3;
  width: 340px;
  max-width: 100%;
}

/* Mismo tamaño, interlineado y color que los textos de Inicio (mismo
   token --text-small ya reducido, mismo azul de marca, mismo
   interlineado apretado del párrafo de bienvenida). */
.project-editorial__text,
.project-editorial__section {
  font-size: var(--text-small);
  line-height: 1.24;
  color: var(--color-brand-blue);
}

@media (max-width: 860px) {
  .project-editorial__text,
  .project-editorial__section {
    line-height: 1.6;
  }
}

/* Fila de tres pistas: un primer carril vacío de 6.9vw (mismo margen que
   la franja de texto del sidebar) seguido de la foto (que así termina
   justo en el 50% real de .project-editorial, exacto porque ya no hay
   contenedor de 84rem de por medio) y la columna de info. No se usa el
   truco de "breakout" con 100vw+transform porque ese 100vw incluye el
   ancho de la barra de scroll en algunos navegadores y desalinea el
   resultado unos px respecto al sidebar. */
.project-editorial__row {
  display: grid;
  /* minmax(0,1fr): sin el 0, el mínimo del contenido (foto de detalle de
     340px + ficha + texto) ensanchaba la columna en pantallas de
     860–1250px y la página desbordaba en horizontal. */
  grid-template-columns: 6.9vw calc(50% - 6.9vw) minmax(0, 1fr);
  align-items: stretch;
}

/* Mismo ancho que antes (3/4) pero 20% menos alto: 0.75 / 0.8 = 15/16. */
.project-editorial__main-photo {
  grid-column: 2;
  aspect-ratio: 15 / 16;
  position: relative;
  /* Ancho fijo al de su columna: sin esto, cuando la columna de la
     derecha se hacía más alta (ventanas medias) la foto se ensanchaba
     para conservar la proporción y pisaba la ficha y el texto. */
  width: 100%;
  min-width: 0;
}

.project-editorial__main-photo img,
.project-editorial__main-photo .photo-placeholder {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Título del proyecto, escrito a mano sobre la foto principal (prueba:
   Casa Artista). mix-blend-mode: multiply (heredado de la receta de
   tinta) funde bien sobre fotos claras; en una foto muy oscura la
   tinta azul podría perder legibilidad y habría que revisarlo. */
.project-editorial__title {
  position: absolute;
  top: 7%;
  left: 8%;
  right: 8%;
  margin: 0;
  font-size: clamp(2.25rem, 5vw, 4rem);
  color: var(--color-brand-blue);
  pointer-events: none;
}

/* Título de la ficha (<h1>): encima del primer texto, Courier Prime en
   negrita a 24 px (elegido por el estudio, 28/10/2026; mockup en
   Mockups/mockup-titulo-ficha-2026-10-28.html). El nombre se guarda en el
   panel en minúscula normal y así se muestra. */
.project-editorial__heading {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1.2;
  color: var(--color-brand-blue);
  margin-bottom: 1.375rem;
}

/* El título dentro de la portada (.project-hero) solo se usa en móvil. */
.project-hero .project-editorial__title {
  display: none;
}

.project-editorial__side {
  grid-column: 3;
  display: flex;
  flex-direction: column;
  padding-left: var(--space-lg);
  padding-right: 6.9vw;
}

/* stretch (no flex-start): la ficha técnica ocupa toda la altura de la
   foto de detalle, para que Publicaciones pueda anclarse a su pie. */
.project-editorial__side-top {
  display: flex;
  gap: var(--space-md);
  align-items: stretch;
}

.project-editorial__data {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  flex: 1;
  text-align: right;
}

/* Anclada al pie de la foto de detalle (la ficha ahora ocupa toda su
   altura vía align-items:stretch en el padre): a medida que se añaden
   publicaciones y el bloque crece, empuja hacia arriba en vez de
   desbordar por debajo de la foto. */
.project-editorial__data-publications {
  margin-top: auto;
}

.project-editorial__data dt {
  font-family: var(--font-mono);
  font-size: var(--text-tag);
  font-weight: 700;
  color: var(--color-brand-blue);
  text-transform: capitalize;
  letter-spacing: 0.05em;
  line-height: 1.24;
}

.project-editorial__data dd {
  font-weight: 400;
  font-size: var(--text-small);
  color: var(--color-brand-blue);
  line-height: 1.24;
}

.project-editorial__data dd a {
  text-decoration: none;
}

.project-editorial__data dd a:hover {
  text-decoration: underline;
}

/* "Formato detalle": 340px de ancho fijo, alto proporcional a 3:4 (igual
   que el formato estándar de 3000×4000px de las fotos del fotógrafo del
   estudio, para no recortarlas a una proporción distinta de la real). */
.project-editorial__detail {
  aspect-ratio: 3 / 4;
  width: 340px;
  max-width: 100%;
  /* Recorta lo que sobresale cuando la foto lleva zoom (transform: scale).
     Con clip-path y no con overflow:hidden: este último cambiaría el
     tamaño mínimo del elemento en las rejillas de la ficha. */
  clip-path: inset(0);
  /* clip-path no recorta el área desplazable: una foto con zoom se salía por
     el lado y en móvil salía scroll horizontal. overflow: clip la recorta sin
     convertir el elemento en contenedor de scroll (no cambia su tamaño mínimo). */
  overflow: clip;
}

.project-editorial__side-top .project-editorial__detail {
  /* Junto a la ficha puede encogerse cuando la columna de la derecha
     es estrecha, en vez de desbordar la página. */
  flex-shrink: 1;
  min-width: 0;
}

.project-editorial__detail img,
.project-editorial__detail .photo-placeholder {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* El resumen se ancla al borde inferior de la foto grande, alineado con
   ella, en vez de ir pegado justo debajo de la ficha técnica. */
.project-editorial__text {
  margin-top: auto;
  padding-top: var(--space-lg);
}

.project-editorial__breakout {
  width: 100%;
  aspect-ratio: 2 / 1;
  margin-bottom: var(--space-section);
}

.project-editorial__breakout img,
.project-editorial__breakout .photo-placeholder {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* "Sección Plano": a diferencia de las fotos, un plano nunca se recorta.
   Ancho completo entre alineación izquierda y derecha (6.9vw), la
   imagen se ve entera (sin cover) y se limita en alto para que no
   domine la página en planos muy alargados. */
.project-editorial__plan {
  padding-inline: 6.9vw;
  margin-bottom: var(--space-section);
}

.project-editorial__plan img,
.project-editorial__plan .photo-placeholder {
  display: block;
  width: 100%;
  max-height: 85vh;
  object-fit: contain;
  margin-inline: auto;
}

/* Como "multiplicar" de Photoshop: el blanco del plano toma el color de
   fondo de la página y las líneas quedan igual. Entre el plano y el fondo
   no debe haber ningún contenedor con fondo propio ni que cree su propio
   contexto de apilamiento (transform, opacity, isolation…). */
.project-editorial__plan img {
  mix-blend-mode: multiply;
}

/* "Formato galería": 3:4, mucho más grandes que el 4/3 anterior, de
   alineación izquierda a alineación derecha con los espacios entre
   ellas repartidos. El ancho lo fijan las 3 columnas del grid (así
   siempre caben exactas entre los dos márgenes, sin desbordar), y de
   ahí sale el alto vía aspect-ratio — en pantallas anchas esto ya da
   fotos considerablemente más altas que el formato anterior. */
.project-editorial__gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-md);
  padding-left: 6.9vw;
  padding-right: 6.9vw;
  margin-bottom: var(--space-section);
}

.project-editorial__gallery > * {
  aspect-ratio: 3 / 4;
}

.project-editorial__gallery img,
.project-editorial__gallery .photo-placeholder {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 860px) {
  /* Un único espacio para TODOS los saltos foto↔texto en móvil, tanto
     entre secciones (antes --space-section, 5.25rem) como dentro de
     una misma sección (antes --space-md, 2rem): se igualan usando
     la misma variable en los dos casos, en vez de dos escalas
     distintas conviviendo en la misma página. */
  :root {
    --space-section: 3.5rem;
  }

  .project-editorial {
    padding-inline: var(--space-md);
    padding-block: var(--space-section);
  }

  .project-editorial__row {
    grid-template-columns: 1fr;
    gap: var(--space-section);
  }

  .project-editorial__main-photo {
    grid-column: auto;
    aspect-ratio: 3 / 4;
  }

  /* Todas las fotos de la ficha en móvil comparten la proporción 3:4
     (la de la foto grande con el título). */
  .project-editorial__breakout {
    aspect-ratio: 3 / 4;
    width: auto;
    margin-inline: var(--space-md);
  }

  .project-editorial__title {
    font-size: clamp(1.75rem, 9vw, 2.75rem);
  }

  .project-editorial__side {
    grid-column: auto;
    padding-left: 0;
    padding-right: 0;
  }

  .project-editorial__section-row {
    grid-template-columns: 1fr;
    gap: var(--space-section);
    padding-left: var(--space-md);
    padding-right: var(--space-md);
  }

  .project-editorial__section-row--reverse .project-editorial__detail {
    grid-column: auto;
    /* grid-row:1 (escritorio) fuerza foto y texto a la misma fila; con
       una sola columna explícita, eso creaba una columna implícita de
       más (255px) en vez de apilar, y desalineaba el texto. */
    grid-row: auto;
    justify-self: stretch;
  }

  .project-editorial__section-row--reverse .prose,
  .project-editorial__section-row--sinfoto .prose,
  .project-editorial__section-row--cierre .prose {
    grid-column: auto;
    grid-row: auto;
  }

  .project-editorial__section-row--cierre::after {
    display: none;
  }

  .project-editorial__section-row .prose {
    max-width: none;
    margin-inline: 0;
  }

  .project-editorial__side-top {
    flex-direction: column;
    gap: var(--space-section);
  }

  .project-editorial__detail {
    width: 100%;
    aspect-ratio: 3 / 4;
    /* Sin esto, una foto vertical muy alta pedía una columna más ancha que
       la pantalla (su alto natural pasado a ancho por el aspect-ratio) y
       salía scroll horizontal (Casa Palau, Detalle 3, a 360 px). */
    min-width: 0;
  }

  .project-editorial__text {
    margin-top: 0;
    padding-top: var(--space-section);
  }

  .project-editorial__plan {
    padding-inline: var(--space-md);
  }

  .project-editorial__gallery {
    grid-template-columns: 1fr;
    padding-left: var(--space-md);
    padding-right: var(--space-md);
    gap: var(--space-section);
  }
}

/* ============================================================
   Responsive — la sidebar deja de estar fija y pasa a bloque
   normal por encima del contenido en pantallas estrechas. El nav
   se coloca primero (grid-template-areas) para que sea lo
   primero accesible, antes que el contacto o el listado.
   ============================================================ */

@media (max-width: 860px) {
  /* El menú de texto (.content-nav) lo sustituye la cabecera móvil
     logo + "+" (.mobile-bar / .mobile-menu, ver más abajo). */
  .content-nav {
    display: none;
  }

  .shell {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto;
    grid-template-areas:
      "sidebar"
      "main";
  }

  .sidebar {
    position: static;
    min-height: 0;
    height: auto;
    overflow: visible;
    padding: 0 var(--space-md) var(--space-md);
    gap: var(--space-md);
  }

  .content-pane {
    padding: var(--space-md) var(--space-md) var(--space-lg);
  }

  .shell--split .content-pane {
    height: auto;
    overflow: visible;
    padding: 0 var(--space-md) var(--space-lg);
    position: static;
  }

  .press-list {
    height: auto;
    overflow-y: visible;
    padding: 0;
    gap: var(--space-md);
  }

  .shell--split .content-photo,
  .shell--split .content-photo img {
    height: auto;
  }

  .shell--split .content-photo--carousel {
    height: 70vh;
  }

  .shell--split .content-photo--carousel .content-photo__slide {
    height: 100%;
  }

  .shell--split .sidebar {
    padding-top: 0;
    padding-left: var(--space-md);
    /* En escritorio este texto va en brand-blue (ver arriba); se
       mantiene el mismo color en móvil en vez de caer al gris casi
       negro del cuerpo de texto general. */
    color: var(--color-brand-blue);
  }

  .shell--proyectos .sidebar {
    height: auto;
  }

  .project-scroll,
  .project-scroll[hidden] {
    display: none;
  }

  .shell--proyectos .sidebar-measure,
  .shell--proyectos .sidebar-measure > div,
  .shell--proyectos .project-list {
    flex: none;
    min-height: 0;
    overflow-y: visible;
  }

  .shell--prensa .sidebar {
    height: auto;
    border-bottom: 0;
  }

  .shell--prensa .sidebar-measure {
    flex: none;
    min-height: 0;
    max-width: none;
    gap: 0;
  }

  .press-columns {
    display: block;
    margin-top: var(--space-xs);
  }

  .press-list__items {
    columns: 1;
    height: auto;
    overflow: visible;
    margin-top: var(--space-sm);
  }

  .press-columns__signoff {
    margin-top: var(--space-md);
  }

  /* Prensa: directamente el listado, sin la identidad (logo/fecha/
     dirección) por delante — ya vive en la cabecera móvil y en el
     desplegable del "+". */
  .shell--prensa .identity {
    display: none;
  }

  .shell--split .identity {
    line-height: 1.6;
    gap: 0.65rem;
  }

  /* El logo ya lo lleva la cabecera móvil (.mobile-bar__logo). */
  .identity__logo {
    display: none;
  }

  .shell--split .sidebar-measure,
  .shell--split .sidebar-signoff {
    font-size: inherit;
  }

  .shell--split .sidebar-measure {
    max-width: none;
    line-height: 1.6;
  }

  .shell--split .project-list {
    width: auto;
    max-width: none;
    margin-left: 0;
  }

  .shell--split .sidebar-signoff {
    align-self: flex-start;
    width: auto;
    text-align: left;
    margin-top: 0;
    margin-left: 0;
  }

  .sidebar-legal {
    width: auto;
    text-align: left;
    margin-top: var(--space-sm);
  }

  /* Inicio: solo logo (cabecera móvil) + primer párrafo, sin el
     listado de proyectos; la foto ocupa el resto del viewport a
     sangre, sin scroll de página. */
  .shell--inicio .shell {
    /* .shell trae min-height:100vh de base (regla sin media query);
       hay que igualar el min-height aquí o gana sobre este height
       más corto y vuelve a forzar el alto completo del viewport. */
    height: calc(100vh - var(--mobile-bar-height));
    height: calc(100dvh - var(--mobile-bar-height));
    min-height: calc(100vh - var(--mobile-bar-height));
    min-height: calc(100dvh - var(--mobile-bar-height));
    overflow: hidden;
    display: flex;
    flex-direction: column;
    /* .shell trae align-items:start de base (para el grid de
       escritorio); en flex eso encoge la foto al ancho de su
       contenido en vez de estirarla a todo el ancho. */
    align-items: stretch;
  }

  .shell--inicio .sidebar {
    flex: 0 0 auto;
    border-bottom: 0;
    padding-bottom: var(--space-lg);
  }

  .shell--inicio .inicio-projects,
  .shell--inicio .sidebar-signoff,
  .shell--inicio .intro-text p:not(.sidebar-heading) {
    display: none;
  }

  .shell--inicio .content-pane {
    flex: 1 1 auto;
    min-height: 0;
    padding: 0;
    /* .shell--split .content-pane trae align-self:start (escritorio);
       en el flex de una columna eso lo encoge a 0 de ancho. */
    align-self: stretch;
  }

  .shell--inicio .content-photo,
  .shell--inicio .content-photo--carousel {
    height: 100%;
    width: 100%;
  }

  .shell--inicio .content-photo__slide {
    height: 100%;
  }

  .shell--inicio .content-photo img {
    height: 100%;
    width: 100%;
    object-fit: cover;
  }

  /* Estudio: foto primero, luego los datos de contacto, luego los
     textos — reordenado sin tocar el DOM (.sidebar pasa a "contents"
     para que la identidad y el cuerpo de texto se vuelvan hermanos
     directos de la foto y puedan reordenarse con flex). */
  .estudio-page .shell {
    display: flex;
    flex-direction: column;
  }

  .estudio-page .sidebar {
    display: contents;
  }

  .estudio-page .content-pane {
    order: 1;
  }

  .estudio-page .identity {
    order: 2;
    padding: 0 var(--space-md) var(--space-section);
  }

  /* Sin fecha en móvil. */
  .identity__date {
    display: none;
  }

  .estudio-page .sidebar__body {
    order: 3;
    padding: 0 var(--space-md) var(--space-md);
  }

  /* Ficha de proyecto: nada de texto arriba, se empieza directamente
     por la foto de cabecera. */
  .shell--proyecto .identity,
  .shell--proyecto .sidebar-measure,
  .shell--proyecto .sidebar-signoff {
    display: none;
  }

  .shell--proyecto .sidebar {
    padding: 0;
    border-bottom: 0;
  }

  /* .shell trae min-height:100vh de base (pensado para páginas de un
     solo viewport); en la ficha de proyecto, sin nada visible en la
     barra lateral, esa altura mínima la repartía el grid como un
     hueco enorme justo antes de la primera foto. */
  .shell--proyecto .shell {
    min-height: 0;
  }

  /* El hueco entre la foto de cabecera y el resto de la ficha no debe
     sumar el padding de .content-pane (pensado para separar una foto
     de lo que viene justo después en páginas normales) al de
     .project-editorial: con los dos juntos duplicaba el espacio frente
     a cualquier otro salto foto↔texto de la ficha. */
  .shell--proyecto .content-pane {
    padding-bottom: 0;
  }

  /* La portada de la cabecera (.project-hero) es la misma foto que la
     principal de la ficha; en móvil se muestra solo esta última (3:4,
     con el título escrito encima) y empieza justo bajo la cabecera. */
  .shell--proyecto .content-pane {
    display: none;
  }

  .project-editorial:first-of-type {
    padding-top: 0;
  }

  /* Con portada propia (distinta de la cabecera) se muestra primero, en 3:4
     y con el título a mano encima; la cabecera pasa a ser la segunda foto,
     ya sin título. */
  .has-portada .shell--proyecto .content-pane,
  .has-portada.shell--proyecto .content-pane {
    display: block;
  }

  .has-portada .project-hero {
    position: relative;
    aspect-ratio: 3 / 4;
  }

  .has-portada .project-hero img,
  .has-portada .project-hero picture {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .has-portada .project-hero .project-editorial__title {
    display: block;
  }

  .has-portada .project-editorial__main-photo .project-editorial__title {
    display: none;
  }

  .has-portada .project-editorial:first-of-type {
    padding-top: var(--space-section);
  }

  /* Quita el pie (copyright/Instagram) en las fichas de proyecto en
     móvil; "Volver arriba," se queda, ya no forma parte visual de un
     pie de página. */
  .site-footer__bottom {
    display: none;
  }
}

/* ---------------- Cabecera móvil: logo + "+" ----------------
   Sustituye al menú de texto por debajo de 860px. El desplegable que
   abre tiene dos niveles: enlaces (Proyectos/Estudio/Prensa) y, si se
   pulsa Proyectos, el listado de fichas (ver assets/js/mobile-menu.js). */

.mobile-bar {
  display: none;
}

@media (max-width: 860px) {
  .mobile-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--color-surface);
    height: var(--mobile-bar-height);
    padding: 0 var(--space-md);
  }

  .mobile-bar__logo {
    display: inline-block;
    width: 5.5rem;
  }

  .mobile-bar__toggle {
    appearance: none;
    background: none;
    border: 0;
    padding: var(--space-xs);
    margin: -0.5rem;
    color: var(--color-brand-blue);
    cursor: pointer;
  }

  .mobile-bar__toggle-icon {
    display: block;
    width: 1.25rem;
    height: 1.25rem;
    position: relative;
    transition: transform 0.2s ease;
  }

  .mobile-bar__toggle-icon::before,
  .mobile-bar__toggle-icon::after {
    content: "";
    position: absolute;
    background: currentColor;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }

  .mobile-bar__toggle-icon::before {
    width: 100%;
    height: 2px;
  }

  .mobile-bar__toggle-icon::after {
    width: 2px;
    height: 100%;
  }

  /* Con el menú abierto el «+» gira a «×»: en la galería de proyectos
     vuelve al menú de tres enlaces, y en este lo cierra (mobile-menu.js). */
  [aria-expanded="true"] .mobile-bar__toggle-icon {
    transform: rotate(45deg);
  }

  /* La cabecera (z-index 20, con fondo) tapa lo que se desplaza por debajo
     de ella; el respiro de debajo lo da cada vista (.mobile-menu__view).
     Sin barra de scroll visible: el menú se sigue desplazando. */
  .mobile-menu {
    position: fixed;
    inset: 0;
    z-index: 19;
    background: var(--color-surface);
    padding: var(--mobile-bar-height) var(--space-md) var(--space-md);
    overflow-y: auto;
    scrollbar-width: none;
    display: flex;
    flex-direction: column;
  }

  .mobile-menu::-webkit-scrollbar {
    display: none;
  }

  .mobile-menu__view {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    padding-top: var(--space-sm);
  }

  /* El atributo HTML "hidden" por sí solo pierde contra las reglas de
     arriba (misma especificidad, estas van después); se refuerza aquí
     para que ambos niveles del desplegable se oculten de verdad. */
  .mobile-menu[hidden],
  .mobile-menu__view[hidden] {
    display: none;
  }

  /* Mismo tamaño, alineación y color que "SahuquillodeArriba" en la
     identidad (.identity__name), para que el menú abierto se sienta
     parte de la misma cabecera. */
  .mobile-menu__link {
    display: inline-block;
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: var(--text-small);
    text-decoration: none;
    color: var(--color-brand-blue);
    /* El círculo a bolígrafo (ver nav-circle.js) se ancla con
       position:absolute al propio enlace: sin relative aquí, se
       posicionaba contra .mobile-menu (fixed) y salía fuera de
       pantalla, invisible. */
    position: relative;
    /* .mobile-menu__view es flex-column; sin esto el enlace se estira
       al ancho del panel (align-items:stretch por defecto) y el
       círculo sale larguísimo en vez de ceñido al texto. */
    align-self: flex-start;
  }

  /* Menú principal del desplegable: texto a 16 px (con --text-small salía a
     11 px en las páginas de foto) y sangrado ~10 px respecto al borde del
     logo. */
  .mobile-menu__view[data-menu-view="main"] .mobile-menu__link {
    font-size: 1rem;
    padding-inline: 0.625rem;
  }

  /* Al pulsar «Proyectos» en el menú: la portada de cada proyecto, una
     encima de otra (partials/project-gallery.njk). Con JavaScript
     (assets/js/galeria-proyectos.js) el título está recogido: el primer
     toque recorta la foto por arriba y lo muestra encima (nombre en
     negrita, el resto normal); el segundo abre la ficha. Sin JavaScript el
     título se ve siempre y cada foto es un enlace directo. */
  .project-gallery {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-lg);
  }

  .project-gallery li {
    scroll-margin-top: calc(var(--mobile-bar-height) + var(--space-sm));
  }

  .project-gallery a {
    display: block;
    text-decoration: none;
    color: var(--color-blue-secondary);
  }

  .project-gallery__title {
    display: block;
    margin-bottom: var(--space-xs);
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    line-height: 1.35;
    color: var(--color-blue-secondary);
  }

  .project-gallery__title b {
    font-weight: 700;
    color: var(--color-brand-blue);
  }

  .project-gallery__title--pending {
    margin-bottom: 0;
  }

  .project-gallery__photo,
  .project-gallery__photo picture {
    display: block;
    width: 100%;
  }

  .project-gallery__photo picture {
    height: 100%;
  }

  .project-gallery__photo {
    overflow: hidden;
    aspect-ratio: 3 / 4;
  }

  .project-gallery__photo img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 100%;
  }

  .js-pen .project-gallery li:not(.is-open) .project-gallery__title:not(.project-gallery__title--pending) {
    max-height: 0;
    margin-bottom: 0;
    opacity: 0;
    overflow: hidden;
  }

  .js-pen .project-gallery__title:not(.project-gallery__title--pending) {
    max-height: 4rem;
    transition: max-height 0.4s ease, margin 0.4s ease, opacity 0.3s ease;
  }

  .js-pen .project-gallery__photo {
    transition: aspect-ratio 0.5s ease;
  }

  .js-pen .project-gallery li.is-open .project-gallery__photo {
    aspect-ratio: 1.1 / 1;
  }

  @media (prefers-reduced-motion: reduce) {
    .js-pen .project-gallery__title,
    .js-pen .project-gallery__photo {
      transition: none;
    }
  }
}

@media (max-width: 640px) {
  .sidebar,
  .content-pane,
  .content-nav {
    padding-inline: var(--space-sm);
  }
}

/* ---------------- Subrayado a mano sobre frases de la ficha ----------------
   Las frases marcadas en el panel se subrayan con un trazo a bolígrafo
   (ver assets/js/annotations.js y Pen.underline), una a una conforme se
   llega a su altura en la página. El círculo con nota a mano se retiró;
   copia en "Gestión Interna/09. Web/_Archivo/círculos-notas-a-mano".
   ---------------------------------------------------------------- */

.annotation-target {
  position: relative;
  display: inline-block;
  white-space: nowrap;
}

/* Frase más ancha que la pantalla (ver annotations.js): se parte en líneas y
   se subraya con CSS normal, sin el trazo a bolígrafo. */
.annotation-target.is-wrap {
  display: inline;
  white-space: normal;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.pen-underline {
  position: absolute;
  left: -2px;
  bottom: -0.2em;
  width: calc(100% + 4px);
  height: 0.7em;
  overflow: visible;
  pointer-events: none;
  mix-blend-mode: multiply;
}

/* ----------------------------------------------------------------
   Página 404: solo el logo (enlace a Inicio) y el aviso escrito con la
   Letra a mano SdA, centrados; se subraya a bolígrafo al acabar.
   ---------------------------------------------------------------- */
.not-found {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-lg);
  padding: var(--space-lg) var(--space-md);
  text-align: center;
}

.not-found__logo {
  width: 8.5rem;
}

/* El sello compensa su margen interno para alinearse a la izquierda con
   el texto de la barra lateral; aquí va centrado. */
.not-found__logo .identity__logo-mark {
  margin-left: 0;
}

.not-found__title {
  position: relative;
  display: inline-block;
  font-family: var(--font-sans);
  font-size: clamp(2rem, 5vw, 3.75rem);
  line-height: 1.1;
  color: var(--color-brand-blue);
}

/* Antes de escribirse ocupa todo el ancho (el motor parte en líneas según
   ese ancho); después se ajusta al trazo, para que el subrayado mida lo
   mismo que la frase escrita. */
.not-found__title:not(.is-escrito) {
  display: block;
  width: 100%;
}

.not-found__title .pen-underline {
  bottom: -0.35em;
  height: 0.35em;
}
