/* USACH Postgrado — visual system.

   Values are taken from the Consejo Universitario site, which is the visual
   reference for this family of sites. Where this sheet departs from it, the
   reason is stated inline; there are four such places and all of them are
   defects in the original rather than design decisions.

   Index at the end of the file. */

/* ------------------------------------------------------------------ fonts */

@font-face {
	font-family: "BebasNeuePro";
	src: url("../fonts/BebasNeuePro-SemiExpRegular.ttf") format("truetype");
	font-weight: 400;
	font-display: swap;
}
@font-face {
	font-family: "HelveticaNeueCn";
	src: url("../fonts/HelveticaNeueLTStd-Cn.ttf") format("truetype");
	font-weight: 400;
	font-display: swap;
}

/* ----------------------------------------------------------------- tokens */

:root {
	/* Institutional palette, shared across USACH postgrad sites. */
	--usp-orange:      #e77500;
	--usp-orange-dark: #cc6600;   /* button hover in the reference */
	--usp-orange-soft: #ffa040;   /* lightest segment of the colour bar */
	--usp-teal:        #00a499;
	--usp-purple:      #8c4799;

	/* Text-safe pairs. The institutional orange and teal are too light to carry
	   normal-size text on white, so anything below the large-text threshold uses
	   these instead. Same hue, darkened until they clear AA -- see the note at
	   the end of this block for the measurements. */
	--usp-orange-text: #ad5700;   /* 5.07:1 on white; also the safe fill behind white text */
	--usp-orange-deep: #8f4800;   /* 6.79:1 — hover of an already-filled orange control */
	--usp-teal-text:   #00766e;   /* 5.50:1 on white */

	/* Text greys. The reference paints headings #666; #525252 is used here for
	   headings because it holds up better at large sizes, and #666 stays for
	   secondary text. */
	--usp-heading: #525252;
	--usp-text:    #333;
	--usp-muted:   #666;
	--usp-line:    #e7e7e7;

	--usp-bg:        #fff;
	--usp-footer-bg: #394049;   /* reference footer, a blue-tinted grey */

	--usp-font-title: "BebasNeuePro", "Arial Narrow", sans-serif;
	--usp-font-body:  "HelveticaNeueCn", "Helvetica Neue", Arial, sans-serif;

	--usp-maxw:   1470px;       /* the reference uses one width sitewide */
	--usp-gap:    20px;         /* and one rhythm between blocks */
	--usp-radius: 10px;
	--usp-shadow: 0 0 10px rgba(0, 0, 0, .22);

	/* Accessibility note, measured: #e77500 scores 3.02:1 on white and #00a499
	   scores 3.10:1, against the 4.5:1 AA minimum for normal text.

	   So the brand pair is only ever painted on text at or above the large-text
	   threshold (24px, or 18.66px when bold), or used as a background behind
	   white, or on borders and rules where contrast rules for text do not apply.
	   Every other piece of text takes --usp-orange-text / --usp-teal-text.

	   Being an active state does NOT license the lighter pair: pairing colour
	   with a second cue satisfies WCAG 1.4.1 (use of colour), which is a
	   different criterion from 1.4.3 (contrast). 1.4.3 judges the text on its
	   own, so an active item still has to clear 4.5:1 by itself. */
}

/* ------------------------------------------------------------------- base */

* { box-sizing: border-box; }

body {
	margin: 0;
	font-family: var(--usp-font-body);
	font-size: 16px;
	/* The reference declares no line-height anywhere. Reading long Spanish
	   paragraphs at browser default is tiring, so one is set here. */
	line-height: 1.6;
	color: var(--usp-text);
	background: var(--usp-bg);
	min-height: 100vh;
	display: flex;
	flex-direction: column;
}

.site-main { flex: 1 0 auto; }

h1, h2, h3, h4 {
	font-family: var(--usp-font-title);
	/* The reference never sets font-weight, so browsers synthesise bold over a
	   single-weight face and the headings render smeared. Fixed explicitly. */
	font-weight: 400;
	line-height: 1.15;
	color: var(--usp-heading);
	margin: 0 0 .5rem;
}

a { color: var(--usp-orange-text); }
a:hover, a:focus-visible { color: var(--usp-teal-text); }

img { max-width: 100%; height: auto; }

.container {
	width: 100%;
	max-width: var(--usp-maxw);
	margin-inline: auto;
	padding: var(--usp-gap);
}

.screen-reader-text {
	position: absolute;
	width: 1px; height: 1px;
	margin: -1px; padding: 0;
	overflow: hidden; clip-path: inset(50%);
	white-space: nowrap;
}

.skip-link:focus {
	position: fixed; top: 8px; left: 8px; z-index: 100;
	width: auto; height: auto; margin: 0; padding: .6rem 1rem;
	clip-path: none;
	background: #fff; color: var(--usp-text);
	box-shadow: 0 2px 8px rgba(0, 0, 0, .25);
}

/* ----------------------------------------------------------------- header */

