/* Платіжка — site styles.
   No framework: one file, custom properties, light/dark by preference + manual toggle.
   Everything sized in rem so the OS font-size setting is respected. */

:root {
  --sapphire:    #1E4CB3;
  --sapphire-lo: #3D6FE0;
  --ink:         #0d1526;
  --ink-soft:    #45536d;
  --ink-faint:   #6b7a94;
  --bg:          #ffffff;
  --bg-tint:     #f4f7fd;
  --line:        #e3e9f5;
  --accent:      var(--sapphire);
  --radius:      18px;
  --measure:     42rem;
  --shadow:      0 1px 2px rgba(13,21,38,.05), 0 12px 32px -12px rgba(13,21,38,.16);
}

:root[data-theme="dark"],
html:not([data-theme="light"]) {
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) {
    --ink:      #e9eef9;
    --ink-soft: #a9b7d0;
    --ink-faint:#7d8caa;
    --bg:       #0c1220;
    --bg-tint:  #141d31;
    --line:     #222e49;
    --accent:   #86a9f5;
    color-scheme: dark;
    --shadow:   0 1px 2px rgba(0,0,0,.4), 0 12px 32px -12px rgba(0,0,0,.6);
  }
}
html[data-theme="dark"] {
  --ink:      #e9eef9;
  --ink-soft: #a9b7d0;
  --ink-faint:#7d8caa;
  --bg:       #0c1220;
  --bg-tint:  #141d31;
  --line:     #222e49;
  --accent:   #86a9f5;
  color-scheme: dark;
  --shadow:   0 1px 2px rgba(0,0,0,.4), 0 12px 32px -12px rgba(0,0,0,.6);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; height: auto; display: block; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { text-decoration-thickness: 2px; }

/* ── layout ─────────────────────────────────────────────────────────── */
.shell { width: 100%; max-width: 64rem; margin-inline: auto; padding-inline: 1.25rem; }
.prose { max-width: var(--measure); }

/* ── header ─────────────────────────────────────────────────────────── */
.top {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid var(--line);
}
.top__in { display: flex; align-items: center; gap: 1rem; height: 4rem; }
.brand {
  display: inline-flex; align-items: center; gap: .6rem;
  font-weight: 800; font-size: 1.0625rem; letter-spacing: -.01em;
  color: var(--ink); text-decoration: none; white-space: nowrap;
}
.brand__mark {
  width: 1.85rem; height: 1.85rem; border-radius: 9px; flex: none;
  background: linear-gradient(145deg, var(--sapphire-lo), var(--sapphire));
  color: #fff; font-size: .95rem; font-weight: 700;
  display: grid; place-items: center;
}
.top nav { margin-inline-start: auto; display: flex; align-items: center; gap: .35rem; }
.navlink {
  color: var(--ink-soft); text-decoration: none; font-weight: 600; font-size: .95rem;
  padding: .45rem .7rem; border-radius: 999px;
}
.navlink:hover, .navlink[aria-current] { color: var(--ink); background: var(--bg-tint); }

.langs { display: flex; gap: .15rem; margin-inline-start: .35rem;
  padding-inline-start: .5rem; border-inline-start: 1px solid var(--line); }
.langs a {
  font-size: .8125rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-faint); text-decoration: none; padding: .35rem .45rem; border-radius: 8px;
}
.langs a:hover { color: var(--ink); background: var(--bg-tint); }
.langs a[aria-current] { color: #fff; background: var(--sapphire); }

.themebtn {
  margin-inline-start: .35rem; width: 2.2rem; height: 2.2rem; flex: none;
  display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 10px;
  background: transparent; color: var(--ink-soft); cursor: pointer;
}
.themebtn:hover { color: var(--ink); background: var(--bg-tint); }
.themebtn svg { width: 1.05rem; height: 1.05rem; }
html:not([data-theme="dark"]) .themebtn .i-sun { display: none; }
html[data-theme="dark"] .themebtn .i-moon { display: none; }
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .themebtn .i-moon { display: none; }
  html:not([data-theme="light"]) .themebtn .i-sun { display: block; }
}

