/* ============================================================
   Page shell: nav, section frame, footer, page-level grid.
   ============================================================ */

/* The gutters carry the safe-area insets because the document is drawn
   edge to edge (viewport-fit=cover in the <head>). On an iPhone held
   sideways the notch and the rounded corners eat about 59px of each
   side; without this the wordmark and the language switch disappear
   under them, while backgrounds still run to the true edge. */
.shell {
  width: 100%;
  max-width: var(--w-page);
  margin-inline: auto;
  padding-inline: calc(var(--pad-x) + env(safe-area-inset-left, 0px))
    calc(var(--pad-x) + env(safe-area-inset-right, 0px));
}

/* ---------- section frame -----------------------------------
   Rhythm is intentionally uneven: a hairline + index number
   opens each section, so the page reads like a stage itinerary. */

.section {
  position: relative;
  padding-block: var(--s-section);
}

.section--tight {
  padding-block: calc(var(--s-section) * 0.6);
}

.section__head {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-5);
  align-items: start;
  padding-top: var(--s-5);
  border-top: var(--hair);
  margin-bottom: var(--s-7);
}

.section__index {
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  color: var(--c-amber);
  padding-top: 0.55em;
}

.section__title {
  font-size: var(--t-d2);
}

.section__title em {
  font-style: normal;
  color: var(--c-ink-mute);
}

.section__intro {
  grid-column: 2;
  margin-top: var(--s-3);
}

@media (max-width: 40rem) {
  .section__head {
    grid-template-columns: 1fr;
    gap: var(--s-2);
  }
  .section__intro {
    grid-column: 1;
  }
}

/* ---------- nav ---------------------------------------------- */

.nav {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: var(--z-nav);
  /* The status bar sits on top of the page on iOS — in a home-screen
     window in portrait, and behind the Dynamic Island in landscape. The
     inset is added to this bar rather than to the document so the hero
     still runs under it, and the row itself keeps its full height. */
  height: calc(var(--nav-h) + env(safe-area-inset-top, 0px));
  padding-block-start: env(safe-area-inset-top, 0px);
  display: flex;
  align-items: center;
  transition:
    background var(--d-mid) var(--e-out),
    border-color var(--d-mid) var(--e-out),
    backdrop-filter var(--d-mid) var(--e-out);
  border-bottom: 1px solid transparent;
}

/* Before the bar sticks it has no background of its own, and over a bright
   frame of the hero the links and the burger wash out. A short scrim keeps
   them legible whatever the photo does, and fades out as the solid bar
   arrives.

   It is anchored to the top and made taller than the bar on purpose, and the
   fade is spent below the bar rather than across it. The bar carries the
   safe-area inset as top padding, so the row sits in the bottom half of the
   box — under a gradient that ran from the top edge to the bottom edge the
   row landed in the part that had already reached transparent, and the
   wordmark, half of it over a pale frame of the photograph, read as cut off.
   The solid stretch now covers the row to the bar's edge and only then
   fades. */
.nav::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  height: calc(100% + var(--nav-scrim));
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgb(11 12 14 / 0.78) 0,
    rgb(11 12 14 / 0.66) calc(100% - var(--nav-scrim)),
    transparent 100%
  );
  transition: opacity var(--d-mid) var(--e-out);
}

.nav[data-stuck="1"] {
  background: rgb(11 12 14 / 0.82);
  /* Safari only understood the prefixed property until version 18, and
     half the phones out there are older than that: without this line the
     bar is flat translucent over the photo instead of frosted. */
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  backdrop-filter: blur(14px) saturate(1.2);
  border-bottom-color: var(--c-edge-soft);
}

.nav[data-stuck="1"]::before {
  opacity: 0;
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  width: 100%;
}

/* The wordmark yields the room, never the controls: it is the one item in the
   bar that can be read at a smaller size, while the language switch and the
   burger are targets and have to keep theirs. Without this the Cyrillic
   wordmark — wider than the Latin one — ran under the switch on a 320px
   screen instead of stopping short of it. */
.nav__mark {
  display: flex;
  align-items: baseline;
  min-width: 0;
  overflow: hidden;
  gap: 0.55rem;
  font-family: var(--f-display);
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* The hare sits to the left of the wordmark. The mark aligns its text on
   the baseline, which an image has no business joining — so the logo
   centres itself against the cap height instead.

   The img carries width/height at its rendered size, not the artwork's, so
   a stale cache of this file cannot fall back to a 227px hare. */
.nav__logo {
  align-self: center;
  height: 2.25rem;
  width: auto;
  /* Stated rather than inferred: `width: auto` on an SVG leaves Safari to
     work the width out from the file, and it has been known to reach for
     the 300px default instead — which shoulders the wordmark out of the
     bar. The ratio is the one the width/height attributes declare. */
  aspect-ratio: 69 / 36;
  flex: none;
}

.nav__mark b {
  font-weight: 700;
}

.nav__mark span {
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  color: var(--c-amber);
}

.nav__links {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 2rem);
}

.nav__link {
  position: relative;
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink-dim);
  padding-block: var(--s-2);
  transition: color var(--d-fast) var(--e-out);
}

/* Underline grows from the left on hover, and stays lit for the
   section currently in view — the nav doubles as a progress read-out. */
.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 100%;
  background: var(--c-amber);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--d-mid) var(--e-out);
}

.nav__link:hover,
.nav__link[aria-current="true"] {
  color: var(--c-ink);
}

.nav__link:hover::after,
.nav__link[aria-current="true"]::after {
  transform: scaleX(1);
}

