/* Arbopedia components.
   Two surface treatments exist — plate (fill + house shadow) and outline (2px ink,
   no shadow) — and they are mutually exclusive. Never both on one element. */

/* ---------------------------------------------------------------- etiqueta */
/* The condensed uppercase micro-label. Smaller size means wider tracking. */

.ap-label {
  display: inline-block;
  font-family: var(--font-body);
  font-stretch: var(--label-stretch);
  font-weight: var(--label-weight);
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--noche);
}
.ap-label--xs { font-size: 9.5px; letter-spacing: .14em; }
.ap-label--sm { font-size: 10px; letter-spacing: .14em; }
.ap-label--lg { font-size: 13px; letter-spacing: .1em; }
.ap-label--cream { color: var(--crema); }
.ap-label--muted { opacity: .7; }

/* A section rule: the label with the 2px underline beneath it. */
.ap-label--rule {
  display: block;
  padding-bottom: 7px;
  border-bottom: var(--borde-fuerte);
}
.ap-label--rule.ap-label--cream { border-bottom-color: var(--crema-borde); }

/* ---------------------------------------------------------------- boton */

.ap-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: var(--radio-pill);
  padding: 12px 18px;
  font-family: var(--font-body);
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 11.5px;
  letter-spacing: .13em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: var(--transicion-boton);
  border: 2px solid transparent;
  background: var(--ambar);
  color: var(--noche);
}
.ap-button:hover { transform: var(--hover-boton); }
.ap-button--sm { padding: 9px 15px; font-size: 10.5px; }
.ap-button--lg { padding: 15px 26px; font-size: 13px; }

.ap-button--amber { background: var(--ambar); color: var(--noche); border-color: var(--ambar); }
.ap-button--night { background: var(--noche); color: var(--ambar); border-color: var(--noche); }
.ap-button--outline { background: transparent; color: var(--noche); border-color: var(--linea-fuerte); }
.ap-button--cream { background: var(--crema); color: var(--noche); border-color: var(--crema); }
/* On dark grounds the outline button borrows the cream ink — but a cream plate
   nested inside a dark section must win it back, or the button turns invisible. */
.ap-on-dark .ap-button--outline {
  color: var(--crema);
  border-color: var(--crema-borde);
}
/* `.ap-hero__plate` was the first of these and is gone: the hero's only outline
   button was «El proyecto», and the plate cannot hold one any more, so the
   selector matched nothing. `test_style_contract.py` could not have caught it —
   both class names are still used elsewhere, just never nested this way. The two
   below are live. */
.ap-on-dark .ap-card--plate .ap-button--outline,
.ap-on-dark .ap-card--outline .ap-button--outline {
  color: var(--noche);
  border-color: var(--linea-fuerte);
}

.ap-button[disabled] { opacity: .4; cursor: not-allowed; }
.ap-button[disabled]:hover { transform: none; }

/* ---------------------------------------------------------------- pastilla */
/* Pressed inverts to solid noche with ambar text. One active pattern, everywhere. */

.ap-pill {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  border: var(--borde-pill-resting);
  background: transparent;
  color: var(--noche);
  border-radius: var(--radio-pill);
  padding: 8px 14px;
  font-family: var(--font-body);
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 10.5px;
  letter-spacing: .13em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
}
.ap-pill__count { opacity: .65; letter-spacing: .1em; font-size: 10px; }
.ap-pill[aria-current] {
  background: var(--noche);
  color: var(--ambar);
  border-color: var(--noche);
}
.ap-pill--wide { justify-content: space-between; width: 100%; }
.ap-pill--square {
  border-radius: var(--radio-suave);
  padding: 9px 0;
  justify-content: center;
  letter-spacing: 0;
}

/* Removable chip above the results grid. */
.ap-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 0;
  background: var(--noche);
  color: var(--ambar);
  border-radius: var(--radio-pill);
  padding: 8px 14px;
  font-family: var(--font-body);
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
}
.ap-chip__x { font-size: 14px; line-height: 1; }

/* ---------------------------------------------------------------- ordenar por */

