/* Бюро Знахідок — the shell every page shares.
 *
 * Tokens, the navigation panel, and the two typographic atoms the whole site
 * is built from: the mono label and the index row. Loaded first, before
 * styles.css (the landing) or legal.css + guide.css (everything else), so the
 * pages can restyle on top of it but never have to redeclare a colour.
 *
 * The layout is a fixed 248px panel down the left edge with the content
 * beside it. Below 1024px the panel lies down into a bar and its contents
 * drop out as a full-screen sheet.
 *
 * Fonts are requested by each page's <head>: Manrope carries both the display
 * and the UI roles (it is the one geometric grotesque in the brand that has a
 * Cyrillic cut), IBM Plex Mono carries labels, numbers and dates.
 */

:root {
  color-scheme: light dark;

  /* Palette — light. Every text tone clears 4.5:1 on all three grounds, so a
     label may sit on the canvas, the panel or a raised row without a check. */
  --bg: #faf0ea;
  --panel: #fdf7f3;
  --surface: #fffbf8;

  --ink: #2a2128;
  --ink-2: #655849;
  --muted: #786a5e;

  --accent: #9b2d5e;
  --accent-hover: #7a2049;
  --accent-quiet: #c9a6b6;

  --line: #e6d7cb;
  --line-soft: #efe2d8;
  --line-strong: #d3bcaa;

  /* Aliases kept for the components written before the shell existed. */
  --cream: var(--bg);
  --berry: var(--accent);
  --berry-dark: var(--accent-hover);

  /* Type */
  --font-ui: Manrope, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --text-mono-sm: 11px;
  --text-mono: 12px;
  --text-mono-md: 13px;
  --text-body-sm: 15px;
  --text-body: 17px;
  --text-body-lg: 19px;
  --text-h-sm: 20px;
  --text-h: 24px;
  --text-h-lg: 34px;

  --tracking-tight: -0.03em;
  --tracking-snug: -0.02em;
  --tracking-micro: -0.015em;
  --tracking-label: 0.14em;

  /* Layout */
  --sidebar-width: 248px;
  --pad-main: 72px;
  --shell-max: 1440px;
  --column: 760px;

  --space-1: 8px;
  --space-2: 12px;
  --space-3: 18px;
  --space-4: 22px;
  --space-5: 26px;
  --space-6: 32px;
  --space-7: 40px;
  --space-8: 56px;
  --space-9: 72px;

  /* Nothing in the shell is rounded and nothing casts a shadow: separation is
     drawn with a hairline. Components that predate it keep their own radii. */
  --radius: 0;
  --transition: 0.2s ease;
  --reveal-shift: 16px;
  --reveal-duration: 700ms;
  --reveal-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* The site has no theme switch, so the OS preference is the whole story: one
   media query, and every colour above is redefined inside it. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #17131a;
    --panel: #1e1821;
    --surface: #241d27;

    --ink: #f3ece9;
    --ink-2: #c3b6b0;
    --muted: #a2958f;

    --accent: #e88bad;
    --accent-hover: #f2a8c2;
    --accent-quiet: #6b4657;

    --line: #322a36;
    --line-soft: #241f28;
    --line-strong: #493e4e;
  }
}

@media (max-width: 1023px) {
  :root {
    --pad-main: 40px;
    /* The bar the panel becomes. The sheet clears it by exactly this much, so
       the logo and the cross stay reachable over the open panel. */
    --bar-height: 68px;
  }
}

@media (max-width: 759px) {
  :root {
    --pad-main: 20px;
  }
}

/* ------------------------------------------------------------------ base */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--text-body);
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--accent);
  text-decoration: none;
}

a:hover {
  color: var(--accent-hover);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 100;
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
}

.skip-link:focus {
  left: var(--space-4);
  top: var(--space-4);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ----------------------------------------------------------------- shell */

.site-shell {
  display: grid;
  grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
  /* Two explicit rows so the panel can span both: content, then whatever
     footer the page puts beside it. Without an explicit second row the
     `1 / -1` below has nothing to reach and the panel's ground stops short. */
  grid-template-rows: 1fr auto;
  min-height: 100vh;
  max-width: var(--shell-max);
  margin-inline: auto;
}

.site-main {
  min-width: 0;
}

/* Past the shell's width the empty margin on the left is filled with the
   panel's own ground, so the panel reads as anchored to the edge of the
   screen instead of floating in the middle of it. */
@media (min-width: 1024px) {
  body {
    background-image: linear-gradient(
      to right,
      var(--panel) 0,
      var(--panel) max(0px, (100% - var(--shell-max)) / 2),
      var(--bg) max(0px, (100% - var(--shell-max)) / 2)
    );
  }
}

/* ----------------------------------------------------------------- panel */

/* The panel element spans the whole column so its ground and its right-hand
   rule run the full length of the page; only what is inside it sticks. */
/* Spans every row of the shell, so a page that puts a footer of its own
   beside the content does not leave the panel's ground stopping short. */
.site-panel {
  grid-row: 1 / -1;
  border-right: 1px solid var(--line);
  background: var(--panel);
}

.site-panel__sticky {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  height: 100vh;
  /* The panel has to clear a laptop screen without scrolling, so the spacing
     is tuned to fit. It still scrolls if it has to — a short window, or a
     browser at a large text size. */
  overflow-y: auto;
  padding: 26px 24px 24px;
}

.site-panel__logo {
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: var(--ink);
}

.site-panel__logo:hover {
  color: var(--ink);
}

.site-panel__logo svg {
  display: block;
}

.site-panel__word {
  font-size: var(--text-h-sm);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: var(--tracking-snug);
}

.site-panel__word em {
  display: block;
  font-style: normal;
  color: var(--accent);
}

/* Two groups, not one run: the logo and the navigation sit at the top of the
   panel, everything else on its floor. */
.site-panel__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-6);
}