.site-header { background: #fff; }

.site-header__bar { display: flex; height: 10px; }
.site-header__bar-seg--teal   { flex: 5; background: var(--usp-teal); }
.site-header__bar-seg--purple { flex: 3; background: var(--usp-purple); }
.site-header__bar-seg--orange { flex: 2; background: var(--usp-orange-soft); }

.site-header__inner {
	max-width: var(--usp-maxw);
	margin-inline: auto;
	padding: 1rem var(--usp-gap) 0;
	/* The reference stacks logo and menu rather than putting them side by side;
	   the menu then sits right-aligned under it. */
	display: grid;
	grid-template-areas: "brand toggle" "nav nav";
	grid-template-columns: 1fr auto;
	align-items: center;
	gap: .5rem;
}

.site-header__brand { grid-area: brand; }
/* An <a> wrapped around an image is still an inline box, so what a visitor can
   actually click is the line box -- 18px tall -- and not the 71px picture
   sitting inside it. On a phone that is a thin strip across the middle of the
   logo. inline-block makes the anchor take the image's own height. */
.custom-logo-link { display: inline-block; }
.site-header__brand img { display: block; width: 400px; max-width: 70vw; height: auto; }

.site-header__title {
	font-family: var(--usp-font-title);
	font-size: 1.9rem;              /* large text: orange is legible here */
	color: var(--usp-orange);
	text-decoration: none;
	line-height: 1.05;
	display: inline-block;
}
.site-header__title:hover { color: var(--usp-orange-dark); }
.site-header__tagline {
	display: block;
	font-family: var(--usp-font-body);
	font-size: .85rem;
	color: var(--usp-muted);
}

.site-nav { grid-area: nav; }
.site-nav__list {
	list-style: none;
	margin: 0;
	padding: .6rem 0;
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	gap: 1.4rem;
	font-family: var(--usp-font-title);
	font-size: 1.15rem;
	border-bottom: 1px solid var(--usp-line);
}
.site-nav__list a {
	color: var(--usp-text);
	text-decoration: none;
	transition: color .15s ease;
}
/* .site-nav__list a (one class, one type) ties with a:focus-visible from the
   base rules and wins on source order, so the focus colour set there never
   reached the primary nav. Naming :focus-visible here is what restores it --
   the same pairing .side-list__link already does. */
.site-nav__list a:focus-visible,
.site-nav__list a:hover,
.site-nav__list .current-menu-item > a,
.site-nav__list .current_page_item > a,
.site-nav__list .current-menu-ancestor > a,
.site-nav__list .current_page_ancestor > a {
	/* 1.15rem (18.4px) at normal weight is below the large-text threshold, so
	   this needs the text-safe orange despite being a title face. */
	color: var(--usp-orange-text);
}

.site-header__toggle { grid-area: toggle; display: none; }
.site-header__toggle-bar {
	display: block; width: 26px; height: 3px;
	background: var(--usp-orange); border-radius: 2px;
	transition: transform .2s ease, opacity .2s ease;
}

/* ----------------------------------------------------------------- layout */

.layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--usp-gap);
	padding-bottom: 3rem;
}

/* Below 900px the grid is one column and the lateral stacks under the content.
   Stacked first, it put 371px of menu between the banner and the first word of
   the page: on a 375x812 phone the reader met 670px of chrome -- 82% of the
   opening screen -- before any content. The client asked to halve the banner
   for exactly this reason, and leaving this in place would have given the space
   straight back.

   This used to be done with `order`, which bought the visual result at the cost
   of a source order that disagreed with it. The aside now follows the main
   column in the source of every template instead. That was the fix for a
   heading defect -- the lateral's h2s came before the page h1, so a screen
   reader met "Enlaces de interés" and the section name before the title of the
   page it was standing on -- and it settles the focus order here for free: at
   this width source and visual order agree, so tabbing no longer jumps to links
   sitting at the bottom of the screen. */

@media (min-width: 900px) {
	/* Reference proportion: the lateral column takes roughly 22% of the row. */
	.layout { grid-template-columns: 300px minmax(0, 1fr); align-items: start; }
	/* The aside comes second in the source, so place both explicitly to keep it
	   on the left. Only .layout__main needs the :has() guard: without it a page
	   with no sidebar would place its content in an implicit second column. */
	.layout > .sidebar { grid-column: 1; grid-row: 1; }
	.layout:has(> .sidebar) > .layout__main { grid-column: 2; grid-row: 1; }
	/* The sidebar template prints nothing when it has neither featured links
	   nor sibling pages; collapse rather than leave an empty rail. */
	.layout:not(:has(> .sidebar)) { grid-template-columns: minmax(0, 1fr); }
}

.layout__main { min-width: 0; }

/* A rule closes the page title. Title and content headings share this theme's
   single-weight display face and the same grey, so size was the only thing
   telling them apart -- too little in a condensed face. Weight is not available
   as a second signal: the face has one weight and asking the browser to bolden
   it smears the glyphs, which is why the base heading rule pins 400.
   The rule separates page identity from content without touching either, and it
   works whatever the content opens with -- heading, paragraph, list or table. */
.page-title {
	font-size: clamp(1.9rem, 3.4vw, 2.5rem);
	margin-bottom: .9rem;
	padding-bottom: .5rem;
	border-bottom: 1px solid var(--usp-line);
}
.page-subtitle { color: var(--usp-muted); margin: 0 0 1.2rem; }
.section-title {
	font-size: 1.6rem;
	margin: 2rem 0 1rem;
}