/* A row of links, not a control with a chrome of its own: the directory already
   carries a filter rail and a chip row above the grid, and a third boxed thing
   would compete with both. So the options read as text and only the chosen one
   is drawn — 2px of ink under the word, which is the outline treatment reduced
   to one edge rather than a second surface. No plate, no shadow. */
.ap-order {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 7px 17px;
  margin-bottom: 21px;
}
.ap-order__title { flex-basis: 100%; margin-bottom: 3px; }
/* Ink at 72 %, which measures 6.32:1 on cream — computed, not guessed, and well
   over AA. The margin matters here because AGENTS.md records that ink at .60 is
   4.30:1 and fails, so the usable band is narrow and 72 sits in the middle of
   it rather than at its edge. */
.ap-order__option {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 14px;
  color: color-mix(in srgb, var(--noche) 72%, transparent);
  text-decoration: none;
  padding-bottom: 3px;
  border-bottom: 2px solid transparent;
}
.ap-order__option:hover { color: var(--noche); }
/* The chosen one is full ink — 15.12:1 on cream, verified against two anchors:
   the function returns exactly 21.0 for white on black, and reproduces the
   4.30:1 that AGENTS.md records for ink at 60 %.

   **What distinguishes the two states, honestly.** Not the 2px rule, and not
   the colour: `--ambar` on `--crema` measures 1.44:1 and the
   delta between the two text colours is 2.39:1 — both under WCAG 1.4.11's 3:1
   for a state indicator, so neither the rule nor the colour carries it alone.
   The weight does, and it is here for that: 700 against 850 is a shape
   difference, not a colour one. The active option is also a `<span>` rather
   than an `<a>` — no pointer, no focus stop — and carries `aria-current`, so
   nothing about the state depends on seeing it.

   The amber is design-system-wide (`--anillo-foco` is the same colour) and is
   not raised further here. */
.ap-order__option--on {
  color: var(--noche);
  font-weight: 850;
  border-bottom-color: var(--ambar);
}

/* ---------------------------------------------------------------- insignia */

/* Two registers can appear in one Estado row — the IUCN's and NOM-059's — and
   they must not sit flush. Inline-block badges are separated only by collapsed
   source whitespace, about 2.5px at this font size, and at 390px the row is
   ~250px wide while one IUCN badge measures ~210px, so the second always wraps
   to its own line where inline-block leaves no row gap at all. 7px is the pill
   gap the design system specifies.

   Named as an element of `.ap-taxon` rather than a standalone `.ap-badges`
   because `test_every_class_a_template_uses_is_defined_in_css` exempts plain
   block classes — legitimately, since a wrapper with no styling of its own
   needs no rule. This one has styling, and deleting the rule would silently
   lose the gap; the `__` puts it back under the guard that exists for that. */
.ap-taxon__badges { display: flex; flex-wrap: wrap; gap: 7px; }

.ap-badge {
  display: inline-block;
  border: 2px solid transparent;
  border-radius: var(--radio-pill);
  padding: 4px 12px 5px;
  font-family: var(--font-body);
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.ap-badge--verified { background: var(--verde); color: var(--crema); }
/* The design system says --rojo survives "as a text-free accent and as the UICN
   danger badge" — but this badge does carry text, and crema on rojo measures
   3.39:1 (noche on rojo is 4.46:1; both fail AA for 10px type). --colorin is the
   system's own AA-safe lift of rojo, and noche on it measures 5.45:1. Same alarm,
   verified pairing. See docs/decisions/0008. */
.ap-badge--danger { background: var(--colorin); color: var(--noche); }
.ap-badge--native { background: transparent; color: var(--noche); border: var(--borde-pill-resting); }
.ap-badge--introduced { background: var(--relleno-suave); color: var(--noche); }
.ap-badge--pending {
  background: transparent;
  color: var(--noche);
  border: 2px dashed var(--borde-pill);
  font-family: var(--font-mono);
  font-stretch: normal;
  font-weight: 500;
  letter-spacing: .04em;
}

/* ---------------------------------------------------------------- capsula */

.ap-search {
  display: flex;
  align-items: center;
  background: var(--noche);
  border-radius: var(--radio-pill);
  padding: 6px 6px 6px 20px;
  box-shadow: var(--sombra-capsula);
  position: relative;
}
.ap-search__input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--crema);
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 500;
  padding: 11px 0;
  outline: none;
}
.ap-search__input::placeholder { color: var(--crema); opacity: .55; }
.ap-search__input::-webkit-search-cancel-button { filter: invert(1); }

