/*
Theme Name: Podii
Description: Легкая кастомная тема новостного агрегатора (без фреймворков — под PageSpeed).
Version: 1.0
Text Domain: podii
*/

:root {
  --color-bg: #faf6ef;
  --color-dark: #1c1f26;
  --color-dark-2: #33384a;
  --color-muted: #9a9fac;
  --color-muted-2: #b7bbc6;
  --color-accent: #ff5a3c;
  --color-accent-hover: #e04321;
  --color-border: #e8e8e8;
  --font-display: 'Archivo', sans-serif;
  --font-body: 'Inter', system-ui, sans-serif;
  --container: 1320px;
  --radius: 2px;
  --shadow-card: 0 4px 18px rgba(28, 31, 38, 0.08);
  --shadow-header: 0 2px 12px rgba(28, 31, 38, 0.06);

  /* Photo treatment — values taken verbatim from the UAPatriot v2 mockup, see the
     ".photo as texture" block below. Deliberately uniform: one field, one photo
     opacity, one accent. Deviating per block type was tried and rejected. */
  --photo-base: radial-gradient(120% 140% at 85% 10%, #143f75 0%, #0b1f3b 50%, #071426 100%);
  --photo-ink: 7, 20, 38;
  --photo-opacity: 0.75;
  --photo-accent: 255, 215, 0;
  --photo-grid: 38px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-bg);
  color: #111;
  font-family: var(--font-body);
}

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

img { max-width: 100%; display: block; }

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 32px;
}

