/* BlueList — hoja de estilos.

   Misma estetica que BlueMusic: monocromo y plano, blanco, negro y grises,
   sin degradados ni sombras. La pagina se compone como las notas de un libro
   de cocina: titular grotesco a la izquierda, ficha tecnica en monoespaciada
   a la derecha, hilos de 1 px como separadores, y las capturas reales de la
   app metidas en marcos dibujados con CSS: el movil apoyado sobre el iPad.

   La web va siempre en modo dia: no hay variante oscura. */

/* ── FUENTES (las escribe fuentes.py: no editar a mano) ── */
/* vietnamese */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/bricolage-grotesque-vietnamese-7e13a14c.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/bricolage-grotesque-latin-ext-1d04719f.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/bricolage-grotesque-latin-85f55a58.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/bricolage-grotesque-vietnamese-7e13a14c.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/bricolage-grotesque-latin-ext-1d04719f.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/bricolage-grotesque-latin-85f55a58.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 800;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/bricolage-grotesque-vietnamese-7e13a14c.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 800;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/bricolage-grotesque-latin-ext-1d04719f.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 800;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/bricolage-grotesque-latin-85f55a58.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-cyrillic-ext-400-c6f09ee0.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-cyrillic-400-7b59d6bf.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-vietnamese-400-0a8b854c.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-ext-400-f1050dc5.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-400-c36f509c.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-cyrillic-ext-500-311098be.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-cyrillic-500-d524dc8f.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-vietnamese-500-b2529fba.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-ext-500-77f03e26.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-500-a76f53ca.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-cyrillic-ext-c01b3de8.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-cyrillic-5bac7252.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-greek-a29d4e63.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-vietnamese-526a4dd3.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-ext-ae1d854f.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-056e4e24.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-cyrillic-ext-c01b3de8.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-cyrillic-5bac7252.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-greek-a29d4e63.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-vietnamese-526a4dd3.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-ext-ae1d854f.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-056e4e24.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-cyrillic-ext-c01b3de8.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-cyrillic-5bac7252.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-greek-a29d4e63.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-vietnamese-526a4dd3.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-ext-ae1d854f.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-056e4e24.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* ── FIN DE LAS FUENTES ── */

:root {
    color-scheme: light;

    --paper: #ffffff;
    --ink: #111111;
    --gray-700: #4a4a4a;
    --gray-500: #6f6f6f;
    --gray-300: #b8b8b8;
    --gray-200: #e3e3e3;
    --gray-100: #f3f3f3;

    --display: 'Bricolage Grotesque', 'Helvetica Neue', Arial, sans-serif;
    --body: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    --topbar: 60px;
    --gutter: 28px;
    --max: 1200px;

    --fast: 0.18s ease;
    --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--topbar) + 16px);
}

body {
    font-family: var(--body);
    font-size: 1rem;
    line-height: 1.55;
    color: var(--ink);
    background: var(--paper);
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
    font-family: var(--display);
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.025em;
    text-wrap: balance;
}

::selection {
    background: var(--ink);
    color: var(--paper);
}

a {
    color: inherit;
    text-decoration: none;
}

img, svg {
    display: block;
}

img {
    max-width: 100%;
    height: auto;
}

a:focus-visible,
button:focus-visible,
summary:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 3px;
}

/* Sobre la banda negra el anillo tiene que ser blanco */
.where a:focus-visible {
    outline-color: var(--paper);
}

.container {
    max-width: var(--max);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

/* Etiquetas y datos, en monoespaciada */
.eyebrow,
.meta,
.badge,
.caption {
    font-family: var(--mono);
    font-size: 0.78rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--gray-500);
}

.lede {
    font-size: 1.1rem;
    color: var(--gray-700);
    max-width: 34em;
}

/* ============================
   BARRA
   ============================ */
.topbar,
.navbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    height: var(--topbar);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 var(--gutter);
    background: var(--paper);
    border-bottom: 1px solid var(--gray-200);
}

.brand,
.navbar .logo span {
    font-family: var(--display);
    font-size: 1.2rem;
    font-weight: 800;
    letter-spacing: -0.03em;
    white-space: nowrap;
}

/* La barra va a sangre, igual que la de la portada: el .container interior
   duplicaba el margen lateral y dejaba el logo pegado al primer enlace. */
.navbar .nav-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    width: 100%;
    max-width: none;
    padding: 0;
}

.menu,
.nav-links {
    display: flex;
    align-items: center;
    gap: 26px;
}

.menu a,
.nav-links a {
    font-size: 0.92rem;
    font-weight: 500;
    color: var(--gray-700);
    padding: 4px 0;
    border-bottom: 1px solid transparent;
    transition: color var(--fast), border-color var(--fast);
    white-space: nowrap;
}

.menu a:hover,
.nav-links a:hover,
.nav-links a.active {
    color: var(--ink);
    border-bottom-color: var(--ink);
}

/* ============================
   BOTONES: rectos, planos
   ============================ */
.actions,
.store-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.btn,
.store-btn,
.btn-primary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 48px;
    padding: 0 26px;
    border: 1px solid var(--ink);
    font-family: var(--body);
    font-size: 0.95rem;
    font-weight: 500;
    transition: background var(--fast), color var(--fast), border-color var(--fast);
}

.btn-solid,
.store-btn,
.btn-primary {
    background: var(--ink);
    color: var(--paper);
}

.btn-solid:hover,
.store-btn:hover,
.btn-primary:hover {
    background: var(--gray-700);
    border-color: var(--gray-700);
}