.back-link {
	display: inline-block;
	margin-bottom: .8rem;
	font-size: .9rem;
	color: var(--usp-muted);
	text-decoration: none;
}
.back-link:hover { color: var(--usp-teal-text); }

/* ---------------------------------------------------------------- sidebar */

/* The blocks used to run flush into one another so the column read as a single
   list, the way the reference's does. That was right for the reference, whose
   featured links are images -- and wrong here, where they are text: the two
   outbound links read as two more pages of the section, and the person who
   built the site said so.

   What fixes it is not the gap on its own. A gap alone was read as a mistake
   before: wider than the space inside an item, too narrow to look deliberate,
   and nothing explaining it. The heading is what explains it, and with a
   heading the gap has a job. */
.sidebar__block + .sidebar__block { margin-top: 1.8rem; }

.sidebar__title {
	font-family: var(--usp-font-title);
	font-size: .82rem;
	font-weight: 400;
	letter-spacing: .09em;
	text-transform: uppercase;
	color: var(--usp-muted);
	margin: 0 0 .5rem;
	padding-bottom: .4rem;
	border-bottom: 2px solid var(--usp-line);
}

/* An arrow after an outbound label. The block heading says these leave the
   site; this repeats it per item, where the click actually happens. */
.side-list__ext { margin-left: .3rem; font-size: .8em; }

.side-list { list-style: disc; margin: 0; padding-left: 1.2rem; }
.side-list__item {
	padding: 10px 4px;
	/* Bullet plus a thin orange rule: the reference's lateral signature. */
	border-bottom: 1px solid var(--usp-orange);
}
.side-list__item::marker { color: var(--usp-text); }

.side-list__link {
	display: block;
	/* The reference uses #808080 here, which scores 3.9:1 on white and misses
	   AA for normal text. --usp-muted (#666) reads the same and passes at 5.7:1. */
	color: var(--usp-muted);
	text-decoration: none;
	transition: color .15s ease;
}
.side-list__link:hover, .side-list__link:focus-visible { color: var(--usp-teal-text); }
.side-list__link.is-active { color: var(--usp-orange-text); font-weight: 700; }

/* A featured link with an image is the image itself: no bullet, no rule. */
.side-list__item--image {
	list-style: none;
	margin-left: -1.2rem;
	padding: 0 0 .8rem;
	border-bottom: 0;
}
.side-list__item--image .side-list__link {
	border-radius: 6px;
	overflow: hidden;
	box-shadow: 0 1px 4px rgba(0, 0, 0, .16);
	transition: transform .15s ease, box-shadow .15s ease;
}
.side-list__item--image .side-list__link:hover {
	transform: translateY(-2px);
	box-shadow: 0 4px 12px rgba(0, 0, 0, .22);
}
.side-list__image { display: block; width: 100%; height: auto; }

/* ------------------------------------------------------------ person card */

.person-grid {
	/* Grid, not centred flex. Flex with fixed 250px cards leaves whatever the row
	   cannot use split as equal side margins, so every full row sat inset from
	   the section heading above it -- 25px here, since this column is 1110px and
	   four cards plus their gaps come to 1060px. The reference has the same
	   inset; its column is narrower so the leftover, and the error, is half.
	   Columns absorb the remainder instead, so both edges line up with the
	   heading at every width. The trade is that a short last row now sits left
	   rather than centred, which keeps every card the same width -- a centred
	   short row can only stay centred by growing its cards. */
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
	gap: var(--usp-gap);
	margin-bottom: 2rem;
}

/* Capping the card only makes sense once the grid is genuinely one column, and
   auto-fill does not reach one column until the main column drops under ~520px
   -- around a 560px viewport, not 899px. Applied at 899px it left every card in
   a two-column tablet row inset inside its own track. */
@media (max-width: 559px) {
	.person-grid { justify-items: center; }
	.person-card { width: 100%; max-width: 320px; }
}

.person-card {
	padding: 10px;
	background: #fff;
	border-radius: var(--usp-radius);
	box-shadow: var(--usp-shadow);
	text-align: center;
	transition: box-shadow .2s ease, transform .2s ease;
}
.person-card:hover { box-shadow: 0 4px 18px rgba(0, 0, 0, .3); transform: translateY(-2px); }
.person-card__link { display: block; color: inherit; text-decoration: none; }

.person-card__photo {
	width: 200px; height: 200px;
	margin: 0 auto 1rem;
	border-radius: 50%;
	overflow: hidden;
	background: #eef2f5;
	display: flex; align-items: center; justify-content: center;
}
.person-card__photo img { width: 100%; height: 100%; object-fit: cover; }
.person-card__initial {
	font-family: var(--usp-font-title);
	font-size: 4rem;
	color: var(--usp-muted);
	opacity: .5;
}

