/* ibm-plex-sans-cyrillic-ext-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-sans-cyrillic-ext-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-cyrillic-ext-400-normal.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-sans-cyrillic-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-cyrillic-400-normal.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-sans-greek-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-greek-400-normal.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-sans-vietnamese-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-vietnamese-400-normal.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-ext-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-sans-latin-ext-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-latin-ext-400-normal.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-sans-latin-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-latin-400-normal.woff) format('woff');
  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;
}
/* ibm-plex-sans-cyrillic-ext-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-sans-cyrillic-ext-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-cyrillic-ext-500-normal.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-sans-cyrillic-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-cyrillic-500-normal.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-sans-greek-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-greek-500-normal.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-sans-vietnamese-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-vietnamese-500-normal.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-ext-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-sans-latin-ext-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-latin-ext-500-normal.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-sans-latin-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-latin-500-normal.woff) format('woff');
  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;
}
/* ibm-plex-sans-cyrillic-ext-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/blog/fonts/ibm-plex-sans-cyrillic-ext-600-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-cyrillic-ext-600-normal.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/blog/fonts/ibm-plex-sans-cyrillic-600-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-cyrillic-600-normal.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/blog/fonts/ibm-plex-sans-greek-600-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-greek-600-normal.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/blog/fonts/ibm-plex-sans-vietnamese-600-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-vietnamese-600-normal.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-ext-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/blog/fonts/ibm-plex-sans-latin-ext-600-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-latin-ext-600-normal.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/blog/fonts/ibm-plex-sans-latin-600-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-sans-latin-600-normal.woff) format('woff');
  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;
}
/* ibm-plex-mono-cyrillic-ext-400-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-mono-cyrillic-ext-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-mono-cyrillic-ext-400-normal.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-mono-cyrillic-400-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-mono-cyrillic-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-mono-cyrillic-400-normal.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-mono-vietnamese-400-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-mono-vietnamese-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-mono-vietnamese-400-normal.woff) format('woff');
  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;
}

/* ibm-plex-mono-latin-ext-400-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-mono-latin-ext-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-mono-latin-ext-400-normal.woff) format('woff');
  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;
}

/* ibm-plex-mono-latin-400-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/ibm-plex-mono-latin-400-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-mono-latin-400-normal.woff) format('woff');
  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;
}
/* ibm-plex-mono-cyrillic-ext-500-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-mono-cyrillic-ext-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-mono-cyrillic-ext-500-normal.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-mono-cyrillic-500-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-mono-cyrillic-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-mono-cyrillic-500-normal.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-mono-vietnamese-500-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-mono-vietnamese-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-mono-vietnamese-500-normal.woff) format('woff');
  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;
}

/* ibm-plex-mono-latin-ext-500-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-mono-latin-ext-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-mono-latin-ext-500-normal.woff) format('woff');
  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;
}

/* ibm-plex-mono-latin-500-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/blog/fonts/ibm-plex-mono-latin-500-normal.woff2) format('woff2'), url(/blog/fonts/ibm-plex-mono-latin-500-normal.woff) format('woff');
  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;
}
/* instrument-serif-latin-ext-400-normal */
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/instrument-serif-latin-ext-400-normal.woff2) format('woff2'), url(/blog/fonts/instrument-serif-latin-ext-400-normal.woff) format('woff');
  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;
}

/* instrument-serif-latin-400-normal */
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/instrument-serif-latin-400-normal.woff2) format('woff2'), url(/blog/fonts/instrument-serif-latin-400-normal.woff) format('woff');
  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;
}
/* instrument-serif-latin-ext-400-italic */
@font-face {
  font-family: 'Instrument Serif';
  font-style: italic;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/instrument-serif-latin-ext-400-italic.woff2) format('woff2'), url(/blog/fonts/instrument-serif-latin-ext-400-italic.woff) format('woff');
  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;
}