.btn-line,
.store-btn.secondary {
    background: transparent;
    color: var(--ink);
}

.btn-line:hover,
.store-btn.secondary:hover {
    background: var(--gray-100);
    border-color: var(--ink);
}

.btn-inverse.btn-solid {
    background: var(--paper);
    color: var(--ink);
    border-color: var(--paper);
}

.btn-inverse.btn-solid:hover {
    background: var(--gray-200);
    border-color: var(--gray-200);
}

.btn-inverse.btn-line {
    color: var(--paper);
    border-color: var(--paper);
}

.btn-inverse.btn-line:hover {
    background: rgba(255, 255, 255, 0.12);
}

/* ============================
   PORTADA
   ============================ */
.hero {
    padding: calc(var(--topbar) + 72px) 0 0;
}

.hero-grid {
    display: grid;
    grid-template-columns: 1.15fr 0.85fr;
    gap: 56px;
    align-items: end;
    padding-bottom: 52px;
}

.hero-copy {
    display: grid;
    gap: 22px;
}

.hero h1 {
    font-size: clamp(2.8rem, 6.4vw, 5.4rem);
    font-weight: 800;
    letter-spacing: -0.035em;
}

/* Ficha tecnica: pares etiqueta/valor separados por hilos */
.spec {
    display: grid;
    font-family: var(--mono);
    font-size: 0.8rem;
}

.spec > div {
    display: grid;
    grid-template-columns: 88px 1fr;
    gap: 16px;
    padding: 12px 0;
    border-top: 1px solid var(--gray-200);
}

.spec > div:last-child {
    border-bottom: 1px solid var(--gray-200);
}

.spec dt {
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--gray-500);
    padding-top: 1px;
}

.spec dd {
    color: var(--ink);
    line-height: 1.5;
}

.spec-light > div {
    border-color: rgba(255, 255, 255, 0.18);
}

.spec-light dt {
    color: var(--gray-300);
}

.spec-light dd {
    color: var(--paper);
}

.spec-light > div:last-child {
    border-bottom-color: rgba(255, 255, 255, 0.18);
}

/* ============================
   LAS CAPTURAS: MOVIL SOBRE IPAD
   ============================ */
.shot,
.where-shot {
    display: flex;
    justify-content: center;
}

.shot {
    padding-top: 8px;
    padding-bottom: 8px;
}

/* El movil se apoya encima del iPad y el conjunto se corta abajo con un
   degradado, en vez de flotar entero sobre el fondo. Los dos aparatos son
   mas altos que el marco: la mascara los recorta y los disuelve. */
.duo {
    position: relative;
    width: 100%;
    max-width: 920px;
    aspect-ratio: 920 / 460;
    -webkit-mask-image: linear-gradient(to bottom, #000 var(--corte, 66%), transparent 100%);
    mask-image: linear-gradient(to bottom, #000 var(--corte, 66%), transparent 100%);
}

.duo .ipad {
    position: absolute;
    left: 2%;
    top: 0;
    width: 78%;
}

.duo .iphone {
    position: absolute;
    left: 68%;
    top: 15%;
    width: 25%;
}

.ipad,
.iphone {
    background: var(--ink);
    border: 1px solid var(--gray-300);
}

.ipad {
    padding: clamp(6px, 1.3vw, 13px);
    border-radius: clamp(14px, 2.4vw, 26px);
}

.ipad-screen {
    position: relative;
    aspect-ratio: 960 / 664;
    border-radius: clamp(7px, 1.2vw, 13px);
    overflow: hidden;
    background: #000000;
}

.iphone {
    padding: clamp(4px, 0.75vw, 8px);
    border-radius: clamp(18px, 3.8vw, 38px);
}

.iphone-screen {
    position: relative;
    aspect-ratio: 603 / 1312;
    border-radius: clamp(14px, 3vw, 30px);
    overflow: hidden;
    background: #000000;
}

.ipad-screen img,
.iphone-screen img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* El iPad solo, entero y sin mascara */
.solo {
    max-width: 900px;
    margin: 0 auto;
}

.solo .ipad {
    width: 100%;
}

.solo figcaption {
    padding-top: 14px;
    text-align: center;
}

/* Tres moviles en fila, cada uno con su pie */
.trio {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 44px;
    padding-top: 8px;
}

.trio figure {
    display: grid;
    gap: 14px;
    align-content: start;
}

.trio figcaption {
    display: grid;
    gap: 4px;
    border-top: 1px solid var(--gray-200);
    padding-top: 12px;
}

.trio figcaption b {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--ink);
}

.trio figcaption small {
    font-size: 0.86rem;
    line-height: 1.5;
    color: var(--gray-500);
}

/* ============================
   COMO FUNCIONA: SOLO TEXTO
   ============================ */
.how {
    padding: 72px 0;
}

.how .eyebrow {
    padding-bottom: 26px;
}

.steps {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0 40px;
}

.step {
    display: grid;
    align-content: start;
    gap: 14px;
    padding-top: 22px;
    border-top: 1px solid var(--ink);
}

.step h2 {
    font-size: clamp(1.8rem, 2.8vw, 2.6rem);
}

.step p {
    color: var(--gray-700);
}

.step .meta {
    color: var(--gray-500);
}

/* ============================
   SECCIONES CON CABECERA
   ============================ */
.section {
    border-top: 1px solid var(--gray-200);
    padding: 72px 0;
}

.section-head {
    display: grid;
    gap: 16px;
    max-width: 40em;
    margin-bottom: 40px;
}

.section-head h2 {
    font-size: clamp(2rem, 4vw, 3.2rem);
}

/* Las cifras, en una rejilla de hilos */
.figures {
    list-style: none;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    border-top: 1px solid var(--gray-200);
    border-left: 1px solid var(--gray-200);
    margin-top: 48px;
}

.figures li {
    display: grid;
    gap: 4px;
    padding: 20px 16px 22px;
    border-right: 1px solid var(--gray-200);
    border-bottom: 1px solid var(--gray-200);
}

.figures .n {
    font-family: var(--display);
    font-size: clamp(1.9rem, 3vw, 2.6rem);
    font-weight: 800;
    letter-spacing: -0.035em;
    line-height: 1;
}

.figures .k {
    font-family: var(--mono);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--gray-500);
}

