/* ==========================================================================
   group-chat — screen.css
   Ghost theme for conversation-archetype sites: WhatsApp-style chat
   rendered as a readable blog transcript.

   Conventions
   - Mobile-first, single breakpoint at 720px.
   - Logical CSS properties (inline-start/end) so html[dir=rtl] just works.
   - Neutral grays + ONE accent (Ghost accent color, green fallback).
   - Text contrast >= 4.5:1 on all backgrounds.
   - Rubik everywhere (fleet rule).
   ========================================================================== */

/* ---------- design tokens ---------- */
:root {
  color-scheme: light;

  --gc-font: "Rubik", "Segoe UI", system-ui, -apple-system, "Segoe UI Emoji",
    "Apple Color Emoji", "Noto Color Emoji", sans-serif;

  /* neutral grays */
  --gc-ink: #1f2430;          /* primary text — 14.8:1 on white */
  --gc-ink-soft: #4a5162;     /* secondary text — 7.4:1 on white */
  --gc-ink-mute: #3c4254;     /* meta text on gray bubbles — 7:1+ */
  --gc-line: #e3e6ec;         /* hairlines */
  --gc-bg: #f6f7f9;           /* page background */
  --gc-surface: #ffffff;      /* cards, header */
  --gc-header-bg: rgba(255, 255, 255, 0.92); /* translucent sticky header */
  --gc-bubble: #f0f2f5;       /* chat bubble */
  --gc-bubble-accent: #e7f6ec;/* accent-tinted bubble */
  --gc-chip: #eceef2;         /* chips */
  --gc-chip-ink: #2c3342;     /* chip text — 9:1 on --gc-chip */
  --gc-placeholder: #6a7284;  /* input placeholder — 4.8:1 on white */
  --gc-code-bg: rgba(21, 26, 38, 0.08);      /* inline code inside a bubble */

  /* the single accent */
  --gc-accent: var(--ghost-accent-color, #16a34a);
  --gc-accent-ink: #146c3a;   /* accent for TEXT on white — 5.2:1 */
  --gc-accent-strong: #0f5a2e;/* accent button bg — 6.5:1 w/ white text */
  --gc-accent-text: var(--gc-accent-strong); /* accent as text on tinted chips */
  --gc-accent-strong-hover: #0c4a26;         /* accent button hover */
  --gc-focus-ring: var(--gc-accent);         /* focus outline (>= 3:1) */

  --gc-radius: 18px;
  --gc-radius-sm: 10px;
  --gc-bubble-gap: 8px;       /* vertical gap between stacked bubbles of one sender */
  --gc-shell: 720px;
  --gc-shadow: 0 1px 2px rgba(21, 26, 38, 0.06), 0 8px 24px rgba(21, 26, 38, 0.07);
  --gc-shadow-hover: 0 2px 4px rgba(21, 26, 38, 0.07), 0 14px 32px rgba(21, 26, 38, 0.1);
  --gc-shadow-panel: 0 24px 64px rgba(10, 14, 24, 0.35);
}

/* ---------- dark palette ----------
   Activated ONLY when html carries data-theme="dark" — the same attribute
   and the same localStorage key ("theme") group-press already uses, so a
   visitor who picked a mode on one blog keeps it on the other. The inline
   head script in default.hbs sets the attribute before the stylesheet is
   applied (no flash of light); assets/js/dark-mode.js owns the toggle.
   Every colour token above is redefined here — nothing light can leak
   through — and all text/background ratios are pinned >= 4.5:1 by
   tests/test_theme_dark_mode.py. */
html[data-theme="dark"] {
  color-scheme: dark;

  /* neutral grays */
  --gc-ink: #e9ecf2;          /* primary text — 15.5:1 on --gc-bg */
  --gc-ink-soft: #b6bdcb;     /* secondary text — 8.8:1 on --gc-surface */
  --gc-ink-mute: #dde2ea;     /* meta text on dark bubbles — 10.8:1 */
  --gc-line: #39404c;         /* hairlines */
  --gc-bg: #12151a;           /* page background */
  --gc-surface: #1b1f26;      /* cards, header */
  --gc-header-bg: rgba(18, 21, 26, 0.9);
  --gc-bubble: #262c35;       /* chat bubble */
  --gc-bubble-accent: #1d3527;/* accent-tinted bubble */
  --gc-chip: #262c35;         /* chips */
  --gc-chip-ink: #e2e6ee;     /* chip text — 11.2:1 on --gc-chip */
  --gc-placeholder: #9aa3b4;  /* 6.5:1 on --gc-surface */
  --gc-code-bg: rgba(255, 255, 255, 0.1);

  /* the single accent — the site's brand accent stays for fills/outlines,
     while accent TEXT switches to a light green: a dark green that reads
     on white cannot read on a dark surface, and vice versa. */
  --gc-accent: var(--ghost-accent-color, #16a34a);
  --gc-accent-ink: #5fd68b;   /* 9.0:1 on --gc-surface */
  --gc-accent-strong: #1f6b41;/* button/chip fill — 6.5:1 w/ white text */
  --gc-accent-text: #5fd68b;  /* 9.0:1 on --gc-surface */
  --gc-accent-strong-hover: #14462a;
  --gc-focus-ring: #7ee2a8;   /* 11.6:1 on --gc-bg */

  --gc-shadow: 0 1px 2px rgba(0, 0, 0, 0.55), 0 8px 24px rgba(0, 0, 0, 0.45);
  --gc-shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.5), 0 14px 32px rgba(0, 0, 0, 0.55);
  --gc-shadow-panel: 0 24px 64px rgba(0, 0, 0, 0.6);
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--gc-font);
  font-size: 16px;
  line-height: 1.6;
  color: var(--gc-ink);
  background: var(--gc-bg);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

img, video { max-width: 100%; height: auto; }

a { color: var(--gc-accent-ink); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
  outline: 3px solid var(--gc-focus-ring);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Both live group-chat blogs inject their own
   `:focus-visible{outline:2px solid var(--primary-subtle-color)}` through Ghost
   code injection. It lands after this sheet, so it wins on equal specificity —
   fine on a white page (9.3:1) but only 1.97:1 on a dark surface, i.e. the
   ring all but disappears in dark mode. One extra ancestor is enough to take
   the ring back there, and dark is the only mode whose look changes. */
html[data-theme="dark"] :focus-visible {
  outline: 3px solid var(--gc-focus-ring);
  outline-offset: 2px;
}

.gc-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.gc-skip-link {
  position: absolute;
  inset-inline-start: 1rem;
  top: -3rem;
  z-index: 100;
  padding: 0.5rem 1rem;
  background: var(--gc-surface);
  color: var(--gc-ink);
  border-radius: 0 0 var(--gc-radius-sm) var(--gc-radius-sm);
  box-shadow: var(--gc-shadow);
  transition: top 0.15s ease;
}
.gc-skip-link:focus { top: 0; }

.gc-shell {
  max-width: var(--gc-shell);
  margin-inline: auto;
  padding-inline: 16px;
}
.gc-shell--post { max-width: 760px; }

.gc-icon { width: 1.15em; height: 1.15em; fill: currentColor; flex: none; }

/* ---------- header ---------- */
.gc-site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--gc-header-bg);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--gc-line);
}
.gc-site-header .gc-shell {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 58px;
  /* Toolbar-wide shell (owner, 2026-10-14): the header is NOT capped at
     the 720px content shell — it stretches much wider so the brand, nav
     and controls share one line without word-wrapping. */
  max-width: 1100px;
}
.gc-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  color: var(--gc-ink);
  font-weight: 600;
  font-size: 1.02rem;
}
.gc-brand:hover { text-decoration: none; }
.gc-brand__icon { border-radius: 9px; flex: none; }
.gc-brand__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gc-nav {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  align-items: center;
  gap: 4px;
  /* Toolbar never word-wraps (owner, 2026-10-14): the header gets its own
     wide shell (see .gc-site-header .gc-shell) so all items fit on one
     line; if a very long site title or many items still squeeze it, the
     nav scrolls horizontally instead of wrapping to a second line. */
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.gc-nav::-webkit-scrollbar { display: none; }
.gc-nav__link {
  padding: 6px 12px;
  border-radius: 999px;
  color: var(--gc-ink-soft);
  font-size: 0.92rem;
  font-weight: 500;
  white-space: nowrap;
}
.gc-nav__link:hover { background: var(--gc-chip); color: var(--gc-ink); text-decoration: none; }
.gc-nav__link.is-current { background: var(--gc-bubble-accent); color: var(--gc-accent-text); }

@media (max-width: 719px) {
  .gc-nav {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .gc-nav::-webkit-scrollbar { display: none; }
  .gc-nav__link { padding: 5px 10px; font-size: 0.86rem; }
}

/* ---------- feed ---------- */
.gc-main { padding-block: 20px 48px; flex: 1 0 auto; }

.gc-feed__header { padding: 10px 4px 18px; }
.gc-feed__title {
  margin: 0 0 6px;
  font-size: 1.35rem;
  font-weight: 700;
}
.gc-feed__desc {
  margin: 0;
  color: var(--gc-ink-soft);
  font-size: 0.95rem;
}

/* --- conversation card --- */
.gc-card {
  background: var(--gc-surface);
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-radius);
  box-shadow: var(--gc-shadow);
  margin-bottom: 14px;
  overflow: hidden;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.gc-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--gc-shadow-hover);
}
.gc-card__link {
  display: block;
  padding: 16px 18px;
  color: inherit;
}
.gc-card__link:hover { text-decoration: none; }