/* instrument-serif-latin-400-italic */
@font-face {
  font-family: 'Instrument Serif';
  font-style: italic;
  font-display: swap;
  font-weight: 400;
  src: url(/blog/fonts/instrument-serif-latin-400-italic.woff2) format('woff2'), url(/blog/fonts/instrument-serif-latin-400-italic.woff) format('woff');
  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;
}
/* ============================================================================
 * MintStash Design Tokens
 * ----------------------------------------------------------------------------
 * Source of truth for all visual primitives. Every color, size, and space
 * in the app and landing reads from here.
 *
 * Naming convention: semantic, not descriptive.
 *   Good:  --color-text-primary, --space-4, --text-lg
 *   Bad:   --color-white, --space-16px, --text-22px
 *
 * When a value changes here, it changes everywhere. When a name is wrong,
 * it lies forever.
 * ========================================================================= */

:root {
  /* ==========================================================================
   * COLORS
   * ========================================================================= */

  /* Backgrounds — three levels of elevation for hierarchy, with optional subtle borders for surface definition */
  --color-bg-base:        #0a0a0b;  /* page background, deepest level */
  --color-bg-surface:     #101012;  /* sections, large containers */
  --color-bg-elevated:    #16161a;  /* cards, modals, elevated panels */
  --color-bg-hover:       #1c1c20;  /* surface lift on hover (one notch above elevated) */
  --color-bg-deep:        #07070a;  /* landing hero/cinema black, deeper than base */

  /* Accent — teal refined from Mantine's default, for a more editorial tone.
   * Two of them, and the split is not decorative: on --color-bg-base the fill
   * teal lands at ~4.6:1, fine behind a button, borderline as text. The text
   * teal is ~5.8:1. Never use --color-accent for text on dark. */
  --color-accent:         #0d9488;  /* fills, buttons, active states */
  --color-accent-hover:   #0f766e;  /* hover state for accent fills */
  --color-accent-text:    #14b8a6;  /* accent on dark bg: links, emphasis text */

  /* State — going up / going down (curation language, not finance) */
  --color-up:             #14b8a6;  /* teal: a change in your favour. Ver Num.css */
  --color-down:           #ef4444;  /* negative value changes */

  /* Radar — data-viz action ramp for the price-movement radar. Bespoke to that
   * surface, so it does NOT reuse --color-up/down.
   *
   * The ramp is named by ROLE, not by action, and that is the whole point: the
   * radar always points at whatever the viewer asked it to look for, so its
   * innermost band is the opportunity whichever direction it is pointing.
   * `Comprar` while it looks at the drops and `Vender` while it looks at the
   * rises are the same role, so they are the same colour. Nothing in this ramp is
   * adverse, which is why no red lives here; `--color-danger` below owns #be123c.
   *
   * Renamed from --color-radar-buy / --color-radar-sell on 2026-09-09. The old
   * pair had the plot painting band 0 teal by index (RadarPlot ACTION) while its
   * own legend chip and its percentage painted the same band red — teal dot,
   * red number, same card, same view. Third instance of the defect rule 07 was
   * written against. */
  --color-radar-opportunity: #14b8a6;  /* the band the radar is pointing at */
  --color-radar-watch:    #d9a521;  /* Vigilar — worth a look */
  --color-radar-hold:     #8b8b93;  /* Mantener — no action */
  --color-radar-flat:     #52525b;  /* Plano — barely moving (hollow) */
  --color-radar-track:    #0d948866;  /* usage-bar fill: accent at 40% */

  /* Text — inverse hierarchy (brighter = more important) */
  --color-text-primary:   #fafafa;  /* titles, destacated values, key numbers */
  --color-text-default:   #e4e4e7;  /* body text, standard reading */
  --color-text-muted:     #a1a1aa;  /* metadata, captions, secondary info */
  /* Subió de #71717a a #84848c el 2026-08-31, y el criterio es la mitad que
   * importa: **el suelo de un tono de texto lo pone la superficie MÁS CLARA
   * donde puede aparecer**, no la habitual. El viejo daba 4,09 sobre el lienzo,
   * 3,93 sobre `bg-surface` y 3,52 sobre la banda editorial: fallaba AA en los
   * tres, y fallaba peor justo donde el texto es más pequeño. Un tono que pasa
   * en su contexto habitual y falla en el peor no está medio bien.
   * Ahora: 5,30 · 5,09 · 4,56. */
  --color-text-subtle:    #84848c;  /* small labels, eyebrows */
  /* NO sube, y la excepción tiene motivo: un control apagado está exento de AA
   * porque no es contenido. Solo tiene que ser identificable, y a 2,5 sobre el
   * lienzo lo es. Lo que hay que vigilar no es su contraste sino DÓNDE se usa:
   * si aparece en algo que no es un control apagado ni un placeholder, el que
   * está mal es ese uso, no el token. */
  --color-text-disabled:  #52525b;  /* placeholders, disabled states only */

  /* Borders — minimal, functional */
  --color-border-subtle:  #27272a;  /* internal dividers, row separators */
  --color-border-defined: #2d2d33;  /* landing chips, pills (mid tier) */
  --color-border-default: #3f3f46;  /* card outlines, input borders (also landing "loud") */

  /* Washes — translucent white, ONLY when something must show through.
   * On an opaque surface the answer is a background, not a wash:
   *   hover on a row or button  → --color-bg-hover
   *   selected / open           → --color-bg-elevated
   *   1px line                  → --color-border-subtle
   * Reach for a wash only over content: the scrolled header, a layer on top
   * of an image, a translucent panel. */
  --color-wash-hover:   rgba(255,255,255,0.04);  /* pointer over a translucent surface */
  --color-wash-active:  rgba(255,255,255,0.08);  /* pressed / selected, translucent surface */
  --color-wash-line:    rgba(255,255,255,0.15);  /* 1px over a translucent surface */
  --color-scrim:        rgba(10,10,11,0.72);     /* veil under a modal — darkens, never lightens */


  /* ==========================================================================
   * TYPOGRAPHY
   * ========================================================================= */

  /* Font families — each has one job.
   *   sans   body text, app and landing alike
   *   mono   every number (price, quantity, percentage, date) and every
   *          eyebrow. In tables it is what keeps columns aligned.
   *   serif  landing hero and its final CTA, and nowhere else. It is the one
   *          editorial moment before the rest goes systematic. Using it inside
   *          the app is a conscious override, never a default. */
  --font-sans:   'IBM Plex Sans', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono:   'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-serif:  'Instrument Serif', Georgia, Cambria, serif;

  /* Sizes — modular scale ~1.2, rounded to even numbers. Product views live in
   * the lower half (2xs–2xl); 3xl and up is landing territory. */
  --text-2xs:   11px;  /* uppercase eyebrows ONLY, and always with --tracking-wide */
  --text-xs:    12px;  /* labels, table captions */
  --text-sm:    14px;  /* secondary body, small captions */
  --text-base:  16px;  /* body default */
  --text-lg:    18px;  /* lead paragraphs, emphasized body */
  --text-xl:    22px;  /* h4, subheaders */
  --text-2xl:   26px;  /* h3 */
  --text-3xl:   32px;  /* h2 */
  --text-4xl:   44px;  /* h1 on internal pages, and the top of the fixed scale */

  /* `--text-5xl: 64px` was deleted on 2026-08-31 (CD, engagement 9). It had gone
   * months with zero consumers, and its note here said "pending review in design
   * engagement 2" — which is a token waiting for a reason to exist rather than
   * the other way round. Between --text-4xl and the fluid display below there is
   * no gap a fixed 64 could fill. Same case as --text-7xl in engagement 1. */

  /* ── Fluid: the editorial layer ──
   * These three are the ONLY typographic values a product surface does not have,
   * and what makes them editorial is not their size — it is their ELASTICITY. A
   * landing is read full-screen at any width; a price table reads the same at
   * 1280 and at 2560, so it wants none of this.
   *
   * `--text-display` predates the others and keeps its name: it is used by the
   * hero and there is no second one. The two `--edit-*` carry the prefix because
   * they exist only for that medium, and the check refuses them outside a
   * [data-editorial] surface. Everything else the landing needs comes from the
   * product scale above — which is the whole answer to engagement 9: the
   * editorial layer is a SCOPE, not a vocabulary. */
  --text-display:     clamp(44px, 8vw, 88px);  /* the hero, and only the hero */
  --edit-display-sm:  clamp(32px, 5vw, 56px);  /* the closing headline, /try's title */
  --edit-lede:        clamp(18px, 2vw, 22px);  /* the paragraph under either of those */

  /* ── The one editorial surface, and why there is exactly one ──
   * Rule 34 lets an editorial page use background as composition. It was painted
   * with `--color-bg-surface`, and measured on 2026-08-31 that came to **1.04:1**
   * against the canvas: it read as two hairlines, not a surface, so the 669px to
   * its right stayed empty instead of becoming the margin of something. The
   * mechanism was installed and its only effect was missing.
   *
   * The obvious repair was a three-level ramp — canvas, band, card — since the
   * card inside the band was the same colour as the band (contrast 1.000). It
   * cannot be built, and the ceiling is not a matter of taste:
   *
   *   fondo      rojo de bajada    banda vs lienzo
   *   #1a1a1d    4.61  AA ✓        1.14  invisible
   *   #1c1c1f    4.52  AA ✓        1.16  ✓  ← el unico
   *   #1d1d20    4.47  AA ✗        1.18
   *   #2a2a2e    3.80  AA ✗        1.38
   *
   * `--color-down` on the alert card is the number that whole block exists to
   * show, and it leaves the dark end room for **one** step, not two. So the band
   * rises to the ceiling and the card shares its colour, marked by its border —
   * an outlined card, the same thing the purpose cards do on the canvas.
   *
   * It carries `--edit-*` because product has no use for a composed surface, and
   * the check refuses it outside a [data-editorial] page. */
  --edit-bg-band: #1c1c1f;

  /* Weights — three only */
  --font-weight-regular:   400;
  --font-weight-medium:    500;
  --font-weight-semibold:  600;

  /* Line heights — larger text wants tighter leading. A 44px title at 1.5 reads
   * airy and fractured; a 14px caption at 1.2 reads cramped. */
  --leading-tight:    1.2;   /* titles text-3xl and up */
  --leading-normal:   1.5;   /* body text-base, text-sm */
  --leading-relaxed:  1.7;   /* small dense text, text-xs captions */

  /* Tracking is not chosen, it follows the size step (UI rule 14):
   *   display, 4xl, 3xl, 2xl  → tight
   *   xl, lg                  → snug
   *   base and below          → 0, no token
   *   2xs uppercase mono      → wide
   * Nothing tighter than tight: at 15px IBM Plex Sans closes "rn" into "m". */
  --tracking-tight:  -0.02em;
  --tracking-snug:   -0.01em;
  --tracking-wide:    0.05em;


  /* ==========================================================================
   * SPACING — base 4, non-linear scale
   * --------------------------------------------------------------------------
   * The steps are uneven because perception is uneven: 4 → 8 is a real change,
   * 20 → 22 is invisible. Few discrete options force consistent decisions.
   *
   * Which step, by relationship:
   *   inside an element (button, input, card)   1–4
   *   icon + text, label + input                1–2
   *   rows of the same list or table            2–3
   *   between info groups in a section          4–6
   *   between sections                          8–12
   *   page edge to content                      8 on mobile, 12–16 on desktop
   *   landing top-level sections                16, and 24–32 for its rhythm
   * ========================================================================= */

  /* Half steps, and only at the small end. Added 2026-08-12, and the code asked
   * for them rather than a designer: with the check finally seeing every value,
   * the four most repeated raw spacings in the whole app were 2, 6, 10 and 14 —
   * exactly the midpoints of 4/8, 8/12 and 12/16 — with 70 uses between them and
   * a majority in product surfaces, not on the landing.
   *
   * That refines the note above instead of contradicting it. "20 → 22 is
   * invisible" still holds; what does not is that 4 → 8 is the smallest useful
   * change, because at these sizes 2px is a whole step in a dense table row.
   * A scale bypassed 70 times is missing rungs, not being disobeyed.
   *
   * They stop at 14: above 16 nobody invented a midpoint, so there is no
   * evidence for --space-5 and it would only widen the menu. */
  --space-0-5: 2px;   /* hairline gap: pip to letter, dense table row */
  --space-1:   4px;   /* micro: icon+text gap, badge padding */
  --space-1-5: 6px;   /* between micro and tight: chip padding, tight columns */
  --space-2:   8px;   /* tight: small input padding, related items */
  --space-2-5: 10px;  /* between tight and small: editorial inline rhythm */
  --space-3:   12px;  /* small: button padding, table row gap */
  --space-3-5: 14px;  /* between small and default: bulk-edit controls */
  --space-4:   16px;  /* default: card padding, element gap */
  --space-6:   24px;  /* medium: info group separation */
  --space-8:   32px;  /* large: generous padding, small section gap */
  --space-12:  48px;  /* xlarge: large section separation */
  --space-16:  64px;  /* hero: top-level section separation */
  --space-24:  96px;  /* landing: section rhythm (base-4 step 9) */
  --space-32: 128px;  /* landing: max section separation (base-4 step 10) */

  /* Ancho de la columna de contenido. Lo comparten el armazon de pagina y los
   * modales que necesitan el mismo espacio que la pagina. Estaba escrito a mano
   * en cinco sitios el 2026-08-27; ver TD-206. */
  --page-max-width: 1200px;

  /* Margen lateral de cualquier superficie que llegue al borde de la ventana.
   * Es un token y no dos valores sueltos porque la cabecera y el contenido de
   * la portada TIENEN que coincidir: cuando no coincidian, la cabecera cortaba
   * en 768px y el contenido en 900, y entre esas dos anchuras la pagina salia
   * desalineada 16px sin que nada lo dijera. El punto de corte vive aqui una
   * sola vez para que no vuelva a haber dos. */
  --page-inset: var(--space-4);

  /* Lo que hay que descontar para salirse de la columna de lectura. Solo lo usa
   * lo que no es texto —un grafico circular, cuyo tamano ES su legibilidad—, y
   * vive aqui en vez de escribirse en cada sitio porque el `-1` suelto de un
   * `calc` cuenta como un valor de espaciado nuevo en una familia cerrada. */
  --page-bleed: calc(-1 * var(--page-inset));


  /* Minimum touch target on coarse pointers (WCAG 2.5.5) */
  --tap-target-min: 44px;

  /* El alto de un boton de la interfaz: lo que mide un Button de Mantine en el
   * tamano que usa este producto. Vive aqui porque no solo lo pintan botones —un
   * segmentado en una fila de mandos tiene que medir lo mismo que el boton de al
   * lado, y sin token esa igualdad se escribe como un numero suelto que nadie
   * relaciona con su origen. */
  --control-height: 36px;


  /* ==========================================================================
   * RADII — minimal set
   * ========================================================================= */

  --radius-sm:  4px;   /* inputs, badges */
  --radius-md:  8px;   /* cards, panels, modals */
  --radius-lg:  12px;  /* larger containers, hero elements */
  /* The step the scale was missing at the top, added 2026-08-12. It was already
   * in use in two places, and — more to the point — `theme.radius.lg` has been
   * 16px all along, so `radius="lg"` and var(--radius-lg) rendered two different
   * corners under one name. This is where that 16 belongs. See TD-152. */
  --radius-xl:  16px;  /* lightbox art, large editorial cards */
  /* A true circle, for dots and avatars. Not the banned 999px pill: that one
   * rounds a rectangle, this one is a circle and the shape is the point. */
  --radius-round: 50%;


  /* Status — three roles, and deliberately ZERO new tones: each borrows a hex
   * the palette already had. In MintStash a price going DOWN is good news, so
   * status cannot share a treatment with movement. The separation is by FORM,
   * not by tone, which is why the hex may coincide without colliding:
   *   movement → bare text or fill, never a surface
   *   status   → tinted surface + border + icon, never coloured text alone
   * The literal is repeated rather than aliased on purpose: if the radar's
   * amber ever moves, "attention" should not follow it by accident. */
  --color-warn:            #d9a521;  /* same hex as radar-watch: watching and attention are one gesture */
  --color-warn-surface:    #d9a5211f;
  --color-warn-line:       #d9a52147;
  --color-danger:          #be123c;  /* darker than --color-down, less alarmist. Sole owner of this hex since the radar ramp gave it up */
  --color-danger-surface:  #be123c1f;
  --color-danger-line:     #be123c47;
  --color-success:         #0d9488;  /* teal, la misma familia que --color-up */
  --color-success-surface: #0d94881f;
  --color-success-line:    #0d948847;

  /* Series — categorical, not ordinal. The radar bands rank (buy beats watch);
   * one series is not better than another. Neither red nor green appears here:
   * both mean something else on every screen of this product. Six is the cap
   * (UI rule 16) — with twelve categories you use five and an "other". */
  --color-series-1: #14b8a6;
  --color-series-2: #818cf8;
  --color-series-3: #d9a521;
  --color-series-4: #d946a6;
  --color-series-5: #38bdf8;
  --color-series-6: #a8a29e;


  /* ==========================================================================
   * ELEVATION — on a dark UI, depth comes from background and border first.
   * Shadow is reserved for what genuinely floats: it must sit above scrolling
   * content AND be dismissible. Two levels are enough.
   * ========================================================================= */

  --shadow-pop:   0 4px 16px rgba(0,0,0,0.45);   /* menus, popovers, tooltips */
  --shadow-modal: 0 16px 48px rgba(0,0,0,0.60);  /* modals, drawers */

  --blur-chrome: 16px;  /* fixed header once it materialises — a brand signature */
  --blur-veil:    8px;  /* content behind a scrim or in a disabled state */


  /* ==========================================================================
   * LAYERS — only what needs coordinating across the whole app. Local stacking
   * (1–10, a badge over an image) is NOT a token: making it one invites
   * bumping the number "just in case".
   * ========================================================================= */

  --z-sticky:   100;
  --z-dropdown: 200;
  --z-scrim:    300;
  --z-modal:    400;
  --z-toast:    500;


  /* ==========================================================================
   * MOTION — named for what moves, not for how long it takes
   * ========================================================================= */

  --motion-tint:   120ms;  /* colour only */
  --motion-move:   200ms;  /* something small appears or shifts */
  --motion-settle: 300ms;  /* a large surface changes state */
  --motion-ease:   cubic-bezier(0.2, 0.7, 0.3, 1);
  /* A loop is not a transition: it goes nowhere, so its pace is set by calm
   * rather than by perception. Skeletons, the radar sweep. */
  --motion-ambient: 1600ms;

  /* No hay escalón de ENTRADA, y la razón es que no hay entradas. El 2026-08-12 se
   * añadieron `--motion-reveal` y `--motion-stagger` para el sistema de revelado
   * al hacer scroll, y al buscar sus consumidores para verificarlo en pantalla
   * resultó que el sistema entero estaba muerto: ni una clase aplicada, y su hook
   * `useInView` tampoco se usaba. Los dos tokens se retiraron el mismo día.
   *
   * Queda escrito porque es el error de `--text-7xl` otra vez: un token que
   * describe algo que nadie pinta sobrevive semanas pareciendo una decisión. Si
   * algún día vuelve a haber entradas, este es el hueco donde va su token. */

  /* DEPRECATED — migrating; use --motion-tint when only colour changes. */
  --transition-base: 150ms ease;


  /* ==========================================================================
   * FOCUS — declared now, applied at the library boundary
   * --------------------------------------------------------------------------
   * Not yet applied globally, on purpose. Mantine draws its own 2px outline
   * with more specificity than a zero-specificity global rule can beat, so
   * applying this today gives two rings. And silencing Mantine's would leave
   * Checkbox, Switch and SegmentedControl with none, because they draw theirs
   * on a sibling label rather than on the focused input. One ring needs the
   * boundary first.
   * ========================================================================= */

  --focus-ring: 0 0 0 2px var(--color-bg-base), 0 0 0 4px var(--color-accent-text);


  /* ==========================================================================
   * DENSITY — row heights for the data surfaces
   * ========================================================================= */

  /* Airy is the tap target on purpose: a comfortable row is a tappable row. */
  --row-height-airy:  var(--tap-target-min);
  --row-height-dense: 32px;
}


