/* tokens.css — Design tokens of «A · Tinción» (histology slide: cold paper, haematoxylin/eosin pigments).
   THE ONLY FILE ALLOWED TO CONTAIN COLOUR VALUES. Components use var(--…) exclusively.
   Gates (scripts/gates/): no colour literal outside this file · every var() used is declared here ·
   the text/background pairs annotated below meet WCAG AA (text 4.5:1, UI 3:1).
   One configuration only (light): Tinción has no dark theme yet — adding one means a second block here
   and a second column in the contrast gate.

   @contrast text: --color-text-primary on --color-bg, --color-surface, --color-surface-sunken, --color-tldr-bg, --color-foryou-bg, --status-ok-bg, --status-warn-bg, --status-danger-bg, --status-info-bg
   @contrast text: --color-text-secondary on --color-bg, --color-surface, --color-surface-sunken, --color-tldr-bg, --color-foryou-bg, --status-ok-bg, --status-warn-bg, --status-danger-bg, --status-info-bg
   @contrast text: --color-link on --color-bg, --color-surface, --color-tldr-bg, --status-ok-bg, --status-warn-bg, --status-info-bg
   @contrast text: --color-on-primary on --color-primary, --color-primary-strong
   @contrast text: --color-text-inverse on --color-text-primary
   @contrast text: --color-tldr-title on --color-tldr-bg
   @contrast text: --pc-cancer on --color-bg, --color-surface
   @contrast text: --pc-alzheimer on --color-bg, --color-surface
   @contrast text: --pc-neurologia on --color-bg, --color-surface
   @contrast text: --pc-ia-medicina on --color-bg, --color-surface
   @contrast text: --pc-medicina-regenerativa on --color-bg, --color-surface
   @contrast text: --pc-longevidad on --color-bg, --color-surface
   @contrast text: --pc-diabetes on --color-bg, --color-surface
   @contrast text: --pc-cardiovascular on --color-bg, --color-surface
   @contrast text: --pc-infecciosas on --color-bg, --color-surface
   @contrast text: --pc-medicina-personalizada on --color-bg, --color-surface
   @contrast ui: --color-control-border on --color-bg, --color-surface
   @contrast ui: --color-focus on --color-bg, --color-surface
   @contrast ui: --color-primary on --color-bg, --color-surface
   @contrast ui: --status-ok on --status-ok-bg
   @contrast ui: --status-warn on --status-warn-bg
   @contrast ui: --status-danger on --status-danger-bg
   @contrast ui: --status-info on --status-info-bg
   @contrast ui: --map-tag on --map-bg
   @contrast ui: --map-link on --map-bg
   @contrast text: --map-text on --map-bg
*/
:root {
  /* Surfaces and text */
  --color-bg: #F4F5F2;
  --color-surface: #FFFFFF;
  --color-surface-sunken: #E8EBE6;
  --color-text-primary: #221A33;
  --color-text-secondary: #5A546B;
  --color-text-inverse: var(--color-bg);
  --color-border: #D8DAD3;          /* decorative separators and card outlines (not a control boundary) */
  --color-border-strong: #AEADB8;
  --color-control-border: #8D8A99;  /* boundary of inputs and chips: ≥ 3:1 (audit 30/64) */

  /* Brand and intent */
  --color-primary: #5B3F95;         /* haematoxylin */
  --color-primary-strong: #4A2F85;
  --color-on-primary: #FFFFFF;
  --color-link: #4A2F85;
  --color-focus: #D9467A;           /* eosin */
  --color-tldr-bg: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface));
  --color-tldr-border: color-mix(in srgb, var(--color-primary) 24%, var(--color-surface));
  --color-tldr-title: var(--color-link);
  --color-foryou-bg: color-mix(in srgb, var(--color-focus) 4%, var(--color-surface));
  --color-header-bg: var(--color-bg);

  /* Status trios, derived from the active surface (never hand-written tints) */
  --status-ok: #2E7D5B;
  --status-warn: #8A5A00;
  --status-danger: #B42343;
  --status-info: #1F5FA6;
  --status-ok-bg: color-mix(in srgb, var(--status-ok) 10%, var(--color-surface));
  --status-warn-bg: color-mix(in srgb, var(--status-warn) 10%, var(--color-surface));
  --status-danger-bg: color-mix(in srgb, var(--status-danger) 10%, var(--color-surface));
  --status-info-bg: color-mix(in srgb, var(--status-info) 10%, var(--color-surface));
  --status-ok-border: color-mix(in srgb, var(--status-ok) 45%, var(--color-surface));
  --status-warn-border: color-mix(in srgb, var(--status-warn) 45%, var(--color-surface));
  --status-danger-border: color-mix(in srgb, var(--status-danger) 45%, var(--color-surface));
  --status-info-border: color-mix(in srgb, var(--status-info) 45%, var(--color-surface));

  /* Pillar pigments (categorical palette; each ≥ 4.5:1 as text on bg and surface) */
  --pc-cancer: #B8305F;
  --pc-alzheimer: #5B3F95;
  --pc-neurologia: #1F5FA6;
  --pc-ia-medicina: #1D6F6D;
  --pc-medicina-regenerativa: #3A7429;
  --pc-longevidad: #8A5A00;
  --pc-diabetes: #A8480F;
  --pc-cardiovascular: #A12836;
  --pc-infecciosas: #56650F;
  --pc-medicina-personalizada: #3346A8;
  --pc: var(--color-primary);       /* current pillar colour, set by [data-pilar] below */

  /* Generative art and brand mark */
  --art-field: #F7F0F4;
  --art-cyto: #E7B9CB;
  --brand-mark-bg: var(--color-text-primary);
  --brand-mark-a: var(--color-focus);
  --brand-mark-b: #9C86D6;
  --brand-mark-c: var(--color-bg);

  /* News map: the canvases of js/explore/** read these colours at runtime (never a literal in the JS) */
  --map-bg: var(--color-bg);
  --map-text: var(--color-text-primary);
  --map-link: #8F8AA0;
  --map-tag: #9088A3;               /* ≥ 3:1 on the map (audit 65) */

  --shadow-card: none;
  --shadow-float: 0 6px 24px color-mix(in srgb, var(--color-text-primary) 22%, transparent);

  /* Typography (fonts self-hosted: /assets/fonts, OFL) */
  --font-display: 'Newsreader', Georgia, serif;
  --font-read: 'Newsreader', Georgia, serif;
  --font-ui: 'Instrument Sans', system-ui, sans-serif;
  --fs-body: 1rem;
  --fs-small: 0.875rem;
  --fs-xsmall: 0.8125rem;
  --fs-display: clamp(2.1rem, 5vw, 3.6rem);
  --fs-page-title: clamp(1.85rem, 3.6vw, 2.6rem);
  --fs-h2: clamp(1.35rem, 2.4vw, 1.8rem);
  --fs-h3: 1.2rem;
  --fs-card: 1.18rem;
  --fs-lead: clamp(1.5rem, 2.4vw, 2rem);
  --fs-article-title: clamp(1.75rem, 4.4vw, 3rem);
  --fs-read: 1.15rem;
  --lh-read: 1.68;
  --lh-tight: 1.15;
  --measure-read: 37rem;            /* ≈ 65-75 characters of Newsreader at --fs-read (measured, not 68ch: audit 33); rem so every reading box aligns */
  --weight-display: 500;
  --weight-heading: 600;
  --weight-strong: 650;
  --tracking-display: -0.015em;

  /* Spacing, radii, layout */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --gap: 22px;
  --radius-sm: 6px;
  --radius-input: 10px;
  --radius-card: 12px;
  --radius-pill: 999px;
  --touch-target: 44px;
  --max-width: 1240px;
  --card-min: 272px;

  /* Layers */
  --z-sticky: 20;
  --z-overlay: 30;
  --z-skip: 50;
}