.gc-card__top {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}

.gc-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--gc-chip);
  color: var(--gc-chip-ink);
  font-size: 0.78rem;
  font-weight: 500;
  line-height: 1.5;
}
.gc-chip--tag { background: var(--gc-bubble-accent); color: var(--gc-accent-text); }
.gc-chip--group .gc-icon { width: 0.95em; height: 0.95em; }

.gc-card__title {
  margin: 0 0 8px;
  font-size: 1.08rem;
  line-height: 1.45;
  font-weight: 600;
}
.gc-card__link:hover .gc-card__title { color: var(--gc-accent-text); }

.gc-card__meta {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--gc-ink-soft);
  font-size: 0.83rem;
}
.gc-card__meta-sep { color: var(--gc-line); }
.gc-card__hint {
  color: var(--gc-accent-ink);
  font-weight: 500;
  margin-inline-start: auto;
}

.gc-card__excerpt {
  margin: 10px 0 0;
  color: var(--gc-ink-soft);
  font-size: 0.9rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---------- pagination (Ghost default markup) ---------- */
.pagination {
  display: flex;
  justify-content: center;
  gap: 18px;
  padding: 18px 0 6px;
  font-size: 0.92rem;
}
.pagination a { color: var(--gc-accent-ink); font-weight: 500; }
.pagination .page-number { color: var(--gc-ink-soft); }

/* ==========================================================================
   POST — the transcript page
   ========================================================================== */
.gc-post { padding-top: 6px; }

.gc-post__header { padding: 14px 2px 18px; }

.gc-post__tag {
  display: inline-block;
  margin-bottom: 10px;
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--gc-bubble-accent);
  color: var(--gc-accent-text);
  font-size: 0.8rem;
  font-weight: 600;
}

.gc-post__title {
  margin: 0 0 10px;
  font-size: 1.45rem;
  line-height: 1.35;
  font-weight: 700;
}
@media (min-width: 720px) {
  .gc-post__title { font-size: 1.7rem; }
}

.gc-post__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  color: var(--gc-ink-soft);
  font-size: 0.88rem;
}
.gc-post__meta-sep { color: var(--gc-line); }
/* writer byline (#45): compact "By <author>" leading the meta row */
.gc-post__byline { display: inline-flex; align-items: baseline; gap: 4px; }
.gc-post__by { color: var(--gc-ink-soft); }
.gc-post__author { color: var(--gc-ink-soft); font-weight: 600; text-decoration: none; }
.gc-post__author:hover { text-decoration: underline; }
.gc-post__excerpt {
  flex-basis: 100%;
  margin: 6px 0 0;
  color: var(--gc-ink-soft);
}

/* --- share row: all buttons visually equal (no default highlight) --- */
.gc-share {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}
.gc-share__btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid var(--gc-line);
  border-radius: 999px;
  background: var(--gc-surface);
  color: var(--gc-ink-soft);
  font-size: 0.86rem;
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
}
.gc-share__btn:hover {
  background: var(--gc-chip);
  color: var(--gc-ink);
  text-decoration: none;
}

/* ==========================================================================
   TRANSCRIPT — server HTML: div.gc-msg blocks with dir="rtl"|"ltr"
   ========================================================================== */
.gc-transcript {
  background: var(--gc-surface);
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-radius);
  box-shadow: var(--gc-shadow);
  padding: 18px 14px 22px;
}
@media (min-width: 720px) {
  .gc-transcript { padding: 26px 26px 30px; }
}

/* generic <hr> inside transcript: subtle divider */
.gc-transcript hr {
  border: none;
  margin: 22px auto 18px;
  max-width: 220px;
  height: 1px;
  background: var(--gc-line);
}

/* ---------- message block ----------
   REAL server contract (pipeline/chat_pipeline.py, committed 10e3c8c):
     <div class="gc-date">2026-10-05</div>                    ← day separator
     <div class="gc-msg" dir="rtl|ltr">                       ← one sender group
       <div class="gc-sender">Dana</div>
       <p>text…</p> <figure class="kg-card">…</figure>        ← wa_to_html frags
       <div class="gc-time">10:04</div>
       <div class="gc-reactions" aria-label="reactions">🔥2 ❤️1</div>
     </div>
     <div class="gc-noise">· +3 short messages</div>

   Layout: padded block + absolutely-positioned avatar in a PHYSICAL gutter
   keyed to the page direction (WhatsApp convention: every avatar hugs the
   thread edge regardless of each bubble's own dir). Note: inset-inline-start
   would follow each block's OWN dir — wrong here — so physical sides below. */
.gc-msg {
  position: relative;
  /* comfortable gap between sender-group blocks; stacked same-sender
     paragraphs inside one block keep tight spacing via the p+p rule (4px) */
  margin: 0 0 22px;
  max-width: 100%;
}
.gc-msg:last-child { margin-bottom: 0; }
html[dir="ltr"] .gc-msg { padding-left: 46px; }
html[dir="rtl"] .gc-msg { padding-right: 46px; }