/* ── hero ───────────────────────────────────────────────────────────── */
.hero { padding: clamp(3rem, 9vw, 6rem) 0 clamp(2rem, 5vw, 3.5rem); }
.hero h1 {
  font-size: clamp(2rem, 6.2vw, 3.4rem); line-height: 1.08;
  letter-spacing: -.025em; margin: 0 0 1rem; text-wrap: balance;
}
.hero .lead { font-size: clamp(1.05rem, 2.4vw, 1.3rem); color: var(--ink-soft); margin: 0 0 2rem; }
.grad { background: linear-gradient(100deg, var(--sapphire-lo), var(--sapphire));
  -webkit-background-clip: text; background-clip: text; color: transparent; }

.btn {
  display: inline-flex; align-items: center; gap: .55rem;
  background: linear-gradient(160deg, var(--sapphire-lo), var(--sapphire));
  color: #fff; text-decoration: none; font-weight: 700;
  padding: .85rem 1.4rem; border-radius: 999px; box-shadow: var(--shadow);
}
.btn:hover { filter: brightness(1.07); }
.btn--ghost {
  background: transparent; color: var(--ink); box-shadow: none;
  border: 1px solid var(--line); font-weight: 600;
}
.btn--ghost:hover { background: var(--bg-tint); filter: none; }
.btnrow { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; }

/* ── feature cards ──────────────────────────────────────────────────── */
.cards { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  padding-block: 1rem 3.5rem; }
.card {
  background: var(--bg-tint); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.35rem 1.4rem;
}
.card h3 { margin: 0 0 .4rem; font-size: 1.0625rem; letter-spacing: -.01em; }
.card p { margin: 0; color: var(--ink-soft); font-size: .97rem; }
.card__ico { font-size: 1.35rem; line-height: 1; margin-bottom: .7rem; display: block; }

/* ── sections & prose ───────────────────────────────────────────────── */
section { padding-block: clamp(2rem, 5vw, 3.5rem); }
h2 { font-size: clamp(1.4rem, 3.4vw, 1.9rem); letter-spacing: -.02em; margin: 0 0 1rem; text-wrap: balance; }
h3 { letter-spacing: -.01em; }
.prose h2 { margin-top: 2.5rem; }
.prose h3 { margin-top: 2rem; margin-bottom: .5rem; font-size: 1.15rem; }
.prose p, .prose li { color: var(--ink-soft); }
.prose > p:first-of-type { font-size: 1.14rem; color: var(--ink); }
.prose ul, .prose ol { padding-inline-start: 1.3rem; }
.prose li { margin-block: .35rem; }
.prose strong { color: var(--ink); }
.prose blockquote {
  margin: 1.6rem 0; padding: .1rem 0 .1rem 1.1rem;
  border-inline-start: 3px solid var(--accent); color: var(--ink-soft);
}
.note {
  background: var(--bg-tint); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.1rem 1.25rem; margin: 1.75rem 0;
}
.note p { margin: 0; }
.note p + p { margin-top: .6rem; }

table { width: 100%; border-collapse: collapse; margin: 1.5rem 0; font-size: .97rem; }
th, td { text-align: start; padding: .6rem .7rem; border-bottom: 1px solid var(--line); }
th { color: var(--ink); font-weight: 700; background: var(--bg-tint); }
td { color: var(--ink-soft); }
.scroll-x { overflow-x: auto; }

/* ── blog list ──────────────────────────────────────────────────────── */
.postlist { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; }
.postlist a {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.25rem 1.35rem; background: var(--bg);
}
.postlist a:hover { border-color: var(--accent); background: var(--bg-tint); }
.postlist h2 { font-size: 1.2rem; margin: 0 0 .35rem; }
.postlist p { margin: 0; color: var(--ink-soft); font-size: .97rem; }
.meta { color: var(--ink-faint); font-size: .8125rem; letter-spacing: .01em; }

.crumbs { padding-top: 1.5rem; font-size: .875rem; color: var(--ink-faint); }
.crumbs a { color: var(--ink-faint); }
/* padding-block, not the `padding` shorthand: the shorthand also sets
   padding-inline to 0, and because .shell is declared earlier it loses at
   equal specificity — which knocked the <h1> 1.25rem left of its own body
   text on every article page. */
.posthead { padding-block: 1rem .5rem; }
.posthead h1 { font-size: clamp(1.7rem, 4.6vw, 2.5rem); line-height: 1.15;
  letter-spacing: -.02em; margin: .5rem 0 .75rem; text-wrap: balance; }

/* ── footer ─────────────────────────────────────────────────────────── */
.foot { border-top: 1px solid var(--line); margin-top: 4rem; padding-block: 2.5rem 3rem;
  color: var(--ink-faint); font-size: .95rem; }
