/* ============================================
   Arzaga Nahil — Estilos base
   ============================================ */

*,
*::after,
*::before {
    box-sizing: border-box;
}

:root {
    font-size: 16px;

    /* Paleta moderna — oscuro con acentos vibrantes */
    --color-bg-start: #0f0f1a;
    --color-bg-end:   #1a1a2e;
    --color-title:      #a5003f;
    --color-text:       #c4c4cf;
    --color-text-alt:   #8b8b9e;
    --color-accent:     #0093a5;
    /* Brillo del borde del CTA al pasar el cursor: violeta de la paleta en
       lugar del rosa, que desentonaba con el resto del sitio. */
    --color-accent-shine: #6c63ff;
    --color-menu:       #e8e8f0;
    --color-menu-hover: #6c63ff;
    --color-menu-border: rgba(108, 99, 255, 0.15);
    --color-link:       #8b8b9e;
    --color-link-hover: #6c63ff;
    --color-heading:    #f0f0f5;
    --size-menu:        4.5vh;
    --font-sans:        'Inter', system-ui, -apple-system, sans-serif;
    --font-mono:        'JetBrains Mono', 'Space Mono', monospace;
    --font-para:        'Tulpen One', cursive, sans-serif;
    --font-name:        'Bruno Ace', 'Inter', sans-serif;
}

html {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: hidden;
    scrollbar-width: none;
}

::selection {
    background: var(--color-accent);
    color: #ffffff;
}

html::-webkit-scrollbar {
    display: none;
}

body {
    margin: 0;
    color: var(--color-text);
    background: #000000;
    font-family: var(--font-sans);
    font-weight: 300;
    min-height: 100vh;
    overflow-x: hidden;
}

/* ---- Three.js Background ---- */
#three-canvas {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    z-index: -1;
    pointer-events: none;
}

#three-canvas canvas {
    display: block;
}

/* ---- Loader ---- */
.js .loading::before,
.js .loading::after {
    content: '';
    position: fixed;
    z-index: 10000;
}

.js .loading::before {
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #000000;
}

.js .loading::after {
    top: 50%;
    left: 50%;
    width: 50px;
    height: 50px;
    margin: -25px 0 0 -25px;
    border-radius: 50%;
    opacity: 0.3;
    background: var(--color-accent);
    animation: loaderAnim 0.8s linear infinite alternate forwards;
}

@keyframes loaderAnim {
    to {
        opacity: 1;
        transform: scale3d(0.4, 0.4, 1);
    }
}

/* ---- Links ---- */
a {
    text-decoration: none;
    color: var(--color-link);
    outline: none;
}

a:hover {
    color: var(--color-link-hover);
}

a:focus {
    outline: none;
    background: transparent;
}

a:focus-visible {
    outline: 2px solid var(--color-accent);
    background: transparent;
}

/* ---- Utility ---- */
.unbutton {
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
    font: inherit;
    cursor: pointer;
}

.unbutton:focus {
    outline: none;
}

/* ---- Main grid layout ---- */
main {
    width: 100%;
    min-height: 100vh;
    display: grid;
    grid-template-columns: 10vw 10vh 10vw 5vw 32vw 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas:
        'side side side frame frame frame'
        'content content content content content content';
}

.no-js main {
    grid-template-areas: 'content content content content content content';
}

/* ---- Frame / top bar ---- */
.frame {
    position: relative;
    grid-area: frame;
    padding: 1rem 2.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: rgba(15, 15, 26, 0.7);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}

.frame__links {
    display: flex;
    gap: 1.5rem;
    font-size: 0.85rem;
    margin-left: 2rem;
}

.frame__links img {    
    width: 28px;
    height: 28px;
    display: block;
}

/* ---- Content / Hero ---- */
.content {
    grid-area: content;
    display: grid;
    place-content: center;
    padding: 2rem 5vw;
    gap: 2rem;
}

.content__column {
    max-width: 40ch;
    padding-left: 0;
}

.content__greeting {
    font-size: 1.2rem;
    text-transform: uppercase;
    letter-spacing: 0.3em;
    color: var(--color-accent);
    margin: 0 0 0.5rem;
    font-weight: 400;
}

.content__headline {
    font-family: var(--font-name);
    font-size: clamp(1.4rem, 2.6vw, 2.4rem);
    font-weight: 200;
    line-height: 1.05;
    color: var(--color-heading);
    margin: 0 0 0.1rem;
    letter-spacing: -0.02em;
}

.content__headline1 {
    font-family: var(--font-name);
    font-size: clamp(1.4rem, 2.6vw, 2.4rem);
    font-weight: 200;
    line-height: 1.05;
    color: var(--color-heading);
    margin: 0 0 1.25rem;
    letter-spacing: -0.02em;
}

.content__sub {
    font-family: var(--font-para);
    font-size: 1.6rem;
    line-height: 1.35;
    margin: 0 0 1.5rem;
    color: var(--color-text-alt);
}

.content__cta {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1.1rem;
    border: 1px solid rgba(0, 147, 165, 0.45);
    border-radius: 100px;
    background: rgba(0, 147, 165, 0.06);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: #7fd4dd;
    transition: border-color 0.3s ease, background 0.3s ease, color 0.3s ease,
        box-shadow 0.3s ease;
}

.content__cta__arrow {
    display: inline-block;
    transition: transform 0.3s ease;
}

.content__cta:hover {
    border-color: var(--color-accent);
    background: rgba(0, 147, 165, 0.12);
    color: var(--color-accent);
    box-shadow: 0 0 18px rgba(0, 147, 165, 0.18);
}

.content__cta:hover .content__cta__arrow {
    transform: translateX(4px);
}

.content__cta:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 3px;
}

.content__image {
    max-width: 100%;
    width: auto;
    height: auto;
    border-radius: 12px;
    display: block;
}

/* ---- Contact Section ---- */
.contact {
    display: grid;
    place-items: center;
    padding: 4rem 2rem;
}

.contact__card {
    width: 100%;
    max-width: 520px;
    background: rgba(15, 15, 26, 0.7);
    backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 16px;
    padding: 2rem 2.4rem;
}

.contact__overline {
    font-family: var(--font-mono);
    font-size: 1rem;
    text-transform: uppercase;
    letter-spacing: 0.3em;
    color: var(--color-accent);
    display: block;
    margin-bottom: 0.15rem;
}

.contact__title {
    font-family: var(--font-name);
    font-size: clamp(1.1rem, 2.5vw, 1.4rem);
    font-weight: 200;
    color: var(--color-heading);
    margin: 0 0 0.5rem;
    letter-spacing: -0.02em;
    line-height: 1.1;
}

.contact__sub {
    font-family: var(--font-para);
    font-size: 1.4rem;
    line-height: 1.35;
    color: var(--color-text-alt);
    margin: 0 0 1.5rem;
}

/* ---- About Section ---- */
.about {
    display: grid;
    place-items: center;
    padding: 2rem;
    gap: clamp(2rem, 5vw, 4rem);
    max-width: 1200px;
    margin: 0 auto;
}

/* La foto a un lado y el texto al otro a partir de 60em. Por debajo se apilan,
   y el orden del HTML es foto primero, que es el que lee bien en móvil donde
   la imagen se ve antes que nada. */
@media (min-width: 60em) {
    .about {
        grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
        align-items: center;
        place-items: stretch;
    }
}