/* Typeahead panel. */
.ap-suggestions {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  z-index: 70;
  background: var(--crema);
  border: var(--borde-fuerte);
  border-radius: var(--radio-tarjeta);
  overflow: hidden;
  box-shadow: var(--sombra-tarjeta);
}
.ap-suggestions:empty { display: none; }
.ap-suggestion {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 10px 16px;
  text-decoration: none;
  border-bottom: 1px solid var(--linea-suave);
}
.ap-suggestion:last-child { border-bottom: 0; }
.ap-suggestion:hover,
.ap-suggestion:focus { background: var(--noche); color: var(--crema); }
.ap-suggestion__name { font-weight: 700; font-size: 15px; }
.ap-suggestion__bin { font-style: italic; font-size: 13px; opacity: .75; }
/* The language of the matched name, in the label face the sheet uses for it.
   `color: inherit` and not `.ap-label--cream`: that modifier is right on the
   sheet, where the label sits on `--verde`, and wrong here, where the panel is
   `--crema` — cream on cream is 1:1 and the language simply does not appear
   until the row is hovered. `.ap-label` sets an explicit `color`, so this span
   would not inherit the row's cream on hover either; inheriting fixes both
   states at once. Ink at .7 over crema is 5.95:1 and crema at .7 over noche is
   7.96:1, so `.ap-label--muted` can stay. */
.ap-suggestion__lang { color: inherit; }
.ap-suggestion__lang[hidden] { display: none; }

/* ---------------------------------------------------------------- tarjeta */

.ap-card {
  border-radius: var(--radio-tarjeta);
  padding: 18px 20px;
  background: var(--crema);
  color: var(--noche);
  border: 2px solid transparent;
}
.ap-card--plate { box-shadow: var(--sombra-tarjeta); }
.ap-card--outline { border: var(--borde-fuerte); box-shadow: none; }
.ap-card--empty {
  background: transparent;
  border: 2px dashed rgba(16, 32, 26, .45);
  box-shadow: none;
}
.ap-card--dark {
  background: var(--selva);
  color: var(--crema);
  box-shadow: var(--sombra-tarjeta);
}

/* ---------------------------------------------------------------- tarjeta de especie */

.ap-species {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--radio-tarjeta);
  padding: 17px;
  min-height: 342px;
  overflow: hidden;
  isolation: isolate;
  text-decoration: none;
  background: var(--species-bg, var(--verde));
  color: var(--species-ink, var(--crema));
  box-shadow: var(--sombra-tarjeta);
  transition: var(--transicion-tarjeta);
}
.ap-species:hover { transform: var(--hover-tarjeta); }

/* The arced photo window, bleeding 8px past the bottom-right corner. */
.ap-species__photo {
  position: absolute;
  right: -8px;
  bottom: -8px;
  width: 40%;
  aspect-ratio: 3 / 4.8;
  border-radius: 999px 999px 14px 14px;
  overflow: hidden;
  display: grid;
  place-items: center;
  /* No padding here. It was insetting the photograph on every side — the window
     is a frame for the picture, not a mat around it. The placeholder that shows
     when there is no photograph carries its own. */
  text-align: center;
  /* 8%, not 16%. The tint is `currentColor` — the card's own ink — over the
     card's accent, and the placeholder's text is that same ink. So every point
     of tint moves the background *towards* the text and costs contrast. At 16%
     with the text at .9 opacity, six of the nine verified accents failed 4.5:1
     on 9px type: verde 3,76, colorín 3,81, naranja 4,10, rosa 4,10, morado
     4,15, cielo 4,75. Raising the opacity alone does not save it — colorín
     reaches only 4,15 at full opacity — and raising the tint makes it worse.
     8% with opaque text puts the worst pair (colorín) at 4,77.

     Only placeholder cards ever show it: where there is a photograph the image
     covers the window entirely. The 1.5px inset stays at 16% because it is a
     frame line and carries no text. */
  background: color-mix(in srgb, currentColor 8%, transparent);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, currentColor 16%, transparent);
}
/* The photograph fills the window and is shown as it was taken. No blend mode:
   the prototype tinted it to the card's accent, and with real photographs on the
   cards that reads as a colour cast over the subject rather than as a treatment.
   A tree is what the sheet is about — the card already carries the colour. */