/* avatar circle in the gutter — physical side follows the page dir */
.gc-msg::before {
  content: "";
  position: absolute;
  top: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z'/%3E%3C/svg%3E"),
    linear-gradient(135deg, #9aa3b2, #6b7280);
  background-size: 20px 20px, cover;
  background-position: center;
  background-repeat: no-repeat;
}
html[dir="ltr"] .gc-msg::before { left: 0; }
html[dir="rtl"] .gc-msg::before { right: 0; }

/* real initials avatar (chat-bubble partial / transcript.js) replaces dot */
.gc-avatar {
  position: absolute;
  top: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  overflow: hidden;
}
html[dir="ltr"] .gc-avatar { left: 0; }
html[dir="rtl"] .gc-avatar { right: 0; }
.gc-msg:has(> .gc-avatar)::before { display: none; }

/* sender name + per-message time from the pipeline */
.gc-msg .gc-sender {
  margin: 0 2px 3px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--gc-accent-ink);
}
.gc-msg .gc-time {
  margin: 3px 2px 0;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--gc-ink-soft);
  text-align: start;
  width: fit-content;
}

/* the bubbles: content paragraphs get bubble chrome */
.gc-msg > p {
  margin: 0 0 4px;
  padding: 9px 14px;
  border-radius: 4px var(--gc-radius) var(--gc-radius) var(--gc-radius);
  background: var(--gc-bubble);
  color: var(--gc-ink-mute);
  overflow-wrap: break-word;
  max-width: 75%;
  width: fit-content;
}
html[dir="rtl"] .gc-msg > p {
  border-radius: var(--gc-radius) 4px var(--gc-radius) var(--gc-radius);
}

/* stacked bubbles from one sender get a real gap (Omer 2026-10-10: they were
   touching). Adjacent block margins collapse, so this margin-top IS the gap -
   it wins over the 4px bottom margin above. Never negative: the old -4px
   cancelled that bottom margin and measured 0px in the browser. */
.gc-msg > p + p {
  margin-top: var(--gc-bubble-gap);
  border-start-start-radius: var(--gc-radius-sm);
}

/* bubble typography */
.gc-msg p { line-height: 1.55; }
.gc-msg a {
  word-break: break-word;
  overflow-wrap: anywhere;
  unicode-bidi: isolate;
  direction: ltr;
  display: inline-block;      /* URL breaks follow LTR order, read naturally */
  max-width: 100%;
}
.gc-msg code {
  background: var(--gc-code-bg);
  border-radius: 5px;
  padding: 1px 5px;
  font-size: 0.88em;
}

/* media inside messages (kg-cards from the pipeline) */
.gc-msg .kg-image-card,
.gc-msg .kg-gallery-card,
.gc-msg .kg-video-card,
.gc-msg figure {
  margin: 8px 0;
  max-width: 75%;
  width: fit-content;
  border-radius: var(--gc-radius-sm);
  overflow: hidden;
  background: var(--gc-chip);
}
.gc-msg img { display: block; max-width: 100%; }
.gc-msg .kg-gallery-container { display: grid; gap: 4px; }
.gc-msg .kg-gallery-row { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px; }
.gc-msg .kg-video-container { position: relative; padding-top: 56.25%; }
.gc-msg .kg-video-container video { position: absolute; inset: 0; width: 100%; height: 100%; }

/* YouTube inline embeds (#45) — sports.nesher.co fleet pattern, copied from
   the live reader CSS: full-width responsive 16:9, no border, rounded, black
   letterbox background. Chat figures are capped at 75% width; media embeds
   break out to full width like the fleet sites. */
figure.r-video { margin: 1.5em 0; max-width: 100%; width: 100%; }
figure.r-video iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16/9;
  height: auto;
  border: 0;
  border-radius: 10px;
  background: #000;
}
.gc-msg figure.r-video { max-width: 100%; width: 100%; }
.gc-msg figcaption {
  padding: 6px 10px;
  font-size: 0.78rem;
  color: var(--gc-ink-soft);
}

/* per-message reaction chips (pipeline: <div class="gc-reactions">🔥2 ❤️1</div>).
   Emoji+count pairs are LTR runs — isolate them so they never invert inside
   an RTL bubble. Subtle pill container keeps ownership unambiguous. */
.gc-msg .gc-reactions {
  margin: 6px 2px 0;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--gc-bubble-accent);
  color: var(--gc-accent-text);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.1em;       /* separate emoji+count pairs */
  width: fit-content;
  unicode-bidi: isolate;
  direction: ltr;
}

/* date separator between days */
.gc-transcript .gc-date {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 20px 0 14px;
  color: var(--gc-ink-soft);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.gc-transcript .gc-date::before,
.gc-transcript .gc-date::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--gc-line);
}

/* skipped-messages notice (pipeline: · +N short messages) — LTR content */
.gc-transcript .gc-noise {
  margin: 8px 0;
  color: var(--gc-ink-soft);
  font-size: 0.78rem;
  font-style: italic;
  unicode-bidi: isolate;
  direction: ltr;
  text-align: start;
}
html[dir="ltr"] .gc-transcript .gc-noise { padding-left: 46px; }
html[dir="rtl"] .gc-transcript .gc-noise { padding-right: 46px; }

/* ==========================================================================
   REACTIONS — pipeline emits per-message rows:
   <div class="gc-reactions" aria-label="reactions">🔥2 ❤️1</div>
   styled above via .gc-msg .gc-reactions; transcript.js fills the aria-label.
   Legacy blockquote form (old render.py) keeps a minimal accent callout.
   ========================================================================== */
.gc-transcript blockquote {
  margin: 14px 0 6px;
  padding: 6px 14px;
  border-inline-start: 3px solid var(--gc-accent);
  border-radius: var(--gc-radius-sm);
  background: var(--gc-bubble-accent);
  color: var(--gc-accent-text);
  font-size: 0.88rem;
}

/* ---------- post footer ---------- */
.gc-post__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 18px 2px 0;
}

.gc-next-thread {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 18px;
  padding: 14px 16px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-radius);
  background: var(--gc-surface);
  color: inherit;
  box-shadow: var(--gc-shadow);
}
.gc-next-thread:hover { text-decoration: none; border-color: var(--gc-accent); }
.gc-next-thread__label {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gc-ink-soft);
}
.gc-next-thread__title { font-weight: 600; color: var(--gc-accent-ink); }

/* ---------- error page ---------- */
.gc-error {
  padding: 64px 8px 40px;
  text-align: center;
}
.gc-error__code {
  margin: 0;
  font-size: 4.5rem;
  font-weight: 700;
  line-height: 1;
  color: var(--gc-accent);
}
.gc-error__title { margin: 12px 0 6px; font-size: 1.3rem; }
.gc-error__text { margin: 0 0 22px; color: var(--gc-ink-soft); }
.gc-btn {
  display: inline-block;
  padding: 10px 22px;
  border-radius: 999px;
  background: var(--gc-accent-strong);
  color: #ffffff;
  font-weight: 600;
}
.gc-btn:hover { background: var(--gc-accent-strong-hover); color: #ffffff; text-decoration: none; }

/* ---------- footer ---------- */
.gc-site-footer {
  border-top: 1px solid var(--gc-line);
  background: var(--gc-surface);
  padding: 20px 0 26px;
}
.gc-footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin-bottom: 10px;
  font-size: 0.88rem;
}
.gc-footer-nav a { color: var(--gc-ink-soft); }
.gc-footer-meta {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  color: var(--gc-ink-soft);
  font-size: 0.84rem;
}
.gc-footer-meta a { color: var(--gc-accent-ink); font-weight: 500; }