.about__card {
    width: 100%;
    max-width: 560px;
    background: rgba(15, 15, 26, 0.7);
    backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 16px;
    padding: 2rem 2.4rem;
}

.about__title {
    font-family: var(--font-name);
    font-size: clamp(1.3rem, 3vw, 1.8rem);
    font-weight: 200;
    color: var(--color-heading);
    margin: 0 0 1rem;
    letter-spacing: -0.02em;
    line-height: 1.1;
}

.about__text {
    font-family: var(--font-para);
    font-size: 1.3rem;
    line-height: 1.4;
    color: var(--color-text-alt);
    margin: 0 0 1.5rem;
}

.about__skills {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    padding: 0;
    margin: 0;
}

.about__skills li {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: #7fd4dd;
    border: 1px solid rgba(0, 147, 165, 0.45);
    border-radius: 100px;
    padding: 0.4rem 1rem;
    background: rgba(0, 147, 165, 0.06);
}

/* Las tres disciplinas del About. Sin separador entre bloques porque cada uno
   lleva su título en mono, que ya hace de línea divisoria. */
.about__discs {
    display: grid;
    gap: 1.4rem;
    margin: 1.6rem 0 0;
    padding: 0;
    list-style: none;
}

.about__disc h3 {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: #7fd4dd;
    margin: 0 0 0.35rem;
}

.about__disc p {
    font-family: var(--font-para);
    font-size: 1.05rem;
    line-height: 1.45;
    color: var(--color-text-alt);
    margin: 0;
}

.about__close {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    letter-spacing: 0.04em;
    color: var(--color-text);
    margin: 1.8rem 0 0;
}

/* ---- Form ---- */
.contact__form {
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.form-label {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-text-alt);
}

.form-input {
    width: 100%;
    background: transparent;
    border: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    padding: 0.45rem 0;
    font-family: var(--font-sans);
    font-size: 0.9rem;
    font-weight: 300;
    color: var(--color-heading);
    outline: none;
    transition: border-color 0.3s ease;
    border-radius: 0;
}

.form-input::placeholder {
    color: var(--color-text-alt);
    opacity: 0.5;
}

.form-input:focus {
    border-bottom-color: var(--color-accent);
}

.form-textarea {
    resize: vertical;
    min-height: 100px;
    line-height: 1.5;
}

/* ---- Shiny CTA Button (adapted from https://codepen.io/hexagoncircle/full/MWMqXbK) ---- */
@property --gradient-angle {
    syntax: "<angle>";
    initial-value: 0deg;
    inherits: false;
}

@property --gradient-angle-offset {
    syntax: "<angle>";
    initial-value: 0deg;
    inherits: false;
}

@property --gradient-percent {
    syntax: "<percentage>";
    initial-value: 5%;
    inherits: false;
}

@property --gradient-shine {
    syntax: "<color>";
    initial-value: white;
    inherits: false;
}

.shiny-cta {
    --animation: gradient-angle linear infinite;
    --duration: 3s;
    --shadow-size: 2px;
    isolation: isolate;
    position: relative;
    overflow: hidden;
    cursor: pointer;
    outline-offset: 4px;
    padding: 1rem 2rem;
    font-family: inherit;
    font-size: 1rem;
    line-height: 1.2;
    border: 1px solid transparent;
    border-radius: 360px;
    color: #fff;
    background: linear-gradient(var(--color-bg-start), var(--color-bg-start))
        padding-box,
      conic-gradient(
          from calc(var(--gradient-angle) - var(--gradient-angle-offset)),
          transparent,
          var(--color-accent) var(--gradient-percent),
          var(--gradient-shine) calc(var(--gradient-percent) * 2),
          var(--color-accent) calc(var(--gradient-percent) * 3),
          transparent calc(var(--gradient-percent) * 4)
        )
        border-box;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06);
    width: 100%;
    margin-top: 0.25rem;
}

.shiny-cta::before,
.shiny-cta::after,
.shiny-cta span::before {
    content: "";
    pointer-events: none;
    position: absolute;
    inset-inline-start: 50%;
    inset-block-start: 50%;
    translate: -50% -50%;
    z-index: -1;
}

.shiny-cta:active {
    translate: 0 1px;
}

/* Dots pattern */
.shiny-cta::before {
    --size: calc(100% - var(--shadow-size) * 3);
    --position: 2px;
    --space: calc(var(--position) * 2);
    width: var(--size);
    height: var(--size);
    background: radial-gradient(
        circle at var(--position) var(--position),
        white calc(var(--position) / 4),
        transparent 0
      )
      padding-box;
    background-size: var(--space) var(--space);
    background-repeat: space;
    -webkit-mask-image: conic-gradient(
      from calc(var(--gradient-angle) + 45deg),
      black,
      transparent 10% 90%,
      black
    );
    mask-image: conic-gradient(
      from calc(var(--gradient-angle) + 45deg),
      black,
      transparent 10% 90%,
      black
    );
    border-radius: inherit;
    opacity: 0.4;
    z-index: -1;
}

/* Inner shimmer */
.shiny-cta::after {
    --animation: shimmer linear infinite;
    width: 100%;
    aspect-ratio: 1;
    background: linear-gradient(
      -50deg,
      transparent,
      var(--color-accent),
      transparent
    );
    -webkit-mask-image: radial-gradient(circle at bottom, transparent 40%, black);
    mask-image: radial-gradient(circle at bottom, transparent 40%, black);
    opacity: 0.6;
}

.shiny-cta span {
    font-family: var(--font-name);
    z-index: 1;
}

.shiny-cta span::before {
    --size: calc(100% + 1rem);
    width: var(--size);
    height: var(--size);
    box-shadow: inset 0 -1ex 2rem 4px var(--color-accent);
    opacity: 0;
}

/* Animate */
.shiny-cta {
    --transition: 800ms cubic-bezier(0.25, 1, 0.5, 1);
    transition: var(--transition);
    transition-property: --gradient-angle-offset, --gradient-percent,
      --gradient-shine;
}

.shiny-cta,
.shiny-cta::before,
.shiny-cta::after {
    animation: var(--animation) var(--duration),
      var(--animation) calc(var(--duration) / 0.4) reverse paused;
    animation-composition: add;
}

.shiny-cta span::before {
    transition: opacity var(--transition);
    animation: calc(var(--duration) * 1.5) breathe linear infinite;
}

.shiny-cta:is(:hover, :focus-visible) {
    --gradient-percent: 20%;
    --gradient-angle-offset: 95deg;
    --gradient-shine: var(--color-accent-shine);
}

.shiny-cta:is(:hover, :focus-visible),
.shiny-cta:is(:hover, :focus-visible)::before,
.shiny-cta:is(:hover, :focus-visible)::after {
    animation-play-state: running;
}

.shiny-cta:is(:hover, :focus-visible) span::before {
    opacity: 1;
}

@keyframes gradient-angle {
    to {
        --gradient-angle: 360deg;
    }
}

@keyframes shimmer {
    to {
        rotate: 360deg;
    }
}

@keyframes breathe {
    from,
    to {
        scale: 1;
    }
    50% {
        scale: 1.2;
    }
}