/* El unico punto de corte del margen lateral, y por eso vive con el token y no
 * en cada hoja que lo consume. 48em es el mismo `sm` de Mantine que usa
 * PageShell, asi que las tres superficies respiran a la vez. */
@media (min-width: 48em) {
  :root {
    --page-inset: var(--space-8);
  }
}


/* Someone who asked the OS for less movement gets less movement, everywhere. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-tint:     1ms;
    --motion-move:     1ms;
    --motion-settle:   1ms;
    --transition-base: 1ms ease;
  }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* Status is an anatomy, not a colour. Publishing the class next to the tokens is
 * what makes UI rule 15 enforceable: without it somebody paints red text and
 * believes they used the token. */
.state-surface {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  border: 1px solid;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  color: var(--color-text-default);
}

.state-surface[data-state='warn'] { background: var(--color-warn-surface); border-color: var(--color-warn-line); }
.state-surface[data-state='danger'] { background: var(--color-danger-surface); border-color: var(--color-danger-line); }
.state-surface[data-state='success'] { background: var(--color-success-surface); border-color: var(--color-success-line); }

.state-surface > .icon { flex-shrink: 0; }
.state-surface[data-state='warn'] > .icon { color: var(--color-warn); }
.state-surface[data-state='danger'] > .icon { color: var(--color-danger); }
.state-surface[data-state='success'] > .icon { color: var(--color-success); }