.ap-species__photo img {
  /* Absolute rather than a grid item, so `place-items: center` cannot shrink it
     to its intrinsic size inside the arch. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ap-species__no-photo {
  padding: 10px;
  font-family: var(--font-mono);
  font-size: 9px;
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: .04em;
  /* No `opacity`. It was .9, which is a contrast cost paid for nothing a
     reader can name — see the tint note above. */
}

/* The three wrappers exist for the 620px two-column restack; on desktop they are
   plain stacked blocks so the card reads as one column. */
.ap-species__text,
.ap-species__side,
.ap-species__foot {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
/* Pushes the height + bloom bar to the foot of the card. */
.ap-species__side { margin-top: auto; }

.ap-species__family {
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 9.5px;
  letter-spacing: .17em;
  text-transform: uppercase;
  opacity: .8;
}
.ap-species__name {
  font-family: var(--font-display);
  font-size: var(--display-card);
  line-height: .95;
  margin: 7px 0 3px;
  max-width: 88%;
}
.ap-species__bin {
  font-style: italic;
  font-weight: 500;
  font-size: 13.5px;
  max-width: 60%;
  line-height: 1.25;
}
/* The card's own sentence (decision 0054). Between the binomial and the
   labels, in the text column that already flexes; `margin-top: auto` on
   `__side` keeps the height and the bloom bar pinned to the foot, so a card
   with a line and one without still line up along the bottom.

   Ink at .88, rather than a grey — there are none — and the number is
   measured, not chosen. `.78` looked right and failed AA on five of the nine
   accents (colorín 4.11, verde 4.21, naranja 4.26, rosa 4.36, morado 4.39);
   .84 is the first value that clears 4.5 everywhere and clears it by .04 on
   colorín, which is no margin at all for a token that may be renotated. .88
   leaves colorín at 4.77. `test_palette.py` reads this number out of this rule
   and recomputes all nine, so lowering it fails the build rather than the
   reader. */
.ap-species__line {
  margin: 8px 0 2px;
  max-width: 92%;
  font-size: 12.5px;
  line-height: 1.35;
  font-weight: 500;
  opacity: .88;
}

.ap-species__labels {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 11px;
  max-width: 56%;
}
.ap-species__wordmark {
  border: 1.5px solid currentColor;
  border-radius: var(--radio-pill);
  padding: 2px 8px;
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 9px;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.ap-species__measure {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding-top: 12px;
  max-width: 56%;
}
.ap-species__height {
  font-family: var(--font-display);
  font-size: 23px;
  line-height: 1;
  white-space: nowrap;
}
.ap-species__height-pending {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .04em;
  line-height: 1.6;
  opacity: .75;
  white-space: nowrap;
}
.ap-species__foliage {
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 9px;
  letter-spacing: .11em;
  text-transform: uppercase;
  line-height: 1.3;
}
.ap-species__months {
  display: flex;
  gap: 2px;
  margin-top: 9px;
  max-width: 56%;
}
.ap-species__month {
  flex: 1;
  height: 7px;
  border-radius: 2px;
  background: color-mix(in srgb, currentColor 22%, transparent);
}
.ap-species__month--on { background: currentColor; }
.ap-species__note {
  margin-top: 5px;
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 8.5px;
  letter-spacing: .11em;
  text-transform: uppercase;
  max-width: 56%;
  line-height: 1.35;
}

/* ---------------------------------------------------------------- banda de floracion */

.ap-band { display: grid; gap: 6px; }
.ap-band__cells { display: flex; gap: 4px; }
.ap-band__cell {
  flex: 1;
  height: 14px;
  border-radius: 4px;
  border: 0;
  padding: 0;
  display: block;
  background: var(--relleno-suave);
}
.ap-band__cell--on { background: var(--band-color, var(--ambar)); }
.ap-band__cell[aria-current] { outline: 2px solid var(--noche); outline-offset: 1px; }
button.ap-band__cell { cursor: pointer; }
.ap-band__months {
  display: flex;
  gap: 4px;
  font-family: var(--font-body);
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 9px;
  letter-spacing: .06em;
  text-transform: uppercase;
  /* .7, not .6: ink at .6 over cream is 4.30:1 and fails AA — the number
     AGENTS.md records — and `aria-hidden` kept axe from ever measuring it. */
  opacity: .7;
}
.ap-band__months span { flex: 1; text-align: center; }

/* ---------------------------------------------------------------- fila de taxonomia */

.ap-taxon {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: 10px;
  align-items: baseline;
  padding: 9px 0;
  border-bottom: 1px solid var(--linea-suave);
}
.ap-taxon__value { font-weight: 600; font-size: 15px; }
.ap-taxon__value--italico { font-style: italic; }

/* ---------------------------------------------------------------- placa de fuentes */

.ap-sources {
  border: var(--borde-fuerte);
  border-radius: var(--radio-tarjeta);
  padding: 18px 20px 16px;
  background: var(--crema);
}
.ap-sources__list {
  margin: 12px 0 0;
  padding-left: 18px;
  display: grid;
  gap: 8px;
  list-style: decimal;
}
.ap-sources__list li { font-size: 13.5px; font-weight: 500; line-height: 1.4; }

/* The mark that ties a sentence to its citation.
   Type, not an icon: a superscript numeral keyed to the numbered source list.
   Ink at .7 over cream is 3.6:1, which fails AA for body text — but this is a
   link, and links carry their own colour, so it takes --selva at full strength
   and earns its contrast the same way every other link on the page does. */
.ap-cita {
  font-size: 10px;
  font-weight: 700;
  vertical-align: super;
  line-height: 0;
  margin-left: 1px;
  padding: 0 1px;
  color: var(--selva);
  text-decoration: none;
}
.ap-cita:hover,
.ap-cita:focus-visible { text-decoration: underline; }
.ap-sources__revised {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 2px solid var(--linea-suave);
  font-family: var(--font-mono);
  font-size: 12px;
  opacity: .7;
}

/* ---------------------------------------------------------------- escala humana */

.ap-scale__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.ap-scale svg { width: 100%; height: auto; display: block; margin-top: 8px; }

/* ---------------------------------------------------------------- navegacion */

.ap-nav {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--selva);
  color: var(--crema);
}
.ap-nav__inner {
  max-width: var(--ancho-ficha);
  margin: 0 auto;
  padding: 0 22px;
  min-height: var(--alto-nav);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
}
.ap-nav--wide .ap-nav__inner { max-width: var(--ancho-directorio); }
.ap-wordmark {
  font-family: var(--font-display);
  font-size: 22px;
  letter-spacing: -.01em;
  text-decoration: none;
  color: var(--crema);
}
.ap-wordmark__mx { color: var(--ambar); }
.ap-nav__links { display: flex; gap: 22px; align-items: center; }
.ap-nav__link {
  font-stretch: var(--label-stretch);
  font-weight: 600;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .1em;
  text-decoration: none;
  color: var(--crema);
}
.ap-nav__link[aria-current] { color: var(--ambar); font-weight: 800; }

/* Mobile disclosure — hidden until the links stop fitting. */
.ap-nav__menu { display: none; position: relative; }
.ap-nav__menu-button {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 15px;
  border: 2px solid var(--ambar);
  background: var(--ambar);
  color: var(--noche);
  border-radius: var(--radio-pill);
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  cursor: pointer;
  list-style: none;
}
.ap-nav__menu-button::-webkit-details-marker { display: none; }
.ap-nav__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 80;
  background: var(--selva);
  border: 2px solid var(--crema-borde);
  border-radius: var(--radio-tarjeta);
  padding: 8px;
  display: grid;
  gap: 2px;
  min-width: 190px;
}
.ap-nav__panel .ap-nav__link {
  padding: 12px 14px;
  border-radius: var(--radio-suave);
  min-height: 44px;
  display: flex;
  align-items: center;
}