/* ============================
   PRECIOS
   ============================ */
.plans {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    border-top: 1px solid var(--gray-200);
    border-left: 1px solid var(--gray-200);
}

.plan {
    display: grid;
    align-content: start;
    gap: 14px;
    padding: 24px 22px 28px;
    border-right: 1px solid var(--gray-200);
    border-bottom: 1px solid var(--gray-200);
}

.plan .tag {
    font-family: var(--mono);
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gray-500);
}

.plan h3 {
    font-size: 1.5rem;
}

.plan ul {
    list-style: none;
    display: grid;
    gap: 8px;
}

.plan ul li {
    position: relative;
    padding-left: 14px;
    font-size: 0.92rem;
    color: var(--gray-700);
    line-height: 1.6;
}

.plan ul li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 11px;
    width: 5px;
    height: 1px;
    background: var(--ink);
}

/* ============================
   DESCARGA: BANDA NEGRA
   ============================ */
.where {
    background: var(--ink);
    color: var(--paper);
}

.where-grid {
    display: grid;
    grid-template-columns: 0.85fr 1.15fr;
    gap: 56px;
    align-items: center;
    padding-top: 80px;
    padding-bottom: 80px;
}

.where-copy {
    display: grid;
    gap: 22px;
    max-width: 32em;
}

.where-copy .eyebrow {
    color: var(--gray-300);
}

.where-copy h2 {
    font-size: clamp(2.2rem, 4.4vw, 3.6rem);
}

.where .ipad,
.where .iphone {
    border-color: var(--gray-700);
}

/* ============================
   LA LISTA COMPLETA, PLEGADA
   ============================ */
.features {
    padding: 64px 0 24px;
}

.full-details {
    border-top: 1px solid var(--gray-200);
    border-bottom: 1px solid var(--gray-200);
}

.full-summary {
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 26px 0;
    cursor: pointer;
}

.full-summary::-webkit-details-marker {
    display: none;
}

.full-summary b {
    display: block;
    font-family: var(--display);
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.02em;
}

.full-summary small {
    display: block;
    font-size: 0.92rem;
    color: var(--gray-500);
}

.full-arrow {
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border: 1px solid var(--ink);
    border-radius: 50%;
    position: relative;
    transition: transform var(--fast);
}

.full-arrow::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 9px;
    height: 9px;
    margin: -7px 0 0 -4.5px;
    border-right: 1.5px solid var(--ink);
    border-bottom: 1.5px solid var(--ink);
    transform: rotate(45deg);
}

.full-details[open] .full-arrow {
    transform: rotate(180deg);
}

/* Nueve bloques: en tres columnas la caja de hilos cierra sola; en dos, el
   ultimo ocupa la fila entera para que no quede una celda abierta. */
.features-list {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    border-top: 1px solid var(--gray-200);
    border-left: 1px solid var(--gray-200);
}

.feature-block {
    padding: 24px 22px 26px;
    border-right: 1px solid var(--gray-200);
    border-bottom: 1px solid var(--gray-200);
}

.feature-block h2 {
    font-size: 1.15rem;
    margin-bottom: 12px;
}

.feature-block p,
.feature-block ul li {
    font-size: 0.92rem;
    color: var(--gray-700);
    line-height: 1.6;
}

.feature-block ul {
    list-style: none;
    display: grid;
    gap: 8px;
}

.feature-block ul li {
    position: relative;
    padding-left: 14px;
}

.feature-block ul li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 11px;
    width: 5px;
    height: 1px;
    background: var(--ink);
}

.feature-note {
    margin-top: 12px;
    padding: 10px 12px;
    background: var(--gray-100);
    font-size: 0.84rem;
    color: var(--ink);
}

/* Suelta al pie de una seccion, la misma nota se estiraria a los 1144 px del
   contenedor: se le pone medida y el aire que lleva el resto de la seccion. */
.section > .container > .feature-note {
    max-width: 65ch;
    margin-top: 36px;
    padding: 14px 16px;
}

/* ============================
   PIE
   ============================ */
.footer {
    padding: 28px 0 40px;
}

.footer-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 10px 24px;
    font-family: var(--mono);
    font-size: 0.78rem;
    color: var(--gray-500);
}

.footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 22px;
}

.footer-links a:hover {
    color: var(--ink);
}

/* ============================
   ENTRADA AL HACER SCROLL: minima
   ============================ */
.js-reveal .reveal {
    opacity: 0.001;
    transform: translateY(10px);
    transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}

.js-reveal .reveal.is-visible {
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    .js-reveal .reveal { opacity: 1; transform: none; transition: none; }
}

/* ============================
   PAGINAS LEGALES
   ============================ */