.person-card__name {
	font-family: var(--usp-font-body);
	font-size: 1.25rem;
	/* 20px at weight 600 sits in the grey area of the large-text rule: WCAG says
	   "14pt bold", and 600 is semi-bold, so a strict auditor reads this as normal
	   text needing 4.5:1 -- which the plain teal misses at 3.10:1. Takes the
	   text-safe teal instead of arguing the point. */
	font-weight: 600;
	color: var(--usp-teal-text);
	margin: 0 0 .2rem;
}
.person-card__role {
	font-size: 1.05rem;
	font-weight: 700;
	/* 16.8px bold still sits under the 18.66px bold threshold. */
	color: var(--usp-orange-text);
	margin: 0 0 .2rem;
}
.person-card__unit,
.person-card__contact {
	font-size: .9rem;
	color: #394049;
	margin: 0;
	word-break: break-word;
}

/* --------------------------------------------------------------- profile */

.profile { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: center; margin-bottom: 1.5rem; }
.profile__photo {
	width: 230px; height: 230px;
	flex: 0 0 auto;
	border-radius: 50%;
	overflow: hidden;
	background: #eef2f5;
	display: flex; align-items: center; justify-content: center;
}
.profile__photo img { width: 100%; height: 100%; object-fit: cover; }
/* The head block had no rule at all, so it inherited flex: 0 1 auto and shrank
   to its longest line while the row stayed 1080px wide -- 632px of dead space
   beside every profile at desktop width. Invisible below 900px, where .profile
   stacks into a column and the gap has nowhere to appear. */
.profile__head { flex: 1 1 auto; min-width: 0; }
.profile__name { font-size: 2rem; margin-bottom: .3rem; }
.profile__meta { margin: 0 0 .2rem; color: var(--usp-muted); }

/* --------------------------------------------------------- content cards */

.card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
	gap: var(--usp-gap);
	margin-bottom: 1.5rem;
}

.content-card {
	background: #fff;
	/* Opposite-corner rounding is the reference's card signature. */
	border-top-left-radius: 15px;
	border-bottom-right-radius: 15px;
	overflow: hidden;
	box-shadow: 0 1px 4px rgba(0, 0, 0, .12);
	transition: box-shadow .2s ease, transform .2s ease;
}
.content-card:hover { box-shadow: 0 3px 8px rgba(0, 0, 0, .2); transform: translateY(-2px); }
/* The link fills the card exactly, and the card clips its overflow to keep the
   opposite-corner radius -- so the browser's focus ring, drawn just outside the
   link's edge, was cut off entirely. Tabbing to a news card showed nothing.
   The ring goes on the card instead: an element's own outline is not clipped by
   its own overflow. :hover is not a substitute -- it never fires on a keyboard. */
.content-card:focus-within {
	outline: 3px solid var(--usp-teal-text);
	outline-offset: 2px;
}
/* A DOI or a long compound word in a title has nothing to wrap on. */
.content-card__title, .content-card__meta, .content-card__excerpt { overflow-wrap: anywhere; }
.content-card__link { display: block; color: inherit; text-decoration: none; height: 100%; }
.content-card__media { aspect-ratio: 16 / 9; overflow: hidden; background: #eef2f5; }
.content-card__media img { width: 100%; height: 100%; object-fit: cover; }
.content-card__body { padding: 1rem; }
.content-card__date {
	display: block;
	font-size: .78rem;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--usp-muted);
	margin-bottom: .3rem;
}
.content-card__title { font-size: 1.35rem; margin: 0 0 .4rem; }
.content-card__excerpt { margin: 0; font-size: .92rem; color: var(--usp-muted); }

/* The front page used to run as one centred ~1000px column, matching the
   reference. It now uses the ordinary two-column section layout instead,
   because the client asked for the lateral menu on the home as well -- so the
   measure comes from .layout like every other page and there is nothing left
   to set here. The news block simply closes the main column. */
.home-news { margin-top: 2.2rem; }
.home-news__more { margin-top: 1.4rem; text-align: center; }

/* The home shows a fixed number of news items, so its grid is fixed too.
   auto-fill computed four columns in the main column at full width and three at
   1280px, which meant the same three cards either left a hole on the right or
   orphaned one onto a second row depending on the window -- the hole is what
   the client saw. Four cards in an explicitly four-column grid always fill
   their rows: 4, then 2+2, then stacked. The feed on Vinculación keeps
   auto-fill, because there the count is a page size and not a layout decision. */
.home-news .card-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1360px) {
	/* Below this the main column cannot give four cards 250px each. */
	.home-news .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
	.home-news .card-grid { grid-template-columns: minmax(0, 1fr); }
}

/* -------------------------------------------------------------- documents */

.filter-bar { display: flex; flex-wrap: wrap; gap: .45rem; margin-bottom: 1.4rem; }
.filter-bar__item {
	font-size: .9rem;
	color: var(--usp-muted);
	text-decoration: none;
	padding: .35rem .85rem;
	border: 1px solid var(--usp-line);
	border-radius: 4px;
	transition: color .15s ease, border-color .15s ease;
}
.filter-bar__item:hover { color: var(--usp-teal-text); border-color: var(--usp-teal); }
.filter-bar__item.is-active {
	/* This label is text on a filled control, so it needs 4.5:1 like any other
	   text. White on --usp-orange is 3.02:1; the comment here used to argue it
	   counted as non-text contrast, which is not what a word inside a button is.
	   --usp-orange-text carries the same hue at 5.07:1. */
	color: #fff;
	background: var(--usp-orange-text);
	border-color: var(--usp-orange-text);
}