/* ---------- motion safety ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .gc-card { transition: none; }
  .gc-theme-toggle { transition: none; }
}

/* ---------- print: transcript reads like a document ---------- */
@media print {
  .gc-site-header, .gc-share, .gc-site-footer, .gc-next-thread { display: none; }
  .gc-transcript { border: none; box-shadow: none; padding: 0; }
  /* printing a dark page would waste ink and print grey-on-black text:
     reset the palette to light for paper. */
  html[data-theme="dark"] {
    color-scheme: light;
    --gc-ink: #1f2430;
    --gc-ink-soft: #4a5162;
    --gc-ink-mute: #3c4254;
    --gc-line: #e3e6ec;
    --gc-bg: #ffffff;
    --gc-surface: #ffffff;
    --gc-bubble: #f0f2f5;
    --gc-bubble-accent: #e7f6ec;
    --gc-chip: #eceef2;
    --gc-chip-ink: #2c3342;
    --gc-accent-ink: #146c3a;
    --gc-accent-text: #0f5a2e;
    --gc-accent-strong: #0f5a2e;
    --gc-shadow: none;
  }
}

/* ==========================================================================
   HERO — site cover image with title overlay (index only)
   ========================================================================== */
.gc-hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 240px;
  max-height: 380px;
  margin: 0 0 20px;
  overflow: hidden;
  background: var(--gc-accent-strong); /* flat fallback band color */
}
.gc-hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
/* scrim keeps the title >= 4.5:1 over ANY cover image */
.gc-hero__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(10, 14, 8, 0.82) 0%, rgba(10, 14, 8, 0.55) 45%, rgba(10, 14, 8, 0.28) 100%),
    linear-gradient(to bottom, rgba(10, 14, 8, 0.35), rgba(10, 14, 8, 0) 30%);
}
.gc-hero__body {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--gc-shell);
  margin-inline: auto;
  padding: 20px 16px 24px;
  color: #ffffff;
  display: flex;
  align-items: center;
  gap: 14px;
}
.gc-hero__icon {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.18);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
.gc-hero__text { min-width: 0; }
.gc-hero__title {
  margin: 0 0 4px;
  font-size: 1.6rem;
  line-height: 1.25;
  font-weight: 700;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.4);
}
.gc-hero__desc {
  margin: 0;
  max-width: 56ch;
  color: rgba(255, 255, 255, 0.94); /* 4.6:1 over scrim bottom */
  font-size: 0.95rem;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
@media (min-width: 720px) {
  .gc-hero { min-height: 280px; }
  .gc-hero__title { font-size: 2rem; }
  .gc-hero__body { padding: 28px 16px 30px; }
}

/* ==========================================================================
   SEARCH — header toggle button + Content API dialog (native-search off)
   ========================================================================== */
.gc-search-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  border: 1px solid var(--gc-line);
  border-radius: 999px;
  background: var(--gc-surface);
  color: var(--gc-ink-soft);
  cursor: pointer;
}
.gc-search-toggle:hover { background: var(--gc-chip); color: var(--gc-ink); }
.gc-search-toggle .gc-icon { width: 18px; height: 18px; }

/* ---------- dark/light toggle — always in the header toolbar ----------
   Deliberately NEVER hidden: no display:none/position:fixed in any media
   query, so it rides the toolbar at every width (>= 320px) in rtl and ltr
   documents alike. Same 38px round look as the search button. The sun/moon
   SVGs are swapped purely by CSS from html[data-theme], so the correct icon
   is painted on the first frame; behaviour: assets/js/dark-mode.js. */
.gc-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid var(--gc-line);
  border-radius: 999px;
  background: var(--gc-surface);
  color: var(--gc-ink-soft);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.gc-theme-toggle:hover { background: var(--gc-chip); color: var(--gc-ink); }
.gc-theme-toggle .gc-icon { width: 18px; height: 18px; }
/* light mode shows the moon (the mode you'd switch to), like group-press */
.gc-theme-toggle__sun { display: none; }
html[data-theme="dark"] .gc-theme-toggle__sun { display: block; }
html[data-theme="dark"] .gc-theme-toggle__moon { display: none; }

/* dialog */
.gc-search[hidden] { display: none; }
.gc-search {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 8vh 16px 16px;
}
.gc-search-open { overflow: hidden; }
.gc-search__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 20, 32, 0.55);
  backdrop-filter: blur(3px);
}
.gc-search__panel {
  position: relative;
  width: 100%;
  max-width: 560px;
  max-height: 76vh;
  display: flex;
  flex-direction: column;
  background: var(--gc-surface);
  border-radius: var(--gc-radius);
  box-shadow: var(--gc-shadow-panel);
  overflow: hidden;
}
.gc-search__form {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--gc-line);
}
.gc-search__form .gc-icon { width: 18px; height: 18px; color: var(--gc-ink-soft); flex: none; }
.gc-search__input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font-family: inherit;
  font-size: 1.05rem;
  color: var(--gc-ink);
}
.gc-search__input::placeholder { color: var(--gc-placeholder); }
.gc-search__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: none;
  border: 1px solid var(--gc-line);
  border-radius: 999px;
  background: var(--gc-surface);
  color: var(--gc-ink-soft);
  cursor: pointer;
}
.gc-search__close:hover { background: var(--gc-chip); color: var(--gc-ink); }
.gc-search__close .gc-icon { width: 16px; height: 16px; }
.gc-search__results {
  overflow-y: auto;
  padding: 8px;
}
.gc-search__item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 10px;
  padding: 10px 12px;
  border-radius: var(--gc-radius-sm);
  color: inherit;
}
.gc-search__item:hover { background: var(--gc-chip); text-decoration: none; }
.gc-search__item-title { font-weight: 600; font-size: 0.95rem; }
.gc-search__item-meta { color: var(--gc-ink-soft); font-size: 0.78rem; }
.gc-search__empty {
  margin: 0;
  padding: 18px 16px 22px;
  color: var(--gc-ink-soft);
  font-size: 0.92rem;
  text-align: center;
}