/* ---------- News map layout (css/explore*.css, pages under /es/explorar/) ----------
   Heights measured 2026-09-29 (Chrome 149, map lab): the site header is 105 px up to 720 px wide (brand row + the
   four-button nav row, the same at 320/360/390/720) and 65 px from 721 px (64 px row + 1 px border, sticky). The bar
   of views sits between the header and the map: one row of 44 px links with 4 px above and below and a 1 px border
   under it. The map section fills the rest of the first screen: svh, not dvh, so the canvas does not resize every
   time a phone's address bar hides or shows. */
:root {
  --map-header-h: 105px;
  --map-switch-h: calc(var(--touch-target) + 2 * var(--space-1) + 1px);
  --map-min-h: 360px;               /* landscape phones: below this the map is not worth drawing */
  --map-panel-w: 400px;             /* desktop overlay column, same as the approved prototype's panel card */
  --map-card-w: 420px;
  --map-panel-max-h: 55svh;         /* an open panel never covers more than about half of a phone's map */

  /* Room for the open panel, whatever the height: it never runs past the stage (the bar of views took 53 px from the
     lab's stage, and at 320 × 568 the open panel ran 50 px under the skip strip: its last controls could not be
     reached, 2026-09-29). The stage is the map section (100svh under the header and the bar of views, at least
     --map-min-h) minus the skip strip and the section's border. Above the panel's body: the overlay's offset, the
     bar's border and padding, the title row (open, the panel wraps under it) and the summary; under it the bar's
     padding and border, and the same offset as above. */
  --map-stage-h: calc(max(var(--map-min-h), 100svh - var(--map-header-h) - var(--map-switch-h)) - var(--touch-target) - 1px);
  --map-bar-chrome: calc(2 * (1px + var(--space-2)) + var(--fs-h3) * var(--lh-tight) + var(--space-2) + var(--touch-target));
  --map-panel-room: calc(var(--map-stage-h) - 2 * var(--space-3) - var(--map-bar-chrome));

  /* «Territorios»: the open panel also ends above the zoom controls, and phones keep a strip of map between the two
     (open panel + card left 0 px of map at 320 × 568 in the lab, 2026-09-29). */
  --map-territories-strip: 96px;
  --map-territories-panel-room: calc(var(--map-panel-room) - (var(--touch-target) + 2px + var(--space-2) + var(--map-territories-strip)));

  /* «Territorios»: box of the server-rendered sketch = the canvas's fit area (js/explore/territories/map.js
     visibleArea without the transient parts) less the fit's padding (FIT_PAD_PX of config.js; a unit test keeps
     them equal). Phones: below the title bar (12 px offset, 1 px border and 8 px padding on each side of a 44 px
     control) and above the zoom controls (12 px + 44 px + their 2 px border), plus the room the area names take
     beyond the land, which the canvas fits in too (they stuck out 10-15 px a side at 390-430 px, 2026-09-29). */
  --map-sketch-pad: 20px;
  --map-sketch-names: 12px;
  --map-sketch-top: calc(var(--space-3) + 2 * (1px + var(--space-2)) + var(--touch-target) + var(--map-sketch-pad));
  --map-sketch-bottom: calc(var(--space-3) + var(--touch-target) + 2px + var(--map-sketch-pad));
  --map-sketch-side: calc(var(--map-sketch-pad) + var(--map-sketch-names));
  --map-sketch-left: var(--map-sketch-side);
}
@media (min-width: 721px) { :root { --map-header-h: 65px; } }
/* Narrow phones: the title bar of «Territorios» wraps into two rows (title, then «Filtrar y resaltar») below 332.4 px,
   measured 2026-09-29 with the site's fonts (12 + 26 px of overlay and bar, 93.1 px of title, 12 px of gap, 177.3 px
   of summary; the lab's «Mapa de noticias» wrapped below 385 px): the sketch starts one title row lower. */