/* La capa de blog. Se sirve CONCATENADA detrás de `src/ui/styles/tokens.css`,
 * nunca sola: aquí no se declara ni un color ni un tamaño de letra propio, solo
 * se consumen los de la marca. Esa es la razón de que se junten al generar en
 * vez de copiarse — un valor de diseño tiene un solo emisor (regla 36).
 *
 * Y es CSS a mano y no el CSS de la app a propósito: un artículo no tiene
 * estado, ni controles, ni tabla. Traerse el paquete entero de la aplicación
 * para pintar texto retrasa el pintado, y la velocidad de pintado cuenta para
 * lo único que este blog viene a hacer. */

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

body {
  margin: 0;
  background: var(--color-bg-base);
  color: var(--color-text-default);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
}

.blog-shell {
  max-width: 44rem;
  margin: 0 auto;
  padding: var(--space-8) var(--space-4) var(--space-16);
}

@media (min-width: 48rem) {
  .blog-shell {
    padding: var(--space-16) var(--space-8) var(--space-24);
  }
}

.blog-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-16);
}

.blog-wordmark {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: var(--font-weight-regular);
  font-size: var(--text-2xl);
  color: var(--color-accent-text);
  text-decoration: none;
}

.blog-volver {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  text-decoration: none;
}

.blog-volver:hover {
  color: var(--color-text-default);
}