/* ---- Menu ---- */
.menu {
    grid-area: 1 / 1 / 2 / 7;
    display: grid;
    grid-template-columns: 5vw 5vw 11vh 5vw 1fr;
    grid-template-rows: auto 1fr;
    position: relative;
    pointer-events: none;
    z-index: 100;
    border-bottom: 1px solid var(--color-menu-border);
}

.no-js .menu {
    display: none;
}

.menu__bg {
    transform: translateX(-100%) translateX(20vw) translateX(11vh); /* esto es para que no se vea el menu */
    grid-area: 1 / 1 / 3 / 6; /* el uno significa que va a ocupar todo el espacio de la grilla */
    position: absolute;
    left: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, var(--color-bg-start), var(--color-bg-end));
    opacity: 0.45;
    border-right: 1px solid var(--color-menu-border);
    pointer-events: none;
}

.menu--open .menu__bg {
    opacity: 1;
}



.menu__button {
    margin: 1.25rem;
    position: relative;
    align-self: start;
    cursor: pointer;
    pointer-events: auto;
    grid-area: 1 / 1 / 2 / 3;
    justify-self: start;
    color: var(--color-heading);
    transition: color 0.2s;
}

.menu__button:hover {
    color: var(--color-accent);
}

.menu__button svg {
    display: block;
}

.menu__button path {
    stroke: currentColor;
    fill: none;
}

.menu__icon-wrapper {
    position: relative;
    display: inline-block;
    width: 34px;
    height: 34px;
    pointer-events: none;
}

.menu__icon-wrapper svg {
    position: absolute;
    top: -33px;
    left: -33px;
    transform: scale(0.1);
    transform-origin: 0 0;
}

.menu__icon-wrapper svg path {
    stroke: currentColor;
    stroke-width: 48px;
    stroke-linecap: round;
    stroke-linejoin: round;
    fill: transparent;
}

.menu__items {
    grid-area: 2 / 1 / 2 / 6;
    justify-content: start;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    position: relative;
    pointer-events: none;
    margin: 1rem;
    padding-bottom: 1rem;
}

.menu--open .menu__items {
    pointer-events: auto;
}

.menu__item {
    font-family: var(--font-mono);
    font-weight: 400;
    font-size: var(--size-menu);
    line-height: 0.9;
    color: var(--color-menu);
    position: relative;
    cursor: pointer;
    /* Una sola línea siempre: si un item parte en dos, descuadra la columna
       vertical de letras (ARZAGA), que va atada a la altura de cada item. */
    white-space: nowrap;
}

.menu__item span {
    pointer-events: none;
}

.menu__item .letter-wrap__inner span:first-child,
.menu__item .letter-wrap__inner span,
.menu__item .letter-wrap span.char {
    transition: color 0.2s ease;
}

.menu--open .menu__item:hover .letter-wrap__inner span:first-child,
.menu--open .menu__item:hover .letter-wrap__inner span,
.menu--open .menu__item:hover .letter-wrap span.char,
.menu--open .menu__item:focus .letter-wrap__inner span:first-child,
.menu--open .menu__item:focus .letter-wrap__inner span,
.menu--open .menu__item:focus .letter-wrap span.char {
    color: var(--color-menu-hover);
}

.menu--open .menu__item:focus-visible {
    outline: 2px solid var(--color-accent);
    background: transparent;
}

.menu__item.splitting .word {
    display: flex;
}

.menu__item.splitting .char {
    flex: none;
    display: flex;
    justify-content: center;
    transform-origin: 50% 100%;
    will-change: transform, color;
}

.menu__item .char {
    color: var(--color-link);
}

.letter-wrap,
.letter-wrap__inner span,
.menu__item.splitting .char {
    width: calc(var(--size-menu) * 0.6);
    display: flex;
    justify-content: center;
    will-change: transform, color;
}

.letter-wrap__inner span:first-child {
    color: var(--color-link);
}

.letter-wrap__inner span:last-child {
    font-weight: 500;
    color: #0093a5;
}

.letter-wrap {
    flex: none;
    height: calc(var(--size-menu) * 0.8833);
    overflow: hidden;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.letter-wrap > span:not(.letter-wrap__inner) {
    opacity: 0;
}

.letter-wrap__inner {
    display: flex;
    flex-direction: column;
    height: fit-content;
}

.menu__tagline {
    display: none;
    grid-area: 1 / 4 / 2 / 6;
    align-self: center;
    justify-self: center;
    margin: 0;
    height: 33vh;
    width: auto;
    object-fit: cover;
    filter: saturate(1.05);
    transform: translateX(-290px);
}

.menu--open .menu__tagline {
    display: none;
}

/* ---- Topnav (minimal pages) ---- */
.topnav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 1rem 2rem;
    z-index: 200;
    background: rgba(15, 15, 26, 0.55);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border-bottom: 1px solid rgba(255, 255, 255, 0.04);
    pointer-events: auto;
}

.topnav__brand {
    font-family: var(--font-name);
    font-size: 1.3rem;
    color: var(--color-heading);
    letter-spacing: -0.02em;
    transition: color 0.2s ease;
}

.topnav__brand:hover {
    color: var(--color-accent);
}

.topnav__toggle {
    display: none;
}

.topnav__links {
    display: flex;
    gap: 1.5rem;
}

.topnav__links a {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-link);
    transition: color 0.2s ease;
}

.topnav__links a:hover {
    color: var(--color-accent);
}

.topnav__links a.is-current {
    color: var(--color-accent);
}

/* ---- Language toggle ---- */
.lang__toggle {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    font-weight: 400;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-accent);
    background: rgba(0, 147, 165, 0.10);
    border: 1px solid rgba(0, 147, 165, 0.45);
    border-radius: 999px;
    padding: 0.45rem 0.9rem;
    cursor: pointer;
    line-height: 1;
    pointer-events: auto;
    align-self: center;
    transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

.lang__toggle:hover,
.lang__toggle:focus-visible {
    color: #ffffff;
    border-color: var(--color-accent);
    background: rgba(255, 255, 255, 0.10);
}

/* ---- Sections: named grid rows on mobile ---- */
.page-development .development { grid-area: development; width: 100%; }
.page-design .design { grid-area: design; width: 100%; }
.page-photography .photography { grid-area: photography; width: 100%; }
.page-about .about { grid-area: about; width: 100%; }
.page-contact .contact { grid-area: contact; width: 100%; }

/* ---- Gooey slideshow (Development / portfolio) ---- */
#gooey-scene {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 1;
    pointer-events: none;
}

.page-title {
    position: fixed;
    top: 5.5rem;
    left: 4vw;
    z-index: 0;
    margin: 0;
    white-space: nowrap;
    user-select: none;
    pointer-events: none;
    font-family: var(--font-name);
    font-size: calc(2vw + 3.25rem);
    font-weight: 400;
    line-height: 0.975;
    letter-spacing: -0.02em;
    color: var(--color-heading);
    opacity: 0.18;
}

.page-title__offset {
    display: block;
    margin-left: 12%;
}

.page-gallery .page-title__offset {
    display: inline;
    margin-left: 0;
}

.devtiles {
    position: relative;
    z-index: 2;
    list-style: none;
    display: flex;
    align-items: center;
    height: 100%;
    margin: 0;
    padding: 0;
    width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
    overscroll-behavior-x: none;
}

.devtiles::-webkit-scrollbar {
    display: none;
}

