/* ---------- Menu overlay (shared by every page) ----------
   Fits the viewport exactly. Three floors, each pinned by a constraint:
     upper  — pinned to the header (crumbs · Archive + War…Plague · date)
     lower  — pinned to the footer (sections · Disaster…Radiation · time + Calendar/Time)
     foot   — pinned to the bottom edge
   The free space between upper and lower is what stretches with the screen height.
   Text boxes are trimmed to cap height (text-box), so rows line up by their capitals,
   not by invisible line boxes. */
.menu {
  --mx: calc(100vw / 1920);
  --my: calc(100vh / 1000);
  --side: calc(80 * var(--mx));
  --col2: calc(520 * var(--mx));            /* main column, from the left edge */
  --row: max(32px, calc(40 * var(--my)));   /* filters row step */
  --nav-row: max(24px, calc(30 * var(--my)));

  position: fixed; inset: 0; z-index: 9000;       /* above everything a page has (its bars, cards, strips…) */
  background: var(--bg);
  color: var(--fg);
  cursor: auto;
  opacity: 0; visibility: hidden;
  transition: opacity .2s, visibility 0s .2s;
}
.menu.is-open { opacity: 1; visibility: visible; transition: opacity .2s; }
.menu a, .menu button { cursor: pointer; }

/* header always stays above the overlay — also while it fades out, so nothing blinks on close */
.header { z-index: 9001; }                        /* the header: the highest of all (only the loader and the Future start screen cover it) */
.menu::before {                                   /* header divider */
  content: ""; position: absolute; left: 0; right: 0; top: 95px;
  height: 1px; background: rgba(255,255,255,.2);
}
body.menu-open .pointer { display: none; }        /* future.html cursor pill */

/* burger: an 80 × 80 hit area around the lines, not just the lines themselves */
/* (30.09) Subscribe and Log in: hidden for now (kept in the pages' markup); Search takes Log in's place — its right edge
   on the right gutter, on every width (and shown on narrow screens too, now there is room) */
.header > .subscribe, .header > .login { display: none !important; }
.header > a.search { left: auto; right: var(--gutter); display: block; }

/* the yellow mark on the header's top edge (30.09): over the page that is open — the brand («We are …») on
   Dates / Time / Future, Index on the Index, Chronology on the Chronology, Search on Search, the menu's cross while the menu is open;
   it slides (never jumps) — from page to page, to the cross and back, and to whatever link the cursor is on */