.blog-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-subtle);
  margin: 0 0 var(--space-3);
}

.blog-articulo h1 {
  font-family: var(--font-serif);
  font-weight: var(--font-weight-regular);
  font-size: var(--edit-display-sm);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text-primary);
  margin: 0 0 var(--space-4);
}

.blog-fecha {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
  margin-bottom: var(--space-12);
}

/* UN SOLO emisor del aire entre párrafos, y el orden de estas dos reglas es la
 * regla: primero se pone todo a cero, después se separa. La versión anterior lo
 * hacía al revés —el `* + *` arriba y un `margin: 0` dentro de `.blog-cuerpo p`
 * abajo— y la segunda ganaba por las dos vías, por más específica y por ir
 * después, así que anulaba exactamente lo que la primera venía a hacer.
 *
 * Doce párrafos pegados, siete pares seguidos a 0px medidos en el preview. Los
 * `h2` se salvaban por llevar su propio margen y las listas por tener su propia
 * regla, y por eso desde fuera parecía una decisión y no un fallo.
 *
 * De aquí en adelante: nada dentro de `.blog-cuerpo` declara márgenes verticales
 * propios salvo lo que quiera separarse MÁS, y eso se escribe debajo. */
.blog-cuerpo > * {
  margin: 0;
}

.blog-cuerpo > * + * {
  margin-top: var(--space-6);
}

