/* briefing-content.css — main pane for the briefing page. Owns the
   news-item card grid, date-bucket separators, topic headers,
   refresh affordances (global + per-region + per-section), the
   stale banner, and the Phase 4 mark-as-read state. */

/* Date-bucket separator inserted between cards when the relative-date
   group changes (Today → Yesterday → N days ago …). Rendered as
   "──── today ────" with hairlines on both sides of centered text. */
.date-separator{display:flex;align-items:center;gap:12px;font-family:'Inter',sans-serif;font-size:11px;font-weight:600;color:#8a93a6;text-transform:uppercase;letter-spacing:.06em;margin:18px 0 10px}
.date-separator::before,
.date-separator::after{content:'';flex:1;height:1px;background:#e0e3ec}
.topic-section .date-separator:first-of-type{margin-top:6px}

.topic-section{margin-bottom:32px}
.topic-section.loading{opacity:.55}

.topic-header{display:flex;align-items:center;gap:10px;margin-bottom:16px;justify-content:space-between}
.topic-header-left{display:flex;align-items:center;gap:10px}
.topic-icon{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:18px}
.topic-icon.tech{background:#cfe2ff}
.topic-icon.politics{background:#e4d4fa}
.topic-icon.adtech{background:#cfeadb}
.topic-icon.football{background:#fbe0c2}
.topic-title{font-size:15px;font-weight:600;color:#0f1117}

/* News card grid. position:relative + padding-right reserve space for
   the Phase 29 mark-as-read tile floating in the top-right corner. */
.news-item{position:relative;display:flex;gap:14px;padding:14px;padding-right:60px;background:#fff;border:1px solid #d9dce6;border-radius:10px;margin-bottom:10px;align-items:flex-start}
.news-item:hover{background:#eef0f7;border-color:#b8bcce}
.news-thumb{width:160px;height:108px;border-radius:8px;overflow:hidden;flex-shrink:0;background:#d9dce6;display:flex;align-items:center;justify-content:center;font-size:36px;color:#5a6172}
.news-thumb img.full-thumb{width:100%;height:100%;object-fit:cover;border-radius:8px;display:block}
.news-thumb img.source-logo{width:32px;height:32px;object-fit:contain;display:block}
.news-content{flex:1;min-width:0}
.news-headline{margin-bottom:6px}
.news-headline a{color:#2945d6;text-decoration:none;font-weight:400;font-size:16px;line-height:1.4;font-family:'Slabo 27px','Slabo 13px',Georgia,serif}
.news-headline a:hover{color:#1f36ac}
.news-summary{font-size:13px;color:#5a6172;line-height:1.55;font-family:'Slabo 13px',Georgia,serif}

.news-meta{display:flex;gap:6px;align-items:center;margin-top:4px;flex-wrap:wrap}
.news-date{font-size:12px;color:#8a93a6;font-weight:500;cursor:help}
.news-date:not(:empty)::after{content:'·';margin-left:6px;color:#b8bcce}
.news-source{font-size:11px;color:#2945d6;font-weight:500;opacity:.85;margin-top:0}

@media(max-width:600px){
  .news-item{flex-direction:column}
  .news-thumb{width:100%;height:180px}
}

.flag{height:1em;width:auto;vertical-align:-0.12em;display:inline-block;margin-right:6px}

/* Refresh affordances — global, per-region, per-section. */
.refresh-wrap{display:flex;align-items:center;gap:10px}
.refresh-btn{padding:8px 16px;background:#2945d6;border:none;border-radius:8px;color:#fff;font-size:13px;font-weight:600;cursor:pointer;font-family:'Inter',sans-serif}
.refresh-btn:hover{background:#1f36ac}
.refresh-btn[disabled]{background:#9aa3c4;cursor:not-allowed}
.refresh-status{font-size:12px;color:#5a6172}

.mini-refresh{background:transparent;border:1px solid #d9dce6;border-radius:6px;padding:3px 8px;font-size:11px;color:#5a6172;cursor:pointer;font-family:'Inter',sans-serif}
.mini-refresh:hover{border-color:#2945d6;color:#2945d6}
.mini-refresh[disabled]{opacity:.5;cursor:not-allowed}

.region-col-header{display:flex;align-items:center;justify-content:space-between;gap:10px}
.region-refresh{background:#2945d6;border:none;border-radius:6px;padding:5px 10px;font-size:12px;color:#fff;cursor:pointer;font-family:'Inter',sans-serif;font-weight:600}
.region-refresh:hover{background:#1f36ac}
.region-refresh[disabled]{background:#9aa3c4;cursor:not-allowed}
.region-panel-bar{display:flex;justify-content:flex-end;margin-bottom:12px}

.header-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
/* Phase 36 follow-up — restyled to match the .show-read-btn alongside
   it in the sidebar header (transparent bg, 1px #dde1ea border, 6px
   radius, 5px×10px padding, #5a6175 idle text, #1a1d26 + #f3f4f8 bg
   on hover). The two utility chrome buttons now read as a matched
   pair. white-space:nowrap kept so the long "↻ Refresh all news"
   label doesn't break onto two lines. */
.global-refresh{padding:5px 10px;background:transparent;border:1px solid #dde1ea;border-radius:6px;color:#5a6175;font-size:12px;font-weight:500;cursor:pointer;font-family:'Inter',sans-serif;white-space:nowrap}
.global-refresh:hover{background:#f3f4f8;color:#1a1d26}
.global-refresh[disabled]{background:transparent;border-color:#e6e8ee;color:#b1b6c2;cursor:not-allowed}

/* Stale banner — shown when the briefing data hasn't been refreshed
   in a while. Static fallback path renders this on file:// loads. */
.stale-banner{display:none;align-items:center;justify-content:space-between;gap:12px;background:#fff4e0;border:1px solid #f4c87a;color:#7a4d00;padding:10px 14px;border-radius:8px;margin:12px 0;font-size:13px}
.stale-banner .stale-text{flex:1}
.stale-banner button{background:#7a4d00;border:none;color:#fff;border-radius:6px;padding:6px 12px;font-size:12px;font-weight:600;cursor:pointer;font-family:'Inter',sans-serif}
.stale-banner button:hover{background:#5a3800}
.refresh-failed{color:#b3261e !important}

/* ── Mark-as-read (Phase 4 + Phase 29) ────────────────────────────── */
/* Read items are hidden by default; toggling Show read on body shows
   them faded so the user can find and unread something they dismissed. */
.news-item.read{display:none}
body.show-read .news-item.read{display:flex;opacity:.55}
body.show-read .news-item.read:hover{opacity:.8}

/* Phase 29 — large floating mark-as-read tile in the top-right corner
   of every .news-item. Replaces the tiny ✓ button that was effectively
   invisible in the modular CSS (no rule existed for it). Visual = a
   green check PNG (read-check.png, hosted under html-root/) shown via
   `background-image`. Same idiom as the Phase 30 pin button: idle
   state is grayscaled + faded, active state is full color. The
   visible glyph IS the icon, no border/box fill needed.
   .news-item already gets position:relative + padding-right above so
   the absolute positioning has a containing block and the title text
   doesn't run under the tile. */
.news-read-tile{
  position:absolute;
  top:10px;
  right:10px;
  width:36px;
  height:36px;
  background-color:#f5f6fa;
  border:1.5px solid #d9dce6;
  border-radius:8px;
  cursor:pointer;
  padding:0;
  overflow:hidden;
  transition:background-color .12s,border-color .12s,box-shadow .12s,transform .08s;
  z-index:2;
}
.news-read-tile::before{
  content:"";
  display:block;
  width:100%;
  height:100%;
  /* Inline green-tick SVG — no file dependency, no precache hop. The
     stroke colour `%233aa971` is `#3aa971` URL-encoded; `%23` ≡ `#`. */
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233aa971' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12.5L10 17.5L19 7'/></svg>");
  background-repeat:no-repeat;
  background-position:center;
  background-size:22px 22px;
  opacity:.5;
  transition:opacity .12s,background-size .12s;
}
.news-read-tile:hover{
  background-color:#fff;
  border-color:#b8bcce;
  box-shadow:0 2px 8px rgba(0,0,0,.08);
}
.news-read-tile:hover::before{opacity:.9}
.news-read-tile:active{transform:scale(.94)}
.news-read-tile[aria-pressed="true"]{
  background-color:#eaf6ee;
  border-color:#9bc8ad;
  box-shadow:0 1px 3px rgba(58,169,113,.18);
}
.news-read-tile[aria-pressed="true"]::before{opacity:1;background-size:26px 26px}
.news-read-tile[aria-pressed="true"]:hover{
  background-color:#dcefdf;
  border-color:#3aa971;
  box-shadow:0 2px 8px rgba(58,169,113,.22);
}
@media (prefers-reduced-motion: reduce){
  .news-read-tile,.news-read-tile::before{transition:none}
  .news-read-tile:active{transform:none}
}
@media (max-width:600px){
  /* On narrow viewports the card switches to flex-direction:column;
     keep the tile in the corner but tighten margins so it doesn't
     crowd a stacked thumbnail above it. */
  .news-item{padding-right:54px}
  .news-read-tile{top:8px;right:8px;width:34px;height:34px}
  .news-read-tile::before{background-size:22px 22px}
  .news-read-tile[aria-pressed="true"]::before{background-size:24px 24px}
}

/* Phase 6 — keyboard-selection highlight. The .selected class is
   added/removed by briefing/keyboard.js's _setSelectedCard as the
   user navigates with j/k. scroll-margin-top accounts for any
   sticky header (the briefing layout's main pane is full-height
   so the value is small; just enough to keep the row from sitting
   right at the viewport edge after scrollIntoView({block:'nearest'}). */
.news-item.selected{
  outline:2px solid #2945d6;
  outline-offset:-2px;
  background:#eef1fb;
  border-color:#2945d6;
  box-shadow:0 2px 12px rgba(41,69,214,.18);
  scroll-margin-top:24px;
}

/* Cheatsheet modal toggled by `?` (briefing/keyboard.js). */
/* Phase 75 — z-index raised well above reader overlays (chapter list /
   onboarding at 1100). Using 9000 to win even against compositing-layer
   promotion from the chapter list's transform animation.
   The `transform:translateZ(0)` on .show forces the cheatsheet into its
   own composited layer so it paints above the chapter-list's transform-
   animated composited layer regardless of GPU layer ordering. The ID rule
   below is belt-and-suspenders: an ID selector outranks .shortcuts-hint
   (class selector) so DevTools will show the right winning rule. */
.cheatsheet{
  position:fixed;
  inset:0;
  background:rgba(15,18,24,.55);
  display:none;
  align-items:center;
  justify-content:center;
  z-index:9000;
  font-family:'Inter',sans-serif;
}
.cheatsheet.show{ display:flex; transform:translateZ(0) }
/* ID rule — higher specificity than any class rule; ensures the modal
   is never pulled down to z-index:60 by .shortcuts-hint or anything else. */
#shortcutsCheatsheet{ z-index:9000 !important }
.cheatsheet-card{
  background:#fff;
  border-radius:14px;
  padding:24px 28px;
  max-width:420px;
  width:calc(100% - 48px);
  box-shadow:0 20px 80px rgba(0,0,0,.35);
}
.cheatsheet-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  margin-bottom:14px;
}
.cheatsheet-head h4{ margin:0; font-size:16px; color:#1c2030 }
.cheatsheet-close{
  background:transparent;
  border:none;
  color:#5a6172;
  font-size:18px;
  cursor:pointer;
  padding:2px 8px;
  border-radius:4px;
}
.cheatsheet-close:hover{ background:#eef0f7; color:#1c2030 }
.cheatsheet-table{
  width:100%;
  border-collapse:collapse;
  font-size:13px;
}
.cheatsheet-table td{ padding:6px 8px; vertical-align:middle }
.cheatsheet-table td.kbd{ width:120px; white-space:nowrap }
.cheatsheet kbd{
  display:inline-block;
  padding:2px 7px;
  background:#f5f6fa;
  border:1px solid #d9dce6;
  border-radius:4px;
  font-family:'JetBrains Mono','Menlo','Consolas',monospace;
  font-size:11px;
  font-weight:600;
  color:#3a4154;
}

/* Floating bottom-right hint button auto-injected by keyboard.js. */
.shortcuts-hint{
  position:fixed;
  bottom:18px;
  right:18px;
  padding:6px 12px;
  background:#fff;
  border:1px solid #d9dce6;
  border-radius:18px;
  font-size:11px;
  color:#5a6172;
  cursor:pointer;
  font-family:'Inter',sans-serif;
  box-shadow:0 2px 8px rgba(15,17,23,.08);
  z-index:9000;
}
.shortcuts-hint:hover{
  border-color:#2945d6;
  color:#2945d6;
}
.shortcuts-hint kbd{
  display:inline-block;
  padding:1px 5px;
  background:#f5f6fa;
  border:1px solid #d9dce6;
  border-radius:3px;
  font-family:'JetBrains Mono','Menlo','Consolas',monospace;
  font-size:10px;
  margin:0 2px;
}
/* Phase 50c — mobile: the keyboard-shortcuts hint is meaningless on a touch
   device (no keys to press, and it just floats over content), so hide it. The
   `?` cheatsheet it opens is keyboard-only and never surfaces on mobile. */
@media (max-width: 800px){
  .shortcuts-hint{ display:none; }
}

/* Phase 13e-ii — Empty-library state. Mounted by loader.js's
   _renderLibraryEmptyState() when /api/briefing returns regions:[]
   (signed-in user with no subscriptions). Centered card in the main
   content pane with a link to /settings. */
.library-empty-state{
  display:flex;
  align-items:center;
  justify-content:center;
  padding:60px 20px;
}
.library-empty-state-card{
  max-width:520px;
  background:#fff;
  border:1px solid #d9dce6;
  border-radius:10px;
  padding:28px 32px;
  text-align:center;
  box-shadow:0 1px 4px rgba(15,17,23,.04);
}
.library-empty-state-card h2{
  margin:0 0 12px;
  font-size:20px;
  font-weight:600;
  color:#0f1117;
}
.library-empty-state-card p{
  margin:0;
  font-size:14px;
  line-height:1.55;
  color:#3a4154;
}
.library-empty-state-card a{
  color:#2945d6;
  text-decoration:none;
  font-weight:500;
}
.library-empty-state-card a:hover{ text-decoration:underline }