/* Every list in the shell spaces itself, so none of them inherits the prose
   `li + li` margin legal.css sets for body copy. */
.site-nav__list li,
.site-nav__sub li,
.site-panel__social li,
.site-panel__legal li,
.index-list li {
  margin-top: 0;
}

.site-nav__list,
.site-nav__sub {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav__list {
  gap: 2px;
}

.site-nav__link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 7px 0;
  color: var(--muted);
  font-size: var(--text-body-sm);
  font-weight: 600;
}

/* The tick is the active marker: every label in the panel carries the same
   weight, so colour alone would have to do the work otherwise. */
.site-nav__tick {
  flex: none;
  width: 14px;
  height: 1px;
  background: var(--line-strong);
  transition: background-color var(--transition), width var(--transition);
}

.site-nav__link:hover,
.site-nav__link:focus-visible {
  color: var(--ink);
}

.site-nav__link:hover .site-nav__tick,
.site-nav__link:focus-visible .site-nav__tick {
  width: 20px;
  background: var(--accent-quiet);
}

/* After the hover rule on purpose: the two match with equal specificity, and
   the active mark must not shrink when the cursor crosses it. */
.site-nav__link.is-active {
  color: var(--ink);
}

.site-nav__link.is-active .site-nav__tick,
.site-nav__link.is-active:hover .site-nav__tick {
  width: 30px;
  background: var(--accent);
}

/* A cluster's articles, listed under it. Indented to the width of the tick
   plus its gap, so they hang off the same seam the labels start at. */
.site-nav__sub {
  gap: 0;
  margin: 2px 0 var(--space-3);
  padding-left: 26px;
}

.site-nav__sub a {
  display: block;
  padding: 4px 0;
  color: var(--muted);
  font-size: var(--text-mono-md);
  line-height: 1.35;
}

.site-nav__sub a:hover {
  color: var(--ink);
}

.site-nav__sub a[aria-current] {
  color: var(--accent);
}

/* The panel's floor: the call to action, the accounts, the blurb. */
.site-panel__foot {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: auto;
}

.site-panel__cta {
  display: block;
  padding: 12px;
  border: 1px solid var(--accent);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-align: center;
  text-transform: uppercase;
  transition: background-color var(--transition), color var(--transition);
}

.site-panel__cta:hover {
  background: var(--accent);
  color: var(--bg);
}