.header {
    padding: calc(var(--topbar) + 64px) 0 40px;
    border-bottom: 1px solid var(--gray-200);
}

.header .container {
    display: grid;
    gap: 16px;
    max-width: 880px;
}

.header h1 {
    font-size: clamp(2.4rem, 5vw, 3.8rem);
}

.subtitle {
    font-size: 1.05rem;
    color: var(--gray-700);
    max-width: 38em;
}

.updated {
    font-family: var(--mono);
    font-size: 0.78rem;
    color: var(--gray-500);
}

/* Las paginas legales de BlueList cuelgan los bloques de un <main class="container">
   sin envoltorio intermedio: la medida y el aire se dan aqui. */
main.container {
    max-width: 880px;
    padding-top: 48px;
    padding-bottom: 96px;
}

.policy-section {
    padding: 32px 0;
    border-bottom: 1px solid var(--gray-200);
}

.policy-section:first-child {
    padding-top: 0;
}

.policy-section:last-child {
    border-bottom: 0;
}

.policy-section h2 {
    font-size: 1.5rem;
    margin-bottom: 14px;
}

.policy-section p {
    color: var(--gray-700);
    line-height: 1.7;
    margin-bottom: 12px;
    max-width: 65ch;
}

.policy-section p:last-child {
    margin-bottom: 0;
}

.policy-section strong {
    color: var(--ink);
    font-weight: 600;
}

.policy-section a {
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.policy-section ul,
.policy-section ol {
    list-style: none;
    display: grid;
    gap: 8px;
    margin: 6px 0 16px;
}

.policy-section ol {
    counter-reset: step;
}

.policy-section ul li,
.policy-section ol li {
    position: relative;
    color: var(--gray-700);
    line-height: 1.65;
    padding-left: 26px;
    max-width: 65ch;
}

.policy-section ul li::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 12px;
    width: 8px;
    height: 1px;
    background: var(--ink);
}

.policy-section ol li {
    counter-increment: step;
}

.policy-section ol li::before {
    content: counter(step);
    position: absolute;
    left: 0;
    top: 2px;
    font-family: var(--mono);
    font-size: 0.8rem;
    color: var(--gray-500);
}

.policy-section .btn-primary {
    color: var(--paper);
    text-decoration: none;
}

.contact-card,
.warning-box {
    background: var(--gray-100);
    padding: 18px 22px;
    margin-top: 16px;
}

.warning-box {
    margin: 16px 0;
    border-left: 1px solid var(--ink);
}

.contact-card p,
.warning-box p {
    margin-bottom: 6px;
}

.contact-card p:last-child,
.warning-box p:last-child {
    margin-bottom: 0;
}

.warning-title {
    font-weight: 600;
    color: var(--ink);
}

.footer-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    text-align: center;
    padding: 0 var(--gutter);
}

.footer-content .logo span {
    font-family: var(--display);
    font-weight: 800;
    font-size: 1.1rem;
}

.footer-content .footer-links {
    justify-content: center;
    font-family: var(--mono);
    font-size: 0.78rem;
    color: var(--gray-500);
}

.footer-content .copyright {
    font-family: var(--mono);
    font-size: 0.78rem;
    color: var(--gray-500);
}

/* ============================
   RESPONSIVE
   ============================ */