.header > .hmark {
  position: absolute; top: 0; left: 0; width: 36px; height: 2px; padding: 0;   /* (its width: the link's, set by menu.js) */ background: var(--accent, #faba1c);
  pointer-events: none; cursor: default; will-change: transform;
}
.header > .hmark.is-moving { transition: transform .5s cubic-bezier(.3, 0, .2, 1), width .5s cubic-bezier(.3, 0, .2, 1); }
.header .is-marked:not(.subscribe) { color: var(--accent, #faba1c); transition: color .25s ease; }
.header > a { transition: color .25s ease; }
.header .burger {
  width: 80px; height: 80px; padding: 0;
  margin-left: -20px;                             /* lines stay where the mock has them */
}
.header .burger::before, .header .burger::after {
  left: 20px;
  transform-origin: 50% 50%;
  transition: transform .2s, top .2s, width .2s, left .2s;
}
/* → a square cross: two 42px lines at ±45° span exactly 30 × 30 */
body.menu-open .header .burger::before,
body.menu-open .header .burger::after { top: 51px; left: 19px; width: 42px; }
body.menu-open .header .burger::before { transform: rotate(45deg); }
body.menu-open .header .burger::after  { transform: rotate(-45deg); }

/* ---------- floors ---------- */
.menu .upper, .menu .lower {
  position: absolute; z-index: 1; left: var(--side); right: var(--side);
  display: grid;
  grid-template-columns: calc(var(--col2) - var(--side)) 1fr auto;
}
.menu .upper { top: calc(96px + max(44px, 68 * var(--my))); align-items: start; }
.menu .lower { bottom: calc(40px + 28px + max(48px, 140 * var(--my))); align-items: end; }

/* breadcrumbs: "Archive ../  Dates ../" — the current page is dimmed */
.menu .crumbs { display: flex; gap: 8px; white-space: nowrap; line-height: 1; }
.menu .crumbs a { text-box: trim-both cap alphabetic; opacity: .8; }
.menu .crumbs a:hover { opacity: 1; }
.menu .crumbs a:last-child { opacity: .3; pointer-events: none; }

/* filters (history tags): one row = one line of --row height; the list is trimmed to the
   capitals of its first and last row, so its top/bottom are the letters themselves */
.menu .filters { font-size: 20px; text-transform: uppercase; }
.menu .filters ul { list-style: none; margin: 0; padding: 0; line-height: var(--row); text-box: trim-both cap alphabetic; }
.menu .filters li.gap { visibility: hidden; }
.menu .filters a { display: inline-flex; align-items: center; gap: 8px; line-height: 1; opacity: .6; transition: opacity .15s; }
.menu .filters a:hover { opacity: 1; }
.menu .filters .name { text-box: trim-both cap alphabetic; }
.menu .filters .count {
  display: inline-flex; align-items: center;
  padding: 3px 4px;
  border: 1px solid currentColor; border-radius: 3px;
  font-size: 12px; line-height: 1;
  font-variant-numeric: lining-nums tabular-nums;
}
.menu .filters .count i { font-style: normal; text-box: trim-both cap alphabetic; }

/* sections */
.menu .nav { font-size: 16px; line-height: var(--nav-row); text-box: trim-both cap alphabetic; }
.menu .nav a { display: block; width: max-content; }
.menu .nav a:hover, .menu .nav a.is-current { color: var(--accent); }
.menu .nav .play { display: inline-block; width: 8px; height: 8px; margin-left: 8px; vertical-align: 0;   /* (30.09: 2px lower than the cap-height middle — reads as centred) */ overflow: visible; }   /* Future: a rounded play triangle */
.menu .toggle .play { display: block; flex: none; width: 8px; height: 8px; margin-left: 6px; overflow: visible; position: relative; top: .5px; }   /* (30.09: .5px below the pill's middle) */   /* the same triangle in the Time pill (an animation too) */
.menu .play path { fill: currentColor; stroke: currentColor; stroke-width: 2.6; stroke-linejoin: round; }
/* (06.10) «Time ▸» in the header: the same rounded triangle after the name; hidden where the header is narrow */
.header .hd-time .play { display: inline-block; width: 8px; height: 8px; margin-left: 8px; vertical-align: 0; overflow: visible; }
.header .hd-time .play path { fill: currentColor; stroke: currentColor; stroke-width: 2.6; stroke-linejoin: round; }
@media (max-width: 1100px) { .header .hd-time { display: none; } }
.menu .nav .play path { fill: currentColor; stroke: currentColor; stroke-width: 2.6; stroke-linejoin: round; }   /* a thick round stroke: soft corners */

/* right column: date (upper), time + Calendar/Time (lower) */
.menu .m-date, .menu .m-time {
  text-align: right;
  font-weight: 300;
  font-size: max(28px, calc(40 * min(var(--mx), var(--my))));
  line-height: 1;
  text-transform: uppercase;
  opacity: .6;
  font-variant-numeric: lining-nums proportional-nums;
  white-space: nowrap;
  text-box: trim-both cap alphabetic;
}
.menu .m-right { align-self: stretch; display: flex; flex-direction: column; justify-content: space-between; align-items: flex-end; }
.menu .toggle { display: flex; gap: 8px; }

/* pills: Calendar / Time and socials — capitals centered in a 28px box */
.menu .pill {
  height: 28px; padding: 0 12px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px; border: 1px solid rgba(255,255,255,.5);
  font-size: 14px; line-height: 1; white-space: nowrap;
}
.menu .pill i { font-style: normal; text-box: trim-both cap alphabetic; }
.menu a.pill:hover { background: var(--accent); color: var(--bg); border-color: var(--accent); }

/* footer — pinned to the bottom edge */
.menu .foot {
  position: absolute; z-index: 1; left: var(--side); right: var(--side); bottom: 40px;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  white-space: nowrap;
}
.menu .socials { display: flex; gap: 8px; }
.menu .copy { opacity: .3; }
.menu .by { justify-self: end; }
.menu .by span { opacity: .3; }
.menu .by b { font-weight: 400; color: var(--accent); }
.menu .by a b { transition: color .15s; }
.menu .by a:hover b { color: var(--fg); }   /* (06.10) the author's site: alex-kovch.com */

/* ---------- hover preview ---------- */
.menu .filters a[data-photo] { cursor: none; }
.menu .preview {
  position: fixed; left: 0; top: 0; z-index: 0;      /* under every link and label of the menu */
  width: max(360px, calc(480 * var(--mx)));      /* 1.5 × the mock's 320 × 200 */
  aspect-ratio: 320 / 200;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  scale: .5;                                       /* position, scale and opacity are driven by menu.js, frame by frame */
  will-change: translate, scale, opacity;
}
.menu .preview img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(1);
  visibility: hidden;                              /* only the selected photo is shown */
}
.menu .preview img.is-on { visibility: visible; }
.menu .ring {
  position: fixed; left: -15px; top: -15px; z-index: 3;
  width: 30px; height: 30px; border-radius: 50%;
  border: 1px solid var(--accent);
  pointer-events: none;
  opacity: 0;
}
.menu .ring::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 4px; height: 4px; margin: -2px 0 0 -2px; border-radius: 50%;
  background: var(--accent);
}
.menu.is-previewing .ring { opacity: 1; }
.menu.is-previewing .filters a[data-photo]:hover { opacity: 1; }

/* ---------- bigger hit areas, same look ----------
   Links get generous padding, cancelled by an equal negative margin: the layout
   and the letters stay exactly where they were, only the clickable box grows.
   Filters: the box fills the whole row vertically and reaches well past the badge. */
.menu .filters a {
  --py: calc((var(--row) - 16px) / 2);
  padding: var(--py) 96px var(--py) 40px;
  margin: calc(var(--py) * -1) -96px calc(var(--py) * -1) -40px;
}
.menu .nav a      { padding: 0 96px 0 40px; margin: 0 -96px 0 -40px; }   /* rows already span --nav-row */
.menu .crumbs a   { padding: 24px 4px; margin: -24px -4px; }              /* 4 + 4 = the 8px gap between crumbs */
.menu .crumbs a:first-child { padding-left: 40px; margin-left: -40px; }

/* ---------- sound toggle: an equalizer right of "Index" ----------
   Six bars: dancing while the music plays, resting as dots and short dashes when it is off. */
.header .sound {
  position: absolute; top: 0;
  padding: 47px 12px 17px;                        /* a generous hit area around a 26 × 14 icon, centered on the text line */
  display: flex; align-items: center; gap: 3px; height: 78px;
  cursor: pointer;
}
.header .sound i {
  display: block; width: 2px; height: 14px; border-radius: 1px;
  background: var(--fg);
  transform-origin: 50% 50%;
  scale: 1 var(--rest);
  opacity: .4;                                    /* muted: dimmed */
  transition: scale .4s ease, opacity .3s ease;
}
.header .sound.is-playing i { opacity: 1; }
.header .sound i:nth-child(1) { --rest: .2;  --dur: .9s;  --del: -.3s; }
.header .sound i:nth-child(2) { --rest: .85; --dur: 1.1s; --del: -.7s; }
.header .sound i:nth-child(3) { --rest: .85; --dur: .8s;  --del: -.1s; }
.header .sound i:nth-child(4) { --rest: .2;  --dur: 1.3s; --del: -.5s; }
.header .sound i:nth-child(5) { --rest: .5;  --dur: 1s;   --del: -.9s; }
.header .sound i:nth-child(6) { --rest: .5;  --dur: .7s;  --del: -.4s; }
.header .sound.is-playing i { animation: eq var(--dur) ease-in-out var(--del) infinite alternate; }
@keyframes eq { 0% { scale: 1 .2; } 45% { scale: 1 1; } 70% { scale: 1 .45; } 100% { scale: 1 .8; } }
.header .sound:hover i { background: var(--accent); }
@media (prefers-reduced-motion: reduce) { .header .sound.is-playing i { animation: none; scale: 1 var(--rest); } }

/* ---------- page transition (every page) ----------
   Leaving: the screen fills with the background, then three yellow squares appear one by one — an ellipsis.
   Arriving: the new page starts under the same veil with the three squares, and it dissolves once the page is ready.
   The arriving veil is pure CSS (body::after + body::before), so it is there from the very first paint;
   menu.js lifts it (html.is-ready). If the script never runs, it lifts itself after 3 s. */
body::after, body::before { position: fixed; z-index: 10000; pointer-events: none; transition: opacity .45s ease; }
body::after { content: ""; inset: 0; background: var(--bg, #252127); animation: veil-safety 0s 3s forwards; }
body::before {                                     /* the three squares: one square and two copies of it (box-shadow) */
  content: ""; z-index: 10001; left: 50%; top: 50%; width: 10px; height: 10px; margin: -5px 0 0 -5px;
  background: var(--accent, #faba1c);
  box-shadow: -36px 0 0 var(--accent, #faba1c), 36px 0 0 var(--accent, #faba1c);
  animation: veil-seq 1s 1s infinite, veil-safety 0s 3s forwards;   /* a long load: after 1 s the squares go round */
}
/* round and round (1 s): gone — the first — the second — the third — gone */
@keyframes veil-seq {
  0%, 24.9%  { background: transparent; box-shadow: -36px 0 0 transparent, 36px 0 0 transparent; }
  25%, 41.9% { background: transparent; box-shadow: -36px 0 0 var(--accent, #faba1c), 36px 0 0 transparent; }
  42%, 58.9% { background: var(--accent, #faba1c); box-shadow: -36px 0 0 var(--accent, #faba1c), 36px 0 0 transparent; }
  59%, 94.9% { background: var(--accent, #faba1c); box-shadow: -36px 0 0 var(--accent, #faba1c), 36px 0 0 var(--accent, #faba1c); }
  95%, 100%  { background: transparent; box-shadow: -36px 0 0 transparent, 36px 0 0 transparent; }
}
html.is-ready body::after, html.is-ready body::before { opacity: 0; }
@keyframes veil-safety { to { opacity: 0; } }

.pageveil { position: fixed; inset: 0; z-index: 10002; background: var(--bg, #252127); opacity: 0; transition: opacity .25s ease; pointer-events: none; cursor: default; }
.pageveil.is-on { opacity: 1; pointer-events: all; }   /* (only while it's up: it catches clicks during the change) */
.pageveil i { position: absolute; left: 50%; top: 50%; width: 10px; height: 10px; margin: -5px 0 0 -5px; background: var(--accent, #faba1c); opacity: 0; }
.pageveil i:nth-child(1) { translate: -36px 0; }
.pageveil i:nth-child(3) { translate: 36px 0; }
.pageveil.is-on i { animation: 1s infinite; }          /* one by one (.25 / .42 / .59 s), all gone at .95 s, and again */
.pageveil.is-on i:nth-child(1) { animation-name: veil-d1; }
.pageveil.is-on i:nth-child(2) { animation-name: veil-d2; }
.pageveil.is-on i:nth-child(3) { animation-name: veil-d3; }
@keyframes veil-d1 { 0%, 24.9% { opacity: 0; } 25%, 94.9% { opacity: 1; } 95%, 100% { opacity: 0; } }
@keyframes veil-d2 { 0%, 41.9% { opacity: 0; } 42%, 94.9% { opacity: 1; } 95%, 100% { opacity: 0; } }
@keyframes veil-d3 { 0%, 58.9% { opacity: 0; } 59%, 94.9% { opacity: 1; } 95%, 100% { opacity: 0; } }
/* soft navigation: the new page is in; the veil dissolves with the three squares still on it */
.pageveil.is-on.is-out { opacity: 0; transition-duration: .45s; pointer-events: none; }
.pageveil.is-on.is-out i { animation: none; opacity: 1; }
@media (prefers-reduced-motion: reduce) { body::after, body::before, .pageveil { transition-duration: .01s; } body::before { animation: veil-safety 0s 3s forwards; } .pageveil.is-on i { animation: none; opacity: 1; } }

/* ---------- the start screen (menu.js): above everything, until «Let’s start» ---------- */
.gate { position: fixed; inset: 0; z-index: 10003; background: var(--bg, #252127); color: var(--fg, #fff);
  font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 14px; line-height: 16px; -webkit-font-smoothing: antialiased;
  transition: opacity 1.6s cubic-bezier(.4, 0, .2, 1); }
.gate.is-out { opacity: 0; pointer-events: none; }
.gate > * { position: absolute; margin: 0; opacity: 0; transition: opacity 2.4s cubic-bezier(.4, 0, .2, 1); }   /* slowly out of the dark */
.gate > .is-on { opacity: 1; }
.gate .g-a, .gate .g-b, .gate .g-go { translate: -50% 0; text-align: center; white-space: nowrap; }
.gate .g-person { fill: rgb(111, 106, 114); overflow: visible; }            /* the Future page's first person, still grey */
.gate .g-spark { fill: #fff; fill-opacity: .3; overflow: visible; }   /* the ai (claude.svg: white at 30 %) */
.gate .g-go {                                       /* exactly the site's pill (the tags' buttons) */
  height: 28px; padding: 0 12px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px; border: 1px solid rgba(255, 255, 255, .5); background: var(--bg, #252127);
  color: inherit; font: inherit; font-size: 14px; line-height: 1; white-space: nowrap; cursor: pointer;
  transition: opacity 2.4s cubic-bezier(.4, 0, .2, 1), border-color .15s; }
.gate .g-go i { font-style: normal; text-box: trim-both cap alphabetic; }   /* centered on the capitals, like every pill */
.gate .g-go:hover { border-color: #fff; }
.gate .g-go:not(.is-on) { pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .gate, .gate > * { transition: none; } }

/* a link to the page one is on leads nowhere (menu.js marks it): no pointer */
a[aria-current="page"], .header a[aria-current="page"], .header a[aria-current="page"] * { cursor: default !important; }