.devtile {
    flex: 0 0 auto;
    width: 100%;
    min-width: 17.5rem;
    max-width: 28vmin;
    margin-left: 22vw;
    transition: transform 0.5s;
}

.devtile:last-child {
    padding-right: 10vw;
    box-sizing: content-box;
}

.tile {
    position: relative;
}

.tile__link {
    display: block;
    color: var(--color-heading);
}

.tile__fig {
    position: relative;
    width: 100%;
    margin: 0;
    border: 2px solid rgba(0, 147, 165, 0.55);
    box-shadow: 0 12px 35px -18px rgba(0, 147, 165, 0.65);
    transition: border-color 0.3s, box-shadow 0.3s;
}

.js-tile:hover .tile__fig {
    border-color: var(--color-accent);
    box-shadow: 0 14px 45px -16px rgba(0, 147, 165, 0.85);
}

.tile__fig::before {
    content: '';
    display: block;
    padding-top: 136.36%;
}

.tile__img {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    opacity: 1;
    transition: opacity 0.3s;
}

.tile__img.is-loaded {
    opacity: 0;
}

.tile__content {
    position: absolute;
    bottom: 3.6rem;
    left: 0;
    width: 100%;
    pointer-events: none;
}

.tile__title {
    margin: 0 0 0 -10%;
    white-space: nowrap;
    font-family: var(--font-name);
    font-size: clamp(1.8rem, 3vw, 2.5rem);
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: -0.01em;
    color: var(--color-heading);
}

.tile__title__offset {
    display: block;
    margin-left: 18%;
}

.devtile:first-child .tile__content {
    bottom: 1.8rem;
}

.devtile:nth-child(2) .tile__content {
    bottom: 2.6rem;
}

/* ---- Gallery (Development -> proyectos) ---- */
.gallery {
    position: relative;
    z-index: 2;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
        'text'
        'carousel';
    width: 100%;
    min-height: 100vh;
    padding: 8.5rem 2rem 2.5rem;
    row-gap: 2.5rem;
}

/* Frase de cierre bajo el carrusel. La usan las cuatro galerías de diseño:
   gallery-design-4 con g_slogan_rescate y 1, 2 y 3 con g_slogan_design. Las
   demás mantienen las dos áreas de siempre. */
.gallery--slogan {
    grid-template-areas:
        'text'
        'carousel'
        'slogan';
}

/* Misma tipografía que el título de la página (.page-title usa --font-name,
   Bruno Ace) pero bastante más pequeña: es una frase larga y esa fuente es
   ancha, así que a tamaño de título se desbordaría. Comparte el color del
   título y sube algo su opacidad (0.18 en .page-title): al ser más pequeña,
   necesita algo más de cuerpo para no perderse del todo.

   La opacidad va en el <span> interior y no aquí a propósito. En CSS la
   opacidad del elemento se multiplica sobre sus pseudo-elementos, así que
   ponerla en el <p> atenuaría también la raya de abajo. Alvivarla en el span
   el texto queda al 0.25 y la raya va a opacidad plena. */
.gallery__slogan {
    grid-area: slogan;
    max-width: 46ch;
    margin: 0.5rem 0 0;
    font-family: var(--font-name);
    font-size: clamp(1.05rem, 1.9vw, 1.6rem);
    font-weight: 400;
    line-height: 1.35;
    text-wrap: balance;
    color: var(--color-heading);
}

.gallery__slogan > span {
    opacity: 0.25;
}

/* Raya de acento bajo la frase, a opacidad plena. */
.gallery__slogan::after {
    content: '';
    display: block;
    width: 3.5rem;
    height: 2px;
    margin-top: 1.1rem;
    background: var(--color-accent);
}

.gallery__back {
    position: relative;
    display: grid;
    place-items: center;
    width: 96px;
    height: 96px;
    color: var(--color-accent);
    transition: color 0.2s ease;
}

.gallery__back__ring {
    grid-area: 1 / 1;
    width: 100%;
    height: 100%;
    animation: gallery-rotate 40s linear infinite;
}

.gallery__back__ring text {
    font-family: var(--font-mono);
    font-size: 14px;
    fill: currentColor;
    opacity: 0.55;
}

.gallery__back__arrow {
    grid-area: 1 / 1;
    display: block;
    font-family: var(--font-mono);
    font-size: 2.2rem;
    line-height: 1;
    transform: translateY(-2px);
}

.gallery__back:hover {
    color: #ffffff;
}

@keyframes gallery-rotate {
    to {
        transform: rotate(1turn);
    }
}

.gallery__desc {
    max-width: 46ch;
    margin: 0;
    font-family: var(--font-para);
    font-size: 1.5rem;
    line-height: 1.45;
    color: var(--color-text-alt);
}

.gallery__text {
    grid-area: text;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 3rem;
}

.gallery__carousel {
    grid-area: carousel;
    display: flex;
    align-items: center;
    overflow: hidden;
}

.gallery__track {
    display: flex;
    gap: 2rem;
    width: max-content;
    will-change: transform;
    /* La duracion NO es fija: la calcula initGalleryCarousel en JS a partir del
       ancho real del track y la deja en --marquee-duration. Con 40s fijos la
       velocidad sale proporcional al ancho, y como cada galeria tiene un track
       mas o menos largo cada una iba a un ritmo distinto: Editorial iba 3,5
       veces mas rapida que Rescate Animal. Los 40s de aqui son solo el valor
       de reserva para cuando el JS no llega a fijarla. */
    animation: gallery-marquee var(--marquee-duration, 40s) linear infinite;
}

/* El hover va en el track, no en .gallery__carousel: el carrusel se estira a
   todo lo alto de la fila de la rejilla (~900px) y las tarjetas solo ocupan
   506px, así que pausar desde el carrusel dejaba casi 200px de zona muerta
   arriba y abajo. El track se ajusta justo a la altura de las tarjetas, con lo
   que el marquee se detiene únicamente sobre las imágenes. */
.gallery__track:hover {
    animation-play-state: paused;
}

.gallery__item__link {
    flex: 0 0 auto;
    width: clamp(220px, 22vw, 340px);
    display: block;
    text-decoration: none;
    color: inherit;
    transition: transform 0.25s ease;
}

.gallery__item__link:hover {
    transform: translateY(-4px);
}

.gallery__item {
    position: relative;
    margin: 0;
    aspect-ratio: 4 / 5;
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.06);
    background: rgba(15, 15, 26, 0.25);
    transition: border-color 0.25s ease;
}

.gallery__item__link:hover .gallery__item {
    border-color: var(--color-accent);
}

/* Tarjetas que todavía no tienen demo: se quedan como contenido y no fingen
   ser un enlace (sin levantarse ni cambiar el borde al pasar el ratón). */
.gallery__item__link--soon {
    cursor: default;
}

.gallery__item__link--soon:hover {
    transform: none;
}

.gallery__item__link--soon:hover .gallery__item {
    border-color: rgba(255, 255, 255, 0.06);
}

.gallery__item img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.gallery__item__desc {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: stretch;
    padding: 1.25rem;
    font-family: var(--font-para);
    font-size: 1.35rem;
    line-height: 1.45;
    color: #ffffff;
    background: linear-gradient(rgba(4, 4, 10, 0) 30%, rgba(4, 4, 10, 0.85) 100%);
    pointer-events: none;
}