@media (max-width: 1000px) {
    .hero-grid,
    .where-grid {
        grid-template-columns: 1fr;
        gap: 40px;
        align-items: start;
    }

    .steps {
        grid-template-columns: 1fr;
        gap: 0;
    }

    .step {
        padding-bottom: 26px;
    }

    .step:last-child {
        padding-bottom: 0;
    }

    .figures {
        grid-template-columns: repeat(2, 1fr);
    }

    .features-list {
        grid-template-columns: repeat(2, 1fr);
    }

    .features-list .feature-block:last-child {
        grid-column: span 2;
    }

    /* Son cinco: la ultima celda se queda sola, asi que ocupa la fila entera */
    .figures li:last-child {
        grid-column: 1 / -1;
    }

    .plans {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 760px) {
    /* Tres moviles a 220 px cada uno se leen; a menos, no. Se apilan. */
    .trio {
        grid-template-columns: 1fr;
        gap: 40px;
        max-width: 300px;
        margin: 0 auto;
    }
}

@media (max-width: 720px) {
    :root {
        --gutter: 18px;
    }

    .topbar .menu {
        display: none;
    }

    .hero {
        padding-top: calc(var(--topbar) + 44px);
    }

    .how,
    .section {
        padding: 56px 0;
    }

    .where-grid {
        padding-top: 56px;
        padding-bottom: 56px;
    }

    .actions .btn,
    .store-buttons .store-btn {
        flex: 1 1 100%;
    }

    .spec > div {
        grid-template-columns: 1fr;
        gap: 4px;
    }

    /* En movil se mantiene la composicion de escritorio: el movil apoyado
       encima del iPad. El marco se hace mas alto y los dos aparatos crecen en
       proporcion, que si no a 320 px no se lee ninguno. */
    .duo {
        aspect-ratio: 920 / 560;
    }

    .duo .ipad {
        left: 0;
        width: 76%;
    }

    .duo .iphone {
        left: 62%;
        top: 12%;
        width: 36%;
    }

    .footer-row {
        flex-direction: column;
    }

    /* Sin el logo caben los cuatro enlaces: antes "Delete account" se salia */
    .navbar .logo {
        display: none;
    }

    .nav-container .nav-links {
        gap: 14px;
        min-width: 0;
        overflow-x: auto;
        scrollbar-width: none;
    }

    .nav-container .nav-links::-webkit-scrollbar {
        display: none;
    }

    .nav-container .nav-links a {
        font-size: 0.82rem;
    }
}

/* Dos columnas de fichas por debajo de 620 px caen a 290 px: se apilan */
@media (max-width: 620px) {
    .features-list {
        grid-template-columns: 1fr;
    }

    .features-list .feature-block:last-child {
        grid-column: auto;
    }
}

/* A 320 px los enlaces se salian por 18 px */
@media (max-width: 380px) {
    .nav-container .nav-links {
        gap: 10px;
    }

    .nav-container .nav-links a {
        font-size: 0.76rem;
    }
}

/* Selector de idioma: un <details>, sin JavaScript */
.idiomas {
    flex-basis: 100%;
    font-family: var(--mono);
    font-size: 0.78rem;
}

.idiomas summary {
    list-style: none;
    cursor: pointer;
    color: var(--gray-500);
    width: fit-content;
}

.idiomas summary::-webkit-details-marker {
    display: none;
}

.idiomas summary::after {
    content: " +";
}

.idiomas[open] summary::after {
    content: " \2212";
}

.idiomas summary:hover {
    color: var(--ink);
}

.idiomas-lista {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 8px 20px;
    padding-top: 14px;
}

.idiomas-lista a {
    color: var(--gray-500);
}

.idiomas-lista a:hover,
.idiomas-lista a[aria-current] {
    color: var(--ink);
}

.footer-content .idiomas {
    text-align: center;
}

.footer-content .idiomas summary {
    margin: 0 auto;
}

/* Aviso de que la pagina es una traduccion */
.aviso-idioma {
    font-family: var(--mono);
    font-size: 0.74rem;
    color: var(--gray-500);
    max-width: 60ch;
}

/* ═══════════════════════════════════════════════════════════════════════════
   EL MOVIMIENTO

   Todo lo que hay de aqui abajo es adorno, y como tal se comporta: cuelga de
   .js-reveal -la clase que solo pone script.js-, de modo que la pagina que
   llega del servidor no esconde nada. Sin JavaScript, con el JavaScript a
   medias, al imprimir o con el movimiento reducido, lo que se ve es la pagina
   de siempre: entera, quieta y legible.

   Sigue sin haber ni un color, ni una sombra, ni un degradado de tinta. Lo
   unico que se anade al vocabulario son filetes que se trazan, palabras que
   suben y una banda que corre.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── El telon ─────────────────────────────────────────────────────────────
   Del mismo blanco del papel: lo unico que se ve es la marca y el hilo que se
   abre bajo ella. Un telon negro sobre una pagina blanca es un fogonazo en la
   cara; uno del color de la pagina solo retrasa medio segundo la portada. */
.js-reveal .telon {
    position: fixed;
    inset: 0;
    z-index: 5000;
    display: grid;
    place-items: center;
    background: var(--paper);
    pointer-events: none;
    transform: translateY(0);
    transition: transform 0.62s var(--ease);
}

.js-reveal .telon.se-va {
    transform: translateY(-101%);
}

.telon-marca {
    position: relative;
    font-family: var(--display);
    font-size: clamp(1.5rem, 4vw, 2.4rem);
    font-weight: 800;
    letter-spacing: -0.03em;
    padding-bottom: 14px;
}

.telon-marca::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: var(--ink);
    transform: scaleX(0);
    animation: telon-hilo 0.5s var(--ease) 0.06s forwards;
}

@keyframes telon-hilo {
    to { transform: scaleX(1); }
}

/* ── Lo que ya se veia ────────────────────────────────────────────────────
   Si el navegador pinto la pagina antes de que llegara script.js, lo que hay
   en pantalla ya se ha leido entero. El script lo pone en su estado final con
   .quieto durante dos fotogramas: sin transiciones, asi que ni se apaga ni
   vuelve a entrar. */
.js-reveal .quieto,
.js-reveal .quieto * {
    transition: none !important;
}

/* ── Titulares que asoman ─────────────────────────────────────────────────
   Palabra a palabra y sin mascaras. Una mascara obliga a recortar el renglon,
   y con line-height: 1 el recorte se come las colas de la g y de la y. */
.js-reveal .asoma .pal {
    display: inline-block;
    opacity: 0.001;
    transform: translateY(0.34em);
    transition: opacity 0.5s var(--ease), transform 0.72s var(--ease);
    transition-delay: calc(var(--i, 0) * var(--paso, 42ms));
}

.js-reveal .asoma.entra .pal {
    opacity: 1;
    transform: none;
}

/* ── Los parrafos que aparecen ────────────────────────────────────────────
   Suben 14 px y se encienden, siete decimas y un pelo detras de su titular.
   Antes salian en el gris 300 -1,98:1 sobre el blanco- y se oscurecian al
   ritmo del scroll: con el dedo quieto, el texto se quedaba casi ilegible. El
   color ya no se toca: el parrafo llega con el suyo. */
.js-reveal .aparece {
    opacity: 0.001;
    transform: translateY(14px);
    transition: opacity 0.7s var(--ease) 0.12s,
                transform 0.9s var(--ease) 0.12s;
}

.js-reveal .aparece.dentro {
    opacity: 1;
    transform: none;
}