/* semantic-archive section — below the content-results list */
.gc-search__semantic {
  flex: 0 1 auto;
  max-height: 38vh;
  overflow-y: auto;
  padding: 10px 14px 14px;
  border-top: 1px solid var(--gc-line);
  background: var(--gc-surface);
}
.gc-search__semantic[hidden] { display: none; }
.gc-search__semantic-title {
  margin: 2px 0 8px;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gc-ink-soft);
}
.gc-search__semantic-loading {
  margin: 0;
  padding: 2px 0 8px;
  color: var(--gc-ink-soft);
  font-size: 0.84rem;
  opacity: 0.85;
}
.gc-search__semantic-loading[hidden] { display: none; }
.gc-search__semantic-item {
  padding: 9px 0;
  border-top: 1px solid var(--gc-line);
}
.gc-search__semantic-results > .gc-search__semantic-item:first-child { border-top: 0; }
.gc-search__semantic-item-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  margin: 0 0 3px;
  color: var(--gc-ink-soft);
  font-size: 0.78rem;
}
.gc-search__semantic-item-sender { font-weight: 600; color: var(--gc-ink); }
.gc-search__semantic-item-sender + .gc-search__semantic-item-date::before { content: "·"; margin-inline: 6px; }
.gc-search__semantic-item-snippet {
  margin: 0;
  color: var(--gc-ink);
  font-size: 0.88rem;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ==========================================================================
   TAGBAR — horizontal scrollable category chip bar (index + tag pages)
   ========================================================================== */
/* topic/person filter dropdown (replaces horizontal chip scroller) */
.gc-tagdrop{display:flex;align-items:center;gap:10px;margin:14px 0 6px}
.gc-tagdrop__label{font-size:.8rem;opacity:.6}
.gc-tagdrop__wrap{position:relative;display:inline-block}
.gc-tagdrop__select{appearance:none;-webkit-appearance:none;min-width:220px;max-width:70vw;
  padding:8px 34px 8px 14px;border-radius:10px;border:1px solid rgba(128,128,128,.3);
  background:rgba(128,128,128,.1);font:inherit;font-size:.9rem;cursor:pointer}
html[dir="rtl"] .gc-tagdrop__select{padding:8px 14px 8px 34px}
.gc-tagdrop__select:focus{outline:2px solid var(--gc-accent-ink,inherit);outline-offset:1px}
.gc-tagdrop__arrow{position:absolute;top:50%;transform:translateY(-50%);pointer-events:none;
  opacity:.55;font-size:.8rem}
.gc-tagdrop__wrap .gc-tagdrop__arrow{inset-inline-end:12px}

.gc-tagbar {
  display: flex;
  gap: 8px;
  margin: 0 -16px 16px; /* bleed to viewport edges on mobile */
  padding: 2px 16px 8px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}
.gc-tagbar::-webkit-scrollbar { display: none; }
.gc-tagbar__chip {
  flex: none;
  scroll-snap-align: start;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--gc-line);
  background: var(--gc-surface);
  color: var(--gc-ink-soft);
  font-size: 0.85rem;
  font-weight: 500;
  white-space: nowrap;
}
.gc-tagbar__chip:hover { background: var(--gc-chip); color: var(--gc-ink); text-decoration: none; }
.gc-tagbar__chip.is-active {
  background: var(--gc-accent-strong);
  border-color: var(--gc-accent-strong);
  color: #ffffff;
}
@media (min-width: 720px) {
  .gc-tagbar { margin: 0 0 16px; }
}

/* ==========================================================================
   REACTIONS SUMMARY — pipeline aside at the top of the transcript
   <aside class="gc-reactions-summary"><span class="gc-rx-total">12</span>
     <span class="gc-rx-chip">🔥×5</span>…</aside>
   ========================================================================== */
.gc-reactions-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  padding: 10px 14px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-radius-sm);
  background: var(--gc-surface);
  box-shadow: var(--gc-shadow);
}
/* content direction (data-dir on transcript root or the aside's own dir) —
   chips flow from the content start edge */
.gc-reactions-summary .gc-rx-total {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--gc-accent-text);
}
.gc-reactions-summary .gc-rx-total::before {
  content: "✦";
  font-size: 0.8em;
  opacity: 0.7;
}
.gc-reactions-summary .gc-rx-chip {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--gc-chip);
  color: var(--gc-chip-ink);
  font-size: 0.82rem;
  font-weight: 500;
  /* emoji×count pairs are neutral/LTR runs — isolate so RTL never inverts */
  unicode-bidi: isolate;
  direction: ltr;
}
/* cap visible chips at 6 (JS hides the rest as a safety net) */
.gc-reactions-summary .gc-rx-chip:nth-child(n + 8) { display: none; }
/* n-th: total is child 1, chips start at 2 → chips 8+ are the 7th+ chip */

/* ==========================================================================
   TOC — thread overview card (post page, filled by transcript.js)
   ========================================================================== */
.gc-toc {
  margin: 0 0 16px;
  padding: 14px 16px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-radius);
  background: var(--gc-surface);
  box-shadow: var(--gc-shadow);
}
.gc-toc[hidden] { display: none; }
.gc-toc__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
}
.gc-toc__stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 72px;
}
.gc-toc__stat-value {
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--gc-ink);
}
.gc-toc__stat-label {
  font-size: 0.72rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gc-ink-soft);
}
.gc-toc__days {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--gc-line);
}
.gc-toc__days[hidden] { display: none; }
.gc-toc__day {
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid var(--gc-line);
  background: var(--gc-surface);
  color: var(--gc-ink-soft);
  font-size: 0.78rem;
  font-weight: 500;
}
.gc-toc__day:hover {
  background: var(--gc-bubble-accent);
  border-color: var(--gc-accent);
  color: var(--gc-accent-text);
  text-decoration: none;
}

/* ==========================================================================
   EXCERPT DIRECTION — alignment follows CONTENT language, not site locale.
   Pipeline contract: transcript root div carries data-dir="rtl|ltr"; theme
   re-uses it via [data-dir] + :dir() selectors so a Hebrew excerpt aligns
   right even on an English (LTR) site and vice versa.
   ========================================================================== */

/* post-card excerpt: server can't know content dir at listing time, so we
   start from the SITE dir and let a [data-dir] hint (pipeline sets it on the
   excerpt span, or transcript.js auto-detects) flip alignment per content
   language. Extra ancestor class = higher specificity than the html[dir]
   rules above, so content language always wins. */
.gc-card__excerpt { text-align: start; }
html[dir="rtl"] .gc-card__excerpt { text-align: right; }
html[dir="ltr"] .gc-card__excerpt { text-align: left; }
.gc-card .gc-card__excerpt[data-dir="rtl"] { text-align: right; }
.gc-card .gc-card__excerpt[data-dir="ltr"] { text-align: left; }

/* post-page excerpt sits inside .gc-post__meta whose dir follows the site;
   content-dir override via data-dir attribute (same contract) */
.gc-post__excerpt { text-align: start; }
html[dir="rtl"] .gc-post__excerpt { text-align: right; }
html[dir="ltr"] .gc-post__excerpt { text-align: left; }
.gc-post .gc-post__excerpt[data-dir="rtl"] { text-align: right; }
.gc-post .gc-post__excerpt[data-dir="ltr"] { text-align: left; }

/* transcript root data-dir governs ALL transcript content alignment when
   present (content language wins over site locale inside the transcript) */
.gc-transcript[data-dir="rtl"] { direction: rtl; }
.gc-transcript[data-dir="rtl"] .gc-noise { text-align: right; }
.gc-transcript[data-dir="ltr"] .gc-noise { text-align: left; }
/* day/date chips are digit runs — keep LTR ordering regardless */
.gc-transcript .gc-date { direction: ltr; }


