/*
 * Shared chrome for every static blog page.
 *
 * The blog is plain HTML served straight from disk, so it cannot import the
 * React header. This file is the other half of that contract: the same tokens,
 * the same `.menubar` markup and the same responsive behaviour as
 * `apps/web/src/styles/base.css`, so a reader moving between the app and the
 * blog meets one header rather than two.
 */

:root {
  color-scheme: light;
  --plat-50: #efefef;
  --plat-100: #dddddd;
  --plat-200: #cccccc;
  --plat-300: #aaaaaa;
  --plat-400: #888888;
  --plat-600: #555555;
  --plat-900: #111111;
  --desktop: #66799b;
  --term-bg: #101410;
  --term-green: #33ff66;
  --term-red: #ff5544;
  --selection: #333399;
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --ui-font: Charcoal, Chicago, Geneva, 'Helvetica Neue', system-ui, sans-serif;
  --mono-font: Monaco, 'SF Mono', Menlo, 'Courier New', monospace;
}

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

/* One column for the whole page — menubar, card, and nothing else — so the card
   can grow into a viewport a short article does not fill and the footer inside
   it can ride down to the floor. See `.site-footer`. */
body {
  margin: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--desktop);
  color: var(--plat-900);
  font: 16px/1.6 var(--ui-font);
}

button {
  font: inherit;
  color: inherit;
}

a:focus-visible,
button:focus-visible,
[role='option']:focus-visible {
  outline: 2px dotted var(--selection);
  outline-offset: 2px;
}

::selection {
  background: var(--selection);
  color: #fff;
}

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

/* ── Header ─────────────────────────────────────────────────────────────── */

.menubar {
  min-height: 22px;
  display: flex;
  align-items: center;
  padding: 0 8px;
  background: var(--plat-100);
  border-bottom: 1px solid var(--plat-900);
  box-shadow: inset 0 1px 0 #fff;
  font: 13px/1.45 var(--ui-font);
  overflow: visible;
}
.menubar__nav {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  white-space: nowrap;
}
.menubar__meta {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  margin-left: auto;
}
.menubar button,
.menubar__item {
  border: 0;
  background: transparent;
  min-height: 22px;
  cursor: pointer;
  padding: 0 10px;
}
.menubar button:hover:not(:disabled),
.menubar__item:hover,
.menubar .is-active {
  background: var(--selection);
  color: #fff;
}
/* A visitor's workspace tabs are inert until blog.js finds a session, so they
   render here the way the product renders them for a reader with no session. */
.menubar button:disabled {
  color: var(--plat-400);
  cursor: not-allowed;
}
.menubar__apple {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-weight: 700;
  padding: 0 10px 0 4px;
  color: inherit;
  text-decoration: none;
  min-height: 22px;
}
.menubar__item {
  display: inline-flex;
  align-items: center;
  color: inherit;
  font: inherit;
  text-decoration: none;
}
.menubar__apple svg,
.menubar__sheet-brand svg {
  width: 12px;
  height: 12px;
  fill: currentColor;
}
.menubar__spacer {
  flex: 1;
  min-width: 16px;
}
.menubar__system {
  font: 11px var(--mono-font);
  color: var(--plat-600);
  padding: 0 8px;
}
.menubar__toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin-left: auto;
}
.menubar__toggle svg {
  width: 16px;
  height: 16px;
}
.menubar__links {
  display: contents;
}
.menubar__close,
.menubar__sheet-head,
.menubar__group-label {
  display: none;
}

.menubar__language {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 22px;
  padding: 0 8px;
  color: var(--plat-600);
  font: 10px var(--mono-font);
  text-transform: uppercase;
}
.menubar__language-button {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 18px;
  padding: 0 6px;
  border: 1px solid var(--plat-400);
  background: var(--plat-50);
  color: var(--plat-900);
  font: 11px var(--ui-font);
  text-transform: none;
  cursor: pointer;
}
.menubar__language-button:hover {
  background: var(--plat-100);
}
.menubar__language-caret {
  width: 8px;
  height: 5px;
  color: var(--plat-600);
}
.menubar__language-listbox {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 20;
  min-width: 140px;
  margin: 2px 0 0;
  padding: 2px 0;
  list-style: none;
  border: 1px solid var(--plat-400);
  background: var(--plat-50);
  box-shadow: 0 4px 10px rgb(0 0 0 / 25%);
}
.menubar__language-listbox[hidden] {
  display: none;
}
.menubar__language-option {
  padding: 4px 10px;
  color: var(--plat-900);
  font: 11px var(--ui-font);
  text-transform: none;
  cursor: pointer;
}
.menubar__language-option:hover,
.menubar__language-option.is-active {
  background: var(--selection);
  color: var(--plat-50);
}
.menubar__language-option[aria-selected='true']::after {
  content: '✓';
  float: right;
}