.gallery__item__desc strong {
    display: block;
    font-weight: 700;
    font-size: 1.2em;
    margin-bottom: 0.2rem;
}

@keyframes gallery-marquee {
    to {
        transform: translate3d(-50%, 0, 0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .gallery__track {
        animation: none;
    }

    .gallery__carousel {
        overflow-x: auto;
    }
}

/* ---- Galería de mosaico: tarjetas sin descripción ---- */

/* Solo la galería con visor: el carrusel se sangra por la derecha sin invadir la columna de texto */
.page-gallery:has(.lightbox) .gallery__carousel {
    margin-right: -2rem;
}

/* Las 18 fotos tienen 13 proporciones distintas (de 0.71 a 2.04), así que la
   tarjeta no puede fijar ancho: fija ALTURA y deja que el ancho salga de la
   proporción natural de cada miniatura. Así ninguna se recorta ni se estira.
   Los <img> llevan width/height con su tamaño real, que es lo que el navegador
   usa como relación de aspecto mientras carga y evita saltos de maquetación.
   Las miniaturas están generadas a 506px de alto, el tope de este clamp, para
   que en pantallas grandes no haya que escalarlas hacia arriba. */
.gallery__card {
    flex: 0 0 auto;
    height: clamp(250px, 41vh, 506px);
    width: auto;
    margin: 0;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 12px;
    background: rgba(15, 15, 26, 0.25);
    overflow: hidden;
    cursor: pointer;
    font: inherit;
    color: inherit;
    text-align: inherit;
    transition: transform 0.25s ease, border-color 0.25s ease;
}

.gallery__card:hover {
    transform: translateY(-4px);
    border-color: var(--color-accent);
}

.gallery__card:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 3px;
}

.gallery__card img {
    display: block;
    height: 100%;
    width: auto;
    max-width: none;
    transition: transform 0.45s ease;
}

.gallery__card:hover img {
    transform: scale(1.05);
}

/* ---- Visor de imagen ---- */

body.is-lightbox-open {
    overflow: hidden;
}

body.is-lightbox-open .gallery__track {
    animation-play-state: paused;
}

body.is-lightbox-open #three-canvas {
    opacity: 0;
}

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: grid;
    place-items: center;
    padding: clamp(3.5rem, 7vw, 5rem) clamp(1rem, 5vw, 5rem);
    visibility: hidden;
    opacity: 0;
}

.lightbox.is-open {
    visibility: visible;
    opacity: 1;
}

.lightbox__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(4, 4, 10, 0.94);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 0;
    padding: 0;
}

.lightbox__stage {
    position: relative;
    z-index: 1;
    display: inline-block;
    line-height: 0;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.9);
}

/* La foto se muestra entera y ampliada hasta que quepa en la ventana: sin
   object-fit, sin recortes y sin transiciones. */
.lightbox__img {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: calc(100vh - 11rem);
    max-height: calc(100dvh - 11rem);
}

.lightbox__btn {
    position: absolute;
    z-index: 2;
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    padding: 0;
    border: 1px solid rgba(0, 147, 165, 0.45);
    border-radius: 50%;
    background: rgba(15, 15, 26, 0.7);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: var(--color-heading);
    font-family: var(--font-mono);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.lightbox__btn:hover {
    background: rgba(0, 147, 165, 0.22);
    border-color: var(--color-accent);
    color: #ffffff;
}

.lightbox__btn:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 3px;
}

.lightbox__btn--prev {
    left: clamp(0.5rem, 2vw, 1.5rem);
    top: 50%;
    transform: translateY(-50%);
}

.lightbox__btn--next {
    right: clamp(0.5rem, 2vw, 1.5rem);
    top: 50%;
    transform: translateY(-50%);
}

.lightbox__btn--close {
    top: clamp(0.75rem, 2vw, 1.5rem);
    right: clamp(0.75rem, 2vw, 1.5rem);
    font-size: 1.4rem;
}

.lightbox__counter {
    position: absolute;
    left: 50%;
    bottom: clamp(0.75rem, 2vw, 1.5rem);
    transform: translateX(-50%);
    z-index: 2;
    margin: 0;
    padding: 0.5rem 1.1rem;
    border: 1px solid rgba(0, 147, 165, 0.35);
    border-radius: 100px;
    background: rgba(15, 15, 26, 0.7);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    font-family: var(--font-mono);
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    color: var(--color-text-alt);
}

@media screen and (max-width: 40em) {
    .lightbox__btn {
        width: 2.5rem;
        height: 2.5rem;
        font-size: 0.95rem;
    }

    .lightbox__btn--prev,
    .lightbox__btn--next {
        top: auto;
        bottom: clamp(0.75rem, 2vw, 1.5rem);
        transform: none;
    }

    .lightbox__counter {
        bottom: 1.35rem;
    }
}

.gallery__links {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

.gallery__btn {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.7rem 1.5rem;
    border: 1px solid rgba(0, 147, 165, 0.45);
    border-radius: 100px;
    background: rgba(0, 147, 165, 0.06);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    font-family: var(--font-mono);
    font-size: 0.85rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: #7fd4dd;
    transition: border-color 0.3s ease, background 0.3s ease, color 0.3s ease,
        box-shadow 0.3s ease;
}

.gallery__btn__arrow {
    display: inline-block;
    transition: transform 0.3s ease;
}

.gallery__btn:hover {
    border-color: var(--color-accent);
    background: rgba(0, 147, 165, 0.12);
    color: var(--color-accent);
    box-shadow: 0 0 18px rgba(0, 147, 165, 0.18);
}

.gallery__btn:hover .gallery__btn__arrow {
    transform: translateX(4px);
}

.gallery__btn:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 3px;
}

@media screen and (min-width: 54em) {
    .page-gallery .gallery {
        column-gap: 3rem;
        padding: 8.5rem 3rem 2.5rem;
    }

    .page-gallery .gallery__text {
        justify-content: center;
        align-items: center;
    }

    .page-gallery .gallery__desc {
        text-align: center;
    }

    /* Sangrado del carrusel solo en escritorio */
    .page-gallery:has(.lightbox) .gallery__carousel {
        margin-right: -3rem;
    }
}

/* ---- Responsive: Tablet ---- */
@media screen and (min-width: 40em) {
    .content {
        gap: 3rem;
        padding: 2rem 6vw;
    }

    .content__column {
        padding-left: 2rem;
    }

    .content__image {
        max-width: 520px;
    }

    .frame__links img {
        width: 32px;
        height: 32px;
    }
}