.ap-breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  font-stretch: var(--label-stretch);
  font-weight: 800;
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  opacity: .9;
}
.ap-breadcrumbs a { text-decoration: none; }

/* ---------------------------------------------------------------- pie */

/* `position: relative` + `overflow: hidden` host the roots drawing: the SVG
   hangs from the footer's top edge and whatever a narrow viewport cannot fit
   is clipped rather than widening the page — the 390px no-horizontal-overflow
   test depends on that clip. */
.ap-footer { background: var(--selva); color: var(--crema); position: relative; overflow: hidden; }
/* The roots are decorative vendored geometry (see the provenance note in
   footer.html). Colour lives here, not in the template: the SVG strokes with
   `currentColor`. Verde-claro at .55 on selva is a drawing, not text, so the
   4.5:1 rule does not apply to it — the content that does carry text sits
   above on its own stacking context. Static by construction: no animation,
   so `prefers-reduced-motion` has nothing to disable. */
.ap-footer__roots {
  position: absolute;
  top: -2px;
  left: 50%;
  transform: translateX(-50%);
  width: min(1180px, 100%);
  opacity: .55;
  color: var(--verde-claro);
}
.ap-footer__roots svg { display: block; width: 100%; height: auto; }
/* Full opacity here, overriding `.ap-label--muted`'s .7: a footer label can
   sit directly over a root stroke, whose ground is verde-claro at .55 over
   selva (#0F7754), and cream at .7 on that composite measures 3.26:1 — under
   the 4.5:1 floor. Cream at .85 still fails at 4.06:1; at 1 it measures
   4.99:1. Decision 0008: the principle wins over the design's example. */