/* ── Page body ──────────────────────────────────────────────────────────── */

.blog-page {
  display: flex;
  flex-direction: column;
  flex: 1 0 auto;
  padding: 48px 24px;
}
main {
  flex: 1 0 auto;
  max-width: 820px;
  margin: 0 auto;
  background: var(--plat-50);
  border: 1px solid var(--plat-900);
  padding: 36px 44px 48px;
  box-shadow: 4px 4px var(--plat-900);
}
main a {
  color: var(--selection);
}
.kicker {
  color: var(--plat-600);
  font: 12px var(--mono-font);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
h1 {
  font-size: 42px;
  line-height: 1.05;
  margin: 14px 0 10px;
  letter-spacing: -0.03em;
}
.lede {
  color: #333;
  font-size: 16px;
  margin: 0 0 20px;
  max-width: 600px;
}

.filter-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 28px 0 0;
  padding: 10px 14px;
  border: 1px solid var(--plat-400);
  background: #e4e4e4;
  font: 11px var(--mono-font);
  flex-wrap: wrap;
}
.filter-bar__label {
  color: var(--plat-600);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.filter-bar button {
  display: inline-block;
  padding: 4px 10px;
  border: 1px solid var(--plat-400);
  background: #fff;
  color: var(--plat-900);
  font: 11px var(--mono-font);
  letter-spacing: 0.04em;
  cursor: pointer;
}
.filter-bar button:hover,
.filter-bar button[aria-pressed='true'] {
  background: var(--selection);
  border-color: var(--selection);
  color: #fff;
}

article {
  border-top: 1px solid var(--plat-400);
  padding: 26px 0;
}
article:first-of-type {
  border-top: 2px solid var(--plat-900);
  margin-top: 28px;
}
.article-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.kicker-tag {
  color: var(--plat-600);
  font: 11px var(--mono-font);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.lang-badge {
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--plat-900);
  background: var(--term-bg);
  color: var(--term-green);
  font: 9px var(--mono-font);
  letter-spacing: 0.08em;
  line-height: 1.8;
  vertical-align: middle;
}
.lang-badge--uk {
  background: #1d3461;
  border-color: #1d3461;
  color: #a8c4f0;
}
article h2 {
  margin: 0 0 4px;
  font-size: 22px;
  letter-spacing: -0.02em;
}
article h2 a {
  text-decoration: none;
}
article h2 a:hover {
  text-decoration: underline;
}
time {
  display: block;
  color: var(--plat-600);
  font: 11px var(--mono-font);
  margin-bottom: 10px;
}
article p {
  margin: 0;
  color: #333;
  font-size: 15px;
  line-height: 1.65;
}

.blog-empty {
  margin-top: 28px;
  padding: 18px;
  border: 1px dashed var(--plat-400);
  color: var(--plat-600);
  font-size: 15px;
}
.blog-empty[hidden] {
  display: none;
}

/* Every blog footer — index and article alike — is this one shape. `position:
   sticky` with a `top` of a whole viewport is what puts it on the floor of a
   short page: the offset asks for a position below the fold, and the sticky
   rectangle — the card, stretched by `flex: 1 0 auto` — clamps it back to its
   own bottom edge. A long article never has that free space, so the footer
   stays exactly where it fell in the flow and nothing overlaps. */
.site-footer {
  position: sticky;
  top: 100vh;
  border-top: 1px solid var(--plat-400);
  margin-top: 40px;
  padding-top: 20px;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  color: var(--plat-600);
  font: 11px var(--mono-font);
}
.site-footer a {
  color: var(--selection);
}

/* Attribution to the studio behind FluxRadar, appended to every blog footer.
   Index and article now share one `.site-footer`, but the row still claims its
   width with `width: 100%` rather than `flex-basis: 100%`: the basis would
   resolve against the height wherever a footer is laid out as a column. */
.powered-by {
  flex: 0 0 auto;
  width: 100%;
  margin-top: var(--sp-2);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}
/* Its own type size rather than the footer's: the three footers set three
   different ones, and the attribution should read the same on all of them.
   Written with the wrapper in front so it outranks `.site-footer a` on
   specificity rather than on where it happens to sit in the file. */
.powered-by .powered-by__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 24px;
  color: var(--selection);
  font: 11px/1.5 var(--mono-font);
  text-decoration: none;
}
.powered-by .powered-by__link:hover {
  text-decoration: underline;
}
/* Spelled out rather than left to the generic `a:focus-visible` above, because
   this link also renders under the article pages' own inline stylesheets. */
