/* ==========================================================================
   CUSTOMIZE HERE — every color the site uses is defined in this block.
   This file is shared by ALL pages: change a value here once, save,
   re-upload this one file, and the whole site updates.
   ========================================================================== */
:root {
  --celeste:   #5FA8C4;  /* lake blue — weave + light accents */
  --azul:      #20607A;  /* header background — deep lake blue    */
  --azul-deep: #194C61;  /* nav bar — darker step of the same blue   */
  --paper:     #F8F7F2;  /* page background — warm cream             */
  --ink:       #26241F;  /* body text                                */
  --muted:     #6E675C;  /* secondary text                           */
  --marigold:  #C99A2E;  /* accent — weave, hover, decoration        */
  --label:     #7C6014;  /* section labels & dates — darker gold so
                            small text stays readable (WCAG AA)      */
  --cochineal: #A03B32;  /* stripe color 2 — deep red                */
  --indigo:    #2C4770;  /* stripe color 3 — textile blue            */
  --border:    #DFDDD2;  /* hairline rules                           */
  --card:      #FFFFFF;  /* service card background                  */
  --link:      #20607A;  /* links, h3 headings, tag chips            */
  --thread: linear-gradient(90deg,
    #D6336C 0 14%, #E8A422 0 27%, #2E5FA3 0 38%, #C93A2E 0 49%,
    #1FA37C 0 61%, #F5F1E6 0 66%, #7B4FA6 0 76%, #E06B1F 0 87%,
    #5FA8C4 0 100%);  /* one strand of the woven band */
  --thread-px: repeating-linear-gradient(90deg,
    #D6336C 0 14px, #E8A422 14px 26px, #2E5FA3 26px 37px, #C93A2E 37px 48px,
    #1FA37C 48px 60px, #F5F1E6 60px 66px, #7B4FA6 66px 76px, #E06B1F 76px 86px,
    #5FA8C4 86px 98px);  /* the same strand at fixed size, for the reading
                            thread: squares are revealed as you read, never
                            stretched */
  /* The dark wash laid over every header photograph so white text on it
     stays readable. Nudge the three numbers toward 1 for a darker wash. */
  --scrim: linear-gradient(180deg,
             rgba(19,62,82,0.78) 0%,
             rgba(19,62,82,0.58) 52%,
             rgba(19,62,82,0.86) 100%);
}
/* Dark happens two ways: the reader's system asks for it, or the reader
   presses the moon in the top-right pill. The pill stores an explicit
   choice as a class on <html> (theme-dark / theme-light), which must win
   over the system either direction — hence the :not() guard inside the
   media query, and the duplicate block after it. KEEP THE TWO TOKEN
   LISTS IDENTICAL when retuning colors. */
@media (prefers-color-scheme: dark) {
  :root:not(.theme-light) {
    color-scheme: dark;
    --paper:  #141A1D;
    --ink:    #E4E8E6;
    --muted:  #A2AFB2;
    --label:  #CBA24A;
    --border: #303D43;
    --card:   #1C2529;
    --link:   #7FB8CE;
  }
}
:root.theme-dark {
  color-scheme: dark;
  --paper:  #141A1D;
  --ink:    #E4E8E6;
  --muted:  #A2AFB2;
  --label:  #CBA24A;
  --border: #303D43;
  --card:   #1C2529;
  --link:   #7FB8CE;
}
:root.theme-light { color-scheme: light; }

/* ==========================================================================
   TYPE — Alegreya, a book face from the Latin American foundry Huerta
   Tipográfica (Buenos Aires). Self-hosted: no outside requests, no
   tracking. Serif for reading, true small caps for labels, the matching
   sans for navigation and captions.
   ========================================================================== */
@font-face {
  font-family: 'Alegreya';
  src: url('fonts/Alegreya.woff2') format('woff2');
  font-weight: 400 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Alegreya';
  src: url('fonts/Alegreya-Italic.woff2') format('woff2');
  font-weight: 400 900; font-style: italic; font-display: swap;
}
@font-face {
  font-family: 'Alegreya SC';
  src: url('fonts/AlegreyaSC-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Alegreya Sans';
  src: url('fonts/AlegreyaSans-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
:root {
  --serif: 'Alegreya', Georgia, 'Times New Roman', serif;
  --caps:  'Alegreya SC', Georgia, serif;
  --sans:  'Alegreya Sans', Arial, Helvetica, sans-serif;
  /* A whisper of paper grain — felt more than seen. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E");
}

/* The woven band: a full faja of thread colors, bright like the real
   thing. Edit the color stops below to retune the cloth. */
.weave {
  height: 8px;
  background:
    repeating-linear-gradient(90deg,
      #D6336C 0 22px,    /* fuchsia    */
      #E8A422 22px 40px, /* marigold   */
      #2E5FA3 40px 56px, /* cobalt     */
      #C93A2E 56px 72px, /* red        */
      #1FA37C 72px 90px, /* quetzal    */
      #F5F1E6 90px 99px, /* white      */
      #7B4FA6 99px 114px,  /* purple   */
      #E06B1F 114px 129px, /* orange   */
      #5FA8C4 129px 147px  /* celeste  */);
}

* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: var(--serif);
  color: var(--ink);
  background-color: var(--paper);
  background-image: var(--grain);
  line-height: 1.62;
  font-size: clamp(1.02rem, 0.97rem + 0.3vw, 1.12rem);
  /* Keeps the footer at the bottom of the window on short pages
     (Contact, CV) instead of leaving a band of empty paper below it. */
  display: flex; flex-direction: column; min-height: 100vh;
}
main { flex: 1 0 auto; }

/* Keyboard access: a visible focus ring, and a skip link for screen
   reader and keyboard users (invisible until focused). */
a:focus-visible, button:focus-visible {
  outline: 2px solid var(--marigold); outline-offset: 2px; border-radius: 2px;
}
nav a:focus-visible, .lang-switch button:focus-visible,
.thm-btn:focus-visible, .srch-btn:focus-visible { outline-color: #F0CE7E; }
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--azul); color: #fff; text-decoration: none;
  font-family: var(--sans); font-size: 0.9rem; padding: 10px 18px;
  border-radius: 0 0 6px 0;
}
.skip:focus { left: 0; }
/* The language buttons and the search magnifier live in a quiet pill at
   the page's top right, over the header photograph, and scroll away with
   it. body is the positioning context: the top of body is the top of the
   header on every page. */
.utils {
  position: absolute; top: 10px; right: 12px; z-index: 30;
  display: flex; align-items: center; gap: 4px;
  /* Opaque on purpose. While this pill was translucent, the contrast of
     the EN/ES lettering depended on whichever part of the photograph
     happened to sit behind it — measured as low as 2.7:1, below the
     standard this site publishes about itself. A solid ground makes the
     contrast the same everywhere: 9.5:1 for the resting button, 8.1:1
     for the pressed one. */
  background: #123243; border-radius: 8px; padding: 4px 6px;
}
body { position: relative; }
@media print { .utils { display: none !important; } }
/* Standalone links (the email address in footers and on the contact card)
   get a taller invisible hit area — 17px of text alone is a hard target on
   a phone. Vertical padding on an inline link paints outside the line box,
   so nothing moves visually. */
a.eml, footer .fmail a { padding-block: 8px; }

/* Text for screen readers only: present in the page, invisible on it. */
.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* A real photograph (Volcán de Agua over Antigua, taken by Josthin) sits
   behind the hero, under a solid scrim so the white text keeps full
   contrast at every viewport width — the photo reads as mood and
   texture, not as something the text has to compete with. */
header.site {
  background-color: var(--azul);
  background-image:
    linear-gradient(175deg, rgba(20,66,86,0.87) 0%, rgba(20,66,86,0.74) 100%),
    url('img/hero-antigua.jpg?v=2');
  /* AVIF first: about a fifth smaller than the JPEG at the same look. A
     browser that cannot decode image-set(), or the avif inside it, falls
     back to the plain url() line above — nothing here needs JavaScript. */
  background-image:
    linear-gradient(175deg, rgba(20,66,86,0.87) 0%, rgba(20,66,86,0.74) 100%),
    image-set(url('img/hero-antigua.avif?v=1') type('image/avif'), url('img/hero-antigua.jpg?v=2') type('image/jpeg'));
  background-size: cover;
  background-position: center 30%;
  background-repeat: no-repeat;
  color: #fff; padding: clamp(36px, 6vw, 64px) 24px;
}
.hero {
  max-width: 880px; margin: 0 auto;
  display: grid; grid-template-columns: 1fr auto; gap: clamp(20px, 4vw, 48px);
  align-items: center;
}
.hero h1 {
  display: inline-block;
  background-image: var(--thread);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 4px;
  padding-bottom: 10px;
  margin: 0 0 10px;
  font-size: clamp(1.9rem, 1.4rem + 2.4vw, 2.7rem);
  letter-spacing: 0.01em; font-weight: 500; line-height: 1.15;
  text-shadow: 0 1px 4px rgba(0,0,0,0.35);
}
.hero .role { margin: 0 0 4px; color: #E4EFF8; font-size: 1.02rem; text-shadow: 0 1px 3px rgba(0,0,0,0.3); }
.hero .line {
  margin: 14px 0 0; color: #EAF3FA; font-size: 0.98rem; font-style: italic;
  max-width: 46ch; text-shadow: 0 1px 3px rgba(0,0,0,0.3);
}
/* A simple frame: one hairline in marigold, a touch of white behind it. */
.hero img {
  inline-size: clamp(150px, 22vw, 210px); block-size: auto; aspect-ratio: 1;
  /* A tall photo is cropped to a square focused near the top, so a
     standing portrait lands as head and shoulders. Nudge the second
     number down (25%, 30%) if a future photo sits too high. */
  object-fit: cover; object-position: 50% 20%; display: block;
  border: 3px solid var(--marigold);
  outline: 1px solid rgba(255,255,255,0.55);
  outline-offset: -6px;
  box-shadow: 0 10px 28px rgba(0,0,0,0.28);
}
nav {
  background: var(--azul-deep);
  display: flex; justify-content: center; align-items: center;
  flex-wrap: wrap; gap: 4px; padding: 4px;
}
nav a {
  color: #EAF2F9; text-decoration: none;
  font-family: var(--sans);
  font-size: 0.84rem; letter-spacing: 0.07em; text-transform: uppercase;
  padding: 12px 16px; border-bottom: 2px solid transparent;
}
nav a:hover { border-bottom-color: var(--marigold); }
nav a[aria-current="page"] { border-bottom-color: var(--marigold); color: #fff; }

main { max-width: 800px; margin: 0 auto; padding: 0 24px; }
section { padding: 48px 0; border-bottom: 1px solid var(--border); scroll-margin-top: 16px; }
section:last-of-type { border-bottom: none; }
h2 {
  font-family: var(--caps); font-weight: 500;
  font-size: 1.05rem; letter-spacing: 0.09em;
  color: var(--label); margin: 0 0 20px; padding-bottom: 8px;
  display: inline-block;
  background-image: var(--thread);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 3px;
}
h3 { font-family: var(--serif); font-size: 1.2rem; font-weight: 700; margin: 24px 0 4px; color: var(--link); }
/* An h2 dressed as an h3, for sections whose first heading sits directly
   under the page title — keeps the document outline h1 > h2 with no jumps,
   which is what campus accessibility checkers look for. */
h2.hh3 {
  font-family: var(--serif); font-size: 1.2rem; font-weight: 700;
  margin: 24px 0 4px; color: var(--link); letter-spacing: normal;
  border: none; padding: 0; display: block; text-transform: none;
  background-image: none;   /* it plays an h3, so no thread under it */
}
.meta { font-family: var(--sans); font-size: 0.87rem; color: var(--muted); margin: 0 0 8px; }
p { margin: 0 0 16px; }
ul.plain { padding-left: 20px; margin: 0 0 16px; }
ul.plain li { margin-bottom: 10px; }
a { color: var(--link); }
a:hover { color: var(--marigold); }
.btn {
  display: inline-block; font-family: var(--sans);
  font-size: 0.9rem; letter-spacing: 0.04em;
  background: var(--azul); color: #fff !important;
  padding: 12px 22px; border-radius: 3px; text-decoration: none; margin-top: 8px;
}
.btn:hover { background: var(--marigold); }
.pub { margin-bottom: 18px; padding-bottom: 18px; border-bottom: 1px solid var(--border); }
.pub:last-child { border-bottom: none; }
.svc {
  margin-bottom: 16px; padding: 18px 20px;
  background: var(--card); border: 1px solid var(--border);
  border-left: 3px solid var(--azul); border-radius: 0 6px 6px 0;
}
.svc h3, .svc h2.hh3 { margin-top: 0; }
.svc p { margin-bottom: 0; }
.tag {
  display: inline-block; font-family: var(--sans);
  font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--link); background: color-mix(in srgb, var(--azul) 10%, var(--paper));
  padding: 2px 8px; border-radius: 10px; margin-bottom: 6px;
}
/* The foot of the page is a solid block, not a stripe floating in space:
   the woven band caps it, and the block below carries the name, the
   address, and the fine print. This bookends the photo header at the top. */
footer {
  background: var(--azul-deep); color: #D3E4EE;
  text-align: center; font-family: var(--sans);
}
footer .foot-in { padding: 36px 24px 42px; }
footer .fname {
  margin: 0 0 4px; font-family: var(--serif); font-size: 1.3rem;
  color: #fff; letter-spacing: 0.01em;
}
footer .frole { margin: 0 0 14px; font-size: 0.83rem; color: #AECBDA; }
footer .fmail { margin: 0 0 18px; font-size: 0.92rem; }
footer .fmail a {
  color: #F0CE7E; text-decoration: none;
  border-bottom: 1px solid rgba(240,206,126,0.45); padding-bottom: 1px;
}
footer .fmail a:hover { color: #fff; border-bottom-color: #fff; }
footer .fine { margin: 0; font-size: 0.77rem; color: #A9C6D6; }
footer .fine a { color: #A9C6D6; }
footer .fine a:hover { color: #F0CE7E; }
/* The flags in the footer are the language buttons a second time — and a
   statement: the Spanish here is carried by the flag of Guatemala, not
   Mexico's and not Spain's. The Guatemalan flag is the official civil
   triband (the version flown without the coat of arms). */
footer .flags { margin: 0 0 18px; display: flex; justify-content: center; align-items: center; gap: 12px; }
.foot-cat .flags { margin-top: 4px; }
button.flag { background: none; border: 0; padding: 5px; cursor: pointer; line-height: 0; border-radius: 4px; }
button.flag svg { display: block; border-radius: 2px; outline: 1px solid rgba(255,255,255,0.4); opacity: 0.82; transition: opacity 0.2s, translate 0.2s; }
button.flag:hover svg { opacity: 1; translate: 0 -1px; }
button.flag[aria-pressed="true"] svg { opacity: 1; outline: 2px solid var(--marigold); }
footer .ig-row { margin: 0 0 16px; }
footer a.ig { color: #A9C6D6; display: inline-block; padding: 6px; border-radius: 4px; }
footer a.ig:hover { color: #F0CE7E; }
@media print { footer .flags, footer .ig-row { display: none; } }
@media (prefers-reduced-motion: reduce) { button.flag svg { transition: none; } button.flag:hover svg { translate: none; } }
.contact-row { font-family: var(--sans); font-size: 0.98rem; }

/* ==========================================================================
   THE PHOTOGRAPHS ON THE CONTACT PAGE — six of your own pictures fading one
   into the next. There is no JavaScript here; it is a plain CSS animation,
   so nothing can fail to load and leave the page broken.

   THE TIMING: six photos, seven seconds each, so one full turn is 42s. If
   you add or remove a photo, change 42s below to (number of photos x 7),
   and give each new photo its own delay, seven seconds apart.

   A reader whose system asks for reduced motion sees the first photo only,
   held still — that setting is usually on for a reason.
   ========================================================================== */
/* On the Contact page the whole space between header and footer is the
   photographs — Guatemala, and days in the archives — changing one after
   another, with the contact card resting on top.

   THE TIMING: eight photos, seven seconds each, so one full turn is 56s.
   If you add or remove a photo in contact.html, change 56s below to
   (number of photos x 7) and give each its own delay, seven seconds apart.

   A reader whose system asks for reduced motion sees the first photo only,
   held still — that setting is usually on for a reason. */
.page-contact main { max-width: none; padding: 0; margin: 0; }
.page-contact .contact-stage { border-bottom: none; }
.contact-stage {
  position: relative; overflow: hidden;
  min-height: max(76vh, 540px);
  display: grid; place-items: center;
  padding: clamp(40px, 7vw, 88px) 20px;
  background: var(--azul);   /* holds the space while photos load */
}
.stage-bg, .stage-bg div { position: absolute; inset: 0; }
/* The photographs are named here rather than in the page, so a phone can be
   given smaller copies. Inline styles cannot be media-queried; these can. */
.stage-bg .s1 { background-image: url('img/slide-1.jpg?v=3'); background-image: image-set(url('img/slide-1.avif?v=1') type('image/avif'), url('img/slide-1.jpg?v=3') type('image/jpeg')); }
.stage-bg .s2 { background-image: url('img/slide-2.jpg?v=3'); background-image: image-set(url('img/slide-2.avif?v=1') type('image/avif'), url('img/slide-2.jpg?v=3') type('image/jpeg')); }
.stage-bg .s3 { background-image: url('img/slide-3.jpg?v=3'); background-image: image-set(url('img/slide-3.avif?v=1') type('image/avif'), url('img/slide-3.jpg?v=3') type('image/jpeg')); }
.stage-bg .s4 { background-image: url('img/slide-4.jpg?v=3'); background-image: image-set(url('img/slide-4.avif?v=1') type('image/avif'), url('img/slide-4.jpg?v=3') type('image/jpeg')); }
.stage-bg .s5 { background-image: url('img/slide-5.jpg?v=3'); background-image: image-set(url('img/slide-5.avif?v=1') type('image/avif'), url('img/slide-5.jpg?v=3') type('image/jpeg')); }
.stage-bg .s6 { background-image: url('img/slide-6.jpg?v=3'); background-image: image-set(url('img/slide-6.avif?v=1') type('image/avif'), url('img/slide-6.jpg?v=3') type('image/jpeg')); }
.stage-bg .s7 { background-image: url('img/slide-7.jpg?v=3'); background-image: image-set(url('img/slide-7.avif?v=1') type('image/avif'), url('img/slide-7.jpg?v=3') type('image/jpeg')); }
.stage-bg .s8 { background-image: url('img/slide-8.jpg?v=3'); background-image: image-set(url('img/slide-8.avif?v=1') type('image/avif'), url('img/slide-8.jpg?v=3') type('image/jpeg')); }
.stage-bg div {
  background-size: cover; background-position: center;
  opacity: 0; animation: stagefade 56s linear infinite;
}
.stage-bg div:nth-child(2) { animation-delay:  7s; }
.stage-bg div:nth-child(3) { animation-delay: 14s; }
.stage-bg div:nth-child(4) { animation-delay: 21s; }
.stage-bg div:nth-child(5) { animation-delay: 28s; }
.stage-bg div:nth-child(6) { animation-delay: 35s; }
.stage-bg div:nth-child(7) { animation-delay: 42s; }
.stage-bg div:nth-child(8) { animation-delay: 49s; }
@keyframes stagefade {
  0%     { opacity: 0 }
  1.8%   { opacity: 1 }   /* a one-second fade in  */
  12.5%  { opacity: 1 }   /* held for six seconds  */
  14.3%  { opacity: 0 }   /* a one-second fade out */
  100%   { opacity: 0 }
}
@media (prefers-reduced-motion: reduce) {
  .stage-bg div { animation: none; }
  .stage-bg div:first-child { opacity: 1; }
}
/* The card is deliberately small: it carries the address and gets out of
   the way, so the photograph behind it is the thing you actually look at.
   Where the browser can blur what is behind it, the card goes much more
   transparent and the photo reads straight through it. */
.stage-card {
  position: relative; z-index: 1;
  max-width: 27rem; text-align: center;
  background: rgba(14, 45, 61, 0.86); color: #fff;
  padding: clamp(24px, 3.4vw, 34px) clamp(22px, 3.4vw, 38px);
  border-radius: 8px;
  border: 1px solid rgba(255,255,255,0.16);
  box-shadow: 0 18px 50px rgba(0,0,0,0.38);
}
@supports ((backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px))) {
  .stage-card {
    background: rgba(14, 45, 61, 0.56);
    -webkit-backdrop-filter: blur(8px) saturate(1.08);
    backdrop-filter: blur(8px) saturate(1.08);
  }
}
.stage-card p:last-child { margin-bottom: 0; }
.stage-card p { color: #fff; }
.stage-card a { color: #F0CE7E; }

/* The copy button beside the address on the Contact card: quiet until it
   earns its two seconds of marigold. */
button.cpy {
  font-family: var(--sans); font-size: 0.78rem; letter-spacing: 0.04em;
  background: rgba(255,255,255,0.12); color: #fff;
  border: 1px solid rgba(255,255,255,0.45); border-radius: 4px;
  padding: 4px 9px; margin-left: 8px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px; vertical-align: 2px;
}
button.cpy:hover { border-color: var(--marigold); }
button.cpy.did { border-color: var(--marigold); color: #F0CE7E; }
button.cpy [hidden] { display: none; }
.stage-card a:hover { color: #fff; }
/* Anastasia herself, in colour — the one place on the site she is not a
   silhouette. She IS the Contact page's footer: that page gives the address
   twice over on the card above it, so repeating it down here would just be
   the same words a third time. Her picture and the question take its place,
   with only the fine print kept underneath. */
.foot-cat .foot-in { padding: 30px 24px 34px; }
.hunt {
  margin: 0 auto 20px; max-width: 34rem;
  display: grid; grid-template-columns: 168px 1fr;
  gap: 22px; align-items: center;
}
/* Her three portraits take turns, six seconds each — one full turn is 18s.
   If you add or remove one, change 18s to (number of pictures x 6) and give
   each its own delay, six seconds apart. Only ever one of her is on screen. */
.hunt-pics {
  position: relative; aspect-ratio: 1; border-radius: 5px; overflow: hidden;
  border: 2px solid rgba(255,255,255,0.8); background: var(--azul);
  box-shadow: 0 10px 26px rgba(0,0,0,0.35);
}
.hunt-pics div {
  position: absolute; inset: 0; opacity: 0;
  background-size: cover; background-position: center;
  animation: huntfade 18s linear infinite;
}
.hunt-pics div:nth-child(2) { animation-delay:  6s; }
.hunt-pics div:nth-child(3) { animation-delay: 12s; }
@keyframes huntfade {
  0%    { opacity: 0 }
  3.3%  { opacity: 1 }   /* a modest fade in   */
  30%   { opacity: 1 }   /* held for five      */
  33.3% { opacity: 0 }   /* and out again      */
  100%  { opacity: 0 }
}
@media (prefers-reduced-motion: reduce) {
  .hunt-pics div { animation: none; }
  .hunt-pics div:first-child { opacity: 1; }
}
.hunt figcaption {
  font-family: var(--sans); font-size: 0.9rem; font-style: italic;
  color: #CFE2EC; text-align: left;
}
@media (max-width: 560px) {
  .hunt { grid-template-columns: 1fr; gap: 14px; max-width: 20rem; }
  .hunt figcaption { text-align: center; }
}
@media print { .hunt { display: none; } }
@media print {
  .stage-bg { display: none; }
  .contact-stage { display: block; min-height: 0; padding: 0; background: #fff; }
  .stage-card {
    background: none; color: #000; box-shadow: none;
    text-align: left; padding: 0; max-width: none;
  }
  .stage-card p, .stage-card a { color: #000; }
  .cat-hunt { display: none; }
}
@media (max-width: 620px) {
  .hero { grid-template-columns: 1fr; text-align: center; }
  .hero img { margin: 0 auto; order: -1; }
  .hero .line { margin-inline: auto; }
  nav a { padding: 10px 10px; font-size: 0.76rem; }
}

/* ==========================================================================
   INSIDE-PAGE HEADERS — each page opens on a band of one of Josthin's own
   photographs of Guatemala, with the page's title set on it. The scrim
   below is a single dark wash that every banner shares, so the white text
   keeps its contrast no matter which photo sits underneath. Raise the
   numbers toward 1 to darken the wash; lower them to let more photo through.
   To swap a page's photo, drop a new file in assets/img/ and change the
   file name in the matching line further down.
   ========================================================================== */
header.compact {
  background-color: var(--azul);
  background-size: cover;
  background-position: center 52%;
  background-repeat: no-repeat;
  color: #fff; text-align: center;
  padding: clamp(30px, 5.5vw, 54px) 24px clamp(28px, 4.5vw, 46px);
}
header.compact a.name {
  color: #fff; text-decoration: none; font-family: var(--serif);
  font-size: 1.1rem; letter-spacing: 0.02em;
  text-shadow: 0 1px 4px rgba(0,0,0,0.45);
}
header.compact a.name:hover { color: #F0CE7E; }
header.compact p {
  margin: 3px 0 0; color: #E7F1F8; font-size: 0.83rem;
  font-family: var(--sans); text-shadow: 0 1px 3px rgba(0,0,0,0.4);
}
header.compact h1 {
  margin: 18px 0 0; font-family: var(--serif); font-weight: 500;
  font-size: clamp(1.75rem, 1.3rem + 2vw, 2.4rem);
  line-height: 1.14; letter-spacing: 0.01em;
  text-shadow: 0 2px 8px rgba(0,0,0,0.5);
}
/* The short gold rule under the title echoes the one under each section
   heading further down the page. */
header.compact h1::after {
  content: ""; display: block; width: 84px; height: 3px;
  background: var(--thread); border-radius: 2px; margin: 14px auto 0;
}

/* ==========================================================================
   THE CATS — traced from your own drawings of your own cat. Nothing here
   comes from the museum piece; that stayed reference only.

   THE BALANCE: every page has exactly ONE cat, and no two pages put her in
   the same place. She moves around the site as you click through it —

     About          along the footer band, and she vanishes when you switch
                    between light and dark mode (the trick, below)
     Research       up on the banner band, right
     Teaching       down on the footer band, left
     Publications   up on the banner band, left
     Notes          up on the banner band, left
     Services       up on the banner band, left, facing the other way
     CV             sitting on the footer band, right
     Contact        not a silhouette at all — three drawings of her in
                    full colour, in the footer
     404            sitting on top of the numerals, as if on a shelf

   Three poses do all of this — lying, sitting, and clinging — every one of
   them traced from Josthin's own drawings of Anastasia, and some mirrored
   so she faces into the page instead of off the edge. Cats drawn from
   scratch were tried and thrown out: next to her real outlines they read
   as clip art. Each is
   resting on, or gripping, something: she reads as being ON the page
   rather than stuck to it. Never two cats on one screen — that was the
   clutter. A hanging cat was tried three ways — her own clinging outline,
   and two drawn from scratch — and none of them resolved into a cat at
   the size a corner allows, so the idea was dropped rather than shipped
   as a blob.
   ========================================================================== */
.weave { position: relative; }

/* --- up on the banner band: a dark silhouette against the photograph --- */
header.compact[data-banner="research"]     + .weave::after,
header.compact[data-banner="notes"]        + .weave::after,
header.compact[data-banner="teaching"]     + .weave::after,
header.compact[data-banner="publications"] + .weave::after,
header.compact[data-banner="services"]     + .weave::after {
  content: ""; position: absolute; bottom: 0; pointer-events: none;
  background-repeat: no-repeat; background-size: contain;
  background-position: bottom center; opacity: 0.86;
}
header.compact[data-banner="research"] + .weave::after {      /* lying, right */
  right: 6%; width: 104px; height: 39px;
  background-image: url('img/cat-lounge.svg');
}
header.compact[data-banner="publications"] + .weave::after {  /* sitting, left */
  left: 6%; width: 42px; height: 59px;
  background-image: url('img/cat-sit.svg');
}
header.compact[data-banner="notes"] + .weave::after {         /* lying, left */
  left: 6%; width: 104px; height: 39px;
  background-image: url('img/cat-lounge.svg');
}
header.compact[data-banner="services"] + .weave::after {      /* sitting, mirrored, right */
  right: 7%; width: 42px; height: 59px;
  background-image: url('img/cat-sit.svg'); transform: scaleX(-1);
}
/* Teaching's cat is in its footer instead — see below — so its banner
   carries none. The rule above just gives the four banners one shape. */
header.compact[data-banner="teaching"] + .weave::after { display: none; }

/* --- down on the footer band: painted in the reading colour, so she shows
       on cream and on near-black alike --- */
.page-teaching footer > .weave::after,
.page-recursos footer > .weave::after,
.page-cv       footer > .weave::after {
  content: ""; position: absolute; bottom: 0; pointer-events: none;
  background-color: var(--ink); opacity: 0.85;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-position: bottom center; mask-position: bottom center;
}
.page-teaching footer > .weave::after {   /* lying, left, mirrored */
  left: 5%; width: 104px; height: 39px;
  -webkit-mask-image: url('img/cat-lounge.svg'); mask-image: url('img/cat-lounge.svg');
  transform: scaleX(-1);
}
.page-recursos footer > .weave::after {   /* sitting, left, mirrored */
  left: 6%; width: 42px; height: 59px;
  -webkit-mask-image: url('img/cat-sit.svg'); mask-image: url('img/cat-sit.svg');
  transform: scaleX(-1);
}
.page-cv footer > .weave::after {         /* sitting, right */
  right: 6%; width: 42px; height: 59px;
  -webkit-mask-image: url('img/cat-sit.svg'); mask-image: url('img/cat-sit.svg');
}

/* Each silhouette is also a real link to the Contact page, where she
   appears in colour — an invisible anchor drawn exactly over the cat, with
   its own screen-reader text and focus ring, so the easter egg is playable
   by keyboard and legible to assistive tech. She stirs when found. The
   home-page pair stays linkless: vanishing is its whole job. */
.weave a.gato { position: absolute; display: block; z-index: 2; }
.weave a.gato:focus-visible {
  outline: 2px solid var(--marigold); outline-offset: 4px; border-radius: 6px;
}
header.compact[data-banner="research"]     + .weave a.gato { right: 6%; bottom: 0; width: 104px; height: 39px; }
header.compact[data-banner="notes"]        + .weave a.gato { left: 6%;  bottom: 0; width: 104px; height: 39px; }
header.compact[data-banner="publications"] + .weave a.gato { left: 6%;  bottom: 0; width: 42px;  height: 59px; }
header.compact[data-banner="services"]     + .weave a.gato { right: 7%; bottom: 0; width: 42px;  height: 59px; }
.page-teaching footer .weave a.gato { left: 5%;  bottom: 0; width: 104px; height: 39px; }
.page-recursos footer .weave a.gato { left: 6%;  bottom: 0; width: 42px;  height: 59px; }
.page-cv       footer .weave a.gato { right: 6%; bottom: 0; width: 42px;  height: 59px; }
header.compact + .weave::after, footer > .weave::after { transition: translate 0.35s ease; }
.weave:has(a.gato:hover)::after,
.weave:has(a.gato:focus-visible)::after { translate: 0 -3px; }
@media (prefers-reduced-motion: reduce) {
  header.compact + .weave::after, footer > .weave::after { transition: none; }
  .weave:has(a.gato:hover)::after,
  .weave:has(a.gato:focus-visible)::after { translate: none; }
}
@media print { .weave a.gato { display: none; } }

/* --- the home page, and the trick --- */
/* She is drawn twice on the footer band, once at each end: the left one in
   DARK mode's paper colour, the right one in LIGHT mode's. Whichever mode
   the reader is in, one of them exactly matches the paper behind it and
   disappears — so only ever one cat is there, and flipping the mode moves
   her across. Spanish moves her too. (If you ever retune --paper at the top
   of this file, repaint these two, or the hidden one stops hiding.) */
.page-home footer > .weave::before,
.page-home footer > .weave::after {
  content: ""; position: absolute; pointer-events: none; bottom: 0;
  width: 104px; height: 39px;
  -webkit-mask-image: url('img/cat-lounge.svg'); mask-image: url('img/cat-lounge.svg');
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-position: bottom center; mask-position: bottom center;
}
.page-home footer > .weave::before { left: 5%;  background-color: #141A1D; }
.page-home footer > .weave::after  { right: 5%; background-color: #F8F7F2;
                                     transform: scaleX(-1); }
.lang-es .page-home footer > .weave::before { background-color: #F8F7F2; }
.lang-es .page-home footer > .weave::after  { background-color: #141A1D; }

@media (max-width: 760px) { header.compact + .weave::after, header.compact + .weave a.gato { display: none; } }
@media print {
  header.compact + .weave::after, footer > .weave::before,
  footer > .weave::after { display: none; }
}

/* Which photograph opens which page. */
header.compact[data-banner="research"]     { background-image: var(--scrim), url('img/banner-research.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-research.avif?v=1') type('image/avif'), url('img/banner-research.jpg?v=2') type('image/jpeg')); }
header.compact[data-banner="teaching"]     { background-image: var(--scrim), url('img/banner-teaching.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-teaching.avif?v=1') type('image/avif'), url('img/banner-teaching.jpg?v=2') type('image/jpeg')); }
header.compact[data-banner="publications"] { background-image: var(--scrim), url('img/banner-publications.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-publications.avif?v=1') type('image/avif'), url('img/banner-publications.jpg?v=2') type('image/jpeg')); background-position: center 14%; }
header.compact[data-banner="notes"]        { background-image: var(--scrim), url('img/banner-notes.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-notes.avif?v=1') type('image/avif'), url('img/banner-notes.jpg?v=2') type('image/jpeg')); }
header.compact[data-banner="services"]     { background-image: var(--scrim), url('img/banner-services.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-services.avif?v=1') type('image/avif'), url('img/banner-services.jpg?v=2') type('image/jpeg')); }
header.compact[data-banner="cv"]           { background-image: var(--scrim), url('img/banner-cv.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-cv.avif?v=1') type('image/avif'), url('img/banner-cv.jpg?v=2') type('image/jpeg')); }
header.compact[data-banner="contact"]      { background-image: var(--scrim), url('img/banner-contact.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-contact.avif?v=1') type('image/avif'), url('img/banner-contact.jpg?v=2') type('image/jpeg')); }
header.compact[data-banner="notfound"]     { background-image: var(--scrim), url('img/banner-notfound.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-notfound.avif?v=1') type('image/avif'), url('img/banner-notfound.jpg?v=2') type('image/jpeg')); }
header.compact[data-banner="recursos"]     { background-image: var(--scrim), url('img/banner-recursos.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-recursos.avif?v=1') type('image/avif'), url('img/banner-recursos.jpg?v=2') type('image/jpeg')); }

/* ==========================================================================
   LANGUAGES — how the EN / ES / K'iche' toggle works.
   Content is written side by side in the pages: elements marked
   data-lang="en" and data-lang="es" (and, where they exist, data-lang="quc").
   The <html> tag carries a class (lang-en, lang-es, lang-quc) that decides
   which set is visible. English is the default when JavaScript is off.
   In K'iche' mode, Spanish text is shown wherever a K'iche' version
   does not exist yet, plus the K'iche' notice at the top of each page.
   ========================================================================== */
[data-lang] { display: none; }
html.lang-en  [data-lang="en"]  { display: revert; }
html.lang-es  [data-lang="es"]  { display: revert; }

.lang-switch { display: flex; gap: 3px; align-items: center; padding: 0 6px; }
.lang-switch button {
  font-family: var(--sans);
  font-size: 0.73rem; letter-spacing: 0.06em; text-transform: uppercase;
  background: transparent; color: #C9DCEC;
  border: 1px solid rgba(255,255,255,0.35); border-radius: 3px;
  padding: 5px 9px; cursor: pointer;
}
.lang-switch button:hover { border-color: var(--marigold); color: #fff; }
.lang-switch button[aria-pressed="true"] {
  background: rgba(255,255,255,0.16); color: #fff; border-color: var(--marigold);
}

/* ==========================================================================
   TIMELINE — the 1944–1954 list on the Research page.
   ========================================================================== */
ul.timeline { list-style: none; margin: 18px 0 0; padding: 0; position: relative; }
ul.timeline::before {
  content: ""; position: absolute; left: 6px; top: 8px; bottom: 8px;
  width: 2px; background: var(--border);
}
ul.timeline li { position: relative; padding: 0 0 22px 32px; margin: 0; }
ul.timeline li:last-child { padding-bottom: 4px; }
ul.timeline li::before {
  content: ""; position: absolute; left: 0; top: 7px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--azul); border: 2px solid var(--paper);
}
ul.timeline .when {
  display: block; font-family: var(--caps);
  font-size: 0.92rem; letter-spacing: 0.07em;
  color: var(--label); margin-bottom: 2px;
}
ul.timeline p { margin: 0; }

/* ==========================================================================
   MAP — the inline SVG map of Guatemala on the Research page.
   Colors follow the site palette automatically, in light and dark mode.
   ========================================================================== */
.map-fig { margin: 22px 0 0; }
.map-fig svg { display: block; width: min(100%, 560px); height: auto; margin: 0 auto; }
.map-cap {
  font-family: var(--sans); font-size: 0.84rem; color: var(--muted);
  text-align: center; max-width: 62ch; margin: 12px auto 0;
}
.map-dept { fill: color-mix(in srgb, var(--celeste) 7%, var(--paper)); stroke: var(--border); stroke-width: 0.8; }
.map-dept.hl { fill: color-mix(in srgb, var(--celeste) 30%, var(--paper)); stroke: var(--azul); stroke-width: 1; }
.map-rail { fill: none; stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 5 4; stroke-linecap: round; }
.map-city { fill: var(--cochineal); stroke: var(--paper); stroke-width: 1.5; }
.map-lbl { font-family: var(--sans); font-size: 13px; fill: var(--ink); }
.map-lbl.dept { font-size: 12px; letter-spacing: 0.06em; fill: var(--azul); }
.map-lbl.sea { font-size: 12px; font-style: italic; letter-spacing: 0.14em; fill: var(--muted); }
@media (prefers-color-scheme: dark) { :root:not(.theme-light) .map-lbl.dept { fill: #7FB8CE; } }
:root.theme-dark .map-lbl.dept { fill: #7FB8CE; }

/* ==========================================================================
   CHART — the tribunal caseload figure on the Research page.
   ========================================================================== */
.chart-fig { margin: 22px 0 0; }
.chart-fig svg { display: block; width: min(100%, 560px); height: auto; margin: 0 auto; }
.cbar { fill: var(--celeste); }
.cval { font-family: var(--sans); font-size: 12.5px; fill: var(--ink); text-anchor: middle; }
.cyr  { font-family: var(--sans); font-size: 12px; fill: var(--muted); text-anchor: middle; }
.cax  { stroke: var(--border); stroke-width: 1.5; }

/* The 1947 date in the Research timeline links to this chart. A dotted
   marigold underline marks it as more than a date; hovering it lights the
   bar the Labor Code produced, clicking carries the reader to it. */
.when a.tochart {
  color: inherit; text-decoration: underline dotted var(--marigold);
  text-decoration-thickness: 2px; text-underline-offset: 4px;
  /* Invisible tap height: 22px of text alone is under the 24px WCAG
     minimum. Padding on an inline link paints outside the line box, so
     nothing moves. */
  padding-block: 4px;
}
.when a.tochart:hover { text-decoration-style: solid; }
#filings { scroll-margin-top: 80px; }
.cbar.lit  { fill: var(--marigold); }
.cval.lit  { fill: var(--label); font-weight: 700; }
.cbar.pulse { fill: var(--marigold); }
.cval.pulse { fill: var(--label); font-weight: 700; }
@media (prefers-reduced-motion: no-preference) {
  .cbar.pulse { animation: barpulse 1.1s ease-in-out 2; }
  @keyframes barpulse { 50% { opacity: 0.35; } }
}

/* ==========================================================================
   CASE CORPUS — the browsable database on cases.html.
   ========================================================================== */
.caveat {
  margin: 22px 0 0; padding: 14px 18px;
  background: color-mix(in srgb, var(--marigold) 10%, var(--paper));
  border: 1px solid var(--border); border-left: 3px solid var(--marigold);
  border-radius: 0 6px 6px 0; font-size: 0.95rem;
}
.caveat p { margin: 0; }
.chart-head {
  font-family: var(--caps); font-size: 0.98rem; letter-spacing: 0.07em;
  color: var(--label); margin: 0 0 6px;
}
.hb-lbl { font-family: var(--sans); font-size: 13px; fill: var(--ink); }
.hb-bar { fill: var(--celeste); }
.hb-val { font-family: var(--sans); font-size: 13px; fill: var(--ink); }
.hb-pct { fill: var(--muted); }

.filters {
  display: flex; flex-wrap: wrap; gap: 12px 16px; align-items: end;
  margin: 18px 0 16px;
}
.fld { display: flex; flex-direction: column; gap: 4px;
  font-family: var(--sans); font-size: 0.78rem; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--muted); }
.fld input[type="search"], .fld select {
  font-family: var(--serif); font-size: 0.98rem; text-transform: none;
  letter-spacing: 0; color: var(--ink); background: var(--card);
  border: 1px solid var(--border); border-radius: 4px; padding: 7px 10px;
  min-width: 11rem;
}
.fld.chk { flex-direction: row; align-items: center; gap: 7px; padding-bottom: 8px; }
.fld.chk input { width: 16px; height: 16px; accent-color: var(--azul); }
.clearbtn {
  font-family: var(--sans); font-size: 0.78rem; letter-spacing: 0.05em;
  text-transform: uppercase; cursor: pointer; color: var(--azul);
  background: transparent; border: 1px solid var(--border);
  border-radius: 4px; padding: 8px 14px; margin-bottom: 1px;
}
.clearbtn:hover { border-color: var(--azul); }
.count { font-family: var(--sans); font-size: 0.85rem; color: var(--muted); margin: 0 0 10px; }
.status {
  margin: 18px 0 0; padding: 13px 17px; font-size: 0.95rem;
  background: color-mix(in srgb, var(--marigold) 9%, var(--paper));
  border: 1px solid var(--border); border-left: 3px solid var(--marigold);
  border-radius: 0 6px 6px 0;
}

.tablewrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 6px; }
table.cases { border-collapse: collapse; width: 100%; font-size: 0.93rem; }
table.cases th {
  font-family: var(--sans); font-size: 0.74rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); text-align: left;
  padding: 10px 12px; background: color-mix(in srgb, var(--celeste) 8%, var(--card));
  border-bottom: 1px solid var(--border); position: sticky; top: 0;
}
table.cases td { padding: 9px 12px; border-bottom: 1px solid var(--border); vertical-align: top; }
table.cases tr:last-child td { border-bottom: none; }
table.cases tr:hover td { background: color-mix(in srgb, var(--celeste) 6%, var(--card)); }
table.cases .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
table.cases .dash { color: var(--muted); }
table.cases .empty { text-align: center; color: var(--muted); padding: 26px 12px; }
.wtag {
  display: inline-block; font-family: var(--sans); font-size: 0.66rem;
  letter-spacing: 0.04em; color: var(--cochineal);
  background: color-mix(in srgb, var(--cochineal) 12%, var(--paper));
  border-radius: 8px; padding: 1px 6px; vertical-align: 1px;
}
@media (max-width: 620px) {
  .fld input[type="search"], .fld select { min-width: 0; width: 100%; }
  .fld { flex: 1 1 100%; }
  table.cases { font-size: 0.86rem; }
}

/* ==========================================================================
   NOTES — entries on the Notes page.
   ========================================================================== */
.note { margin: 0 0 30px; padding: 0 0 26px; border-bottom: 1px solid var(--border); }
.note:last-of-type { border-bottom: none; padding-bottom: 0; }
.note h3 { margin-top: 0; }

/* Notes read as a notebook: each entry carries a small gold label saying
   what KIND of note it is, and hangs off a rule down the left. The layout is
   built to look deliberate with one or two entries, not only with twenty. */
.note {
  position: relative; padding: 4px 0 4px 22px; margin: 0 0 40px;
  border-left: 2px solid var(--border);
}
.note:last-child { margin-bottom: 8px; }
.note::before {
  content: ""; position: absolute; left: -5px; top: 12px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--marigold);
}
.note .kind {
  font-family: var(--caps); font-size: 0.78rem; letter-spacing: 0.1em;
  color: var(--label); margin: 0 0 2px;
}
.note h3, .note h2.hh3 { margin: 0 0 2px; font-size: 1.28rem; }
.note .meta { margin: 0 0 12px; }
@media (max-width: 620px) { .note { padding-left: 16px; } }

/* The fields, shown not told: chips under the About text. */
.fields { margin-top: 20px; display: flex; flex-wrap: wrap; gap: 8px; }
.fields .tag { margin-bottom: 0; }

/* The unlisted art page: a plain grid that photographs drop into. */
.art-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 18px; margin-top: 26px;
}
.art-grid figure { margin: 0; }
.art-grid img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--border); border-radius: 3px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.14);
}
.art-grid figcaption {
  font-family: var(--sans); font-size: 0.84rem; color: var(--muted);
  margin-top: 6px;
}

/* Which photograph opens each unlisted page (reusing existing banners). */
header.compact[data-banner="art"]       { background-image: var(--scrim), url('img/banner-notfound.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-notfound.avif?v=1') type('image/avif'), url('img/banner-notfound.jpg?v=2') type('image/jpeg')); }
header.compact[data-banner="portfolio"] { background-image: var(--scrim), url('img/banner-cv.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-cv.avif?v=1') type('image/avif'), url('img/banner-cv.jpg?v=2') type('image/jpeg')); }
header.compact[data-banner="access"]    { background-image: var(--scrim), url('img/banner-teaching.jpg?v=2'); background-image: var(--scrim), image-set(url('img/banner-teaching.avif?v=1') type('image/avif'), url('img/banner-teaching.jpg?v=2') type('image/jpeg')); }

/* ==========================================================================
   THE CV ON THE PAGE — the same record as the PDF, in folding sections.
   All of them stand OPEN when the page loads, so the CV reads top to
   bottom like a document; each heading folds its section away for the
   reader who only wants one part. Native <details>, no JavaScript.
   ========================================================================== */
.cv-list { margin-top: 26px; }
details.cvs { border-bottom: 1px solid var(--border); padding: 4px 0 20px; }
details.cvs:last-child { border-bottom: none; }
details.cvs summary {
  cursor: pointer; list-style: none; display: inline-block;
  font-family: var(--caps); font-weight: 500; font-size: 1.05rem;
  letter-spacing: 0.09em; color: var(--label);
  padding: 16px 0 8px; margin-bottom: 4px;
  background-image: var(--thread); background-repeat: no-repeat;
  background-position: 0 100%; background-size: 100% 3px;
}
details.cvs summary::-webkit-details-marker { display: none; }
details.cvs summary::before {
  content: ""; display: inline-block; width: 9px; height: 10px;
  margin-right: 10px; background: var(--marigold);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  transition: transform 0.22s ease;
}
details.cvs[open] summary::before { transform: rotate(90deg); }
details.cvs summary:hover { color: var(--ink); }
.cvi { margin: 16px 0 0; }
.cvt {
  margin: 0; font-weight: 700;
  display: flex; gap: 14px; justify-content: space-between; align-items: baseline;
}
.cvt .cvd {
  font-family: var(--sans); font-weight: 400; font-size: 0.84rem;
  color: var(--muted); white-space: nowrap;
}
.cvx { margin: 3px 0 0; font-size: 0.94rem; color: var(--muted); }
/* The dissertation abstract on the CV: a paragraph to be read, not a
   caption — full reading color and size, unlike the .cvx notes. */
.cvab { margin: 5px 0 0; max-width: 74ch; }
@media (max-width: 560px) { .cvt { flex-direction: column; gap: 0; } }
@media (prefers-reduced-motion: reduce) { details.cvs summary::before { transition: none; } }
@media print {
  details.cvs summary { color: #000; background: none; border-bottom: 1pt solid #000; }
  details.cvs summary::before { display: none; }
  .cvt .cvd, .cvx { color: #333; }
}

/* ==========================================================================
   404 — the "page not found" page. Anastasia sleeps on top of the numerals
   as if they were a shelf; the cat is painted in the ink color, so she
   shows in light and dark mode alike.
   ========================================================================== */
.oops { text-align: center; padding: 56px 0; }
.oops .code {
  font-family: var(--caps); font-size: 3.2rem; letter-spacing: 0.12em;
  color: var(--label); margin: 0 0 6px;
}
@supports (mask-repeat: no-repeat) or (-webkit-mask-repeat: no-repeat) {
  .oops .code::before {
    content: ""; display: block; width: 150px; height: 59px;
    margin: 0 auto -12px;
    -webkit-mask: url('img/cat-sit.svg') no-repeat bottom center / contain;
    mask: url('img/cat-sit.svg') no-repeat bottom center / contain;
    background-color: var(--ink); opacity: 0.9;
  }
}
.oops .oops-line {
  font-style: italic; font-size: 1.18rem; color: var(--label);
  margin: 0 0 18px;
}
.oops div p { max-width: 46ch; margin-inline: auto; }


/* ==========================================================================
   PRINT — search committees and readers print pages. This strips the
   navigation and backgrounds, keeps the text black on white, and spells
   out where links point.
   ========================================================================== */
@media print {
  nav, .skip, .lang-switch, .weave { display: none !important; }
  body {
    background: #fff !important; color: #000;
    font-size: 11pt; line-height: 1.45;
  }
  header.site, header.compact {
    background: #fff !important; color: #000; text-align: left;
    padding: 0 0 10pt; border-bottom: 1pt solid #999;
  }
  header.site .role, header.site .line, header.compact p { color: #333; }
  header.compact a.name, .hero h1, header.compact h1 { color: #000; text-shadow: none; }
  header.compact h1::after { display: none; }
  main { max-width: none; padding: 0; }
  /* A section taller than a page (the CV) must be allowed to break, or the
     browser pushes it whole onto the next sheet and leaves the first one
     empty. What holds together is each entry; a heading never sits alone
     at the bottom of a page. */
  section { padding: 14pt 0; border-bottom: none; }
  .cvi { break-inside: avoid; }
  details.cvs summary, h2, h3 { break-after: avoid; }
  /* Paper cannot click: the download button and the sentence explaining
     the page's own controls say nothing on it. */
  #cv > p:first-child, a.btn { display: none; }
  h2 { color: #000; border-bottom: 1pt solid #000; }
  h3 { color: #000; }
  a { color: #000; text-decoration: underline; }
  /* Spell out link targets, since a printed page cannot be clicked. */
  main a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #444; }
  .hero img { border: 1pt solid #999; box-shadow: none; }
  .svc, .caveat, .status, .lang-note { border: 1pt solid #999; background: #fff; }
  figure, ul.timeline li, .pub, .note { break-inside: avoid; }
  footer {
    background: #fff !important; border-top: 1pt solid #999;
    color: #333; text-align: left;
  }
  footer .foot-in { padding: 10pt 0 0; }
  footer .fname { color: #000; font-size: 12pt; }
  footer .frole, footer .fine { color: #333; }
  footer .fmail a { color: #000; border: none; }
}


/* ==========================================================================
   MOTION — the site breathes. Everything here is pure CSS, runs on the
   compositor, needs no JavaScript, and obeys three rules: a browser that
   does not understand it shows the plain page; a reader who asks for
   reduced motion gets stillness; nothing moves more than a few pixels.

   1. PAGES MELT INTO EACH OTHER. Cross-document view transitions: clicking
      a nav link crossfades the two pages instead of flashing white. The
      nav bar and footer are pinned by name, so they hold still while the
      content changes under them — the site feels like one continuous
      place, not nine documents.
   2. SECTIONS BREATHE IN as they enter the window, the timeline steps in
      one date at a time, and the chart's bars grow up from their baseline
      when the reader reaches them.
   3. A READING THREAD in marigold fills along the bottom edge of the nav
      as the reader moves down the page — a woven thread being pulled.
   ========================================================================== */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation-duration: 0.20s; }
::view-transition-new(root) { animation-duration: 0.20s; }
nav    { view-transition-name: site-nav; }
footer { view-transition-name: site-foot; }

@media (prefers-reduced-motion: no-preference) {
  /* the first paint of the home page: name and portrait settle into place */
  .hero > div { animation: settle 0.55s ease both; }
  .hero img   { animation: settle 0.55s ease 0.12s both; }

  /* sections and cards breathe in as they enter (a browser without
     scroll-driven animations completes these instantly — same page,
     no motion) */
  main section, .pub, .svc, .note, .timeline li {
    animation: breathe both;
    animation-timeline: view();
    animation-range: entry 0% entry 40%;
  }
  .timeline li { animation-range: entry 0% entry 55%; }

  /* the filings chart: bars grow from the baseline */
  .chart-fig rect {
    transform-box: fill-box; transform-origin: bottom;
    animation: grow both;
    animation-timeline: view();
    animation-range: entry 10% entry 60%;
  }

  /* the threads weave themselves in */
  h2:not(.hh3) { animation: weave both; animation-timeline: view(); animation-range: entry 0% entry 30%; }
  .hero h1 { animation: stitch 0.9s ease 0.25s both; }
  header.compact h1::after { transform-origin: 50% 50%; animation: draw 0.6s ease 0.3s both; }

  /* the hero photograph drifts slightly as the reader scrolls: depth */
  header.site {
    animation: herodepth both;
    animation-timeline: scroll(root);
  }

  /* the reading thread, on the window's own top edge */
  body::after {
    content: ""; position: fixed; top: 0; left: 0; right: 0; z-index: 60;
    height: 3px; background: var(--thread-px); pointer-events: none;
    clip-path: inset(0 100% 0 0);
    animation: thread linear both;
    animation-timeline: scroll(root);
  }
}
@keyframes settle  { from { opacity: 0; transform: translateY(10px); } }
@keyframes breathe { from { opacity: 0.12; transform: translateY(14px); } }
@keyframes grow    { from { transform: scaleY(0.15); } }
@keyframes thread  { to { transform: scaleX(1); } }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none !important; }
}


/* ==========================================================================
   TOUCH — how the page answers the reader's hand. Small, consistent, and
   all of it in the site's own thread: select text and it highlights in
   marigold; rest on a link and the faja weaves in under it; the tab you
   are on wears the thread; cards rise a breath to meet the pointer; the
   portrait gives a small warm tilt. Nothing moves more than three pixels,
   and under prefers-reduced-motion nothing moves at all.
   ========================================================================== */
::selection { background: #C99A2E; color: #26241F; }

/* Links keep their honest underline always (never color alone); on hover
   or keyboard focus the underline gives way to the woven thread. */
main a:not(.btn):not(.gato) {
  background-image: var(--thread);
  background-repeat: no-repeat;
  background-position: 0 calc(100% - 1px);
  background-size: 0% 2px;
  padding-bottom: 2px;
  transition: background-size 0.25s ease, text-decoration-color 0.25s ease;
}
main a:not(.btn):not(.gato):hover,
main a:not(.btn):not(.gato):focus-visible {
  background-size: 100% 2px;
  text-decoration-color: transparent;
}

/* The tab you are on carries the thread. */
nav a[aria-current="page"] {
  border-bottom: 3px solid transparent;
  border-image: var(--thread-px) 1;
}

/* Cards rise a breath. */
.svc { transition: translate 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease; }
.svc:hover {
  translate: 0 -2px;
  border-left-color: var(--marigold);
  box-shadow: 0 8px 20px rgba(0,0,0,0.10);
}
.note { transition: translate 0.22s ease; }
.note:hover { translate: 0 -2px; }
.note:hover::before { background: #D6336C; }

/* The portrait answers. */
.hero img { transition: rotate 0.35s ease, translate 0.35s ease; }
.hero img:hover { rotate: -1.2deg; translate: 0 -3px; }

@media (prefers-reduced-motion: reduce) {
  main a:not(.btn):not(.gato), .svc, .note, .hero img { transition: none; }
  .svc:hover, .note:hover { translate: none; }
  .hero img:hover { rotate: none; translate: none; }
}


/* ==========================================================================
   SEARCH — press / (or Ctrl/Cmd-K), or the magnifier in the nav. A native
   <dialog>: the browser handles focus and Escape. All local: the index is
   built with the site and matching happens in the reader's browser, in the
   language they are reading in.
   ========================================================================== */
.srch-btn {
  background: none; border: 1px solid #5E93AC; border-radius: 3px;
  color: #EAF2F9; cursor: pointer; padding: 6px 9px; line-height: 0;
  margin-left: 4px;
}
.srch-btn:hover { border-color: var(--marigold); color: #fff; }

/* The moon/sun button, same quiet dress as the magnifier. It shows the
   mode you would switch TO: a moon by day, a sun by night. Hidden until
   lang.js wakes it, since without JavaScript it could do nothing. */
.thm-btn {
  background: none; border: 1px solid #5E93AC; border-radius: 3px;
  color: #EAF2F9; cursor: pointer; padding: 6px 9px; line-height: 0;
  margin-left: 4px;
}
.thm-btn:hover { border-color: var(--marigold); color: #fff; }
.thm-btn .sun { display: none; }

/* The speaker beside the name on the home page — dormant until the
   recording exists; see the PRONUNCIATION comment in index.html. */
.say {
  background: none; border: 1.5px solid rgba(255,255,255,0.55); color: #fff;
  border-radius: 50%; width: 34px; height: 34px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  vertical-align: 8px; margin-left: 10px; line-height: 0; padding: 0;
}
.say:hover { border-color: var(--marigold); color: #F0CE7E; }
@media print { .say { display: none; } }
@media (prefers-color-scheme: dark) {
  :root:not(.theme-light) .thm-btn .sun  { display: inline; }
  :root:not(.theme-light) .thm-btn .moon { display: none; }
}
:root.theme-dark .thm-btn .sun  { display: inline; }
:root.theme-dark .thm-btn .moon { display: none; }
dialog.srch {
  border: none; border-radius: 8px; padding: 0;
  width: min(560px, 92vw); background: var(--card); color: var(--ink);
  box-shadow: 0 30px 80px rgba(0,0,0,0.45);
  margin-top: 12vh;
}
dialog.srch::backdrop { background: rgba(12,32,42,0.55); }
.srch-thread { height: 4px; background: var(--thread-px); border-radius: 8px 8px 0 0; }
dialog.srch input {
  width: 100%; border: none; outline: none; background: transparent;
  color: var(--ink); font-family: var(--serif); font-size: 1.1rem;
  padding: 16px 18px; border-bottom: 1px solid var(--border);
}
dialog.srch ul { list-style: none; margin: 0; padding: 0; max-height: 52vh; overflow: auto; }
dialog.srch li a {
  display: block; padding: 11px 18px; text-decoration: none;
  background: none; border-bottom: 1px solid var(--border);
}
dialog.srch li:last-child a { border-bottom: none; }
dialog.srch li a:hover, dialog.srch li a.sel {
  background: color-mix(in srgb, var(--azul) 9%, var(--card));
}
.srch-t { display: block; font-family: var(--serif); font-weight: 700; color: var(--link); }
.srch-w {
  display: block; font-family: var(--caps); font-size: 0.72rem;
  letter-spacing: 0.09em; color: var(--label); margin: 1px 0 3px;
}
.srch-s { display: block; font-family: var(--sans); font-size: 0.84rem; color: var(--muted); }
.srch-s mark { background: var(--marigold); color: #26241F; border-radius: 2px; padding: 0 2px; }
.srch-none { padding: 14px 18px; font-family: var(--sans); font-size: 0.9rem; color: var(--muted); }
.srch-hint {
  margin: 0; padding: 9px 18px; font-family: var(--sans); font-size: 0.74rem;
  color: var(--muted); border-top: 1px solid var(--border);
}
@media print { .srch-btn, dialog.srch { display: none; } }

/* On narrow screens the pill sits where the header text begins, so the
   headers start a little lower there. (This lives at the end of the file
   on purpose: it must come after the headers' base padding to win.) */
@media (max-width: 700px) {
  header.site, header.compact { padding-top: 58px; }
}

/* Nine tabs fit a single row on a tablet by tightening, not wrapping.
   (End of file on purpose: it must outrank the base nav rules.) */
@media (max-width: 1260px) {
  nav a { padding: 10px 9px; font-size: 0.77rem; letter-spacing: 0.035em; }
}


/* Phone-sized photographs. A phone crops these to a tall sliver anyway, so
   the smaller copies look identical there and cost about half the data. */
@media (max-width: 700px) {
  .stage-bg .s1 { background-image: url('img/slide-1-sm.jpg?v=3'); background-image: image-set(url('img/slide-1-sm.avif?v=1') type('image/avif'), url('img/slide-1-sm.jpg?v=3') type('image/jpeg')); }
  .stage-bg .s2 { background-image: url('img/slide-2-sm.jpg?v=3'); background-image: image-set(url('img/slide-2-sm.avif?v=1') type('image/avif'), url('img/slide-2-sm.jpg?v=3') type('image/jpeg')); }
  .stage-bg .s3 { background-image: url('img/slide-3-sm.jpg?v=3'); background-image: image-set(url('img/slide-3-sm.avif?v=1') type('image/avif'), url('img/slide-3-sm.jpg?v=3') type('image/jpeg')); }
  .stage-bg .s4 { background-image: url('img/slide-4-sm.jpg?v=3'); background-image: image-set(url('img/slide-4-sm.avif?v=1') type('image/avif'), url('img/slide-4-sm.jpg?v=3') type('image/jpeg')); }
  .stage-bg .s5 { background-image: url('img/slide-5-sm.jpg?v=3'); background-image: image-set(url('img/slide-5-sm.avif?v=1') type('image/avif'), url('img/slide-5-sm.jpg?v=3') type('image/jpeg')); }
  .stage-bg .s6 { background-image: url('img/slide-6-sm.jpg?v=3'); background-image: image-set(url('img/slide-6-sm.avif?v=1') type('image/avif'), url('img/slide-6-sm.jpg?v=3') type('image/jpeg')); }
  .stage-bg .s7 { background-image: url('img/slide-7-sm.jpg?v=3'); background-image: image-set(url('img/slide-7-sm.avif?v=1') type('image/avif'), url('img/slide-7-sm.jpg?v=3') type('image/jpeg')); }
  .stage-bg .s8 { background-image: url('img/slide-8-sm.jpg?v=3'); background-image: image-set(url('img/slide-8-sm.avif?v=1') type('image/avif'), url('img/slide-8-sm.jpg?v=3') type('image/jpeg')); }
  header.site { background-image: linear-gradient(175deg, rgba(20,66,86,0.87) 0%, rgba(20,66,86,0.74) 100%), url('img/hero-antigua-sm.jpg?v=2'); background-image: linear-gradient(175deg, rgba(20,66,86,0.87) 0%, rgba(20,66,86,0.74) 100%), image-set(url('img/hero-antigua-sm.avif?v=1') type('image/avif'), url('img/hero-antigua-sm.jpg?v=2') type('image/jpeg')); }
}