/* ---- Responsive: Desktop ---- */
@media screen and (min-width: 54em) {
    body {
        --size-menu: 11.25vh;
    }

    .topnav {
        padding-left: 4vw;
    }

    /* Enlaces y botón de idioma centrados verticalmente entre sí */
    .topnav__links {
        align-items: center;
    }

    main {
        height: 100vh;
        overflow: hidden;
        grid-template-rows: 100%;
        grid-template-areas: 'side side side content content content';
    }

    .menu {
        grid-area: 1 / 1 / 2 / 6;
        grid-template-rows: 100%;
        border: 0;
    }

    .menu__items {
        grid-area: 1 / 3 / 2 / 6;
        justify-content: center;
        margin: 1vh 0 0 0;
        padding-bottom: 0;
    }

    .frame {
        background: none;
        backdrop-filter: none;
        border: none;
        grid-area: content;
        display: grid;
        align-content: space-between;
        pointer-events: none;
        grid-template-columns: 50% 50%;
        grid-template-rows: auto auto auto;
        grid-template-areas:
            '... ...'
            '... ...'
            'title links';
        padding: 1.5rem 2rem;
    }

    /* Selector de idioma: arriba a la derecha, al mismo alto y borde que el topnav.
       Absoluto para no alterar el layout móvil (donde va dentro de .frame__links). */
    .frame .lang__toggle {
        position: absolute;
        top: 1rem;
        right: 2rem;
    }

    .frame::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        pointer-events: none;
        width: 100%;
        height: 100%;
        z-index: 10;
        background: #000000;
        opacity: 0;
        transition: opacity 0.8s ease-in-out 0.3s;
    }

    .menu--open ~ .frame::after {
        opacity: 0.75;
        transition-delay: 0s;
        pointer-events: auto;
    }

    .frame__links {
        grid-area: links;
        justify-self: end;
        align-self: end;
        pointer-events: auto;
    }

    .frame__links img {
        width: 36px;
        height: 36px;
    }

    .menu__tagline {
        display: block;
    }

    .menu__button {
        align-self: center;
        justify-self: center;
        margin: 0;
        grid-area: 1 / 1.5 / 2 / 2;
    }

    .content {
        display: flex;
        justify-content: end;
        align-items: center;
        padding: 0;
    }

    .content__column {
        max-width: 66ch;
        padding: 1rem 2rem;
    }

    .content__column:first-child {
        margin-top: calc(-8vh + 20px);
        padding-left: 4rem;
    }

    .content__column:last-child {
        margin: 2vh 2vh 2vh 2vh;
        max-width: none;
        min-width: 0;
        border-left: 2px solid var(--color-accent);
        padding-left: 3.5rem;
    }

    .content__image {
        max-width: 448px;
        width: 100%;
        height: auto;
        border-radius: 12px;
        display: block;
        margin-right: 2rem;
        padding: 1rem;
    }
}

/* ---- Gooey: layout desktop ---- */
@media screen and (min-width: 54em) {
    .page-title {
        font-size: calc(2vw + 4rem);
    }

    .devtiles {
        height: 100%;
    }

    .devtile:nth-child(1) {
        transform: translateY(8vh);
    }

    .devtile:nth-child(2) {
        transform: translateY(-8vh);
    }

    .devtile:nth-child(3) {
        transform: translateY(8vh);
    }

    .tile__title {
        margin-left: -45%;
    }
}

/* ---- Dev nav: flechas prev/next ---- */
.dev-nav {
    position: fixed;
    z-index: 4;
    left: 50%;
    bottom: 2rem;
    transform: translateX(-50%);
    display: flex;
    gap: 1rem;
    pointer-events: none;
}

.dev-nav__arrow {
    pointer-events: auto;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.25);
    background: rgba(15, 15, 26, 0.5);
    backdrop-filter: blur(6px);
    color: var(--color-heading);
    font-size: 1.35rem;
    line-height: 1;
    display: grid;
    place-items: center;
    cursor: pointer;
    user-select: none;
    transition: background 0.3s, border-color 0.3s, color 0.3s, opacity 0.3s;
}

.dev-nav__arrow:hover {
    background: rgba(0, 147, 165, 0.18);
    border-color: rgba(0, 147, 165, 0.6);
    color: var(--color-accent);
}

.dev-nav__arrow.is-disabled {
    opacity: 0.2;
    pointer-events: none;
}

@media screen and (min-width: 54em) {
    .dev-nav {
        left: 0;
        right: 0;
        bottom: auto;
        top: 50%;
        transform: translateY(-50%);
        justify-content: space-between;
        padding: 0 1.5rem;
    }

    .dev-nav__arrow {
        width: 54px;
        height: 54px;
    }
}

/* ---- Scroll hint (dev / design / photography) ---- */
.scroll-hint {
    position: fixed;
    left: 2rem;
    bottom: 2rem;
    z-index: 4;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    color: #7fd4dd;
    opacity: 1;
    transition: opacity 0.5s ease;
    pointer-events: none;
    animation: scroll-hint-bob 2s ease-in-out infinite;
}

.scroll-hint.is-hidden {
    opacity: 0;
}

.scroll-hint__mouse {
    display: block;
    width: 20px;
    height: 31px;
}

.scroll-hint__wheel {
    transform-box: fill-box;
    transform-origin: center;
    animation: scroll-hint-wheel 1.6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

.scroll-hint__label {
    font-family: var(--font-mono);
    font-size: 0.6rem;
    letter-spacing: 0.25em;
    text-transform: uppercase;
}

@keyframes scroll-hint-bob {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-6px);
    }
}

@keyframes scroll-hint-wheel {
    0% {
        transform: translateY(0);
        opacity: 1;
    }
    50% {
        transform: translateY(10px);
        opacity: 0.3;
    }
    100% {
        transform: translateY(0);
        opacity: 1;
    }
}

@media (prefers-reduced-motion: reduce) {
    .scroll-hint,
    .scroll-hint__wheel {
        animation: none;
    }
}