.blog-cuerpo p {
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.blog-cuerpo h2 {
  font-family: var(--font-serif);
  font-weight: var(--font-weight-regular);
  font-size: var(--text-2xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text-primary);
  margin: var(--space-12) 0 0;
}

.blog-cuerpo h3 {
  font-size: var(--text-xl);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  margin: var(--space-8) 0 0;
}

.blog-cuerpo a {
  color: var(--color-accent-text);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.blog-cuerpo strong {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}

.blog-cuerpo ul,
.blog-cuerpo ol {
  margin: 0;
  padding-left: var(--space-6);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.blog-cuerpo li + li {
  margin-top: var(--space-2);
}

.blog-cuerpo blockquote {
  margin: 0;
  padding-left: var(--space-4);
  border-left: 2px solid var(--color-accent);
  color: var(--color-text-muted);
}

.blog-estantes {
  margin-top: var(--space-16);
}

.blog-grupo + .blog-grupo {
  margin-top: var(--space-16);
}

.blog-grupo-cabecera {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border-subtle);
  margin-bottom: var(--space-6);
}

/* El nombre del estante en mono y en caja alta, no en serif: la serif de la
   portada del blog es su titular, y dos serifs del mismo tamaño compitiendo
   dejarían de leerse como título y subtítulo. Esto es una etiqueta. */
.blog-grupo-titulo {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--font-weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-subtle);
}

.blog-grupo-cuenta {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--color-text-subtle);
  font-variant-numeric: tabular-nums;
}