@media (max-width: 332px) {
  :root { --map-sketch-top: calc(var(--space-3) + 2 * (1px + var(--space-2)) + var(--fs-h3) * var(--lh-tight) + var(--space-2) + var(--touch-target) + var(--map-sketch-pad)); }
}
@media (min-width: 900px) {
  :root {
    --map-panel-room: calc(var(--map-stage-h) - 2 * var(--space-4) - var(--map-bar-chrome));
    --map-territories-panel-room: calc(var(--map-panel-room) - (var(--touch-target) + 2px + var(--space-2)));
    --map-sketch-top: var(--map-sketch-pad);
    --map-sketch-bottom: var(--map-sketch-pad);
    --map-sketch-side: var(--map-sketch-pad);
    --map-sketch-left: calc(var(--space-4) + var(--map-panel-w) + var(--map-sketch-pad));
  }
}
/* Short screens (landscape phones): the zoom controls of «Territorios» go beside the title bar (three buttons:
   2 × 44 px + «Ver todo» ≈ 174 px) and the sketch loses its bottom strip. SHORT_PX of config.js is this height. */
@media (max-width: 899px) and (max-height: 480px) {
  :root { --map-territories-zoom-w: 11.5rem; --map-sketch-bottom: var(--map-sketch-pad); }
}

/* Pillar colour wiring: one rule per pillar sets --pc for everything inside (no inline style, CSP). */
[data-pilar="cancer"] { --pc: var(--pc-cancer); }
[data-pilar="alzheimer"] { --pc: var(--pc-alzheimer); }
[data-pilar="neurologia"] { --pc: var(--pc-neurologia); }
[data-pilar="ia-medicina"] { --pc: var(--pc-ia-medicina); }
[data-pilar="medicina-regenerativa"] { --pc: var(--pc-medicina-regenerativa); }
[data-pilar="longevidad"] { --pc: var(--pc-longevidad); }
[data-pilar="diabetes"] { --pc: var(--pc-diabetes); }
[data-pilar="cardiovascular"] { --pc: var(--pc-cardiovascular); }
[data-pilar="infecciosas"] { --pc: var(--pc-infecciosas); }
[data-pilar="medicina-personalizada"] { --pc: var(--pc-medicina-personalizada); }

/* Self-hosted fonts (SIL Open Font License 1.1, see /assets/fonts/OFL-*.txt). Variable weight axes. */
@font-face {
  font-family: 'Newsreader'; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url(../fonts/newsreader-latin.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;
}
@font-face {
  font-family: 'Newsreader'; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url(../fonts/newsreader-latin-ext.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;
}
@font-face {
  font-family: 'Instrument Sans'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(../fonts/instrument-sans-latin.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;
}
@font-face {
  font-family: 'Instrument Sans'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(../fonts/instrument-sans-latin-ext.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;
}