.doc-list { list-style: none; margin: 0; padding: 0; }
.doc-list__item {
	display: flex;
	align-items: center;
	gap: 1rem;
	padding: .9rem .2rem;
	border-bottom: 1px solid #ececec;
}
.doc-list__icon { flex: 0 0 auto; width: 34px; height: 34px; object-fit: contain; }
.doc-list__info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
.doc-list__title {
	font-family: var(--usp-font-title);
	font-size: 1.2rem;
	color: var(--usp-heading);
	text-decoration: none;
	line-height: 1.25;
}
.doc-list__title:hover { color: var(--usp-orange-text); }
.doc-list__meta { font-size: .82rem; color: var(--usp-muted); }
.doc-list__action { flex: 0 0 auto; }
.doc-list__pending {
	flex: 0 0 auto;
	font-size: .85rem;
	font-style: italic;
	/* Not #999: that scores 2.85:1. Empty states are easy enough to miss. */
	color: var(--usp-muted);
}

.doc-detail {
	display: flex;
	align-items: flex-start;
	gap: 1.2rem;
	padding: 1.2rem;
	border: 1px solid var(--usp-line);
	border-radius: var(--usp-radius);
	margin-bottom: 1.5rem;
}
.doc-detail__icon { width: 56px; height: 56px; flex: 0 0 auto; }
.doc-detail__meta { margin: 0 0 .8rem; font-size: .88rem; color: var(--usp-muted); }

/* ---------------------------------------------------------------- buttons */