.site-panel__social {
  display: flex;
  flex-direction: row;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-panel__social a {
  display: flex;
  color: var(--muted);
}

.site-panel__social a:hover {
  color: var(--accent);
}

.site-panel__social svg {
  width: 17px;
  height: 17px;
}

/* Two columns: four rows of one is a quarter of the panel's floor spent on
   links almost nobody follows. */
.site-panel__legal {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-panel__legal a {
  color: var(--muted);
  font-size: var(--text-mono-sm);
  line-height: 1.45;
}

.site-panel__legal a:hover {
  color: var(--accent);
}

.site-panel__copyright {
  margin: 0;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  letter-spacing: 0.04em;
}

/* Both exist only once the panel is a bar. */
.site-panel__toggle,
.site-footer {
  display: none;
}

/* ------------------------------------------------------- panel as a bar */

@media (max-width: 1023px) {
  .site-shell {
    grid-template-columns: minmax(0, 1fr);
  }

  .site-panel {
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  /* Without the script there is nothing to open a sheet with, so the panel
     stays a plain block at the top of the page — logo, links, then the
     content. A worse bar, and a perfectly good menu. Everything that turns it
     into one is gated on .js below. */
  .site-panel__sticky {
    position: static;
    height: auto;
    overflow: visible;
    padding: var(--space-4) var(--pad-main);
  }

  .js .site-panel {
    position: sticky;
    top: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--bar-height);
    padding: 0 var(--pad-main);
  }

  /* The bar lays out the logo and the toggle itself, so the sticky wrapper
     steps out of the box tree rather than nesting another flex. */
  .js .site-panel__sticky {
    display: contents;
  }

  .site-panel__logo {
    flex-direction: row;
    align-items: center;
    gap: 10px;
  }

  .site-panel__word {
    font-size: 18px;
  }

  .site-panel__word em {
    display: inline;
  }

  /* Both ride over the open sheet: the logo so its strip is not left empty,
     the toggle because it is the cross that closes it. */
  .site-panel__logo,
  .site-panel__toggle {
    position: relative;
    z-index: 2;
  }

  /* Only once there is a script to make it do something. */
  .js .site-panel__toggle {
    display: flex;
  }

  .site-panel__toggle {
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-right: -10px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--ink);
    cursor: pointer;
  }

  /* Three rules from one element: the bar itself plus its two edges. */
  .site-panel__toggle-bar,
  .site-panel__toggle-bar::before,
  .site-panel__toggle-bar::after {
    display: block;
    width: 20px;
    height: 1px;
    background: currentcolor;
    transition: transform var(--transition), opacity var(--transition);
  }

  .site-panel__toggle-bar::before,
  .site-panel__toggle-bar::after {
    content: "";
    position: relative;
  }

  .site-panel__toggle-bar::before {
    top: -6px;
  }

  .site-panel__toggle-bar::after {
    top: 5px;
  }

  .site-panel__toggle[aria-expanded="true"] .site-panel__toggle-bar {
    background: transparent;
  }

  .site-panel__toggle[aria-expanded="true"] .site-panel__toggle-bar::before {
    transform: translateY(6px) rotate(45deg);
  }

  .site-panel__toggle[aria-expanded="true"] .site-panel__toggle-bar::after {
    transform: translateY(-5px) rotate(-45deg);
  }

  /* Only collapsed once the script is there to open it again: with no JS the
     navigation stays in the flow under the bar, which is a worse bar and a
     perfectly good menu. */
  .js .site-panel__body {
    position: fixed;
    z-index: 1;
    inset: 0;
    gap: var(--space-6);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: calc(var(--bar-height) + var(--space-6)) var(--pad-main) var(--space-8);
    background: var(--panel);
    transform: translateX(100%);
    transition: transform 0.3s ease-out, visibility 0.3s;
    visibility: hidden;
  }

  .js .site-panel__body.is-open {
    transform: none;
    visibility: visible;
  }

  /* The page underneath must not scroll while the sheet is open; the sheet
     scrolls itself when the menu is longer than the screen. */
  body.is-menu-open {
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
  }

  .site-nav__list {
    gap: 0;
  }

  .site-nav__item + .site-nav__item {
    border-top: 1px solid var(--line-soft);
  }

  .site-nav__link {
    padding: 14px 0;
    font-size: var(--text-h-sm);
  }

  .site-nav__sub {
    display: none;
  }

  /* The accounts, the text pages and the copyright belong at the end of the
     page here, not on the floor of a menu. Rendered in both and shown in one, so
     assistive technology reads them once. */
  .site-panel__meta {
    display: none;
  }

  .site-footer {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-8) var(--pad-main);
    border-top: 1px solid var(--line);
    background: var(--panel);
  }
}

@media (max-width: 1023px) and (prefers-reduced-motion: reduce) {
  .js .site-panel__body {
    transition: none;
  }
}

/* ----------------------------------------------------------------- atoms */

/* The mono label that names a band. Wide tracking is what makes 12px read as
   a label rather than as small text. */
.label {
  margin: 0;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

/* ------------------------------------------------------------ index rows */

.index-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.index-row {
  border-bottom: 1px solid var(--line-soft);
}

.index-row:first-child {
  border-top: 1px solid var(--line-soft);
}

.index-row__link {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: var(--space-5);
  align-items: baseline;
  /* The row's own tint has to reach past the section padding, or the
     highlight would stop short of the rules above and below it. */
  margin-inline: -20px;
  padding: 24px 20px;
  color: inherit;
  transition: background-color var(--transition);
}

.index-row__link:hover {
  background: var(--surface);
  color: inherit;
}

.index-row__num {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  font-variant-numeric: tabular-nums;
  transition: color var(--transition);
}

.index-row__link:hover .index-row__num {
  color: var(--accent);
}

.index-row__title {
  display: block;
  color: var(--ink);
  font-size: var(--text-h);
  font-weight: 700;
  line-height: 1.24;
  letter-spacing: var(--tracking-micro);
  text-wrap: pretty;
}

.index-row__summary {
  display: block;
  margin-top: var(--space-1);
  color: var(--muted);
  font-size: var(--text-body-sm);
  line-height: 1.6;
  text-wrap: pretty;
}

@media (max-width: 759px) {
  /* The number rides above the title on a phone: a 56px gutter beside a
     narrow measure leaves the entry nowhere to go. */
  .index-row__link {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
    padding: 20px;
  }

  .index-row__title {
    font-size: var(--text-h-sm);
  }

  .index-row__num {
    font-size: var(--text-mono-sm);
  }
}

/* ---------------------------------------------------------------- reveal */

/* Bands fade up as they come into view. Two guards decide whether any of this
   applies: the .js class, set only when the browser has an IntersectionObserver
   to trigger with, and the motion preference. Fail either and the content is
   simply visible, which is the correct default. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal] {
    opacity: 0;
    transform: translateY(var(--reveal-shift));
    transition:
      opacity var(--reveal-duration) var(--reveal-ease),
      transform var(--reveal-duration) var(--reveal-ease);
  }

  .js [data-reveal="in"] {
    opacity: 1;
    transform: none;
  }
}