/* ── Filetes que se trazan ────────────────────────────────────────────────
   Los hilos de 1 px de la pagina NO se tocan: siguen impresos, con JavaScript
   o sin el. Lo que se anade encima es una pasada de tinta que los recorre y se
   disuelve, como quien repasa una regla a lapiz. Si el JS no llega no falta ni
   un hilo: falta la pasada. */
.js-reveal .spec > div,
.js-reveal .step,
.js-reveal .full-details {
    position: relative;
}

.js-reveal .spec > div::before,
.js-reveal .full-details::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -1px;
    height: 1px;
    background: var(--ink);
    transform: scaleX(0);
    transform-origin: left center;
    opacity: 0;
    pointer-events: none;
}

.js-reveal .spec.trazada > div::before,
.js-reveal .full-details.trazada::before {
    animation: pasada 0.95s var(--ease) both;
    animation-delay: calc(var(--i, 0) * 85ms);
}

@keyframes pasada {
    0%   { transform: scaleX(0); opacity: 1; }
    58%  { transform: scaleX(1); opacity: 1; }
    100% { transform: scaleX(1); opacity: 0; }
}

/* Sobre la ficha clara de la banda negra la pasada tiene que ser de papel */
.js-reveal .spec-light > div::before {
    background: var(--paper);
}

/* El hilo del paso ya es negro: aqui no se pinta, se DESTAPA. Un velo del
   color del papel se retira y deja la regla a la vista. */
.js-reveal .step::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -1px;
    height: 1px;
    background: var(--paper);
    transform: scaleX(1);
    transform-origin: right center;
    pointer-events: none;
}

.js-reveal .step.trazada::before {
    animation: destapa 0.9s var(--ease) both;
    animation-delay: calc(var(--i, 0) * 110ms);
}

@keyframes destapa {
    to { transform: scaleX(0); }
}

/* Lo que el navegador ya habia pintado antes de que llegara el script se
   queda trazado sin pasada: ni la regla negra del paso se vuelve a tapar para
   destaparla, ni la de la ficha se repasa delante de quien ya la estaba
   leyendo. */
.js-reveal .ya-trazada > div::before,
.js-reveal .ya-trazada::before {
    animation: none;
}

.js-reveal .step.ya-trazada::before {
    transform: scaleX(0);
}

/* ── La escena de los aparatos ────────────────────────────────────────────
   Paralaje dentro de la caja que ya ocupaba: ni se clava, ni crece, ni empuja
   nada de lo que hay debajo. Al cargar se asienta con una transicion corta,
   porque la portada ya esta a media pantalla y al efecto le toca un
   desplazamiento que no es cero. */
.js-reveal .en-vuelo.asentando .ipad,
.js-reveal .en-vuelo.asentando .iphone {
    transition: transform 0.6s var(--ease);
}

/* Los tres moviles de "Dentro" son .reveal y llevan paralaje. El transform lo
   escribe el script en cada fotograma, y la transicion de transform de .reveal
   -seis decimas- se quedaba puesta para siempre: el asentar solo quita la
   suya. La fila iba por detras del dedo y seguia moviendose al parar. Aqui la
   entrada es solo de opacidad: el desplazamiento ya lo pone el paralaje, que
   pisa el de .reveal desde el primer fotograma. */
.js-reveal .trio > figure {
    transition: opacity 0.6s var(--ease);
}

.js-reveal .trio.en-vuelo.asentando > figure {
    transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}

/* ── Cifras que ruedan ────────────────────────────────────────────────────
   El numero de verdad se queda en el DOM ocupando su ancho: solo se vuelve
   transparente mientras dura la cuenta, y Ctrl+F lo sigue encontrando. La
   rueda va encima, suelta, y a la basura.

   Cada ventanilla la coloca el script encima de SU digito, con la posicion y
   el alto medidos en el numero de verdad (--alto). Antes median 1em a ojo con
   una tira de cifras deslizandose dentro, y la caja de una cifra de la
   Bricolage mide 1,2em: en mitad del giro asomaban dos medias cifras en cada
   ventanilla. Ahora no se desliza nada, y con el alto de la propia cifra como
   interlineado el digito cae en el mismo renglon que el de verdad. Y como
   cada una va en su sitio medido, da igual que la pagina se lea de derecha a
   izquierda: antes eran un flex en fila, y en arabe pintaban los digitos al
   reves si no se forzaba el sentido. */
.cifra {
    position: relative;
    display: inline-block;
    font-variant-numeric: tabular-nums;
}

.js-reveal .cifra.rodando .cifra-real {
    opacity: 0;
}

.rueda {
    position: absolute;
    inset: 0;
    pointer-events: none;
    user-select: none;
}

.rueda-col {
    position: absolute;
    display: block;
    height: var(--alto, 1.2em);
    line-height: var(--alto, 1.2em);
    text-align: center;
    white-space: nowrap;
}

/* ── La marquesina ────────────────────────────────────────────────────────
   La unica banda de la pagina que se mueve sola. Por eso esta sola. */
/* direction: ltr en la BANDA, no solo en la cinta. Quien decide de que borde
   cuelga un hijo que desborda es el contenedor, no el hijo: con la banda en rtl
   la cinta seguia pegandose al borde derecho por mucho ltr que llevara encima,
   y como el reciclado del script trabaja en negativo, en arabe la banda se veia
   entera NEGRA Y VACIA. Es decoracion con aria-hidden: aqui no se lee nada, asi
   que forzar el sentido de la caja no le quita nada a nadie. */
.marquesina {
    direction: ltr;
    background: var(--ink);
    color: var(--paper);
    overflow: hidden;
    padding: 24px 0;
    user-select: none;
}