.powered-by .powered-by__link:focus-visible {
  outline: 2px dotted var(--selection);
  outline-offset: 3px;
}
.powered-by__mark {
  color: var(--plat-600);
}

/* The static blog offers the same choice as the React shell: necessary storage,
   plus preferences and analytics, both off until ticked. It is a non-modal dock,
   so reading and keyboard focus are never trapped behind it. */
.blog-cookie-dock {
  position: fixed;
  z-index: 80;
  inset: auto 0 0;
  display: flex;
  justify-content: flex-end;
  padding: var(--sp-3);
  padding-bottom: max(var(--sp-3), env(safe-area-inset-bottom));
  pointer-events: none;
}
.blog-cookie-consent {
  width: min(100%, 720px);
  min-width: 0;
  max-height: min(440px, 50dvh);
  overflow: auto;
  overflow-wrap: anywhere;
  pointer-events: auto;
  background: var(--plat-100);
  border: 1px solid var(--plat-900);
  box-shadow: 2px 2px 0 rgb(0 0 0 / 35%);
  font: 13px/1.5 var(--ui-font);
}
.blog-cookie-consent__titlebar {
  padding: 3px var(--sp-3);
  text-align: center;
  background: repeating-linear-gradient(0deg, #fff 0 1px, var(--plat-200) 1px 2px);
}
.blog-cookie-consent__titlebar h2 {
  display: inline;
  padding: 0 var(--sp-2);
  background: var(--plat-100);
  font: 700 13px/1.5 var(--ui-font);
}
.blog-cookie-consent__body {
  padding: var(--sp-3) var(--sp-4);
}
.blog-cookie-consent__body p {
  margin: 0 0 var(--sp-2);
}
.blog-cookie-consent__body a {
  color: var(--selection);
}
.blog-cookie-consent__options {
  min-width: 0;
  margin: 0 0 var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--plat-400);
}
.blog-cookie-consent__options legend {
  padding: 0 var(--sp-1);
  font-weight: 700;
}
.blog-cookie-consent__option {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 24px;
  font-weight: 700;
}
.blog-cookie-consent__option input {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--plat-900);
}
/* Indented to the label text, not the box. */
.blog-cookie-consent__body .blog-cookie-consent__hint {
  margin: 0 0 var(--sp-2);
  padding-left: 24px;
  color: var(--plat-600);
}
/* Three equal buttons: refusing everything is exactly as direct as allowing it.
   Pinned to the foot of the banner like the app's, so on a phone the choice
   never scrolls out of reach behind the category descriptions. */
.blog-cookie-consent__actions {
  position: sticky;
  bottom: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-2);
  margin: var(--sp-3) 0 calc(-1 * var(--sp-3));
  padding: var(--sp-2) 0 var(--sp-3);
  background: var(--plat-100);
}
.blog-cookie-consent__actions button,
.blog-cookie-settings {
  min-height: 44px;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--plat-900);
  background: var(--plat-50);
  color: var(--plat-900);
  box-shadow:
    inset 1px 1px #fff,
    inset -1px -1px var(--plat-400);
  cursor: pointer;
  font: 700 13px/1.4 var(--ui-font);
}
.blog-cookie-consent__actions button {
  white-space: normal;
}
.blog-cookie-settings {
  max-width: 100%;
  pointer-events: auto;
}
.blog-cookie-consent__error {
  padding-top: var(--sp-2);
  color: #8b1a12;
  font-weight: 700;
}
.blog-cookie-consent :focus-visible,
.blog-cookie-settings:focus-visible {
  outline: 2px solid var(--selection);
  outline-offset: 3px;
}

/* The language filter: JS records the choice on <html>, the rest is CSS. */
html[data-blog-lang='en'] [data-article-lang='uk'],
html[data-blog-lang='uk'] [data-article-lang='en'] {
  display: none;
}