/* Top bar */
.topbar { background: var(--color-dark); }
.topbar__inner {
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 32px; font-size: 13px; color: var(--color-muted-2);
  max-width: var(--container); margin: 0 auto;
}
.topbar__left { display: flex; align-items: center; gap: 18px; }
.topbar__left span:first-child + span { color: #4a4f5c; }
.topbar a { color: var(--color-muted-2); font-weight: 500; }

/* Header */
.site-header { background: #fff; box-shadow: var(--shadow-header); }
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px 32px 18px; max-width: var(--container); margin: 0 auto;
}
.logo {
  font-family: var(--font-display); font-weight: 900; font-size: 28px;
  letter-spacing: -0.5px; color: var(--color-dark);
}
.logo span { color: var(--color-accent); }
.main-nav { display: flex; align-items: center; gap: 36px; }
.main-nav a { font-size: 15px; font-weight: 600; color: #777; padding-bottom: 4px; }
.main-nav a.is-active { color: var(--color-dark); border-bottom: 2px solid var(--color-accent); }
.search-box {
  display: flex; align-items: center; gap: 8px; background: #f1ede5;
  border-radius: 20px; padding: 9px 16px; width: 220px;
}
.search-box input {
  border: none; background: none; outline: none; font-family: var(--font-body);
  font-size: 14px; color: var(--color-dark); width: 100%;
}

/* Ticker */
.ticker {
  display: flex; align-items: center; gap: 18px; padding: 14px 0;
  border-bottom: 1px solid var(--color-border); margin-top: 0;
}
.ticker__badge {
  display: flex; align-items: center; gap: 7px; background: var(--color-accent);
  color: #fff; font-size: 11.5px; font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase; padding: 6px 12px; border-radius: var(--radius); flex-shrink: 0;
}
.ticker__dot {
  width: 7px; height: 7px; border-radius: 50%; background: #fff;
  animation: pulse-dot 1.6s ease-in-out infinite;
}
@keyframes pulse-dot { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
/* Auto-scrolling marquee, same on mobile and desktop. .ticker__list is the clipping
   viewport; .ticker__track holds two identical .ticker__set copies back to back and
   animates translateX(-50%) — exactly one copy's width — so it loops with no visible
   seam. The 2nd copy is `inert` (skipped by screen readers and tab order alike, unlike
   aria-hidden alone which would leave its links focusable-but-invisible). */
.ticker__list { flex: 1; min-width: 0; overflow: hidden; }
.ticker__track {
  display: flex; align-items: center; width: max-content;
  animation: ticker-scroll 52s linear infinite;
}
.ticker__list:hover .ticker__track,
.ticker.is-paused .ticker__track { animation-play-state: paused; }
.ticker__set { display: flex; align-items: center; }
@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
.ticker__list a { font-size: 14px; font-weight: 600; color: #333; white-space: nowrap; }
.ticker__sep { color: #ccc; font-size: 13px; margin: 0 20px; }

@media (prefers-reduced-motion: reduce) {
  .ticker__track { animation: none; }
  .ticker__list { overflow-x: auto; }
}

/* ------------------------------------------------------------------
   Photo as texture, not as content

   Ported from the client's UAPatriot v2 mockup, values verbatim. The images are
   keyword-matched stock photos — generic by construction — so a full-colour photo at
   the top of a card reads as the loudest thing on the page while carrying none of the
   meaning. The fix is not "darken the image": it's that the container owns a designed
   gradient field and the photo is laid over it at reduced opacity, so it becomes
   surface rather than subject. A weak, irrelevant or missing photo then degrades
   into a deliberate-looking dark block instead of a wrong picture.

   The field is the mockup's deep navy (#071426…#143f75) rather than the theme's
   charcoal, and the accent glow is its yellow — that pairing is what makes the
   treatment read as designed rather than as a dimmed photo.

   Uniform on purpose. An earlier pass varied opacity by block (hero .55 / cards .7 /
   article .86) plus a desaturation filter; it read as "everything is equally dimmed"
   without buying any hierarchy, so it was dropped for the mockup's single value.

   Four layers over the photo, painted top-down in this order:
     1. accent glow   — a corner warmth so the field isn't flat grey
     2. hairline grid  — the mockup's signature; instantly reads "designed surface"
     3. diagonal sheen — a faint light streak across the panel
     4. scrim          — the actual darkening, heaviest where type sits
   All four live in one pseudo-element as stacked background-images, so no template
   needs four extra divs.
   ------------------------------------------------------------------ */

/* Hero */
.hero-grid { display: grid; grid-template-columns: 1fr; gap: 28px; margin-top: 32px; }
.hero {
  position: relative; display: block; border-radius: var(--radius); overflow: hidden;
  min-height: 460px; color: inherit;
}
/* Absolutely positioned, like .article-hero img — and for the same reason. Left in flow,
   the photo is what sizes the hero: `height: 100%` has no definite parent height to
   resolve against, so it falls back to auto and the frame takes the image's own ratio.
   The stock photos come from Pexels at whatever ratio they were shot in, so a 3:2 one
   rendered the hero ~950px tall instead of the 460 asked for here. */
.hero__img {
  position: absolute; inset: 0;
  background: var(--photo-base);
}
.hero__img img {
  width: 100%; height: 100%; object-fit: cover;
  opacity: var(--photo-opacity);
}
/* Mockup's hero stack: 105° scrim (heavy left, where the type sits), sheen, 56px grid,
   accent glow in the bottom-right corner. */
.hero__scrim {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(circle at 100% 100%, rgba(var(--photo-accent), 0.16) 0%, rgba(var(--photo-accent), 0) 55%),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px) 0 0 / 56px 100%,
    linear-gradient(118deg, rgba(255, 255, 255, 0) 38%, rgba(255, 255, 255, 0.07) 46%, rgba(255, 255, 255, 0) 54%),
    linear-gradient(105deg, rgba(var(--photo-ink), 0.92) 0%, rgba(var(--photo-ink), 0.74) 58%, rgba(var(--photo-ink), 0.56) 100%);
}
.hero__content { position: absolute; left: 28px; right: 28px; bottom: 26px; pointer-events: none; }
.hero__title {
  font-family: var(--font-display); font-weight: 800; font-size: 36px; line-height: 1.14;
  color: #fff; margin: 14px 0 10px;
}
.hero__time { color: #d8d8d8; font-size: 14px; font-weight: 500; }

.badge {
  display: inline-block; color: #fff; font-size: 12px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; padding: 5px 10px; border-radius: var(--radius);
}

/* News grid */
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-top: 56px; border-bottom: 1px solid var(--color-border); padding-bottom: 14px;
}
.section-head h2 {
  font-family: var(--font-display); font-weight: 800; font-size: 22px;
  letter-spacing: 0.02em; text-transform: uppercase; margin: 0;
}
.news-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 36px 32px; margin-top: 32px;
}
.news-card { display: block; color: inherit; }
.news-card__img {
  position: relative; width: 100%; aspect-ratio: 16 / 10; border-radius: var(--radius); overflow: hidden;
  background: var(--photo-base);
  /* Category colour, lightened until it survives on the dark field. Set per card as
     --cat; the raw token (e.g. Політика #2b3ea8) is unreadable here undiluted. */
  --cat-lit: color-mix(in srgb, var(--cat, var(--color-accent)) 42%, #ffffff);
}
.news-card__img img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: var(--photo-opacity);
}
/* Mockup's card stack: 160° scrim (heaviest at the bottom, under the rubric), sheen, 38px grid.
   The first layer is an extra bottom-anchored scrim added when the headline moved onto the
   photo: the 160° one runs diagonally, so it thins out towards the bottom-left corner —
   exactly where the first word of every headline sits. */
.news-card__img::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(var(--photo-ink), 0) 42%, rgba(var(--photo-ink), 0.55) 72%, rgba(var(--photo-ink), 0.9) 100%),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px) 0 0 / var(--photo-grid) 100%,
    linear-gradient(118deg, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0.06) 48%, rgba(255, 255, 255, 0) 56%),
    linear-gradient(160deg, rgba(var(--photo-ink), 0.48) 0%, rgba(var(--photo-ink), 0.88) 100%);
}
/* The rubric sits on the photo, as in the mockup — it gives the panel editorial
   meaning the stock photo doesn't have. */