.ap-footer .ap-label--muted { opacity: 1; }
.ap-footer__inner {
  max-width: var(--ancho-ficha);
  margin: 0 auto;
  padding: 48px 22px 40px;
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(auto-fit, minmax(150px, 1fr));
  gap: 34px;
  position: relative;
}
.ap-footer__wordmark { font-family: var(--font-display); font-size: 26px; }
.ap-footer__tagline { margin-top: 10px; font-weight: 500; font-size: 14.5px; max-width: 38ch; line-height: 1.45; }
.ap-footer__column { display: grid; gap: 7px; margin-top: 12px; }
.ap-footer__column a { text-decoration: none; font-weight: 600; font-size: 14.5px; }
.ap-footer__licence-bar { border-top: 1px solid var(--crema-linea); position: relative; }
.ap-footer__licence {
  max-width: var(--ancho-ficha);
  margin: 0 auto;
  padding: 16px 22px;
  font-family: var(--font-mono);
  font-size: 12px;
  opacity: .7;
}

/* The gallery: the photographs a sheet carries beyond the hero, as a compact
   strip of square thumbnails below «Descripción». Each item is the `.ap-open`
   link itself — no credit line under a thumbnail; every credit renders in that
   photograph's own lightbox, one activation away (decision 0051).
   `auto-fill` with a minimum rather than a fixed column count, so 390px shows
   three and a wide screen shows seven without a breakpoint to maintain. */
.ap-gallery {
  margin-top: 14px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 10px;
}
/* Two classes: `.ap-open` declares its own radius later in this file, and the
   ring on a square thumb should trace the thumb. */
.ap-gallery .ap-gallery__item { display: block; border-radius: var(--radio-suave); }
.ap-gallery__item img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--radio-suave);
}

/* ---------------------------------------------------------------- fotografías que abren */

