* { box-sizing: border-box; -webkit-tap-highlight-color: rgba(255,255,0,.18); }
html, body {
  margin: 0; padding: 0; background: #184B81; color: #FFFF00;
  font: 15px/1.5 Verdana, Geneva, "DejaVu Sans", Tahoma, sans-serif;
  min-height: 100vh;
}
body { display: flex; flex-direction: column; min-height: 100vh; }
/* The fragment-swap wrapper must not exist as far as layout is concerned. body is a
   flex column and the top bar, message and bottom bar are its flex items — with a real
   box in between, body has ONE child, the message stops growing, and the bottom bar
   rides up under the text instead of sitting at the bottom of the screen.
   display:contents removes the wrapper from the box tree while keeping it in the DOM,
   which is exactly what a swap target should be. */
#ez-swap { display: contents; }
/* Belt-and-suspenders: every native element inside the page inherits
   the same Verdana stack, so quoted upstream HTML (which may carry
   inline font="" / <font face=…> tags) doesn't fall back to a serif. */
.ez-body, .ez-body * { font-family: Verdana, Geneva, "DejaVu Sans", Tahoma, sans-serif; }

a { color: #FFFF00; }
a:visited { color: #FFFF00; }
a:active { color: #FFD; }

/* ── Top bar ────────────────────────────────────────────────────────────
   Subtle vertical gradient + bright yellow accent. The center column is
   a 2-row stack:
     row 1 — №ID (loud) + author (italic, dimmer) + date (tabular, muted)
     row 2 — pill-shaped chips for the per-author actions
   Both rows flex-wrap independently on narrow viewports, so a long
   nickname or a wide chip never pushes content off the screen. */
.ez-top {
  position: sticky; top: 0; z-index: 10;
  display: grid; grid-template-columns: 44px 1fr 44px;
  align-items: center; gap: 4px;
  padding: 8px 6px 10px;
  background: linear-gradient(180deg, #143961 0%, #102b4d 100%);
  border-bottom: 1px solid rgba(255, 255, 0, .35);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .35);
  font-family: Verdana, Geneva, "DejaVu Sans", Tahoma, sans-serif;
}
.ez-top .ez-nav {
  display: flex; align-items: center; justify-content: center;
  height: 38px; width: 38px; margin: 0 auto;
  border-radius: 50%; font-size: 18px; line-height: 1;
  color: #FFFF00; text-decoration: none;
  background: rgba(255, 255, 0, .08);
  border: 1px solid rgba(255, 255, 0, .25);
  transition: background .12s ease;
}
.ez-top .ez-nav:active { background: rgba(255, 255, 0, .28); }
.ez-top .ez-nav.ez-disabled {
  color: rgba(255, 255, 0, .22); border-color: rgba(255, 255, 0, .12);
  background: transparent; pointer-events: none;
}

.ez-id { text-align: center; min-width: 0; }
.ez-id-line {
  display: flex; gap: 4px 10px; justify-content: center; align-items: baseline;
  flex-wrap: wrap; line-height: 1.2;
}
.ez-id-num {
  color: #FFFF00; text-decoration: none;
  font-size: 17px; font-weight: 700; letter-spacing: .2px;
}
.ez-id-num:hover { text-decoration: underline; }
.ez-author {
  color: #d6e9ff; font-style: italic; font-weight: 600; font-size: 14px;
  max-width: 60vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Adepts — fellow proxy-interface users. Tinted light-cyan and tagged
   with a small bolt badge so they stand out among the regular forum
   crowd. Same colour family as the main pipeline (#ccffff) but slightly
   richer so it reads well on the dark header gradient. */
/* Compound selector (both classes are on the element) so the adept tint
   survives a user-set font colour: ColorOverride injects
   `.ez-author{color:FC!important}` (specificity 0,1,0) *after* this block,
   so a bare `.ez-author-adept` — equal specificity, no !important — would
   lose. `.ez-author.ez-author-adept` is 0,2,0 !important and wins on
   specificity regardless of source order. Mirrors the gb reader, where the
   adept colour also overrides the chosen font colour. */
.ez-author.ez-author-adept {
  color: #b9f7ff !important;
  text-shadow: 0 0 6px rgba(185, 247, 255, .35);
}
.ez-adept-badge {
  display: inline-block; margin-left: 5px; font-size: 11px; line-height: 1;
  color: #b9f7ff; opacity: .85; cursor: help;
  transform: translateY(-1px);
}
.ez-body .ez-adept { color: #b9f7ff !important; text-shadow: 0 0 6px rgba(185, 247, 255, .35); }
.ez-date {
  color: rgba(255, 255, 255, .55);
  font-size: 11px; font-variant-numeric: tabular-nums;
  font-family: ui-monospace, Consolas, "Lucida Console", monospace;
}

.ez-chips {
  display: flex; gap: 6px; justify-content: center; flex-wrap: wrap;
  margin-top: 7px;
}
.ez-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 0, .08);
  border: 1px solid rgba(255, 255, 0, .4);
  color: #FFFF00;
  font: 600 11.5px/1 Verdana, Geneva, sans-serif;
  letter-spacing: .2px;
  text-decoration: none;
  white-space: nowrap;
  transition: background .12s ease, border-color .12s ease;
}
.ez-chip:active { background: rgba(255, 255, 0, .26); border-color: rgba(255, 255, 0, .85); }
.ez-chip:hover  { background: rgba(255, 255, 0, .16); border-color: rgba(255, 255, 0, .65); }
.ez-chip-ico { font-size: 13px; line-height: 1; }
/* Reaction buttons, sized for a thumb.
   reactions.js styles the widget for the desktop guestbook: 12px text in a pill about
   22px tall, roughly half the ~44px a finger hits reliably — and this reader is used on
   a phone — though 40px overshot in practice, so these sit at 32px: still a comfortable
   thumb target in the header chip row, without the buttons dominating it.
   Scoped under #ez-swap, not .ez-body: the widget lives in the header chip row
   (.ez-top > .ez-chips), so a .ez-body prefix matched nothing at all. #ez-swap wraps
   every element of the reader and its 1,1,0 specificity beats the .fbr-* rules
   reactions.js injects at runtime, which land later in the cascade and would otherwise
   win on a tie.
   Both shapes are covered: the enhanced .fbr-trigger, and the server-rendered
   .ez-react-emoji/.ez-react-count pair that is on screen until reactions.js enhances it —
   or permanently, if a blocker ate that script. */
#ez-swap .fbr-trigger {
  font-size: 13px; padding: 5px 11px; border-radius: 9px; gap: 6px; opacity: 1;
  min-height: 32px; box-sizing: border-box;
}
#ez-swap .fbr-trig-emoji { font-size: 16px; }
#ez-swap .fbr-summary, #ez-swap .fbr-opt { font-size: 13px; }
#ez-swap .fbr-opt { padding: 5px 8px; }
#ez-swap .ez-react-emoji,
#ez-swap .ez-react-count {
  font-size: 16px; padding: 4px 9px; line-height: 1.15; min-height: 32px;
  border-radius: 8px; box-sizing: border-box;
}
#ez-swap .ez-react-count { font-size: 12px; }

/* Reaction widget («.ez-react») base styling lives in /reactions.js (shared with the
   gb reader) so the Facebook-style control is identical on both pages. */

/* Message body — single column, generous size, mobile-first */
.ez-body {
  flex: 1; max-width: 720px; width: 100%; margin: 0 auto;
  padding: 16px 14px 24px; word-wrap: break-word; overflow-wrap: anywhere;
}
.ez-body img { max-width: 100%; height: auto; }
.ez-body iframe, .ez-body video { max-width: 100%; }
.ez-body a { color: #fff8a8; }
.ez-body b { color: #FFFF00; }
/* Spoilers — <details> collapses natively; this only themes it for the dark EZ page. */
.ez-body details.obsilf-spoiler {
  display: inline-block; vertical-align: baseline;
  border: 1px dashed rgba(255,255,255,.4); border-radius: 4px;
  padding: 0 6px; margin: 1px 0; max-width: 100%;
}
.ez-body details.obsilf-spoiler > summary {
  cursor: pointer; user-select: none; font-size: .88em;
  opacity: .7; font-style: italic; list-style-position: inside;
}
.ez-body details.obsilf-spoiler[open] > summary { opacity: .45; }
.ez-body details.obsilf-spoiler[open] { border-style: solid; padding: 2px 6px; }
.ez-body .obsilf-code {
  display: block; font-family: ui-monospace, Consolas, "Courier New", monospace;
  white-space: pre-wrap; word-break: break-word; font-size: .92em;
  background: rgba(0,0,0,.28); border: 1px solid rgba(255,255,255,.28);
  border-radius: 4px; padding: 4px 8px; margin: 3px 0;
}
/* Topic label — leading <div class="topic"> on posts authored via this proxy.
   Yellow pill surfaces the topic and marks the post as "ours"; empty collapses. */
.ez-body .topic {
  display: block; width: fit-content; max-width: 100%;
  margin: 0 0 8px; padding: 1px 9px;
  font-size: 12px; font-weight: 700; line-height: 1.6;
  /* !important so the badge keeps its own dark-on-yellow palette even when the
     user set a font colour — ColorOverride injects `.ez-body *{color:FC!important}`
     after this block, which would otherwise repaint the label (e.g. yellow text on
     the yellow badge = invisible). (0,2,0)!important beats that (0,1,0)!important. */
  color: #10104a !important; background: #ffe86b !important; border-radius: 10px;
  letter-spacing: .02em; word-break: break-word;
}

/* Written through this site. Set server-side from a topic marker at the START of the
   body, so a quoted copy of someone else's proxy post does not mark this one.

   Just the icon: no rule, no wash, no padding. position:relative is the only other
   property, and only because the glyph is positioned against the message box. */
.ez-body.obsilf-authored { position: relative; }
.ez-body.obsilf-authored::after {
  content: "✎";
  position: absolute; top: 6px; right: 10px;
  font-size: 13px; line-height: 1; opacity: .6; pointer-events: none;
}
.ez-body .topic:empty { display: none; }
.ez-body cite { display: block; background: rgba(0,0,0,.18); padding: 8px 12px; margin: 8px 0; border-left: 3px solid #FFFF0080; font-style: italic; }
.ez-body font[color="WHITE"] { color: transparent !important; font-size: 0 !important; }

/* Bottom action bar — wraps on narrow screens, fat tap targets */
.ez-bottom {
  position: sticky; bottom: 0; z-index: 10;
  display: flex; flex-wrap: wrap; gap: 6px; justify-content: center;
  background: #143961; border-top: 1px solid #FFFF0066;
  padding: 8px;
}
.ez-btn {
  flex: 1 1 auto; min-width: 90px;
  text-align: center; text-decoration: none;
  padding: 10px 8px; border: 1px solid #FFFF00; border-radius: 4px;
  background: #184B81; color: #FFFF00; font: bold 13px 'book antiqua', serif;
}
.ez-btn:active { background: #FFFF00; color: #184B81; }
.ez-btn.ez-disabled { color: #FFFF0033; border-color: #FFFF0033; pointer-events: none; }
.ez-btn.reply { background: #FFFF00; color: #184B81; }
.ez-btn.refresh { flex: 0 0 56px; min-width: 56px; }
.ez-btn.unread { background: #1f5d9f; }
.ez-btn.newmsg { background: #1f5d9f; }
.ez-btn.last { background: #1f5d9f; }

/* Empty state */
.ez-empty {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 32px 18px; text-align: center; gap: 12px;
}
.ez-empty-icon { font-size: 64px; }
.ez-empty h1 { margin: 0; font-size: 22px; font-weight: bold; }
.ez-empty-meta { opacity: .85; font-size: 15px; }
.ez-hint { opacity: .6; font-size: 13px; }
.ez-empty-actions {
  display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 12px;
  width: 100%; max-width: 420px;
}

/* AI-portrait modal — same look as the main pipeline so the experience
   is identical when launched from EZ Reader. */
.ez-modal {
  position: fixed; inset: 0; z-index: 100; background: rgba(0,0,0,.72);
  display: flex; align-items: center; justify-content: center; padding: 12px;
}
.ez-modal-body {
  background: #222; color: #eee; border-radius: 8px; padding: 14px 18px;
  max-width: 680px; width: 92vw; max-height: 85vh; overflow-y: auto;
  border: 1px solid rgba(255,255,0,.4); position: relative;
  white-space: normal; word-break: normal; line-height: 1.5;
  font-family: system-ui, sans-serif;
}
.ez-modal-title { font-weight: bold; font-size: 14px; margin-bottom: 4px; }
.ez-modal-status { font-size: 12px; opacity: .7; margin-bottom: 10px; }
.ez-modal-content { white-space: pre-wrap; font-size: 13px; }
/* AI-розбір (understanding) modal content */
.ez-u-subj { font-weight: bold; font-size: 14px; color: #FFFF99; margin-bottom: 8px; }
.ez-u-meta { font-size: 11.5px; opacity: .85; margin: 8px 0 3px; }
.ez-u-meta a { color: #93c5fd; text-decoration: none; }
.ez-u-stance { background: rgba(255,255,0,.14); border: 1px solid rgba(255,255,0,.4); border-radius: 10px; padding: 1px 7px; font-size: 11px; }
.ez-u-tldr { font-size: 13px; line-height: 1.5; margin: 3px 0; }
.ez-u-ents { font-size: 11.5px; opacity: .75; margin-top: 5px; }
.ez-u-sep { border: none; border-top: 1px solid rgba(255,255,255,.13); margin: 12px 0; }
.ez-modal-btnrow { display: flex; justify-content: flex-end; margin-top: 14px; }
.ez-modal-close {
  padding: 5px 14px; cursor: pointer; font-size: 13px;
  background: #333; color: #eee; border: 1px solid #555; border-radius: 4px;
}

/* «№ NNN» message-ref preview popover styles live in /msg-preview.js (shared). */

/* «🆕 Нове повідомлення» toast — appears when the background poll
   discovers a message newer than the one currently displayed. Pinned
   to the top of the viewport, just under the header, with a soft glow
   so the user notices it even mid-scroll. Tap navigates to the new
   message; the ✕ dismisses without navigating. */
.ez-toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  top: 12px; z-index: 50;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px 8px 14px;
  background: #FFFF00; color: #184B81;
  border-radius: 999px;
  box-shadow: 0 4px 20px rgba(255, 255, 0, .35), 0 2px 8px rgba(0, 0, 0, .4);
  font: 700 13px/1.2 Verdana, Geneva, sans-serif;
  text-decoration: none;
  animation: ez-toast-in .25s ease-out;
  max-width: calc(100vw - 24px);
}
.ez-toast:active { transform: translateX(-50%) scale(.97); }
.ez-toast-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: rgba(24, 75, 129, .15); color: #184B81;
  border: none; font: 600 14px/1 sans-serif; cursor: pointer;
  padding: 0;
}
.ez-toast-close:hover { background: rgba(24, 75, 129, .3); }
/* Pulse-glow under the top bar — header gets a subtle yellow underline
   while the toast is up, so it's clear «something fresh waits». */
body.ez-has-new .ez-top { border-bottom-color: #FFFF00; box-shadow: 0 2px 12px rgba(255, 255, 0, .35); }
@keyframes ez-toast-in {
  from { opacity: 0; transform: translateX(-50%) translateY(-10px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* Keyboard-shortcut hint strip — small, dismissable, lives just under
   the bottom action bar. Hidden by default on coarse-pointer devices
   (phones/tablets) since they don't have a keyboard anyway. */
.ez-keys {
  position: sticky; bottom: 56px; z-index: 9;
  text-align: center; font-size: 11px; opacity: .7;
  padding: 4px 8px; background: #143961;
  border-top: 1px solid #FFFF0033;
}
.ez-keys kbd {
  display: inline-block; font-family: ui-monospace, Consolas, monospace;
  font-size: 10px; padding: 1px 5px; margin: 0 1px;
  border: 1px solid #FFFF0080; border-radius: 3px; background: #184B81;
}
.ez-keys.ez-keys-hidden { display: none; }
@media (pointer: coarse) and (hover: none) { .ez-keys { display: none; } }