/* ==========================================================================
   UI LANGUAGE PICKER — segmented [עב | EN] control (assets/js/ui-lang.js)
   Chrome labels only; <html dir> is never touched. direction:ltr keeps the
   segment order stable in RTL documents.
   ========================================================================== */
.gc-uilang {
  direction: ltr;
  display: inline-flex;
  align-items: center;
  flex: none;
  border: 1px solid var(--gc-line);
  border-radius: 999px;
  background: var(--gc-surface);
  overflow: hidden;
}
.gc-uilang__btn {
  -webkit-appearance: none;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--gc-ink-soft);
  cursor: pointer;
  font-family: var(--gc-font);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  line-height: 1;
  min-width: 32px;
  padding: 7px 8px;
  text-align: center;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.gc-uilang__btn + .gc-uilang__btn { border-left: 1px solid var(--gc-line); }
.gc-uilang__btn:hover { background: var(--gc-chip); color: var(--gc-ink); }
.gc-uilang__btn.is-active { background: var(--gc-accent-strong); color: #ffffff; }
.gc-uilang__btn.is-active:hover { color: #ffffff; }
.gc-uilang__btn:focus-visible { outline: 3px solid var(--gc-focus-ring); outline-offset: -3px; }
@media (max-width: 719px) {
  .gc-uilang__btn { min-width: 30px; padding: 6px 7px; font-size: 0.68rem; }
  .gc-nav { min-width: 0; } /* keep the nav scrollable, never push the picker out */
}

/* ==========================================================================
   DARK MODE — pipeline-published static pages
   (stats / members / gallery / about / directory)

   Those pages are generated by pipeline/pages.py, directory_page.py and
   gallery_page.py and ship their own inline <style> with hard-coded light
   colors. The generators are deliberately NOT touched (a change there would
   force a republish of every page on every site); instead these overrides
   carry one extra `html[data-theme="dark"]` ancestor, so they win over the
   inline same-class rules by specificity regardless of document order.
   Inline style ATTRIBUTES (the period note, heatmap cells) and SVG
   presentation attributes (chart bars/ticks) cannot be beaten by
   specificity, so those get a targeted selector / `!important` / fill rule.
   ========================================================================== */
html[data-theme="dark"] .gs-page { color: var(--gc-ink); background: var(--gc-surface); }
html[data-theme="dark"] .gs-page-foot { color: var(--gc-ink-soft); border-top-color: var(--gc-line); }
html[data-theme="dark"] .gs-page-foot a { color: var(--gc-accent-ink); }

/* cards + tables (stats / members) */
html[data-theme="dark"] .gs-card { background: var(--gc-chip); border-color: var(--gc-line); }
html[data-theme="dark"] .gs-card .l { color: var(--gc-ink-soft); }
html[data-theme="dark"] .gs-table th,
html[data-theme="dark"] .gs-table td { border-bottom-color: var(--gc-line); }
html[data-theme="dark"] .gs-table th { color: var(--gc-ink-soft); }

/* reactions leaderboard + inline-styled period note */
html[data-theme="dark"] .gs-rx { background: var(--gc-chip); border-color: var(--gc-line); }
html[data-theme="dark"] .gs-rx .c { color: var(--gc-ink-soft); }
html[data-theme="dark"] .gs-page [style*="color:#595959"] { color: var(--gc-ink-soft) !important; }

/* inline SVG chart: CSS fill beats the presentation attribute */
html[data-theme="dark"] .gs-page svg rect { fill: #5e93d8; }
html[data-theme="dark"] .gs-page svg text { fill: #a9b1c0; }

/* activity heatmap: cell intensity is an inline rgba() we cannot recompute,
   so keep the blue wash (it reads fine on dark) and only lift the labels +
   give the zero cells a faint outline so the grid stays visible */
html[data-theme="dark"] .gs-heat .gs-hd,
html[data-theme="dark"] .gs-heat .gs-hh { color: var(--gc-ink-soft); }
html[data-theme="dark"] .gs-heat .gs-hc { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06); }

/* members page */
html[data-theme="dark"] .gs-mcount { color: var(--gc-ink-soft); }
html[data-theme="dark"] .gs-member { background: var(--gc-chip); border-color: var(--gc-line); color: var(--gc-ink); }
html[data-theme="dark"] .gs-av0 { background: #24405f; color: var(--gc-ink); }
html[data-theme="dark"] .gs-phone { color: var(--gc-ink-soft); }
html[data-theme="dark"] .gs-mlink { color: var(--gc-accent-ink); }

/* gallery page (both generators share .gs-* names) */
html[data-theme="dark"] .gs-gallery figure { background: var(--gc-chip); border-color: var(--gc-line); }
html[data-theme="dark"] .gs-gallery img { background: var(--gc-chip); }
html[data-theme="dark"] .gs-gallery figcaption { color: var(--gc-ink-soft); }
html[data-theme="dark"] .gs-more { border-color: var(--gc-accent-ink); background: transparent; color: var(--gc-accent-ink); }
html[data-theme="dark"] .gs-more:hover { background: var(--gc-accent-strong); color: #ffffff; }
html[data-theme="dark"] .gs-gempty,
html[data-theme="dark"] .gs-gstatus { color: var(--gc-ink-soft); }
html[data-theme="dark"] .gs-gstatus.gs-gretry { color: var(--gc-accent-ink); }

/* about page */
html[data-theme="dark"] .gs-about-stats,
html[data-theme="dark"] .gs-about-members { color: var(--gc-ink-soft); }
html[data-theme="dark"] .gs-about-join { border-top-color: var(--gc-line); }

/* directory page — its own CSS is rgba(128,128,128,*) (neutral, adapts on
   its own); only the two fixed gradients need a nudge so they do not glare
   against the dark surface. Text on them is white in both modes. */
html[data-theme="dark"] .gs-dir-ava,
html[data-theme="dark"] .gs-dir-conv {
  background: linear-gradient(135deg, #24384f, #46617d);
}

/* Sort toolbar (directory pages) in dark mode — the generator ships light
   pills; these win by specificity like the rest of this block. */
html[data-theme="dark"] .gs-dir-sortbtn {
  border-color: var(--gc-line);
  color: var(--gc-ink-soft);
}
html[data-theme="dark"] .gs-dir-sortbtn:hover { background: var(--gc-chip); }
html[data-theme="dark"] .gs-dir-sortbtn.is-active {
  background: var(--gc-accent-strong);
  color: #ffffff;
  border-color: var(--gc-accent-strong);
}

/* Reply context inside a bubble (quoted message mirror, chat_pipeline
   .gc-quote): compact WhatsApp-style block above the message text. */
.gc-quote {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 0 8px;
  padding: 7px 11px;
  border-inline-start: 3px solid var(--gc-line);
  border-radius: 6px;
  background: var(--gc-chip);
  font-size: .86em;
}
.gc-quote__name { font-weight: 600; color: var(--gc-ink-soft); }
.gc-quote__text {
  color: var(--gc-ink-soft);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}

/* --- poll bubble (pipeline/polls.py) ----------------------------------- */
.gc-poll { background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.12);
           border-radius: 10px; padding: 10px 12px; margin: 6px 0; }
.gc-poll-q { font-weight: 700; margin-bottom: 8px; }
.gc-poll-multi { font-size: .72em; font-weight: 400; opacity: .7; }
.gc-poll-opt { margin: 8px 0; }
.gc-poll-opt-row { display: flex; justify-content: space-between; gap: 8px;
                   font-size: .95em; }
.gc-poll-opt-count { font-weight: 700; opacity: .85; }
.gc-poll-bar { height: 6px; border-radius: 3px; background: rgba(255,255,255,.12);
               overflow: hidden; margin-top: 4px; }
.gc-poll-bar span { display: block; height: 100%; border-radius: 3px;
                    background: #34b7f1; }
.gc-poll-voters { font-size: .78em; opacity: .65; margin-top: 3px; }
.gc-poll-total { font-size: .78em; opacity: .6; margin-top: 8px;
                 border-top: 1px solid rgba(255,255,255,.1); padding-top: 6px; }
.gc-poll-unavail { font-size: .75em; opacity: .5; margin-top: 4px; }

/* --- voice note + document cards (wa_format) ---------------------------- */
.gc-audio-card { display: flex; align-items: center; gap: 10px;
                 padding: 10px 12px; background: rgba(255,255,255,.06);
                 border: 1px solid rgba(255,255,255,.12); border-radius: 10px; }
.gc-audio-card audio { width: 100%; min-width: 200px; height: 36px; }
.gc-audio-label { font-size: 1.2em; }
.gc-audio-name { font-size: .8em; opacity: .7; }
.gc-file-card { display: flex; align-items: center; gap: 10px; padding: 12px 14px;
                background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.12);
                border-radius: 10px; text-decoration: none; color: inherit; }
.gc-file-card:hover { background: rgba(255,255,255,.1); }
.gc-file-icon { font-size: 1.3em; }
.gc-file-name { word-break: break-all; }

/* --- document card viewer (document_card / wa_format; #47 → #51) ---------
   #51: the doc card carries .gc-file-card too, whose flex ROW laid head,
   viewer and download side by side (visible on group-press; the kg-card
   figure styles themselves never reflow it). The doc card now forces its
   own vertical stack — display:block + float:none, children flow as blocks
   in DOM order (head -> viewer -> actions), so the post text above the
   card keeps its place in BOTH themes. Sizing fits the window per doc
   type: office landscape 16/10 with a 480px floor (the ~90px Office
   toolbar never crops the slide out of frame), PDF portrait 1/1.35 with a
   560px floor; both width:100% and capped at 85vh. The base rule keeps a
   portrait fallback for cards published before #51. The fullscreen button
   overlays the viewer's top corner (outside the Office iframe's own
   toolbar; the handler lives inline on the button). The <object> fallback
   paragraph is rendered only by browsers that cannot embed the PDF
   (soft-fail path) and never duplicates the head's filename while the
   viewer renders. #52: attachments that share a stem (same filename minus
   extension — one deck sent as .pptx + .pdf) render ONE viewer; the other
   formats are listed as compact download rows (.gc-doc-alt) under the
   download action. */
.gc-doc-card { display: block; float: none; margin: 10px 0; }
.gc-doc-card .gc-file-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.gc-doc-card .gc-file-name { font-weight: 600; word-break: break-all; }
.gc-doc-card .gc-file-size { opacity: .7; font-size: .85em; white-space: nowrap; }
.gc-doc-card .gc-doc-viewer { position: relative; width: 100%; aspect-ratio: 3 / 4; min-height: 420px; max-height: 85vh; margin: 10px 0 12px; background: #000; border-radius: 8px; overflow: hidden; }
.gc-doc-card .gc-doc-viewer.gc-doc-pdf { aspect-ratio: 1 / 1.35; min-height: 560px; }
.gc-doc-card .gc-doc-viewer.gc-doc-office { aspect-ratio: 16 / 10; min-height: 480px; }
.gc-doc-card .gc-doc-viewer object,
.gc-doc-card .gc-doc-viewer iframe { position: absolute; inset: 0; width: 100%; height: 100%; display: block; border: 0; background: #000; }
.gc-doc-card .gc-doc-fallback { position: absolute; inset: 0; margin: 0; display: flex; align-items: center; justify-content: center; padding: 12px; background: #111; color: #ddd; font-size: .9em; text-align: center; }
.gc-doc-card .gc-doc-fs { position: absolute; top: 8px; inset-inline-end: 8px; z-index: 10; padding: 5px 12px; font-size: .8em; font-weight: 600; line-height: 1.4; color: #111 !important; background: rgba(255,255,255,.95) !important; border: 1px solid rgba(0,0,0,.35) !important; border-radius: 6px; cursor: pointer; box-shadow: 0 1px 3px rgba(0,0,0,.35); }
.gc-doc-card .gc-doc-fs:hover { background: #fff !important; }
.gc-doc-card .gc-file-actions { margin: 10px 0 0; text-align: start; }
.gc-doc-card .gc-file-actions a { overflow-wrap: break-word; word-break: normal; text-decoration: underline; }
.gc-doc-missing { display: inline-flex; align-items: center; gap: 8px; opacity: .75; }
/* #52: compact download rows for the OTHER formats of the same document
   (same stem -> one viewer; the rest listed right under the download action) */
.gc-doc-card .gc-doc-alts { display: grid; gap: 4px; margin: 10px 0 0; }
.gc-doc-card .gc-doc-alt { display: flex; align-items: baseline; gap: 8px; padding: 4px 8px; border-radius: 6px; background: rgba(255,255,255,.06); color: inherit; text-decoration: none; }
.gc-doc-card .gc-doc-alt:hover { background: rgba(255,255,255,.12); }
.gc-doc-card .gc-doc-alt .gc-file-name { flex: 1 1 auto; min-width: 0; overflow-wrap: break-word; }
.gc-doc-card .gc-doc-alt .gc-file-size { opacity: .7; font-size: .85em; white-space: nowrap; }

/* --- post translation (docs/translation.md; group-chat 0.3.7) --------------
   translate.js swaps the transcript for a translated one and tags the
   container with gc-dir-ltr|gc-dir-rtl (plus a dir attribute on each
   .gc-msg when the reading direction flips). The base rules above key the
   avatar gutter and bubble alignment off <html dir> — the SITE language —
   so these re-key them to the TRANSLATED direction: bubbles and avatars
   flip sides, text-align follows, quote bars and poll bars mirror. */
.js-translate[hidden] { display: none !important; }  /* .gc-share__btn is inline-flex; the hidden attribute alone would lose */
.gc-transcript.gc-dir-ltr { text-align: left; }
.gc-transcript.gc-dir-rtl { text-align: right; }
.gc-transcript.gc-dir-ltr .gc-msg { direction: ltr; text-align: left;
                                    padding-left: 46px; padding-right: 0; }
.gc-transcript.gc-dir-rtl .gc-msg { direction: rtl; text-align: right;
                                    padding-right: 46px; padding-left: 0; }
.gc-transcript.gc-dir-ltr .gc-msg::before { left: 0; right: auto; }
.gc-transcript.gc-dir-rtl .gc-msg::before { right: 0; left: auto; }
.gc-transcript.gc-dir-ltr .gc-avatar { left: 0; right: auto; }
.gc-transcript.gc-dir-rtl .gc-avatar { right: 0; left: auto; }
.gc-transcript.gc-dir-ltr .gc-msg > p { margin-left: 0; margin-right: auto;
  border-radius: 4px var(--gc-radius) var(--gc-radius) var(--gc-radius); }
.gc-transcript.gc-dir-rtl .gc-msg > p { margin-right: 0; margin-left: auto;
  border-radius: var(--gc-radius) 4px var(--gc-radius) var(--gc-radius); }
.gc-transcript.gc-dir-ltr .gc-msg .gc-time { text-align: left; }
.gc-transcript.gc-dir-rtl .gc-msg .gc-time { text-align: right; }
.gc-transcript.gc-dir-ltr .gc-noise { padding-left: 46px; padding-right: 0; }
.gc-transcript.gc-dir-rtl .gc-noise { padding-right: 46px; padding-left: 0; }
/* quoted-reply bar, legacy blockquote and poll bars mirror to the
   translated reading edge (physical overrides beat the inline-start rules) */
.gc-transcript.gc-dir-ltr .gc-quote { border-left: 3px solid var(--gc-line); border-right: none; }
.gc-transcript.gc-dir-rtl .gc-quote { border-right: 3px solid var(--gc-line); border-left: none; }
.gc-transcript.gc-dir-ltr blockquote { border-left: 3px solid var(--gc-accent); border-right: none; }
.gc-transcript.gc-dir-rtl blockquote { border-right: 3px solid var(--gc-accent); border-left: none; }
.gc-transcript.gc-dir-ltr .gc-poll-bar { direction: ltr; }
.gc-transcript.gc-dir-rtl .gc-poll-bar { direction: rtl; }

/* caption injected under images whose text the vision pass translated */
figcaption.gc-tr-imgcap, .gc-msg figcaption.gc-tr-imgcap {
  display: block;
  padding: 5px 10px 7px;
  font-size: 0.74rem;
  font-style: italic;
  color: var(--gc-ink-soft);
  background: var(--gc-chip);
}

/* "show original" pill (translate.js inserts it after the transcript) */
.gs-tr-pill {
  display: inline-flex;
  align-items: center;
  margin: 10px 2px 0;
  padding: 6px 14px;
  border: 1px solid var(--gc-line);
  border-radius: 999px;
  background: var(--gc-surface);
  color: var(--gc-accent-ink);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--gc-shadow);
}
.gs-tr-pill:hover { border-color: var(--gc-accent); }
.gs-tr-pill[hidden] { display: none; }

/* error toast */
.gs-tr-toast {
  position: fixed;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9600;
  max-width: min(92vw, 480px);
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--gc-ink);
  color: var(--gc-bg);
  font-size: 0.88rem;
  box-shadow: var(--gc-shadow);
}

/* in-progress status pill: same spot/palette as the toast but persistent —
   translate.js raises it on choose() and takes it down on every terminal
   path (success, failure toast, poll cap). No auto-dismiss. */
.gs-tr-busy {
  position: fixed;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9600;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  max-width: min(92vw, 480px);
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--gc-ink);
  color: var(--gc-bg);
  font-size: 0.88rem;
  box-shadow: var(--gc-shadow);
}
.gs-tr-spin {
  width: 12px;
  height: 12px;
  flex: none;
  border-radius: 50%;
  border: 2px solid var(--gc-bg);
  border-top-color: transparent;
  opacity: 0.9;
}
/* the translate button while a job runs: progress cursor + spinning icon
   (a first-hit translation polls for minutes with no other page change) */
.js-translate[aria-busy="true"] { cursor: progress; }
@keyframes gs-tr-rot { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: no-preference) {
  .js-translate[aria-busy="true"] .gc-icon {
    animation: gs-tr-rot 1s linear infinite;
  }
  .gs-tr-spin { animation: gs-tr-rot 1s linear infinite; }
}
@media (prefers-reduced-motion: reduce) {
  .js-translate[aria-busy="true"] .gc-icon { opacity: 0.45; }
  .gs-tr-spin { animation: none; opacity: 0.45; }
}

/* language picker modal — the share-modal pattern */
.gs-tr-overlay {
  position: fixed;
  inset: 0;
  z-index: 9500;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(10, 14, 24, 0.55);
}
.gs-tr-overlay[hidden] { display: none; }
.gs-tr {
  width: min(92vw, 380px);
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  padding: 18px 20px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-radius);
  background: var(--gc-surface);
  color: var(--gc-ink);
  box-shadow: var(--gc-shadow);
}
.gs-tr__title { margin: 0 0 10px; font-size: 1.02rem; font-weight: 700; text-align: start; }
.gs-tr__list { margin: 0; padding: 0; list-style: none; overflow-y: auto; }
.gs-tr__item + .gs-tr__item { border-top: 1px solid var(--gc-line); }
.gs-tr__opt {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  width: 100%;
  padding: 9px 6px;
  border: 0;
  background: none;
  color: inherit;
  font-family: inherit;
  font-size: 0.95rem;
  text-align: start;
  cursor: pointer;
}
.gs-tr__opt:hover { background: var(--gc-chip); }
.gs-tr__native { font-weight: 600; }
.gs-tr__name { font-size: 0.8rem; color: var(--gc-ink-soft); }
.gs-tr__actions { display: flex; justify-content: flex-end; margin-top: 12px; }
.gs-tr__btn {
  padding: 7px 16px;
  border: 1px solid var(--gc-line);
  border-radius: 8px;
  background: none;
  color: inherit;
  font-family: inherit;
  font-size: 0.88rem;
  cursor: pointer;
}
.gs-tr__btn:hover { border-color: var(--gc-accent); }

/* daily summaries page (#53) — same pipeline-published-page pattern as the
   blocks above: the generator ships hard-coded light styles, the dark
   variants here carry one extra ancestor and win by specificity.
   #59 adds the linked day-cards (index) + the digest post body. */
html[data-theme="dark"] .gs-sum-card { background: var(--gc-chip); border-color: var(--gc-line); }
html[data-theme="dark"] .gs-sum-date { color: var(--gc-ink); }
html[data-theme="dark"] .gs-sum-chip { background: var(--gc-surface); border-color: var(--gc-line); color: var(--gc-ink); }
html[data-theme="dark"] .gs-sum-empty { color: var(--gc-ink-soft); }

/* events page (#60) — same pipeline-published-page pattern as the blocks
   above: the generator ships hard-coded light styles, the dark variants
   here carry one extra ancestor and win by specificity. */
html[data-theme="dark"] .gs-ev-card { background: var(--gc-chip); border-color: var(--gc-line); }
html[data-theme="dark"] .gs-ev-title { color: var(--gc-accent); }
html[data-theme="dark"] .gs-ev-where { color: var(--gc-ink-soft); }
html[data-theme="dark"] .gs-ev-status { background: var(--gc-surface); border-color: var(--gc-line); color: var(--gc-ink); }
html[data-theme="dark"] .gs-ev-past-head { border-color: var(--gc-line); color: var(--gc-ink-soft); }
html[data-theme="dark"] .gs-ev-empty { color: var(--gc-ink-soft); }