/* The link around a photograph. Block, so the whole image is the target rather
   than a strip of it, and the image keeps whatever shape its own rule gave it.

   The cue on hover and focus is the amber ring the design system already uses
   for focus (`--anillo-foco`), not a new treatment and not an overlay: a
   photograph is the content, and dimming it to say «clickable» hides the thing
   the reader came to look at. */
.ap-open {
  display: block;
  border-radius: var(--radio-tarjeta);
  outline-offset: 3px;
}
.ap-open img { display: block; }
.ap-open:hover { outline: var(--anillo-foco); }

/* The lightbox. `display: none` until its fragment is the target, which is the
   whole no-JavaScript mechanism — `.ap-panel` opens the mobile filters the same
   way. Nothing here needs a script; `js/gallery.js` only adds the keyboard.

   Fixed and full-bleed, above the sheet's own layers (the header's crowns sit
   at 2 and its inner at 6). */
.ap-lightbox { display: none; }
.ap-lightbox:target {
  display: grid;
  position: fixed;
  inset: 0;
  z-index: 60;
  place-items: center;
  padding: 22px;
}

/* Ink at .96, not a blur. AGENTS.md: nothing is frosted, and there are no
   greys — a muted fill is ink at an opacity. Nearly opaque rather than half,
   because the credit and the counter sit on it and have to stay legible over
   whatever the photograph behind them happens to be.

   An anchor rather than a div: clicking away closes, which is what a reader
   expects, and with `:target` that has to be a link to somewhere. */
.ap-lightbox__scrim {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--noche) 96%, transparent);
}
.ap-lightbox__frame {
  position: relative;
  display: grid;
  gap: 12px;
  max-width: min(1080px, 100%);
  justify-items: center;
}
/* Bounded by the viewport, not by the file: a 4000px photograph should fit the
   screen with its caption still on it, so the height leaves room for the foot. */
.ap-lightbox__image {
  display: block;
  max-width: 100%;
  max-height: 78vh;
  width: auto;
  border-radius: var(--radio-tarjeta);
}
.ap-lightbox__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 8px 16px;
  max-width: 62ch;
  text-align: center;
}
/* Full cream on ink: 15.12:1, the same pairing the sheet header uses. */
.ap-lightbox__credit {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--crema);
}
.ap-lightbox__credit a { color: var(--crema); }
/* The count is a data graphic, so it is mono and it is exact — «3 / 5», never
   «a few more». */
.ap-lightbox__count {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ambar);
}

/* The controls. Outline treatment — 2px ink border, no fill, no shadow — except
   that on this ground the «ink» is cream, because that is the ink of a dark
   surface. Never both treatments: there is no plate under these. */
.ap-lightbox__step,
.ap-lightbox__close {
  position: absolute;
  display: grid;
  place-items: center;
  border: 2px solid var(--crema-borde);
  border-radius: var(--radio-pill);
  color: var(--crema);
  text-decoration: none;
  /* 44px: the smallest thing a finger should have to hit, and the same floor
     the mobile controls use. */
  min-width: 44px;
  min-height: 44px;
  font-size: 26px;
  line-height: 1;
}
.ap-lightbox__step:hover,
.ap-lightbox__close:hover { border-color: var(--crema); background: rgba(255, 241, 214, .12); }
.ap-lightbox__step--prev { left: 16px; top: 50%; transform: translateY(-50%); }
.ap-lightbox__step--next { right: 16px; top: 50%; transform: translateY(-50%); }
.ap-lightbox__close { top: 16px; right: 16px; font-size: 22px; }

/* At 390px the arrows would sit on top of the photograph. They move to the foot
   and share the row with the count, which is where a thumb reaches anyway. */
@media (max-width: 640px) {
  .ap-lightbox:target { padding: 14px; }
  .ap-lightbox__step { top: auto; bottom: 16px; transform: none; }
  .ap-lightbox__step--prev { left: 22px; }
  .ap-lightbox__step--next { right: 22px; }
  .ap-lightbox__image { max-height: 62vh; }
}