/* ---- Responsive: Mobile (≤ 53.99em) ---- */
@media screen and (max-width: 53.99em) {

    /* --- Topnav aligned with the page title --- */
    .topnav {
        padding-left: 1.25rem;
    }

    /* --- Topnav: collapse links behind a hamburger --- */
    .topnav__toggle {
        display: flex;
        width: 44px;
        height: 44px;
        align-items: center;
        justify-content: center;
        background: none;
        border: 0;
        padding: 0;
        cursor: pointer;
        z-index: 202;
    }

    .topnav__toggle-inner,
    .topnav__toggle-inner::before,
    .topnav__toggle-inner::after {
        content: '';
        display: block;
        position: absolute;
        left: 0;
        width: 24px;
        height: 2px;
        border-radius: 2px;
        background: var(--color-heading);
        transition: transform 0.25s ease, top 0.25s ease, background 0.25s ease;
    }

    .topnav__toggle-inner {
        position: relative;
    }

    /* Separación de 8px (no 7): así las tres líneas caen en la misma fase de
       píxel también al 125 % y al 150 % de escalado de Windows, donde con 7px
       la superior y la inferior se rasterizaban más finas que la central. */
    .topnav__toggle-inner::before { top: -8px; }
    .topnav__toggle-inner::after { top: 8px; }

    .topnav.is-open .topnav__toggle-inner { background: transparent; }
    .topnav.is-open .topnav__toggle-inner::before { top: 0; transform: rotate(45deg); }
    .topnav.is-open .topnav__toggle-inner::after { top: 0; transform: rotate(-45deg); }

    .topnav__links {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        gap: 0;
        padding: 0.5rem 0;
        background: rgba(15, 15, 26, 0.97);
        backdrop-filter: blur(10px);
        -webkit-backdrop-filter: blur(10px);
        border-bottom: 1px solid rgba(255, 255, 255, 0.06);
        opacity: 0;
        visibility: hidden;
        transform: translateY(-8px);
        pointer-events: none;
        transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
    }

    .topnav.is-open .topnav__links {
        opacity: 1;
        visibility: visible;
        transform: none;
        pointer-events: auto;
    }

    .topnav__links a {
        padding: 0.85rem 2rem;
        font-size: 0.85rem;
    }

    .topnav__links .lang__toggle {
        align-self: flex-start;
        margin: 0.85rem 2rem;
    }

    /* --- Duplicated frame bar is covered by the fixed topnav: hide it --- */
    body.page-development .frame,
    body.page-design .frame,
    body.page-photography .frame,
    body.page-about .frame,
    body.page-gallery .frame {
        display: none;
    }

    /* --- Home / Contact: el botón de idioma queda al mismo borde que el topnav --- */
    .frame {
        padding-right: 2rem;
    }

    /* --- Home / Contact: los 49px de desbordamiento horizontal ---
       La rejilla base (`10vw 10vh 10vw 5vw 32vw 1fr`) deja a `.frame` con 228px
       de ancho a 390 de viewport, y dentro necesita 205px: 3 iconos de 28 + 3
       huecos de 24 + el botón de idioma de 49. Se salían 49px por la derecha y
       la página se podía panear. Medido: ocultar `.frame__links` deja
       `scrollWidth` en 390, así que es el único culpable; el canvas solo
       arrastraba la anchura que ya estaba rota. Por debajo de 40em, que es
       donde la caja es tan estrecha, se encoge lo justo para que quepa. */
    @media screen and (max-width: 39.99em) {
        .frame__links {
            gap: 0.6rem;
            margin-left: 0;
        }

        .frame__links img {
            width: 24px;
            height: 24px;
        }

        .frame .lang__toggle {
            padding: 0.4rem 0.65rem;
        }
    }

    /* --- Page title: fit the screen, wrap, clear the topnav ---
       En móvil pasa de `fixed` a `absolute`: no hay nada que le reserve hueco,
       así que cualquier cosa que scrollea (el párrafo de las galerías, el botón
       de vuelta) se le colaba por debajo. Medido a 360x640: `p.gallery__desc`
       con 5372px² de solape, y la primera tile de Diseño y Fotografía recortada
       13px. `main` no está posicionado, así que `absolute` resuelve contra el
       documento y el título se va al hacer scroll, sin alterar el flujo. */
    .page-title {
        position: absolute;
        top: 4.75rem;
        left: 1.25rem;
        right: 1.25rem;
        width: auto;
        white-space: normal;
        font-size: clamp(1.5rem, 4.5vw + 0.6rem, 2.3rem);
        line-height: 1.12;
        opacity: 0.22;
    }

    /* --- Diseño / Fotografía / Desarrollo: aquí el título no tiene escapatoria ---
       Su contenido es un carrusel horizontal, así que la página NO scrollea en
       vertical (`scrollY` se queda en 0) y no hay forma de que el título se vaya
       como en las galerías. Medido a 360x640: la primera card (`li.devtile`)
       queda siempre debajo con 2939px² de solape. En móvil se oculta, igual que
       ya se ocultan `.frame` y el `h2` de `.devtiles` en estas mismas páginas. */
    body.page-design .page-title,
    body.page-photography .page-title,
    body.page-development .page-title {
        display: none;
    }

    .page-title__offset {
        margin-left: 8%;
    }

    /* --- Tiles sections: full-width row with room for the nav arrows --- */
    .page-development .development,
    .page-design .design,
    .page-photography .photography {
        padding: 7rem 0 6.5rem;
    }

    /* --- Contact: compact paddings on small screens --- */
    .page-contact .contact {
        padding: 1.5rem 1.25rem 3rem;
    }

    .page-contact .contact__card {
        padding: 1.5rem;
    }
}

/* ============================================================================
   LAYOUT POR PÁGINA — consolidado (sesión 21)
   ----------------------------------------------------------------------------
   Estos bloques vivían en un <style> dentro del <head> de cada página, es
   decir DESPUÉS de esta hoja. Por eso se mantienen al FINAL de style.css:
   así conservan exactamente la misma prioridad de cascada que tenían.
   Se pasó de ~500 líneas repetidas en 8 páginas a un único bloque.
   ============================================================================ */

/* ---- 1. Rejilla de `main` (móvil): dos filas, la sección en la segunda ---- */
.page-about main {
    grid-template-areas:
        'side side side frame frame frame'
        'about about about about about about';
}

.page-contact main {
    grid-template-areas:
        'side side side frame frame frame'
        'contact contact contact contact contact contact';
}

.page-development main {
    grid-template-areas:
        'side side side frame frame frame'
        'development development development development development development';
}

.page-design main {
    grid-template-areas:
        'side side side frame frame frame'
        'design design design design design design';
}

.page-photography main {
    grid-template-areas:
        'side side side frame frame frame'
        'photography photography photography photography photography photography';
}

.page-gallery main {
    grid-template-areas:
        'side side side frame frame frame'
        'gallery gallery gallery gallery gallery gallery';
}

/* ---- 2. Sección contenedora de cada página ---- */
.page-about .about {
    display: grid;
    place-items: center;
    padding: 5.5rem 2rem 2rem;
}

.page-contact .contact {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0;
    padding: 4rem 2rem 2rem;
    transform: translateY(-36px);
}

.page-contact .contact__stack {
    align-self: center;
    width: 100%;
    max-width: 469px;
    margin: 0 auto;
}

.page-development .development,
.page-design .design,
.page-photography .photography {
    position: relative;
    z-index: 2;
    display: grid;
    place-items: center;
    padding: 6.5rem 2rem 4rem;
}

.page-contact .contact__card {
    width: 100%;
    max-width: 469px;
}

.page-gallery .gallery {
    grid-area: gallery;
}