.foot__in { display: flex; flex-wrap: wrap; gap: 1rem 2rem; justify-content: space-between; }
.foot a { color: var(--ink-soft); }

/* ── narrow screens ─────────────────────────────────────────────────── */
@media (max-width: 46rem) {
  .top__in { height: auto; padding-block: .7rem; flex-wrap: wrap; }
  .top nav { margin-inline-start: 0; width: 100%; overflow-x: auto; }
  .brand { font-size: 1rem; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Home page: gradient mesh, device mockups, reveal-on-scroll.

   Rules this section obeys:
   · Motion is CSS-driven and decorative only — no content depends on it.
   · Reveal effects apply only under `html.js`, so without JavaScript every
     block renders visible. A crawler or reader-mode never sees opacity:0.
   · All of it collapses under prefers-reduced-motion.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── animated gradient mesh ──────────────────────────────────────────── */
.mesh { position: relative; isolation: isolate; overflow: clip; }
.mesh::before,
.mesh::after {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  inset: -30% -10% auto -10%; height: 130%;
  background:
    radial-gradient(38rem 26rem at 18% 22%, color-mix(in srgb, var(--sapphire-lo) 30%, transparent), transparent 65%),
    radial-gradient(30rem 22rem at 82% 12%, color-mix(in srgb, #7b5cff 26%, transparent), transparent 62%),
    radial-gradient(34rem 24rem at 62% 78%, color-mix(in srgb, #17c1c7 20%, transparent), transparent 66%);
  filter: blur(6px);
  animation: drift 26s ease-in-out infinite alternate;
}
.mesh::after {
  inset: -20% -20% auto -20%;
  background:
    radial-gradient(26rem 20rem at 78% 42%, color-mix(in srgb, var(--sapphire) 22%, transparent), transparent 60%),
    radial-gradient(24rem 18rem at 12% 68%, color-mix(in srgb, #ff7ac3 16%, transparent), transparent 60%);
  animation: drift2 34s ease-in-out infinite alternate;
}
@keyframes drift {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to   { transform: translate3d(3%, 2%, 0) scale(1.08); }
}
@keyframes drift2 {
  from { transform: translate3d(2%, 1%, 0) scale(1.05); }
  to   { transform: translate3d(-3%, -2%, 0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .mesh::before, .mesh::after { animation: none; }
}

/* ── hero layout with a device beside the copy ───────────────────────── */
.hero--split {
  display: grid; gap: clamp(2rem, 5vw, 4rem); align-items: center;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  padding-block: clamp(2.5rem, 8vw, 5.5rem) clamp(2rem, 6vw, 4rem);
}
.hero--split .prose { max-width: 34rem; }
.hero__art { display: grid; place-items: center; }

/* eyebrow */
.eyebrow {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: .8125rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-radius: 999px; padding: .4rem .8rem; margin-bottom: 1.1rem;
}
.eyebrow .dot {
  width: .45rem; height: .45rem; border-radius: 50%; background: currentColor;
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.8); } }
@media (prefers-reduced-motion: reduce) { .eyebrow .dot { animation: none; } }

/* ── phone frame ─────────────────────────────────────────────────────── */
.device {
  --w: clamp(13rem, 30vw, 17.5rem);
  width: var(--w); padding: .5rem; border-radius: 2.1rem;
  background: linear-gradient(160deg, #2b3550, #0f1524);
  box-shadow: 0 2px 4px rgba(9,14,26,.3), 0 34px 60px -24px rgba(9,14,26,.55),
              inset 0 0 0 1px rgba(255,255,255,.09);
  transform: rotate(-1.6deg);
  transition: transform .5s cubic-bezier(.2,.7,.2,1);
}
.device:hover { transform: rotate(0deg) translateY(-6px); }
.device img { border-radius: 1.7rem; display: block; }
.device--flat { transform: none; }
.device--flat:hover { transform: translateY(-6px); }
@media (prefers-reduced-motion: reduce) {
  .device, .device:hover, .device--flat:hover { transition: none; transform: none; }
}

/* ── official Google Play badge ──────────────────────────────────────── */
/* Google's badge must not be redrawn or restyled — it is shipped as their
   PNG at its own aspect ratio, with clear space around it. */
.gplay { display: inline-block; line-height: 0; }
.gplay img { width: 11.5rem; height: auto; }
.gplay:hover img { filter: brightness(1.06); }

/* ── split section (text + art) ──────────────────────────────────────── */
.split {
  display: grid; gap: clamp(1.75rem, 5vw, 3.5rem); align-items: center;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
/* Sides come from DOM order alone: put the image first in the markup and it
   renders on the left. An extra class to swap them turned out to make every
   section land the same way round, which is the opposite of alternating. */

/* ── stat strip ──────────────────────────────────────────────────────── */
.stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 1px; background: var(--line); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; margin-block: 1rem 0;
}
.stats div { background: var(--bg); padding: 1.1rem 1.2rem; }
.stats b { display: block; font-size: 1.5rem; letter-spacing: -.02em; }
.stats span { color: var(--ink-faint); font-size: .875rem; }

/* ── cards get depth and lift ────────────────────────────────────────── */
.card { transition: transform .35s cubic-bezier(.2,.7,.2,1), border-color .35s, box-shadow .35s; }
.card:hover {
  transform: translateY(-4px); border-color: color-mix(in srgb, var(--accent) 40%, var(--line));
  box-shadow: var(--shadow);
}
@media (prefers-reduced-motion: reduce) { .card, .card:hover { transition: none; transform: none; } }

/* ── closing call to action ──────────────────────────────────────────── */
.cta {
  border: 1px solid var(--line); border-radius: calc(var(--radius) + 6px);
  padding: clamp(1.75rem, 5vw, 3rem); text-align: center; margin-block: 1rem 0;
  background: var(--bg-tint);
}
.cta h2 { margin-bottom: .75rem; }
.cta p { color: var(--ink-soft); max-width: 34rem; margin-inline: auto; }
.cta .btnrow { justify-content: center; margin-top: 1.5rem; }

/* ── reveal on scroll (JS only) ──────────────────────────────────────── */
html.js .reveal { opacity: 0; transform: translateY(14px); }
html.js .reveal.in { opacity: 1; transform: none;
  transition: opacity .6s ease, transform .6s cubic-bezier(.2,.7,.2,1); }
html.js .reveal:nth-child(2) { transition-delay: .06s; }
html.js .reveal:nth-child(3) { transition-delay: .12s; }
html.js .reveal:nth-child(4) { transition-delay: .18s; }
html.js .reveal:nth-child(5) { transition-delay: .24s; }
html.js .reveal:nth-child(6) { transition-delay: .3s; }
@media (prefers-reduced-motion: reduce) {
  html.js .reveal { opacity: 1; transform: none; transition: none; }
}

/* ── mobile ──────────────────────────────────────────────────────────── */
@media (max-width: 56rem) {
  .hero--split { grid-template-columns: 1fr; padding-block: 2.25rem 1.5rem; }
  .hero--split .prose { max-width: none; }
  .hero__art { order: 2; }
  .device { --w: min(15rem, 62vw); transform: none; }
  .split { grid-template-columns: 1fr; }
  /* One column: the text always reads first, whichever side it sits on wide. */
  .split > .hero__art { order: 2; }
}
@media (max-width: 30rem) {
  body { font-size: 1rem; }
  .shell { padding-inline: 1rem; }
  .gplay img { width: 10.5rem; }
  .stats b { font-size: 1.3rem; }
  .cards { gap: .75rem; }
}

/* ── footer pinned to the bottom on short pages ──────────────────────── */
/* Blog indexes and 404 are short; without this the footer floats mid-screen. */
body { min-height: 100dvh; display: flex; flex-direction: column; }
main { flex: 1 0 auto; }
.foot { flex: none; }

/* ── pagination ──────────────────────────────────────────────────────── */
.pager {
  display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
  margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--line);
}
.pager a, .pager span {
  min-width: 2.5rem; padding: .5rem .7rem; border-radius: 10px; text-align: center;
  font-weight: 600; font-size: .95rem; text-decoration: none;
  border: 1px solid var(--line); color: var(--ink-soft);
}
.pager a:hover { color: var(--ink); background: var(--bg-tint); border-color: var(--accent); }
.pager [aria-current] { background: var(--sapphire); border-color: var(--sapphire); color: #fff; }
.pager .gap { border: 0; color: var(--ink-faint); min-width: 1rem; padding-inline: .2rem; }
.pager__side { margin-inline-start: auto; }
@media (max-width: 30rem) {
  .pager { justify-content: center; }
  .pager__side { margin-inline-start: 0; }
}

/* ── article kind + freshness ─────────────────────────────────────────── */
/* News posts must wear their date visibly: an undated claim about prices
   quietly turns false, and that is what destroys trust in a site like this. */
.kind {
  display: inline-block; font-size: .75rem; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase;
  padding: .2rem .5rem; border-radius: 6px; margin-inline-end: .5rem;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent);
}
.kind--news { background: color-mix(in srgb, #d97706 18%, transparent); color: #b45309; }
html[data-theme="dark"] .kind--news { color: #fbbf24; }
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .kind--news { color: #fbbf24; }
}
.postlist .meta { display: flex; align-items: center; flex-wrap: wrap; gap: .15rem .35rem; margin-bottom: .45rem; }

/* ── alternating text/image sections ─────────────────────────────────── */
.split + .split { margin-top: clamp(1rem, 4vw, 2.5rem); }
.split .prose { max-width: 32rem; }
.split .note { margin-bottom: 0; }

/* ═══ layout polish ═══════════════════════════════════════════════════ */

/* Text fills its column. Inside a .split the column is already ~30rem wide,
   which sits in the comfortable 45–75 character range, so an extra max-width
   there only left a ragged gap. Full-bleed body text across the whole 64rem
   shell is still avoided on purpose: past ~75 characters the eye loses the
   start of the next line. */
.split .prose { max-width: none; }
.hero--split .prose { max-width: 38rem; }
.hero h1, .hero .lead { max-width: 100%; }

/* Devices in the alternating sections are close to hero size now — the earlier
   step-down made the first screenshot look like a different product. */
.split .device { --w: clamp(12.5rem, 27vw, 16.5rem); }

/* A soft backdrop so a phone does not float alone on plain white. */
.hero__art { position: relative; }
.split .hero__art::before {
  content: ""; position: absolute; z-index: -1; inset: 8% -6% 2% -6%;
  border-radius: 50%;
  background:
    radial-gradient(closest-side, color-mix(in srgb, var(--sapphire-lo) 22%, transparent), transparent 72%),
    radial-gradient(closest-side at 70% 30%, color-mix(in srgb, #17c1c7 16%, transparent), transparent 70%);
  filter: blur(14px);
}
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .split .hero__art::before { opacity: .8; }
}
html[data-theme="dark"] .split .hero__art::before { opacity: .8; }

/* Give the alternating sections breathing room instead of hard edges. */
.split { padding-block: clamp(1.5rem, 4vw, 2.5rem); }

/* ── justified body text ─────────────────────────────────────────────── */
/* Paragraphs and list items are justified; headings are not — a justified
   heading stretches two words across a whole line and reads as broken. */
.prose p,
.prose li,
.note p {
  text-align: justify;
  /* ⚠ Automatic hyphenation is off deliberately. The browser produced breaks
     that do not exist in Ukrainian — "еле-ктроенергію" instead of "елек-" —
     which reads as illiteracy on a Ukrainian-language page. There is evidently
     no uk dictionary in play, only a generic fallback, and a wrong break costs
     more than the whitespace it saves. */
  hyphens: manual;
  -webkit-hyphens: manual;
  text-wrap: pretty;
}

/* Narrow screens fit few words per line, so justification turns into visible
   gaps. Below this width ragged-right simply reads better. */
@media (max-width: 34rem) {
  .prose p, .prose li, .note p { text-align: left; }
}

/* The hero lead stays ragged-right: it is display copy, and justifying a short
   two-line paragraph under a headline looks like a mistake rather than a
   choice. */
.hero .lead { text-align: left; }

/* Card icons were tried and dropped: a row of emoji renders differently on
   every OS, and a set of drawn marks read as decoration in a product that sells
   itself on not having decoration. The real screenshots carry the visuals. The
   icon set still lives in build.py as {{ICON_*}} if a card ever needs one. */
.card h3:first-child { margin-top: 0; }

/* ── card illustrations ──────────────────────────────────────────────── */
/* The generated art carries its own dark background — asking a model for
   transparency did not produce it, and keying a dark gradient out cleanly is
   not possible without halos. So the dark panel becomes the design: it reads as
   deliberate in the light theme and blends into the dark one. */
.card { padding: 0; overflow: hidden; }
.card > picture { display: block; }
.card__ill {
  width: 100%; height: auto; display: block;
  border-bottom: 1px solid var(--line);
}
.card h3 { margin: 1.15rem 1.4rem .4rem; }
.card p { margin: 0 1.4rem 1.35rem; }