.nav__side {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex: none;
}

/* A 320px screen — an SE, or any iPhone in the zoomed display mode — has
   about 280px between the gutters, and the bar at its full size wants more
   than that. The wordmark comes down a step so the row still fits with air
   in it. */
@media (max-width: 22.5rem) {
  .nav__inner {
    gap: var(--s-3);
  }

  .nav__mark {
    font-size: 1.1rem;
    gap: 0.4rem;
  }

  .nav__logo {
    height: 1.85rem;
  }

  .nav__side {
    gap: var(--s-3);
  }
}

/* language switcher */
.lang {
  display: flex;
  align-items: center;
  border: var(--hair);
  border-radius: var(--r-sm);
  overflow: hidden;
}

.lang__btn {
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0.4rem 0.6rem;
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-ink-mute);
  transition:
    color var(--d-fast) var(--e-out),
    background var(--d-fast) var(--e-out);
}

.lang__btn:hover {
  color: var(--c-ink);
}

.lang__btn[aria-pressed="true"] {
  background: var(--c-amber);
  color: var(--c-void);
}

/* scroll progress hairline pinned under the nav */
.nav__progress {
  position: absolute;
  left: 0;
  bottom: -1px;
  height: 2px;
  width: 100%;
  transform: scaleX(var(--progress, 0));
  transform-origin: left;
  background: linear-gradient(90deg, var(--c-amber-deep), var(--c-amber-hot));
}

/* burger — bars are absolutely centred on one point and pushed apart by
   transform, so the open state collapses them into a true X. Laying them
   out in normal flow leaves each bar in its own row and the "X" reads as
   a chevron instead. */
.burger {
  display: none;
  position: relative;
  width: 2.5rem;
  height: 2.5rem;
  border: var(--hair);
  border-radius: var(--r-sm);
  background: none;
  cursor: pointer;
  padding: 0;
}

.burger span:not(.visually-hidden) {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1.1rem;
  height: 1px;
  margin-left: -0.55rem;
  background: var(--c-ink);
  transition: transform var(--d-mid) var(--e-out), opacity var(--d-fast);
}

.burger span:nth-child(1) {
  transform: translateY(-5px);
}
.burger span:nth-child(2) {
  transform: translateY(0);
}
.burger span:nth-child(3) {
  transform: translateY(5px);
}

.burger[aria-expanded="true"] span:nth-child(1) {
  transform: rotate(45deg);
}
.burger[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}
.burger[aria-expanded="true"] span:nth-child(3) {
  transform: rotate(-45deg);
}

@media (max-width: 62rem) {
  .burger {
    display: block;
  }

  /* The drawer hangs off the bottom edge of the bar, so it starts below
     the safe-area inset too, keeps the same gutters as the page, and is
     allowed to scroll — five links and their padding are taller than a
     phone held sideways. */
  .nav__links {
    position: fixed;
    inset: calc(var(--nav-h) + env(safe-area-inset-top, 0px)) 0 auto 0;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s-4);
    padding: var(--s-6) calc(var(--pad-x) + env(safe-area-inset-right, 0px)) var(--s-7)
      calc(var(--pad-x) + env(safe-area-inset-left, 0px));
    max-height: calc(100svh - var(--nav-h) - env(safe-area-inset-top, 0px));
    overflow-y: auto;
    background: rgb(11 12 14 / 0.97);
    -webkit-backdrop-filter: blur(18px);
    backdrop-filter: blur(18px);
    border-bottom: var(--hair);
    /* Closed, the drawer has to clear the top of the screen, and a percentage
       alone cannot do it: it hangs off the bottom of the bar, so -110% of its
       own height still leaves its last tenth — the closing link and a strip of
       its opaque backdrop — parked over the bar, which is what chopped the
       wordmark in half on a phone. The offset is its full height plus
       everything above it. */
    transform: translateY(calc(-100% - var(--nav-h) - env(safe-area-inset-top, 0px) - 2px));
    transition: transform var(--d-mid) var(--e-in-out);
  }

  .nav__links[data-open="1"] {
    transform: translateY(0);
  }

  .nav__link {
    font-size: 1rem;
    letter-spacing: 0.12em;
  }
}

/* ---------- footer ------------------------------------------- */

.footer {
  border-top: var(--hair);
  background: var(--c-void);
  padding-block: var(--s-7) var(--s-6);
}

.footer__grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(2, minmax(0, 1fr));
  gap: var(--s-6);
  align-items: start;
}

.footer__word {
  font-family: var(--f-display);
  font-size: clamp(3rem, 1rem + 9vw, 8rem);
  line-height: 0.82;
  text-transform: uppercase;
  color: var(--c-raise);
  letter-spacing: -0.02em;
  margin-block: var(--s-7) var(--s-5);
  user-select: none;
}

.footer__col h4 {
  font-size: var(--t-small);
  letter-spacing: var(--ls-label);
  color: var(--c-ink-mute);
  margin-bottom: var(--s-3);
}

.footer__col li + li {
  margin-top: var(--s-2);
}

.footer__col a {
  color: var(--c-ink-dim);
  transition: color var(--d-fast) var(--e-out);
}

.footer__col a:hover {
  color: var(--c-amber);
}

.footer__base {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  justify-content: space-between;
  align-items: center;
  margin-top: var(--s-7);
  padding-top: var(--s-4);
  border-top: var(--hair-soft);
  color: var(--c-ink-mute);
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

@media (max-width: 52rem) {
  .footer__grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 34rem) {
  .footer__grid {
    grid-template-columns: 1fr;
  }
}