/* Y en la cinta tambien, para que el orden de las piezas dentro del flex sea el
   del DOM. El sentido de la marcha lo sigue eligiendo el script. */
.marquesina-cinta {
    display: flex;
    direction: ltr;
    width: max-content;
    will-change: transform;
}

.marquesina-grupo {
    display: flex;
    align-items: center;
}

.marquesina-grupo span {
    font-family: var(--display);
    font-size: clamp(1.7rem, 4.2vw, 3.2rem);
    font-weight: 800;
    letter-spacing: -0.03em;
    line-height: 1.1;
    white-space: nowrap;
    padding: 0 0.3em;
}

.marquesina-grupo span::after {
    content: "·";
    margin-left: 0.6em;
    color: var(--gray-700);
}

/* Piezas cortas -siglas de formato, dias de la semana- a este cuerpo se pegan
   unas con otras: el tracking cerrado que le sienta bien a una palabra escrita
   -0.03em- le sienta fatal a MP3 o a AIFF. Se abre a cero y se acorta la
   separacion, que con ocho piezas cortas la banda ya tiene su propio ritmo y no
   necesita tanto aire. */
.marquesina-cortas span {
    letter-spacing: 0;
}

.marquesina-cortas span::after {
    margin-left: 0.5em;
}

/* ── La rejilla de cifras, viva ────────────────────────────────────────────
   La casilla se levanta del papel: gris muy claro, el rotulo en tinta y el
   filete de abajo en negro. El hover va en CSS puro, asi que funciona sin
   JavaScript y en cualquier ventana; lo unico que pone el JS es el recorrido
   automatico, la clase .destacada. */
.figures li {
    position: relative;
    transition: background var(--fast);
}

.figures li::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: var(--ink);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.45s var(--ease);
}

.figures li:hover,
.figures li.destacada {
    background: var(--gray-100);
}

.figures li:hover::after,
.figures li.destacada::after {
    transform: scaleX(1);
}

.figures li .n {
    transition: transform 0.45s var(--ease);
}

.figures li:hover .k,
.figures li.destacada .k {
    color: var(--ink);
}

.figures li:hover .n,
.figures li.destacada .n {
    transform: translateY(-2px);
}

/* ── Indice y progreso ────────────────────────────────────────────────────
   El filete vive DENTRO de la barra, pegado a su borde inferior: no le suma ni
   un pixel de altura, que la pagina cuenta con que la barra mide exactamente
   var(--topbar). */
.progreso {
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: var(--ink);
    transform: scaleX(0);
    transform-origin: left center;
}

/* El numero de seccion en gris 500 y no en gris 300: es texto con informacion,
   no un adorno, y el gris claro sobre blanco no llega ni a 2:1 de contraste. */
/* margin-inline-start y no margin-left: el indice se anade al final de la
   etiqueta, asi que en arabe se dibuja a su izquierda y el margen fisico le
   dejaba el aire del lado que no era, pegandolo al texto. */
.indice {
    margin-inline-start: 0.9em;
    color: var(--gray-500);
    letter-spacing: 0.04em;
}

/* Sobre la banda de tinta, el gris 500 se queda en 3,9:1. Es el unico indice
   que cae ahi dentro, y es texto permanente: sube a gris 300, que sobre negro
   da 8,6:1. */
.where .indice {
    color: var(--gray-300);
}

.menu a.activo {
    color: var(--ink);
    border-bottom-color: var(--ink);
}

/* ── La barra se pasa a tinta ─────────────────────────────────────────────
   Mientras la banda negra ocupa lo alto de la pantalla, la barra se invierte
   con ella: si no, parece un recorte blanco pegado encima de la tinta. */
.topbar {
    transition: background 0.32s var(--ease), border-color 0.32s var(--ease);
}

.barra-en-tinta .topbar {
    background: var(--ink);
    border-bottom-color: var(--gray-700);
}

.barra-en-tinta .topbar .brand {
    color: var(--paper);
}

.barra-en-tinta .topbar .menu a {
    color: var(--gray-300);
}

.barra-en-tinta .topbar .menu a:hover,
.barra-en-tinta .topbar .menu a.activo {
    color: var(--paper);
    border-bottom-color: var(--paper);
}

.barra-en-tinta .topbar a:focus-visible {
    outline-color: var(--paper);
}

.barra-en-tinta .progreso {
    background: var(--paper);
}

/* ── La cruz y el iman ────────────────────────────────────────────────────
   Una cruz de registro de 1 px, del grosor de los filetes de la pagina, que se
   abre en un circulo sobre lo que se puede pulsar.

   Va en blanco con mezcla por diferencia: sobre el papel sale negra y sobre la
   banda de tinta sale blanca, sin tener que saber lo que tiene debajo. Es el
   unico sitio de la hoja donde hace falta un truco, y es justo el truco
   monocromo: la diferencia entre blanco y lo que haya. */
/* Invisible salvo encima de un enlace o un boton. La flecha del sistema no se
   toca: esto es una marca de punteria, no un cursor. */
.cruz {
    opacity: 0;
    transition: opacity 0.22s var(--ease);
    position: fixed;
    left: 0;
    top: 0;
    z-index: 4000;
    width: 0;
    height: 0;
    pointer-events: none;
    mix-blend-mode: difference;
}

.cruz i {
    position: absolute;
    background: #ffffff;
    transition: transform 0.3s var(--ease);
}