/* ---- 3. Escritorio (>= 54em) ---- */
@media screen and (min-width: 54em) {

    /* Una sola fila a pantalla completa en las páginas con topnav */
    .page-about main,
    .page-contact main,
    .page-development main,
    .page-design main,
    .page-photography main,
    .page-gallery main {
        height: 100vh;
        overflow: hidden;
        grid-template-rows: 100%;
    }

    /* Área de la sección, por página */
    .page-about main { grid-template-areas: 'side side side about about about'; }
    .page-contact main { grid-template-areas: 'side side side contact contact contact'; }
    .page-development main { grid-template-areas: 'development development development development development development'; }
    .page-design main { grid-template-areas: 'design design design design design design'; }
    .page-photography main { grid-template-areas: 'photography photography photography photography photography photography'; }
    .page-gallery main { grid-template-areas: 'gallery gallery gallery gallery gallery gallery'; }

    /* Sección: colocación en la rejilla + padding de escritorio */
    .page-about .about {
        grid-area: about;
        padding: 6.5rem 2rem 2rem;
    }

    .page-contact .contact {
        grid-area: contact;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        justify-content: center;
        gap: 1rem;
        padding: clamp(1.5rem, 4vh, 4rem) 2rem clamp(2rem, 5vh, 4rem);
    }

    .page-contact .contact__stack {
        margin-top: clamp(0px, 6vh, 50px);
        gap: clamp(0.75rem, 2vh, 1.5rem);
    }

    .page-development .development { grid-area: development; }
    .page-design .design { grid-area: design; }
    .page-photography .photography { grid-area: photography; }

    .page-gallery .gallery {
        grid-template-columns: minmax(280px, 2fr) minmax(0, 5fr);
        grid-template-areas: 'text carousel';
    }

    /* La frase no puede robarle sitio a la fila de texto y carrusel: en
       escritorio se vuelve a las dos areas de siempre y el lema se superpone
       al hueco que ya queda libre bajo el carrusel. Al salir de flujo no
       genera ninguna fila ni columna implicita. */
    .page-gallery .gallery--slogan {
        grid-template-areas: 'text carousel';
    }

    /* El lema se alinea al borde izquierdo del carrusel compartiendo su celda
       de rejilla: el area 'carousel' empieza exactamente donde empieza el
       carrusel, sin tener que calcular a mano la fraccion 2fr/5fr de las
       columnas. justify-self: start lo pega a ese borde. Al bajar el lema un
       rem respecto a como estaba, el margen inferior pasa de 2rem a 1rem:
       align-self: end lo ancla al pie de la celda, asi que reducir ese margen
       es lo que lo baja, y el hueco de respiro lo aporta el 2.5rem que ya
       separa las filas de la rejilla. */
    .page-gallery .gallery__slogan {
        grid-area: carousel;
        align-self: end;
        justify-self: start;
        width: auto;
        max-width: min(46ch, 60vw);
        margin: 0 0 1rem;
    }

    /* La barra superior (frame) se vuelve overlay transparente */
    .page-about .frame,
    .page-contact .frame,
    .page-development .frame,
    .page-design .frame,
    .page-photography .frame,
    .page-gallery .frame {
        background: none;
        backdrop-filter: none;
        border: none;
        display: grid;
        align-content: space-between;
        pointer-events: none;
        grid-template-columns: 50% 50%;
        grid-template-rows: auto auto auto;
        grid-template-areas:
            '... ...'
            '... ...'
            'title links';
        padding: 1.5rem 2rem;
    }

    /* Solo estas páginas necesitan contexto de apilado propio */
    .page-development .frame,
    .page-design .frame,
    .page-photography .frame,
    .page-gallery .frame,
    .page-contact .frame {
        z-index: 3;
    }

    .page-about .frame { grid-area: about; }
    .page-contact .frame { grid-area: contact; }
    .page-development .frame { grid-area: development; }
    .page-design .frame { grid-area: design; }
    .page-photography .frame { grid-area: photography; }
    .page-gallery .frame { grid-area: gallery; }

    /* Velo negro al abrir el menú LetterShuffle (páginas con menú) */
    .page-about .frame::after,
    .page-contact .frame::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        pointer-events: none;
        width: 100%;
        height: 100%;
        z-index: 10;
        background: #000000;
        opacity: 0;
        transition: opacity 0.8s ease-in-out 0.3s;
    }

    .page-about .menu--open ~ .frame::after,
    .page-contact .menu--open ~ .frame::after {
        opacity: 0.75;
        transition-delay: 0s;
        pointer-events: auto;
    }

    /* Redes sociales y botón de idioma dentro del frame */
    .page-about .frame__links,
    .page-contact .frame__links,
    .page-development .frame__links,
    .page-design .frame__links,
    .page-photography .frame__links,
    .page-gallery .frame__links {
        grid-area: links;
        justify-self: end;
        align-self: end;
        pointer-events: auto;
    }

    .page-about .frame__links img,
    .page-contact .frame__links img,
    .page-development .frame__links img,
    .page-design .frame__links img,
    .page-photography .frame__links img,
    .page-gallery .frame__links img {
        width: 36px;
        height: 36px;
    }
}

/* ============================================
   Custom Cursor
   ============================================ */

/* Con el cursor propio activo se oculta el del navegador en toda la página,
   para que solo se vean el anillo y el punto. El anillo ya crece al pasar por
   encima de un elemento interactivo (ver initCustomCursor en js/index.js), así
   que no se pierde la pista de qué es pulsable.

   .has-cursor la añade el propio módulo de JS justo después de crear el anillo.
   Si ese módulo falla al cargar (por ejemplo, si el CDN de Three.js no
   responde), el selector no coincide y el puntero del navegador sigue estando.
   Antes colgaba de html.js, una clase que pone un script en línea y que se
   ejecuta siempre, así que esa red de seguridad no existía: un error de módulo
   dejaba la página sin ningún cursor.

   El selector con * es a propósito: los cursor: pointer de botones y enlaces son
   menos específicos, así que sin él se vería la flecha por encima del anillo. */
html.has-cursor body,
html.has-cursor body * {
    cursor: none;
}

/* Excepción: en los campos del formulario de contacto el puntero es
   imprescindible para saber dónde se está escribiendo. Quitar estas tres líneas
   si prefieres el efecto completo también ahí. */
html.has-cursor body input,
html.has-cursor body textarea,
html.has-cursor body select {
    cursor: text;
}

.custom-cursor {
    position: fixed;
    top: 0;
    left: 0;
    pointer-events: none;
    z-index: 9999;
    mix-blend-mode: difference;
    transition: opacity 0.2s ease;
}

.custom-cursor .cursor-ring {
    position: absolute;
    width: 40px;
    height: 40px;
    border: 2px solid #fff;
    border-radius: 50%;
    transform: translate(-50%, -50%);
    transition: width 0.3s ease, height 0.3s ease, border-color 0.3s ease, background 0.3s ease;
}

.custom-cursor .cursor-dot {
    position: absolute;
    width: 6px;
    height: 6px;
    background: #fff;
    border-radius: 50%;
    transform: translate(-50%, -50%);
}

.custom-cursor.cursor-hover .cursor-ring {
    width: 60px;
    height: 60px;
    border-color: var(--color-accent);
    background: rgba(0, 147, 165, 0.15);
}

.custom-cursor.cursor-hover .cursor-dot {
    background: var(--color-accent);
    width: 8px;
    height: 8px;
}

.custom-cursor.cursor-click .cursor-ring {
    width: 30px;
    height: 30px;
}

@media (pointer: coarse) {
    .custom-cursor {
        display: none;
    }
}

/* Nota + tarjeta del formulario. La nota va arriba, en el lado opuesto al
   botón Enviar, para no competir con la animación del CTA. */
.page-contact .contact {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    padding-left: 0;
}

.page-contact .contact__note {
    margin-top: 4rem;
    /* La columna está centrada con `justify-content: center`: un margin-top
       real repartiría el hueco y movería también la tarjeta. El desplazamiento
       relativo baja solo la nota; el formulario queda clavado donde está. */
    position: relative;
    top: 2rem;
}

@media screen and (max-width: 53.99em) {
    /* En móvil el hueco nota↔tarjeta es solo el `gap` de 1rem: 0.75rem deja
       4 px de caja (el interlineado añade aire visual) sin empujar la tarjeta. */
    .page-contact .contact__note {
        top: 0.75rem;
    }
}

.contact__stack {
    display: grid;
    gap: 1.5rem;
    width: 100%;
    max-width: 469px;
    margin-top: 0;
}

.contact__note {
    margin: 0 auto;
    width: 100%;
    max-width: 700px;
    text-align: center;
    align-self: center;
    font-family: var(--font-para);
    font-size: clamp(1rem, 0.8rem + 0.8vw, 1.25rem);
    line-height: 1.35;
    color: var(--color-text-alt);
}

.contact__note--title {
    display: block;
    font-family: var(--font-name);
    font-size: 1.1rem;
    font-weight: 400;
    line-height: 1.4;
    color: var(--color-heading);
}

.contact__note--sub {
    display: block;
    margin-top: 0.25rem;
    font-size: 1.5rem;
}