.blog-tema {
  margin: 0 0 var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-accent-text);
}

.blog-indice {
  list-style: none;
  margin: 0;
  padding: 0;
}

.blog-indice li + li {
  margin-top: var(--space-8);
  padding-top: var(--space-8);
  border-top: 1px solid var(--color-border-subtle);
}

.blog-entrada-titulo {
  display: inline-block;
  font-family: var(--font-serif);
  font-weight: var(--font-weight-regular);
  font-size: var(--text-2xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text-primary);
  text-decoration: none;
  margin-bottom: var(--space-2);
}

.blog-entrada-titulo:hover {
  color: var(--color-accent-text);
}

.blog-entrada-descripcion {
  margin: 0;
  color: var(--color-text-muted);
  line-height: var(--leading-normal);
}

.blog-pie {
  margin-top: var(--space-24);
  padding-top: var(--space-8);
  border-top: 1px solid var(--color-border-subtle);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.blog-pie a {
  color: var(--color-accent-text);
  text-decoration: none;
}

/* ── La página de un artículo ────────────────────────────────────────────── */

.blog-meta {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
  font-variant-numeric: tabular-nums;
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--color-border-subtle);
  margin-bottom: var(--space-12);
}

.blog-meta-sep {
  width: 3px;
  height: 3px;
  border-radius: var(--radius-round);
  background: var(--color-border-default);
}

.blog-cierre {
  margin-top: var(--space-24);
  padding-top: var(--space-8);
  border-top: 1px solid var(--color-border-subtle);
}

/* La ficha NO lleva cifra, y la ausencia es la decisión: un porcentaje escrito a
   mano en la cabecera del artículo se queda viejo al día siguiente y nadie se
   entera. El número vive en la lista, que lo calcula cada vez. Aquí se enlaza. */
.blog-ficha {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-top: var(--space-4);
  padding: var(--space-5);
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-md);
  text-decoration: none;
}

.blog-ficha:hover {
  background: var(--color-bg-hover);
  border-color: var(--color-border-default);
}

.blog-ficha-que {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}

.blog-ficha-ir {
  font-size: var(--text-sm);
  color: var(--color-accent-text);
}

.blog-siguiente {
  margin-top: var(--space-12);
}

.blog-siguiente-titulo {
  display: inline-block;
  margin-top: var(--space-2);
  font-family: var(--font-serif);
  font-weight: var(--font-weight-regular);
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text-primary);
  text-decoration: none;
}

.blog-siguiente-titulo:hover {
  color: var(--color-accent-text);
}