.cruz i:nth-child(1) { left: -14px; top: -0.5px; width: 9px; height: 1px; }
.cruz i:nth-child(2) { left: 5px;   top: -0.5px; width: 9px; height: 1px; }
.cruz i:nth-child(3) { left: -0.5px; top: -14px; width: 1px; height: 9px; }
.cruz i:nth-child(4) { left: -0.5px; top: 5px;   width: 1px; height: 9px; }

.cruz b {
    position: absolute;
    left: -17px;
    top: -17px;
    width: 34px;
    height: 34px;
    border: 1px solid #ffffff;
    border-radius: 50%;
    opacity: 0;
    transform: scale(0.55);
    transition: opacity 0.26s var(--ease), transform 0.32s var(--ease);
}

.cruz.abierta {
    opacity: 1;
}

.cruz.abierta b {
    opacity: 1;
    transform: scale(1);
}

.cruz.abierta i:nth-child(1) { transform: translateX(-9px); }
.cruz.abierta i:nth-child(2) { transform: translateX(9px); }
.cruz.abierta i:nth-child(3) { transform: translateY(-9px); }
.cruz.abierta i:nth-child(4) { transform: translateY(9px); }

/* ── La lista completa ────────────────────────────────────────────────────
   El indice del reverso de la caja: cada ficha con su numero en monoespaciada,
   la ficha bajo el puntero levantada del papel con su filete de tinta arriba, y
   el despliegue en cascada en vez de las dieciocho fichas de una tacada.

   Ojo con el orden: el numero se mete DENTRO del <h2>, asi que hay que devolver
   a la linea del titulo la familia y el peso que el h2 impone, o el corchete
   sale en grotesca a 1,15 rem. */
.indice-bloque {
    display: block;
    margin-bottom: 8px;
    font-family: var(--mono);
    font-size: 0.72rem;
    font-weight: 400;
    letter-spacing: 0.06em;
    color: var(--gray-500);
}

.js-reveal .feature-block {
    position: relative;
    transition: background var(--fast);
}

/* La misma pasada de tinta que la rejilla de origenes, por el borde de arriba */
.js-reveal .feature-block::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -1px;
    height: 1px;
    background: var(--ink);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.45s var(--ease);
    pointer-events: none;
}

.js-reveal .feature-block:hover {
    background: var(--gray-100);
}

.js-reveal .feature-block:hover::before {
    transform: scaleX(1);
}

/* La nota gris de dentro se levanta con la ficha: sobre el gris 100 del hover
   desaparecia, que es justo el fondo que ya tenia. */
.js-reveal .feature-block:hover .feature-note {
    background: var(--paper);
}

/* La cascada al desplegar. 'both' deja la ficha en su sitio pase lo que pase:
   el estado de partida solo vive durante el retardo. */
.js-reveal .features-list.cascada .feature-block {
    animation: asomaFicha 0.6s var(--ease) both;
    animation-delay: calc(var(--i, 0) * 34ms);
}

@keyframes asomaFicha {
    from { opacity: 0.001; transform: translateY(14px); }
}

/* El resorte: al pasar por encima, el circulo se pasa a tinta */
.full-summary:hover .full-arrow {
    background: var(--ink);
}

.full-summary:hover .full-arrow::after {
    border-color: var(--paper);
}

/* ── En arabe todo lo que corre, corre al otro lado ─────────────────────
   Sin espacio entre [dir="rtl"] y .js-reveal: las dos viven en el MISMO <html>
   -build.py escribe <html lang="ar" dir="rtl"> y script.js le anade js-reveal
   ahi mismo-, asi que el combinador descendente no tenia con que casar y estas
   reglas no seleccionaban absolutamente nada. La pasada de tinta seguia yendo
   de izquierda a derecha en la unica pagina que se lee al reves. */
[dir="rtl"].js-reveal .spec > div::before,
[dir="rtl"].js-reveal .full-details::before,
[dir="rtl"].js-reveal .feature-block::before,
[dir="rtl"] .figures li::after,
[dir="rtl"] .progreso {
    transform-origin: right center;
}

[dir="rtl"].js-reveal .step::before {
    transform-origin: left center;
}

/* ── Nada de esto sobrevive a estas tres cosas ──────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .js-reveal .telon { display: none; }
    .js-reveal .asoma .pal { opacity: 1; transform: none; transition: none; }
    .js-reveal .aparece { opacity: 1; transform: none; transition: none; }
    .js-reveal .trio > figure { transition: none; }
    .js-reveal .spec > div::before,
    .js-reveal .full-details::before,
    .js-reveal .step::before { display: none; }
    .marquesina-cinta { transform: none !important; }
    .figures li,
    .figures li::after,
    .figures li .n { transition: none; }
    .topbar { transition: none; }
}

@media print {
    .telon,
    .marquesina,
    .cruz,
    .progreso,
    .indice { display: none !important; }

    .js-reveal .reveal { opacity: 1 !important; transform: none !important; }
    .js-reveal .asoma .pal { opacity: 1 !important; transform: none !important; }
    .js-reveal .aparece { opacity: 1 !important; transform: none !important; }
    .js-reveal .spec > div::before,
    .js-reveal .full-details::before,
    .js-reveal .feature-block::before,
    .js-reveal .step::before { display: none !important; }
    .js-reveal .features-list.cascada .feature-block { animation: none !important; opacity: 1 !important; transform: none !important; }
    .js-reveal .duo .ipad,
    .js-reveal .duo .iphone,
    .js-reveal .solo .ipad,
    .js-reveal .trio > figure { transform: none !important; }
}