.button {
	display: inline-block;
	background: var(--usp-orange);
	color: #fff;
	font-family: var(--usp-font-title);
	font-size: 1.05rem;
	letter-spacing: .03em;
	text-decoration: none;
	padding: .5rem 1.2rem;
	border: 0;
	border-radius: 4px;
	cursor: pointer;
	transition: background .15s ease;
}
/* Keep the label white on hover: recolouring it turns orange-on-orange. */
.button:hover, .button:focus-visible { background: var(--usp-orange-dark); color: #fff; }

/* --------------------------------------------------------------- content */

.entry-content { font-size: 1rem; }

/* Reading measure.

   A cap lived here that held prose to 72ch (about 85 characters). It halved the
   line length -- Postulantes ran to 216 characters without it -- but it also
   left the right half of every prose page empty, and centring the column to
   balance that made it worse. Reviewed on screen and reverted: the text runs the
   width of its column, left-aligned, as it did before.

   If the long lines become a problem once the real text is loaded, the fix is a
   max-width on the same selectors, NOT a centred column: the empty half was the
   objection, and centring only moved it to both sides at once. */

.entry-content > *:first-child { margin-top: 0; }
/* ...except a heading. The reset above stops the body copy from sagging away
   from the page title, but when the content opens with a heading it collapses
   the gap to nothing and the <h1> and that heading read as one title/subtitle
   pair. Half the rhythm headings get further down the flow is enough here: the
   rule under the page title already does most of the separating, so the full
   1.8rem left the opening heading floating away from its own title. */
.entry-content > :is(h2, h3, h4):first-child { margin-top: .9rem; }
.entry-content h2 { font-size: 1.6rem; margin: 1.8rem 0 .6rem; }
.entry-content h3 { font-size: 1.3rem; color: var(--usp-text); margin: 1.4rem 0 .5rem; }
.entry-content p { margin: 0 0 1rem; }
.entry-content ul, .entry-content ol { padding-left: 1.3rem; margin: 0 0 1rem; }
.entry-content li { margin-bottom: .4rem; }
.entry-content a { text-decoration: underline; }
.entry-content blockquote {
	margin: 1.2rem 0;
	padding: .5rem 0 .5rem 1rem;
	border-left: 3px solid var(--usp-line);
	color: var(--usp-muted);
}
.entry-media { margin: 0 0 1.5rem; }
.entry-media img { width: 100%; height: auto; border-radius: var(--usp-radius); }

/* Tables: a real curriculum grid needs to scroll rather than push the page. */
.entry-content table { width: 100%; border-collapse: collapse; margin: 0 0 1.2rem; font-size: .95rem; }
.entry-content th, .entry-content td { padding: .55rem .7rem; border: 1px solid var(--usp-line); text-align: left; }
.entry-content th { background: #f5f5f5; font-weight: 700; }
.entry-content { overflow-x: auto; }

.plain-list { list-style: none; margin: 0; padding: 0; }
.plain-list__item { padding: .8rem 0; border-bottom: 1px solid #ececec; }
.plain-list__link { font-family: var(--usp-font-title); font-size: 1.25rem; text-decoration: none; }
.plain-list__excerpt { margin: .2rem 0 0; color: var(--usp-muted); font-size: .9rem; }

/* ------------------------------------------------------------- pagination */

.pagination { margin: 1.5rem 0; }
/* Two code paths build pagination here: the_posts_pagination() wraps its links
   in core's <div class="nav-links">, while the page templates that run their own
   query call paginate_links() and print the anchors straight into <nav>. This
   rule only ever matched the first, so Vinculación and Documentos -- the two
   listings that actually paginate -- fell back to inline spacing. */
.pagination .nav-links,
.pagination:not(:has(.nav-links)) { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.pagination .page-numbers {
	display: inline-block;
	padding: .4rem .75rem;
	border: 1px solid var(--usp-line);
	border-radius: 4px;
	color: var(--usp-text);
	text-decoration: none;
	font-size: .9rem;
}
.pagination .page-numbers:hover { border-color: var(--usp-orange); color: var(--usp-orange-text); }
.pagination .page-numbers.current { background: var(--usp-orange); border-color: var(--usp-orange); color: #fff; }
.pagination .page-numbers.dots { border-color: transparent; }

/* --------------------------------------------------------------- carousel */

.carousel { position: relative; overflow: hidden; background: #dfe3e6; }
/* Half the previous height. The client wanted the banner gone entirely so the
   home could lead with content; halving it keeps the slider without pushing
   the intro and the lateral menu below the fold, which was the actual
   complaint. The caption and the controls shrink with it -- a 44px arrow on a
   220px band reads as an overlay, not a control. */
.carousel__track { position: relative; height: clamp(140px, 16vw, 230px); }
.carousel__slide {
	position: absolute; inset: 0;
	background-size: cover; background-position: center;
	display: flex; align-items: flex-end;
	opacity: 0; visibility: hidden;
	transition: opacity .6s ease, visibility .6s ease;
}
.carousel__slide.is-active { opacity: 1; visibility: visible; }
/* No overlay behind the caption: slides are flat colour, and every colour in
   the palette clears 4.5:1 against white on its own. Adding a scrim back means
   re-checking that contrast. */
.carousel__caption {
	width: 100%;
	padding: .7rem 1.1rem;
	font-family: var(--usp-font-title);
	font-size: clamp(1rem, 1.6vw, 1.4rem);
	color: #fff;
}
.carousel__caption a { color: #fff; text-decoration: none; }
.carousel__caption a:hover { text-decoration: underline; }

.carousel__nav {
	position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
	/* 34px keeps the 24x24 minimum target of WCAG 2.2 (2.5.8) with room to
	   spare, while fitting the shorter band. */
	width: 34px; height: 34px;
	border: 0; border-radius: 50%;
	background: rgba(0, 0, 0, .35);
	color: #fff; font-size: 1.5rem; line-height: 1;
	cursor: pointer;
	transition: background .15s ease;
}
.carousel__nav:hover, .carousel__nav:focus-visible { background: var(--usp-orange); }
.carousel__nav--prev { left: 12px; }
.carousel__nav--next { right: 12px; }

/* 13px, not .45rem: it is what keeps the 24px hit areas below from overlapping. */
.carousel__dots { position: absolute; left: 0; right: 0; bottom: 10px; z-index: 2; display: flex; justify-content: center; gap: 13px; }
/* The dot stays 11px to the eye; what grows is what a finger can hit.

   WCAG 2.2 asks for 24x24, and the spacing exception did not rescue these: at
   11px wide with a 7.2px gap the centres sat 18.2px apart, under the 24px that
   exception requires. Padding on the button itself would have moved the white
   ring outwards with it, so the target is an invisible pseudo-element centred
   on the dot, and the gap widens to 13px so that adjacent 24px targets meet
   without overlapping -- overlapping targets would hand a near-miss to whichever
   dot happens to come later in the DOM. */
.carousel__dot {
	position: relative;
	width: 11px; height: 11px; padding: 0;
	border: 2px solid #fff; border-radius: 50%;
	background: transparent; cursor: pointer;
	transition: background .15s ease;
}
.carousel__dot::after {
	content: "";
	position: absolute;
	top: 50%; left: 50%;
	transform: translate(-50%, -50%);
	width: 24px; height: 24px;
	border-radius: 50%;
}
.carousel__dot.is-active { background: #fff; }

@media (prefers-reduced-motion: reduce) {
	.carousel__slide { transition: none; }
}

/* ----------------------------------------------------------------- footer */

.site-footer { flex-shrink: 0; background: var(--usp-footer-bg); color: #fff; }
/* Two equal halves with each block centred inside its own half, mirroring the
   reference footer. Anchoring the two to the outer edges instead pushes them
   about 1400px apart on a wide screen and they stop reading as one footer. */
.site-footer__inner {
	max-width: var(--usp-maxw);
	margin-inline: auto;
	padding: 2rem var(--usp-gap);
	display: grid;
	grid-template-columns: 1fr 1fr;
	align-items: center;
	gap: 1.5rem;
}
.site-footer__logo { display: flex; justify-content: center; }
.site-footer__logo img { max-height: 72px; width: auto; }
.site-footer__center { text-align: center; }
.site-footer__social { list-style: none; display: flex; justify-content: center; gap: .3rem; margin: 0 0 .6rem; padding: 0; }
/* Same inline-box problem as the logo, and worse here because the icons are the
   only thing in the footer anyone taps: the anchor measured 26x18 around a 26px
   icon. A 44px box is the comfortable touch size and clears WCAG 2.2's 24px
   minimum with room; the gap shrinks to keep the icons the same distance apart
   as before. */
.site-footer__social a {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
}
.site-footer__social img { display: block; width: 26px; height: 26px; }
.site-footer__address { margin: 0; font-size: .88rem; line-height: 1.5; }

/* ------------------------------------------------------------- responsive */

@media (max-width: 899px) {
	.site-header__inner {
		grid-template-areas: "brand toggle" "nav nav";
		padding-bottom: .4rem;
	}
	.site-header__title { font-size: 1.5rem; }

	.site-header__toggle {
		display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
		width: 44px; height: 44px; padding: 0 9px;
		background: transparent; border: 0; cursor: pointer;
	}
	.site-header__toggle[aria-expanded="true"] .site-header__toggle-bar:nth-child(1) { transform: translateY(8px) rotate(45deg); }
	.site-header__toggle[aria-expanded="true"] .site-header__toggle-bar:nth-child(2) { opacity: 0; }
	.site-header__toggle[aria-expanded="true"] .site-header__toggle-bar:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

	.site-nav__list { display: none; flex-direction: column; align-items: stretch; gap: 0; border-bottom: 0; }
	.site-nav__list.is-open { display: flex; }
	.site-nav__list li { border-bottom: 1px solid var(--usp-line); }
	.site-nav__list a { display: block; padding: .7rem .2rem; }

	/* The grid already collapses to a single column here; the card just needs a
	   ceiling so a lone card does not stretch the full width of a tablet. */

	.doc-list__item { flex-wrap: wrap; }
	.doc-list__action, .doc-list__pending { margin-left: calc(34px + 1rem); }

	.site-footer__inner { grid-template-columns: 1fr; text-align: center; }

	.profile { flex-direction: column; text-align: center; }
}

/* ------------------------------------------------------- research identity

   Lines of research, ORCID and thesis topics: the fields that place a person
   and a publication in the programme. They appear on cards, on profiles and in
   the feed, so they are styled once here rather than three times below. */

.person-card__lineas,
.person-card__thesis {
	margin: 0 0 .25rem;
	font-size: .85rem;
	line-height: 1.35;
	color: var(--usp-muted);
}
.person-card__lineas { color: var(--usp-orange-text); }
.person-card__thesis {
	/* Thesis titles run long and a card is 250px wide. Three lines then an
	   ellipsis: enough to recognise the topic, not enough to make every card in
	   the row as tall as the worst one. */
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.person-card__orcid {
	margin: .35rem 0 0;
	font-size: .8rem;
	color: var(--usp-muted);
	font-variant-numeric: tabular-nums;
}

/* ORCID's own mark is a green circle with "iD" in it. Reproducing it as a
   glyph avoids shipping an image for something that appears on every card. */
.orcid-mark {
	display: inline-block;
	width: 15px; height: 15px;
	margin-right: .25rem;
	border-radius: 50%;
	background: #a6ce39;
	color: #fff;
	font-size: .6rem;
	font-weight: 700;
	line-height: 15px;
	text-align: center;
	vertical-align: -2px;
}

/* The three links on a profile -- back, ORCID, laboratorio -- were 18 to 23px
   tall. Each is isolated enough to pass WCAG 2.2 on the spacing exception, but
   they are the only things to click on the page, so they get a real target. */
.back-link, .profile__orcid a, .profile__links a { display: inline-block; padding: 3px 0; }
.profile__orcid a { color: var(--usp-muted); text-decoration: none; }
.profile__orcid a:hover { color: var(--usp-teal-text); text-decoration: underline; }
.profile__lineas { margin: .6rem 0 .3rem; display: flex; flex-wrap: wrap; gap: .35rem; }
.profile__links { margin: .4rem 0 0; display: flex; flex-wrap: wrap; gap: 1rem; font-size: .92rem; }

/* ------------------------------------------------------------------ chips

   The kind filter on Vinculación e Investigación, and the línea tags on a
   profile. Same pill, two jobs.

   The active state is white on --usp-orange-text, not on --usp-orange. A chip
   label is text, so 4.5:1 applies to it against its own background: white on
   #e77500 measures 3.02:1 and fails. #ad5700 -- the token that already exists
   because the institutional orange is unsafe for text -- gives 5.07:1 with the
   same hue. The resting state uses --usp-muted at 5.74:1 on white. */

.chip {
	display: inline-block;
	padding: .4rem .95rem;
	border: 1px solid var(--usp-line);
	border-radius: 999px;
	font-size: .9rem;
	line-height: 1.2;
	color: var(--usp-muted);
	text-decoration: none;
	white-space: nowrap;
	transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.chip:hover, .chip:focus-visible { color: var(--usp-teal-text); border-color: var(--usp-teal); }
.chip.is-active {
	background: var(--usp-orange-text);
	border-color: var(--usp-orange-text);
	color: #fff;
}
/* --usp-orange-dark would only reach 3.84:1; this goes darker, not lighter. */
.chip.is-active:hover { color: #fff; border-color: var(--usp-orange-deep); background: var(--usp-orange-deep); }

.chip--sub { font-size: .84rem; padding: .3rem .8rem; }
/* Same rule for the teal: white on --usp-teal is 2.7:1, on --usp-teal-text it
   is 5.50:1. */
.chip--sub.is-active { background: var(--usp-teal-text); border-color: var(--usp-teal-text); }
.chip--sub.is-active:hover { background: var(--usp-teal-text); border-color: var(--usp-teal-text); color: #fff; }

.chip--sm { font-size: .8rem; padding: .22rem .7rem; }

/* ----------------------------------------------------------------- filters */

.filters {
	display: flex;
	flex-direction: column;
	gap: .7rem;
	margin-bottom: 1.6rem;
	padding-bottom: 1.2rem;
	border-bottom: 1px solid var(--usp-line);
}
.filters__row { display: flex; flex-wrap: wrap; gap: .45rem; }
/* The subtype row is a refinement of the row above it, so it is indented and
   quieter -- otherwise two equal rows of pills read as two independent
   filters, and picking from the wrong one is the obvious mistake. */
.filters__row--sub { padding-left: 1rem; border-left: 2px solid var(--usp-line); }

.filters__form {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: .8rem;
	margin: .3rem 0 0;
}
.filters__field { display: flex; flex-direction: column; gap: .2rem; margin: 0; }
.filters__field label { font-size: .8rem; color: var(--usp-muted); }
.filters__field select {
	font-family: inherit;
	font-size: .92rem;
	padding: .4rem .6rem;
	border: 1px solid var(--usp-line);
	border-radius: 4px;
	background: #fff;
	color: var(--usp-text);
	min-height: 2.2rem;
}
.filters__submit { margin: 0; }

.feed__count { font-size: .85rem; color: var(--usp-muted); margin: 0 0 1rem; }

.listing-empty {
	padding: 1.6rem 0;
	color: var(--usp-muted);
	font-style: italic;
}

/* ------------------------------------------------------------- feed cards

   The Vinculación grid reuses .content-card and adds the three lines that only
   a mixed listing needs: what kind of thing this is, who made it, and which
   línea it belongs to. */

.content-card__kind {
	margin: 0 0 .3rem;
	font-family: var(--usp-font-title);
	font-size: .8rem;
	letter-spacing: .05em;
	text-transform: uppercase;
	color: var(--usp-teal-text);
}
.content-card__meta {
	margin: 0 0 .4rem;
	font-size: .85rem;
	line-height: 1.4;
	color: var(--usp-text);
}
.content-card__lineas {
	margin: .5rem 0 0;
	font-size: .8rem;
	color: var(--usp-orange-text);
}
/* A producción has no image, so its card is all text; the title carries it. */
.content-card--produccion .content-card__title { font-size: 1.2rem; line-height: 1.3; }

.content-card__media { position: relative; }
.content-card__play {
	position: absolute;
	top: 50%; left: 50%;
	transform: translate(-50%, -50%);
	width: 46px; height: 46px;
	border-radius: 50%;
	background: rgba(0, 0, 0, .55);
}
.content-card__play::after {
	content: "";
	position: absolute;
	top: 50%; left: 54%;
	transform: translate(-50%, -50%);
	border-style: solid;
	border-width: 9px 0 9px 15px;
	border-color: transparent transparent transparent #fff;
}

/* ----------------------------------------------------------------- contact */

/* auto-fill, not auto-fit: with two contacts, auto-fit collapses the empty
   tracks and stretches the real ones to 683px each, which is a business card
   the width of a paragraph. Every other grid in this file uses auto-fill for
   the same reason. */
.contact-list {
	list-style: none;
	margin: 1.5rem 0 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: var(--usp-gap);
}
.contact-card {
	padding: 1.1rem 1.2rem;
	background: #fff;
	border-top-left-radius: 15px;
	border-bottom-right-radius: 15px;
	box-shadow: 0 1px 4px rgba(0, 0, 0, .12);
}
.contact-card__name {
	margin: 0 0 .15rem;
	font-family: var(--usp-font-title);
	font-size: 1.25rem;
	color: var(--usp-heading);
}
.contact-card__role { margin: 0 0 .5rem; font-size: .88rem; color: var(--usp-orange-text); }
.contact-card__line { margin: 0 0 .15rem; font-size: .92rem; color: var(--usp-muted); }
/* The mailto link was 17px tall. It passes WCAG 2.2 on the spacing exception --
   nothing else is tappable within 24px of it -- but an email address is the one
   thing anyone comes to this page to tap, so it gets a real target anyway. */
.contact-card__line a { display: inline-block; padding: 4px 0; }
.contact-address { font-style: normal; color: var(--usp-muted); }

@media (max-width: 767px) {
	/* Chip rows scroll sideways instead of wrapping to four lines and pushing
	   the results themselves off the screen. */
	.filters__row {
		flex-wrap: nowrap;
		overflow-x: auto;
		padding-bottom: .3rem;
		-webkit-overflow-scrolling: touch;
	}
	.filters__form { flex-direction: column; align-items: stretch; }
	.filters__field select { width: 100%; }
}

/* --------------------------------------------------------------- sections
   fonts · tokens · base · header · layout · sidebar · person card · profile
   research identity · chips · filters · feed cards · contact
   content cards · documents · buttons · content · pagination · carousel
   footer · responsive
   ------------------------------------------------------------------------ */