@media (max-width: 699px) {
  .blog-page {
    padding: 12px;
  }
  main {
    padding: 20px 18px 28px;
  }
  h1 {
    font-size: 30px;
  }
  .blog-cookie-dock {
    padding: var(--sp-2);
    padding-bottom: max(var(--sp-2), env(safe-area-inset-bottom));
  }
  .blog-cookie-consent__actions {
    grid-template-columns: 1fr;
  }
}

/* The header switches to the burger at the React header's width, below 1000px,
   not with the page rules above: the full row does not fit the bar until then. */
@media (max-width: 999px) {
  .menubar__system {
    display: none;
  }
  .menubar__toggle {
    display: inline-flex;
  }
  .menubar__links {
    display: none;
  }
  .menubar__links.is-open {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    position: fixed;
    inset: 0;
    z-index: 50;
    background: var(--plat-100);
    padding: 0 0 var(--sp-4);
    overflow-y: auto;
    /* One left edge for the whole sheet, as on the React header: the group
       labels, the navigation items, the brand and the language control each
       used to compute their own inset, so their text started in three
       different columns. The 3px active rail is subtracted from the padding
       rather than added in front of it, so a selected row's label stays on
       the line as the others. */
    --sheet-inset: var(--sp-4);
    --sheet-rail: 3px;
  }
  .menubar__sheet-head {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    min-height: 44px;
    padding: 0 var(--sheet-inset);
    background: var(--term-bg);
    color: var(--plat-50);
    border-bottom: 2px solid var(--plat-900);
  }
  .menubar__sheet-brand {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 6px;
    font: 700 13px var(--mono-font);
    letter-spacing: 0.02em;
  }
  .menubar__sheet-brand svg {
    fill: var(--term-green);
  }
  /* The Ukrainian station name is long enough to wrap and push the head to two
     rows, which broke the alignment of the brand and the close box against the
     44px strip. It is a subtitle, so it gives way with an ellipsis instead. */
  .menubar__sheet-status {
    min-width: 0;
    overflow: hidden;
    font: 10px var(--mono-font);
    color: var(--term-green);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-left: var(--sp-2);
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .menubar__group-label {
    display: block;
    font: 700 10px var(--mono-font);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--plat-600);
    padding: var(--sp-3) var(--sheet-inset) var(--sp-1);
  }
  .menubar__nav {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    overflow: visible;
    white-space: normal;
    border-bottom: 1px solid var(--plat-300);
    padding-bottom: var(--sp-2);
  }
  .menubar__meta {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    margin-left: 0;
    padding: var(--sp-1) 0 0;
  }
  .menubar__links.is-open .menubar__language {
    min-height: 44px;
    padding: 0 calc(var(--sheet-inset) - var(--sp-2));
    align-self: stretch;
    justify-content: flex-start;
  }
  /* The same 40px minimum tap target the rest of the sheet offers, so the
     language control is not a 22px exception in a column of 44px rows. */
  .menubar__links.is-open .menubar__language-button {
    min-height: 40px;
    padding: 0 var(--sp-2);
    font-size: 14px;
  }
  .menubar__language-listbox {
    left: calc(var(--sheet-inset) - var(--sp-2));
    right: auto;
    top: calc(100% + 2px);
  }
  /* The word "Language" is what names the combobox for a screen reader, so it
     is hidden from the sheet rather than removed — the React header hides it
     the same way, and a visible label was the one row the two sheets differed
     on. */
  .menubar__language > span {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
  .menubar__links.is-open .menubar__item {
    min-height: 44px;
    justify-content: flex-start;
    padding: 0 var(--sheet-inset) 0 calc(var(--sheet-inset) - var(--sheet-rail));
    margin: 0;
    font-size: 16px;
    border-left: var(--sheet-rail) solid transparent;
  }
  .menubar__links.is-open .menubar__item:hover:not(:disabled) {
    background: var(--plat-200);
    color: inherit;
    border-left-color: var(--plat-300);
  }
  .menubar__links.is-open .is-active {
    background: var(--selection);
    color: #fff;
    border-left-color: var(--term-green);
    font-weight: 700;
  }
  .menubar__links.is-open .menubar__spacer {
    display: none;
  }
  .menubar__sheet-head .menubar__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: center;
    margin-left: auto;
    width: 32px;
    height: 32px;
    border: 1px solid var(--plat-300);
    background: var(--plat-900);
    color: var(--plat-50);
  }
  .menubar__sheet-head .menubar__close:hover {
    background: var(--term-red);
    border-color: var(--term-red);
  }
  .menubar__close svg {
    width: 12px;
    height: 12px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    transition-duration: 1ms !important;
  }
}
