/* The Executive SitRep — shared design system (2026-09-02)
   ESR dark theme (era-pulse tokens) + wysecarts-grade polish:
   Urbanist display type, Public Sans body, masthead layout, section rhythm. */
:root {
  --bg: #04070d; --panel: #0a101c; --panel-2: #0d1626; --line: #1e3a5f;
  --text: #e6f1ff; --muted: #8fa3bf; --accent: #6fa5e8; --signal: #30d158;
  --hairline: rgba(111, 165, 232, .18);
  --font-display: "Urbanist", "Segoe UI", sans-serif;
  --font-body: "Public Sans", -apple-system, "Segoe UI", Roboto, sans-serif;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  background: var(--bg); color: var(--text);
  font-family: var(--font-body); font-size: 16px; line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  background-image:
    radial-gradient(ellipse 90% 45% at 50% -18%, rgba(111,165,232,.10), transparent 70%),
    radial-gradient(ellipse 60% 40% at 100% 110%, rgba(48,209,88,.04), transparent 60%);
  background-attachment: fixed;
}
::selection { background: var(--accent); color: #04070d; }
a { color: var(--accent); text-decoration: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.wrap { max-width: 1160px; margin: 0 auto; padding: 0 1.5rem; }

/* ── Masthead ─────────────────────────────────────────────── */
.masthead {
  position: sticky; top: 0; z-index: 50;
  background: rgba(4, 7, 13, .78);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid var(--hairline);
}
.masthead .wrap { display: flex; align-items: center; justify-content: space-between; gap: 1rem; height: 66px; flex-wrap: wrap; }
.brand { display: flex; align-items: center; gap: .7rem; color: var(--text); }
.brand img { width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--line); }
.brand .name { font-family: var(--font-display); font-weight: 800; font-size: 1rem; letter-spacing: .02em; line-height: 1.1; }
.brand .name span { color: var(--accent); }
.brand .name small { display: block; font-family: var(--font-body); font-weight: 600; font-size: .6rem; letter-spacing: .3em; text-transform: uppercase; color: var(--muted); }
nav.main { display: flex; gap: .3rem; }
nav.main a {
  padding: .5rem 1rem; border-radius: 8px; text-decoration: none;
  color: var(--muted); font-size: .84rem; font-weight: 600; letter-spacing: .01em;
  border: 1px solid transparent; transition: all .16s ease;
}
nav.main a:hover { color: var(--text); background: rgba(111,165,232,.07); }
nav.main a.active { color: var(--text); border-color: var(--hairline); background: rgba(111,165,232,.1); }
/* Spotify sits in the top nav between Podcast and RSS and reads as a button: it is the one nav item
   that leaves the site, so it gets the Spotify green tint instead of the muted nav treatment. */
nav.main a.nav-spotify {
  display: inline-flex; align-items: center; gap: .45rem;
  color: var(--text); border-color: rgba(30,215,96,.42); background: rgba(30,215,96,.10);
}
nav.main a.nav-spotify:hover { color: #fff; border-color: #1ed760; background: rgba(30,215,96,.2); }
nav.main a.nav-spotify .ico { width: 1.1em; height: 1.1em; }

/* ── Kickers / headings ───────────────────────────────────── */
.kicker {
  font-family: var(--font-display); font-size: .72rem; font-weight: 700;
  letter-spacing: .26em; text-transform: uppercase; color: var(--accent);
}
h1 { font-family: var(--font-display); font-size: clamp(2rem, 4.6vw, 2.9rem); font-weight: 800; letter-spacing: -.025em; line-height: 1.08; }
h1 .amp { color: var(--accent); }
h2 { font-family: var(--font-display); font-weight: 800; letter-spacing: -.015em; }
.lead { color: var(--muted); font-size: 1.08rem; line-height: 1.75; max-width: 46em; }
.lead strong { color: var(--signal); font-weight: 700; }

/* ── Buttons ──────────────────────────────────────────────── */
.btn-row { display: flex; gap: .8rem; flex-wrap: wrap; }
.btn {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-display); font-weight: 700; font-size: .82rem;
  letter-spacing: .14em; text-transform: uppercase;
  padding: .95rem 1.7rem; border-radius: 9px; border: 1px solid transparent;
  cursor: pointer; transition: all .18s ease; text-decoration: none;
}
.btn.primary { background: var(--accent); color: #04070d; box-shadow: 0 8px 28px rgba(111,165,232,.28); }
.btn.primary:hover { background: #86b8f0; transform: translateY(-1px); box-shadow: 0 12px 34px rgba(111,165,232,.4); }
.btn.ghost { border-color: var(--hairline); color: var(--text); background: rgba(10,16,28,.6); }
.btn.ghost:hover { border-color: var(--accent); transform: translateY(-1px); }

/* ── Hero (home) — layered: Nate's photo full-bleed, ESR branding over it ── */
.hero {
  position: relative; margin-top: -66px; min-height: 700px;
  display: flex; align-items: flex-end; overflow: hidden;
  padding: 66px 0 0; text-align: left;
}
.hero .photo {
  /* Size: HEIGHT-driven and constant, so the subject keeps the same drawn size at every viewport
     width. Width-driven `cover` shrank him to a speck in a 3:1 strip at 2560 and the hero stopped
     matching the approved render at 1440.

     700px hero x 160% = 1120px drawn photo = 3377px wide (x the 3.015 image aspect), which is the
     same drawn width as the old 880px hero at 125% - i.e. he renders the same size while the hero
     itself is 180px shorter, so the copy block AND everything under the hero move up 180px.
     top:-31% puts his chin at 0.52*160% - 31% = 52.1% of the hero (365px), which is what lets the
     headline sit just below it while the band under the CTAs stays tight. The head top lands at
     y=7, in frame.

     Placement: he sits ~2/3 across, and that is viewport-relative on purpose. The subject's x is
        face_x = W - 0.4 * photo_width + R      (R = how far the photo overhangs the right edge)
     so a fixed R would drift him left as the window narrows (R=0 put him at 47% at 2560 and 7% at
     1440). Solving face_x = (2/3)W gives R = 1366 - 0.3333W, i.e. right = 33.33vw - 1366px.
     The second term is a guard: R <= 3390 - W keeps the photo's left edge at or past the hero's
     left edge, so an ultrawide viewport gets him slightly left of 2/3 instead of a dark gap down
     the left side of the hero. Recompute both constants if the hero height (700) or the photo
     scale (160%) changes: R = 0.4 * (scale * H * 3.015) - (1/3)W, guard = scale * H * 3.015 + 15. */
  position: absolute; top: -31%; height: 160%; width: auto; object-fit: cover;
  right: max(33.33vw - 1366px, 100vw - 3390px);
}
.hero .scrim {
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(90deg, var(--bg) 0%, rgba(4,7,13,.9) 7%, rgba(4,7,13,0) 28%),
    radial-gradient(120% 90% at 18% 78%, rgba(4,7,13,.94) 0%, rgba(4,7,13,.55) 45%, rgba(4,7,13,.15) 75%),
    linear-gradient(180deg, rgba(4,7,13,.55) 0%, rgba(4,7,13,.22) 34%, rgba(4,7,13,.55) 62%, rgba(4,7,13,.95) 100%);
}
.hero .inner {
  position: relative; z-index: 2; width: 100%;
  /* The copy block is bottom-anchored, so this bottom padding is the knob that sets how high the
     whole block (mark, kicker, headline, lead, CTAs) sits above the hero's bottom edge. Kept small
     so there is no dead band under the CTAs before the Today's Brief frame.
     gap = hero_height - padding_bottom - 257, where 257px is the headline's distance from the
     block's bottom edge: 700 - 32 - 257 = 411. His chin sits at 365, so the headline lands 46px
     (0.5 inch) below it.
     Calibration: on the 2560px-wide 32" panel 1 inch ~= 92px at 100% display scaling (2560/27.9");
     at 125% scaling the same 92px reads as 1.24". Add 46px (2.875rem) to lift the copy half an inch
     (toward his chin); subtract to drop it. Note the knob is coupled: raising the copy this way also
     widens the dead band below the CTAs, so to raise the copy AND the frame together, shorten the
     hero and re-solve the photo scale/top instead (see .hero .photo). */
  padding-block: 2.4rem 2rem;
}
.hero .mark { width: min(92px, 22vw); display: block; margin-bottom: .9rem; filter: drop-shadow(0 6px 26px rgba(4,7,13,.8)); }
.hero .kicker { margin-bottom: .6rem; }
.hero h1 { max-width: none; margin: 0 0 .8rem; font-size: clamp(1.9rem, 3.4vw, 3.1rem); }
.hero .lead { margin: 0 0 1.2rem; max-width: 76ch; color: #cddcf0; }
.hero .lead strong { color: var(--text); }
.hero .btn { text-transform: none; letter-spacing: .02em; font-size: .95rem; padding: .95rem 1.5rem; }
.hero .btn-row { margin-bottom: 0; }
@media (max-width: 720px) {
  .hero { min-height: 620px; }
  .hero .photo { top: -18%; height: 118%; }
  .hero .inner { padding-block: 2rem 1.6rem; }
  .hero h1 { max-width: 100%; }
  .hero h1 br, .hero .lead br { display: none; }   /* let them wrap naturally on a phone */
}

/* ── Featured panel (podcast on home) ─────────────────────── */
.panel {
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--hairline); border-radius: 16px;
  padding: 1.8rem 1.9rem 1.6rem; text-align: left;
  box-shadow: 0 18px 60px rgba(0,0,0,.35);
}
.panel .kicker { display: flex; align-items: center; gap: .5rem; margin-bottom: .5rem; }
/* Today's brief today lives in its own frame rather than a full-bleed band: ~2/3 of the screen at
   most, fluid at every width. `max(66.67vw, min(100%, 640px))` is exactly 2/3 down to a 960px
   viewport, then holds a 640px floor so small screens keep the normal wrap width instead of
   collapsing to a 260px sliver on a phone. Both terms are fluid, so resizing never steps.
   The margin centres it on the page: 50% is the wrap's content centre, which is the page centre. */
.panel-wide {
  --brief-w: max(66.67vw, min(100%, 640px));
  width: var(--brief-w);
  margin-inline: calc(50% - var(--brief-w) / 2);
  padding-inline: clamp(1.25rem, 2vw, 2.25rem);
  border-radius: 14px;
}
.panel-wide .podcast audio { max-width: 880px; }
.panel .kicker .pulse { width: 8px; height: 8px; border-radius: 50%; background: var(--signal); animation: p 2s infinite; }
@keyframes p { 0%,100%{opacity:1} 50%{opacity:.35} }
.podcast { margin-top: .4rem; }
.pod-head { color: var(--text); font-size: .95rem; line-height: 1.55; margin-bottom: .9rem; }
.pod-head b { font-family: var(--font-display); }

/* Today's brief — topic list (bullets, one topic per line, full titles) */
.brief-topics {
  list-style: none; display: grid; grid-template-columns: 1fr;
  gap: .32rem; margin: 0 0 1rem;
}
.brief-topics li {
  position: relative; padding-left: 1.1rem;
  font-size: .92rem; line-height: 1.5; color: var(--text);
}
.brief-topics li::before {
  content: ""; position: absolute; left: .1rem; top: .58em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--accent);
}
@media (min-width: 900px) {
  .brief-topics { grid-template-columns: 1fr 1fr; gap: .3rem 1.8rem; }
}
@media (min-width: 1500px) {
  .panel-wide .brief-topics { grid-template-columns: repeat(3, 1fr); gap: .45rem 2.2rem; }
}
.pod-topics-empty { color: var(--muted); font-size: .9rem; margin-bottom: 1rem; }
.podcast audio { width: 100%; margin-top: .2rem; height: 44px; }
.podcast audio::-webkit-media-controls-panel { background: var(--panel); }

/* ── Custom audio player (JS-enhanced; see player.js) ──────────────────────
   The generated <audio> keeps its native controls as the no-JS fallback; once player.js has built
   the replacement UI the element itself is hidden and only drives playback. Centred in the panel
   and deliberately high-contrast: the native control was a washed-out grey bar on this dark field. */
.player {
  display: flex; align-items: center; gap: 1.05rem;
  width: 100%; max-width: 880px; margin: 1.1rem auto 0;   /* centred */
  padding: .85rem 1.15rem; border-radius: 14px;
  background: linear-gradient(180deg, rgba(111,165,232,.11), rgba(10,16,28,.75));
  border: 1px solid var(--line);
  box-shadow: 0 16px 44px rgba(0,0,0,.34), inset 0 1px 0 rgba(255,255,255,.04);
}
.player-audio { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.pl-btn {
  flex: 0 0 auto; width: 58px; height: 58px; border: 0; border-radius: 50%; cursor: pointer;
  display: grid; place-items: center; color: #04070d; background: var(--accent);
  box-shadow: 0 8px 26px rgba(111,165,232,.4); transition: transform .15s ease, background .15s ease, box-shadow .15s ease;
}
.pl-btn:hover { background: #86b8f0; transform: translateY(-1px); box-shadow: 0 12px 32px rgba(111,165,232,.5); }
.pl-btn svg { width: 26px; height: 26px; fill: currentColor; display: block; }
.pl-btn .pl-pause { display: none; }
.player.is-playing .pl-btn .pl-play { display: none; }
.player.is-playing .pl-btn .pl-pause { display: block; }
.pl-body { flex: 1 1 auto; min-width: 0; }
.pl-bar {
  position: relative; height: 10px; border-radius: 999px; cursor: pointer;
  background: rgba(255,255,255,.12); box-shadow: inset 0 1px 2px rgba(0,0,0,.4);
}
.pl-bar:hover { background: rgba(255,255,255,.17); }
.pl-fill { position: absolute; top: 0; bottom: 0; left: 0; width: 0; border-radius: 999px; background: linear-gradient(90deg, var(--accent), #a9cef7); }
.pl-thumb {
  position: absolute; top: 50%; left: 0; width: 15px; height: 15px; border-radius: 50%;
  background: #eef5ff; box-shadow: 0 0 0 4px rgba(111,165,232,.28), 0 2px 8px rgba(0,0,0,.55);
  transform: translate(-50%, -50%); pointer-events: none; opacity: 0; transition: opacity .15s ease;
}
.player:hover .pl-thumb, .player:focus-within .pl-thumb { opacity: 1; }
.pl-meta {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin-top: .5rem; font-size: .78rem; letter-spacing: .06em; color: #a8bedb; font-variant-numeric: tabular-nums;
}
.pl-meta .pl-label { font-family: var(--font-display); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--signal); }
.pl-live { display: inline-flex; align-items: center; gap: .45rem; }
.pl-live i { width: 7px; height: 7px; border-radius: 50%; background: var(--signal); animation: p 2s infinite; }
.player.compact { max-width: 360px; padding: .35rem .6rem; gap: .6rem; margin-top: .3rem; }
.player.compact .pl-btn { width: 34px; height: 34px; }
.player.compact .pl-btn svg { width: 15px; height: 15px; }
.player.compact .pl-bar { height: 6px; }
.player.compact .pl-thumb { width: 11px; height: 11px; }
.player.compact .pl-meta { margin-top: .15rem; font-size: .68rem; }
@media (max-width: 560px) {
  .player { gap: .8rem; padding: .7rem .85rem; }
  .pl-btn { width: 48px; height: 48px; }
  .pl-btn svg { width: 22px; height: 22px; }
  .pl-meta { font-size: .72rem; }
}

/* ── Bio / socials ────────────────────────────────────────── */
.bio {
  color: var(--muted); font-size: .95rem; line-height: 1.75;
  border-top: 1px solid var(--hairline); padding-top: 1.4rem; margin: 2.2rem 0 1.6rem;
  text-align: left;
}
.bio b { color: var(--text); }
.socials { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .7rem; }
.socials a {
  display: flex; align-items: center; justify-content: center; gap: .45rem;
  padding: .8rem 1rem; border: 1px solid var(--line); border-radius: 10px;
  color: var(--text); font-size: .85rem; font-weight: 600;
  transition: all .16s ease; background: rgba(10,16,28,.5);
}
.socials a:hover { border-color: var(--accent); background: rgba(111,165,232,.08); transform: translateY(-1px); }
.socials .soon { color: var(--muted); cursor: default; }
.socials .soon:hover { border-color: var(--line); background: none; transform: none; }

/* Spotify brand mark (official icon, sourced from Spotify's own asset pack) on the Spotify links */
.ico { width: 1.05em; height: 1.05em; display: inline-block; vertical-align: -.16em; flex: 0 0 auto; }

/* ── Page head (news) ─────────────────────────────────────── */
.page-head { padding: 2.6rem 0 1rem; }
.page-head .kicker { margin-bottom: .7rem; }
.page-head h1 { margin-bottom: .5rem; }
.page-head .lead { font-size: 1rem; }
.page-head .lead .pulse { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--signal); margin-right: .4rem; vertical-align: 1px; animation: p 2s infinite; }
.page-head .updated { font-size: .8rem; color: #5a6f8f; margin-top: .4rem; font-family: var(--font-display); letter-spacing: .02em; }
.page-head .updated .pulse { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--signal); margin-right: .4rem; vertical-align: 1px; animation: p 2s infinite; }

/* ── Category sections ────────────────────────────────────── */
.cat { margin: 1.8rem 0 2.4rem; }
.cat-head { display: flex; align-items: center; gap: .8rem; margin-bottom: .2rem; }
.cat-head h2 { font-size: 1.3rem; display: flex; align-items: center; gap: .5rem; }
.cat-head .n {
  font-family: var(--font-display); font-size: .68rem; font-weight: 700;
  letter-spacing: .12em; color: var(--accent); border: 1px solid var(--hairline);
  border-radius: 999px; padding: .14rem .6rem; text-transform: uppercase;
}
.cat-desc { color: var(--muted); font-size: .86rem; margin-bottom: 1rem; }
.cat-head-rule { height: 1px; background: linear-gradient(90deg, var(--hairline), transparent); margin: .9rem 0 1.1rem; }

/* ── Story cards ──────────────────────────────────────────── */
.grid { display: grid; grid-template-columns: 1fr; gap: .9rem; }
@media (min-width: 720px) { .grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1080px) { .grid { grid-template-columns: 1fr 1fr 1fr; } }
.card {
  position: relative; display: flex; flex-direction: column;
  background: linear-gradient(180deg, rgba(13,22,38,.9), rgba(10,16,28,.96));
  border: 1px solid var(--line); border-radius: 14px; padding: 1.15rem 1.25rem 1.05rem;
  color: var(--text); text-decoration: none;
  transition: all .18s ease; overflow: hidden;
}
.card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: linear-gradient(90deg, var(--accent), transparent 70%);
  opacity: 0; transition: opacity .18s ease;
}
.card:hover { border-color: rgba(111,165,232,.55); transform: translateY(-3px); box-shadow: 0 18px 44px rgba(0,0,0,.5); }
.card:hover::before { opacity: 1; }
.card .row { display: flex; align-items: center; gap: .45rem; margin-bottom: .55rem; flex-wrap: wrap; }
.badge {
  font-family: var(--font-display); font-size: .62rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; padding: .2rem .55rem; border-radius: 999px;
}
.badge.hot { background: rgba(48,209,88,.12); color: var(--signal); border: 1px solid rgba(48,209,88,.35); }
.badge.multi { background: rgba(111,165,232,.1); color: var(--accent); border: 1px solid rgba(111,165,232,.35); }
.badge.cve { background: rgba(255,180,60,.1); color: #ffb43c; border: 1px solid rgba(255,180,60,.35); }
.card h3 { font-family: var(--font-display); font-size: .98rem; line-height: 1.38; font-weight: 700; margin-bottom: .45rem; letter-spacing: -.01em; }
.card p { color: var(--muted); font-size: .85rem; line-height: 1.55; margin-bottom: .8rem; flex-grow: 1; }
.meta { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; font-size: .73rem; color: #5a6f8f; }
.meta .src { color: var(--accent); font-weight: 600; text-transform: capitalize; }
.meta .dot { width: 3px; height: 3px; border-radius: 50%; background: #5a6f8f; }
.readmore {
  margin-left: auto; color: var(--accent); font-size: .78rem; font-weight: 700;
  font-family: var(--font-display); letter-spacing: .05em; transition: all .16s ease;
}
.card:hover .readmore { transform: translateX(3px); }
.empty { color: var(--muted); font-size: .85rem; font-style: italic; }

/* ── Footer ───────────────────────────────────────────────── */
footer.site { margin-top: 3rem; border-top: 1px solid var(--hairline); padding: 2.2rem 0 2.6rem; }
.foot-grid { display: grid; gap: 1.6rem; grid-template-columns: 1fr; }
@media (min-width: 760px) { .foot-grid { grid-template-columns: 2fr 1fr 1fr; } }
.foot-grid .fg-brand img { width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--line); margin-bottom: .7rem; }
.foot-grid .fg-brand p { color: var(--muted); font-size: .82rem; max-width: 30em; line-height: 1.65; }
.foot-grid h4 { font-family: var(--font-display); font-size: .7rem; letter-spacing: .22em; text-transform: uppercase; color: var(--muted); margin-bottom: .8rem; font-weight: 700; }
.foot-grid ul { list-style: none; display: grid; gap: .45rem; }
.foot-grid ul a { color: var(--muted); font-size: .86rem; transition: color .15s ease; }
.foot-grid ul a:hover { color: var(--accent); }
.foot-legal { margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--hairline); display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; font-size: .76rem; color: #5a6f8f; }
.foot-legal .pulse { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--signal); margin-right: .4rem; vertical-align: 1px; animation: p 2s infinite; }