.news-card__rubric {
  position: absolute; z-index: 2; left: 14px; top: 13px;
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-body); font-size: 10.5px; font-weight: 800;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--cat-lit);
}
.news-card__rubric::before { content: ''; width: 16px; height: 2px; background: var(--cat-lit); }
.news-card__title {
  font-family: var(--font-display); font-weight: 700; font-size: 19px; line-height: 1.3;
  margin: 8px 0 6px; color: #fff;
}
.news-card__time { font-size: 13px; color: #d8d8d8; font-weight: 500; }
/* Headline over the photo, same treatment as .hero__content — the card is one panel
   rather than a picture with a caption under it. */
.news-card__body {
  position: absolute; z-index: 2; left: 16px; right: 16px; bottom: 14px;
  pointer-events: none;
}
.news-card__body .ai-badge { margin-left: 0; }

/* Ken Burns on hover — slow zoom with a drift, across all three photo panels.
   Two transitions, not one: 9s going in (a Ken Burns that finishes fast isn't one — the
   point is that the movement is barely perceptible while it happens), 700ms coming back,
   because a pointer that leaves after half a second would otherwise spend nine more
   crawling home. Only the <img> moves; the scrim, rubric and headline are siblings or
   pseudo-elements, so the type stays put while the picture drifts under it.
   Gated on (hover: hover) — on touch the state latches on tap and never clears. */
@media (hover: hover) {
  .hero__img img,
  .news-card__img img,
  .article-hero img {
    /* 1.001, not 1: a non-identity transform is what gets the image its own compositing
       layer, so the zoom starts smoothly instead of stuttering on the first frame while
       the layer is created. Cheaper than will-change, which would pin a layer per image
       and costs real memory on a nine-card grid. */
    transform: scale(1.001);
    transition: transform 700ms ease-out;
  }
  .hero:hover .hero__img img,
  .news-card:hover .news-card__img img,
  .article-hero:hover img {
    transform: scale(1.09) translate3d(-1.6%, -1.4%, 0);
    transition: transform 9s cubic-bezier(0.16, 0.6, 0.32, 1);
  }
}
@media (prefers-reduced-motion: reduce) {
  .hero:hover .hero__img img,
  .news-card:hover .news-card__img img,
  .article-hero:hover img { transform: none; transition: none; }
}

/* Article page */
.article-back { display: inline-block; font-size: 14px; font-weight: 600; color: #777; margin-top: 24px; }
/* The headline block now sits inside .article-hero, over the photo — everything here
   is set for the dark field, not for paper. */
.article-title {
  font-family: var(--font-display); font-weight: 800; font-size: 38px; line-height: 1.15;
  margin: 16px 0 18px; color: #fff; text-wrap: balance; max-width: 780px;
}
.article-meta {
  display: flex; align-items: center; gap: 12px;
  border-top: 1px solid rgba(255, 255, 255, 0.14); padding-top: 16px;
}
.article-meta__avatar {
  width: 36px; height: 36px; border-radius: 50%; display: flex;
  align-items: center; justify-content: center; font-family: var(--font-display);
  font-weight: 800; font-size: 14px; flex-shrink: 0;
  background: rgba(255, 255, 255, 0.14); color: #fff;
}
.article-meta__name { font-size: 14px; font-weight: 700; color: rgba(255, 255, 255, 0.86); }
.article-meta__time { font-size: 13px; color: rgba(255, 255, 255, 0.55); }
/* No aspect-ratio any more: the headline lives inside, so the block is sized by its
   content with a floor. */
.article-hero {
  max-width: 1000px; margin: 24px auto 0; position: relative; width: 100%;
  min-height: 440px; display: flex; align-items: flex-end;
  border-radius: var(--radius); overflow: hidden; background: var(--photo-base);
}
.article-hero img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: var(--photo-opacity);
}
/* Mockup's article stack, 64px grid. Same 105° direction as the home hero, but the
   final stop is raised well above the mockup's 0.22: their photos are dark and shot
   for the layout, ours are bright keyword-matched stock, and a headline has to stay
   legible over whatever the search returned. */
.article-hero::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(circle at 100% 100%, rgba(var(--photo-accent), 0.15) 0%, rgba(var(--photo-accent), 0) 55%),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px) 0 0 / 64px 100%,
    linear-gradient(118deg, rgba(255, 255, 255, 0) 38%, rgba(255, 255, 255, 0.07) 46%, rgba(255, 255, 255, 0) 54%),
    linear-gradient(105deg, rgba(var(--photo-ink), 0.92) 0%, rgba(var(--photo-ink), 0.74) 58%, rgba(var(--photo-ink), 0.58) 100%);
}
.article-hero__content { position: relative; z-index: 2; padding: 40px 44px 34px; width: 100%; }
.article-hero__credit { z-index: 3; }
.article-hero__credit {
  position: absolute; right: 10px; bottom: 8px; font-size: 11px; color: #fff;
  background: rgba(0, 0, 0, 0.45); padding: 3px 8px; border-radius: var(--radius);
}
/* TEMPORARY — client-review marker, see podii_ai_badge() in functions.php.
   Renders only while PODII_SHOW_AI_BADGE is defined in wp-config.php (test server only). */
/* Amber on dark, the inverse of every category badge (white on colour). Two reasons for
   this colour and not another: the six editorial categories already occupy blue, orange,
   teal, violet, green and pink, so yellow is the only hue left that can't be misread as a
   rubric — and it's already in the design system as --photo-accent, the gold glow in the
   photo stack. Dark ink on a light chip also reads as a system marker rather than a label
   the newsroom chose. */
.ai-badge {
  display: inline-block; vertical-align: middle; margin-left: 8px;
  padding: 3px 9px; border-radius: 999px;
  background: rgb(var(--photo-accent)); color: #221a00;
  font-size: 11px; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; font-family: var(--font-body);
}
.ai-badge--card { margin-left: 6px; padding: 2px 7px; font-size: 10px; }

.article-body { max-width: 720px; margin: 36px auto 0; font-size: 18px; line-height: 1.7; color: #222; }
.article-body p { margin: 0 0 20px; }
/* Structure emitted by the wplb-ai-news generator: a lead paragraph, and an h2 for the
   originality block ("Що кажуть різні джерела" and friends). Imported RSS posts are plain
   paragraphs and are unaffected. */
.article-body p.wplb-ain-lead { font-size: 20px; font-weight: 500; color: #111; }
.article-body h2 {
  font-family: var(--font-display); font-weight: 800; font-size: 24px; line-height: 1.25;
  color: #111; margin: 34px 0 14px;
}
.article-body .wplb-ain-sources { margin-top: 28px; font-size: 14px; color: #777; }
.article-source {
  max-width: 720px; margin: 20px auto 0; font-size: 14px; color: #777;
  padding: 14px 16px; background: #fff; border-radius: var(--radius); box-shadow: var(--shadow-card);
}
.article-footer {
  max-width: 720px; margin: 32px auto 0; padding-top: 24px; border-top: 1px solid var(--color-border);
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 16px;
}
.tag-list { display: flex; gap: 8px; flex-wrap: wrap; }
.tag {
  font-size: 13px; font-weight: 600; color: #666; background: #fff; border-radius: 14px;
  padding: 6px 14px; box-shadow: var(--shadow-card);
}
.share-list { display: flex; gap: 10px; }
.share-list a {
  width: 36px; height: 36px; border-radius: 50%; background: #fff; box-shadow: var(--shadow-card);
  display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700;
  color: var(--color-dark);
}
/* Prev/next between articles. Two fixed columns rather than auto-fit: at the ends of the
   archive only one neighbour exists, and `--next` is pinned to column 2 so the single
   remaining button stays on its own side instead of sliding under the other one's label. */
.post-nav {
  max-width: 720px; margin: 32px auto 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
}
.post-nav__link {
  display: flex; flex-direction: column; gap: 7px;
  padding: 16px 18px; background: #fff; border-radius: var(--radius);
  box-shadow: var(--shadow-card); color: inherit;
  transition: box-shadow .2s ease, transform .2s ease;
}
.post-nav__link:hover { box-shadow: 0 8px 24px rgba(28, 31, 38, 0.14); transform: translateY(-2px); color: inherit; }
.post-nav__link--next { grid-column: 2; text-align: right; align-items: flex-end; }
.post-nav__label {
  font-family: var(--font-body); font-size: 11px; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase; color: var(--color-accent);
}
.post-nav__title {
  font-family: var(--font-display); font-weight: 700; font-size: 16px; line-height: 1.35;
  color: var(--color-dark);
}

.related-grid { max-width: 1000px; margin: 64px auto 0; }
.related-grid .news-grid { grid-template-columns: repeat(3, 1fr); }

/* Opinions */
.opinions-intro { max-width: 760px; margin: 36px 0 0; }
.opinions-intro h1 { font-family: var(--font-display); font-weight: 800; font-size: 32px; margin: 0 0 10px; }
.opinions-intro p { font-size: 15px; color: #666; line-height: 1.6; margin: 0; }
.opinions-layout { display: grid; grid-template-columns: 1fr 340px; gap: 32px; margin: 32px 0 0; align-items: start; }
.opinion-form-card { background: #fff; border-radius: var(--radius); padding: 32px; box-shadow: var(--shadow-card); }
.opinion-form-card h3 { font-family: var(--font-display); font-weight: 800; font-size: 19px; margin: 0 0 20px; }
.opinion-form-card label { display: block; font-size: 13px; font-weight: 700; color: var(--color-dark); margin: 18px 0 8px; }
.opinion-form-card label:first-of-type { margin-top: 0; }
.opinion-form-card textarea,
.opinion-form-card input {
  width: 100%; box-sizing: border-box; border: 1px solid #ddd; border-radius: var(--radius);
  padding: 12px 14px; font-family: var(--font-body); font-size: 15px; outline: none;
}
.opinion-form-card textarea { min-height: 110px; line-height: 1.5; resize: vertical; }
.opinion-counter { text-align: right; font-size: 12.5px; color: #999; margin-top: 6px; }
.opinion-hint { font-size: 12.5px; color: #999; margin-top: 6px; }
.opinion-error { margin-top: 14px; font-size: 13.5px; color: var(--color-accent); font-weight: 600; }
.opinion-btn {
  margin-top: 22px; width: 100%; background: var(--color-dark); color: #fff; border: none;
  border-radius: var(--radius); padding: 14px; font-family: var(--font-body); font-size: 15px;
  font-weight: 700; cursor: pointer;
}
.opinion-btn--ghost { background: none; color: #888; padding: 6px; font-size: 13.5px; margin-top: 10px; }
.opinion-btn--outline { background: none; border: 1px solid var(--color-dark); color: var(--color-dark); width: auto; padding: 11px 20px; }
.opinion-code-input {
  font-family: var(--font-display); font-size: 22px; font-weight: 700; letter-spacing: 10px;
  text-align: center; padding: 14px;
}
.opinion-demo-hint {
  background: #fff; border: 1px dashed #ccc; border-radius: var(--radius); padding: 10px 14px;
  font-size: 13px; color: #999; margin-bottom: 18px;
}
.opinion-side { display: flex; flex-direction: column; gap: 20px; }
.opinion-howto { background: var(--color-dark); color: #fff; border-radius: var(--radius); padding: 26px 22px; }
.opinion-howto h4, .opinion-rules h4 {
  font-family: var(--font-display); font-weight: 800; font-size: 15px; letter-spacing: 0.03em;
  text-transform: uppercase; margin: 0 0 18px;
}
.opinion-howto__step { display: flex; gap: 14px; margin-bottom: 16px; }
.opinion-howto__step:last-child { margin-bottom: 0; }
.opinion-howto__num { font-family: var(--font-display); font-weight: 800; font-size: 18px; color: var(--color-accent); flex-shrink: 0; width: 20px; }
.opinion-howto__text { font-size: 14px; line-height: 1.5; color: #ddd; }
.opinion-rules { background: #fff; border-radius: var(--radius); padding: 24px 22px; box-shadow: var(--shadow-card); }
.opinion-rules ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.opinion-rules li { display: flex; gap: 10px; font-size: 14px; color: #444; line-height: 1.5; }
.opinion-rules li::before { content: '—'; color: var(--color-accent); flex-shrink: 0; }
.opinions-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 28px; }
.opinion-card { background: #fff; border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow-card); }
.opinion-card p { font-size: 15.5px; line-height: 1.6; color: #222; margin: 0 0 16px; }
.opinion-card__meta { display: flex; align-items: center; justify-content: space-between; }
.opinion-card__name { font-size: 13.5px; font-weight: 700; color: var(--color-dark); }
.opinion-card__date { font-size: 12.5px; color: #999; }
.opinion-card__source {
  display: block; margin-top: 14px; padding-top: 12px; border-top: 1px solid #eee;
  font-size: 13px; font-weight: 600; color: var(--color-accent);
}
.opinion-success { text-align: center; padding: 12px 0; }
.opinion-success__check {
  width: 44px; height: 44px; border-radius: 50%; background: var(--color-dark); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 20px; font-weight: 800;
  margin: 0 auto 16px;
}

/* Opinion popup modal (triggered from an article or from another comment) */
.opinion-modal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; padding: 24px; }
.opinion-modal[hidden] { display: none; }
.opinion-modal__backdrop { position: absolute; inset: 0; background: rgba(28, 31, 38, 0.55); }
.opinion-modal__card {
  position: relative; background: #fff; border-radius: 4px; padding: 32px; width: 100%;
  max-width: 480px; max-height: 90vh; overflow-y: auto; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
.opinion-modal__close {
  position: absolute; top: 14px; right: 14px; width: 32px; height: 32px; border: none; background: none;
  font-size: 22px; line-height: 1; color: #999; cursor: pointer;
}
.opinion-modal__close:hover { color: var(--color-dark); }
.opinion-modal__replying-to {
  font-size: 13px; color: #777; background: #f7f4ee; border-radius: var(--radius);
  padding: 8px 12px; margin: 0 0 16px;
}

/* Comments thread (single.php) */
.comments-section { max-width: 720px; margin: 56px auto 0; }
.comment-thread { margin-top: 24px; display: flex; flex-direction: column; gap: 16px; }
.comment {
  background: #fff; border-radius: var(--radius); padding: 18px 20px; box-shadow: var(--shadow-card);
}
.comment__meta { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.comment__name { font-size: 13.5px; font-weight: 700; color: var(--color-dark); }
.comment__date { font-size: 12px; color: #999; }
.comment__text { font-size: 15px; line-height: 1.6; color: #222; margin: 0 0 10px; }
.comment__reply-btn {
  border: none; background: none; padding: 0; font-size: 12.5px; font-weight: 700;
  color: var(--color-accent); cursor: pointer;
}
.comment__children { margin: 14px 0 0 24px; padding-left: 18px; border-left: 2px solid #eee; display: flex; flex-direction: column; gap: 14px; }
.comment--reply { box-shadow: none; border: 1px solid #eee; }

/* Side ad rails — placeholders, no ad network wired up yet */
.ad-rail {
  position: fixed; top: 50%; transform: translateY(-50%); z-index: 5;
  width: 160px; height: 600px;
}
.ad-rail--left { left: max(12px, calc(50% - var(--container) / 2 - 176px)); }
.ad-rail--right { right: max(12px, calc(50% - var(--container) / 2 - 176px)); }
.ad-rail__inner {
  width: 100%; height: 100%; border: 1px dashed #d8d0c2; border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.5); display: flex; align-items: center; justify-content: center;
}
.ad-rail__label {
  font-size: 12px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: #aaa;
}
/* A real banner sizes the rail; only the empty placeholder needs the reserved 600px box. */
.ad-rail--filled { height: auto; }
.ad-rail__link { display: block; }
.ad-rail__img { display: block; width: 100%; height: auto; border-radius: var(--radius); }
.ad-rail__code { width: 100%; }
.ad-rail__code img,
.ad-rail__code iframe { max-width: 100%; }
@media (max-width: 1700px) {
  .ad-rail { display: none; }
}

/* Static pages (About) */
.page-content { max-width: 760px; margin: 40px auto 0; font-size: 17px; line-height: 1.7; color: #222; }
.page-content h1 { font-family: var(--font-display); font-weight: 800; font-size: 32px; color: var(--color-dark); }

/* Footer */
.site-footer { margin-top: 80px; background: var(--color-dark); }
.site-footer__inner { padding: 48px 32px 28px; max-width: var(--container); margin: 0 auto; }
.footer-grid { display: grid; grid-template-columns: 1.3fr 1fr 1fr 1fr; gap: 32px; }
.footer-grid .logo { color: #fff; }
.footer-about { font-size: 14px; color: var(--color-muted); line-height: 1.6; max-width: 280px; margin: 0; }
.footer-grid h4 {
  font-size: 13px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase;
  color: #fff; margin: 0 0 14px;
}
.footer-links { display: flex; flex-direction: column; gap: 10px; }
.footer-links a { font-size: 14px; color: var(--color-muted-2); }
.site-footer__bottom {
  margin-top: 36px; padding-top: 20px; border-top: 1px solid var(--color-dark-2);
  font-size: 13px; color: #7d818d;
}

@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; }
  .news-grid, .opinions-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .opinions-layout { grid-template-columns: 1fr; }
  .related-grid .news-grid { grid-template-columns: 1fr; }
}

/* Bottom app-style tab bar — markup in header.php, hidden entirely above the app-mode
   breakpoint so it never affects desktop layout. */
.mobile-tabbar { display: none; }

/* App mode: compact sticky top bar (logo only, like a mobile app) + fixed bottom tab bar
   with icons instead of the desktop topbar/.main-nav/.search-box row. */
@media (max-width: 768px) {
  body { padding-bottom: calc(58px + env(safe-area-inset-bottom, 0px)); }

  .container,
  .topbar__inner,
  .site-footer__inner { padding-left: 16px; padding-right: 16px; }

  /* Top bar (date/Kyiv/ads links) is desktop-only info chrome — no room for it in app mode. */
  .topbar { display: none; }

  .site-header { position: sticky; top: 0; z-index: 120; }
  .site-header__inner {
    padding: 14px 16px;
    justify-content: center;
    position: relative;
  }
  .logo { font-size: 21px; }
  .main-nav { display: none; }

  /* .search-box becomes a dropdown under the header, revealed by the bottom-bar Search tab
     (assets/js/mobile-nav.js toggles .is-search-open on .site-header). */
  .search-box {
    position: absolute;
    top: 100%; left: 0; right: 0;
    width: auto; margin: 0; border-radius: 0;
    background: #fff;
    box-shadow: var(--shadow-header);
    max-height: 0; opacity: 0; overflow: hidden;
    padding: 0 16px;
    transition: max-height .2s ease, opacity .15s ease, padding .2s ease;
  }
  .site-header.is-search-open .search-box {
    max-height: 64px; opacity: 1; padding: 12px 16px;
  }

  .mobile-tabbar {
    display: flex;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 150;
    background: #fff;
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -2px 14px rgba(28, 31, 38, 0.08);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .mobile-tabbar__item {
    flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; padding: 8px 4px 7px; border: none; background: none; cursor: pointer;
    font-family: var(--font-body); font-size: 10.5px; font-weight: 600; color: var(--color-muted);
  }
  .mobile-tabbar__item svg { width: 21px; height: 21px; }
  .mobile-tabbar__item.is-active,
  .mobile-tabbar__item[aria-expanded="true"] { color: var(--color-accent); }

  /* Compact typography/spacing — desktop values are tuned for a 1320px canvas. */
  .ticker { gap: 12px; }
  .ticker__sep { margin: 0 14px; }

  .hero { min-height: 300px; }
  .hero__content { left: 18px; right: 18px; bottom: 18px; }
  .hero__title { font-size: 24px; margin: 10px 0 8px; }

  .section-head { margin-top: 32px; padding-bottom: 12px; }
  .section-head h2 { font-size: 18px; }
  .news-grid { gap: 24px 20px; margin-top: 20px; }
  .news-card__title { font-size: 17px; margin: 6px 0; }

  .article-title { font-size: 26px; margin: 12px 0 14px; }
  /* The headline sits inside now, so the floor has to clear it — 200px would clip. */
  .article-hero { min-height: 340px; margin-top: 16px; }
  /* One column: the pinned column-2 and right alignment both have to be undone, or a
     lone "next" link sits in a phantom second column. */
  .post-nav { grid-template-columns: 1fr; gap: 12px; }
  .post-nav__link--next { grid-column: 1; text-align: left; align-items: flex-start; }
  .article-hero__content { padding: 24px 18px 20px; }

  /* The 105° scrim is built for a wide block: on a narrow portrait one it runs almost
     straight across, leaving the right half at its lightest stop right where the
     headline sits. Go bottom-heavy vertical instead — same layers, different axis. */
  .hero__scrim,
  .article-hero::after {
    background:
      radial-gradient(circle at 100% 100%, rgba(var(--photo-accent), 0.15) 0%, rgba(var(--photo-accent), 0) 55%),
      linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px) 0 0 / 44px 100%,
      linear-gradient(118deg, rgba(255, 255, 255, 0) 38%, rgba(255, 255, 255, 0.07) 46%, rgba(255, 255, 255, 0) 54%),
      linear-gradient(180deg, rgba(var(--photo-ink), 0.42) 0%, rgba(var(--photo-ink), 0.76) 46%, rgba(var(--photo-ink), 0.95) 100%);
  }
  .article-body { font-size: 16px; }

  .opinions-intro h1 { font-size: 24px; }
  .opinion-modal { padding: 16px; }
  .opinion-form-card { padding: 20px; }
  .comment__children { margin-left: 12px; padding-left: 12px; }

  .site-footer { margin-top: 48px; }
  .site-footer__inner { padding-top: 32px; padding-bottom: 20px; }
  .footer-grid { gap: 24px; }
}
