/* ============================================================
   Home page - Dispatch design language applied to the front door.

   Tokens come from dispatch-tokens.css (loaded site-wide in
   base.html). No particles, no gradients, no theatre - flat
   surfaces, editorial typography, single accent color.
   ============================================================ */

/* Push the body to the home page's deep background so the area outside the
   1200px container blends in instead of showing the storm.css body gray. */
body:has(.home) {
    background: var(--dispatch-bg);
}

/* .home spans the viewport (no max-width); the masthead is full-bleed
   background/glow with its content constrained via .home-masthead-inner,
   and everything else lives in .home-content which carries the 1200px
   reading column. */
.home {
    margin: 0;
    padding: 0 0 5rem;
    background: var(--dispatch-bg);
    color: var(--dispatch-text);
    font-feature-settings: 'tnum' 1, 'zero' 1;
}

.home-content {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 2rem;
}

.home a { color: inherit; text-decoration: none; }

.home-sep { color: var(--dispatch-text-faint); margin: 0 0.4em; }


/* ============================================================
   Masthead - meta line + editorial title + blurb + CTAs
   ============================================================ */

/* Full-bleed masthead: extends to viewport edges, content constrained
   inside via .home-masthead-inner. The ambient cyan glow lives here so
   it spans the viewport like the section background. */
.home-masthead {
    position: relative;
    padding: 4rem 2rem 3rem;
    margin-bottom: 0;
    border-bottom: 1px solid var(--dispatch-border);
    overflow: hidden;
}
.home-masthead::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background:
        radial-gradient(circle at 15% 25%, rgba(0, 212, 255, 0.08) 0%, transparent 50%),
        radial-gradient(circle at 75% 45%, rgba(30, 144, 255, 0.06) 0%, transparent 55%);
    pointer-events: none;
    z-index: 0;
}
.home-masthead-inner {
    position: relative;
    z-index: 1;
    max-width: 1200px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 3rem;
    flex-wrap: wrap;
}

.home-masthead-content {
    flex: 1 1 520px;
    min-width: 0;
    text-align: center;
}
.home-masthead-content .home-blurb {
    margin-left: auto;
    margin-right: auto;
}
.home-masthead-content .home-ctas {
    justify-content: center;
}

/* Right slot for the welcome-back widget (authenticated users only).
   The widget hides itself when there's nothing to resume, so when
   server-rendered the slot is reserved but stays empty in that case. */
.home-masthead-aside {
    flex: 0 1 460px;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1.25rem;
}

.home-aside-glyph {
    width: 88px;
    height: 88px;
    flex: 0 0 auto;
    opacity: 0.95;
    filter: drop-shadow(0 0 18px rgba(0, 212, 255, 0.4));
}

@media (max-width: 1024px) {
    .home-masthead {
        padding: 1.5rem 1rem 2rem;
    }
    .home-masthead-inner {
        flex-direction: column;
        align-items: stretch;
        gap: 2rem;
    }
    /* Reset flex basis on mobile - without this, the basis values from
       the desktop layout (520px / 340px) bleed into the column axis and
       create a phantom gap between the hero content and the widget. */
    .home-masthead-content,
    .home-masthead-aside {
        flex: 0 0 auto;
    }
    /* Drop the inner flex on the aside so the widget can span the full
       column width instead of being centered/right-aligned at its
       desktop max-width. */
    .home-masthead-aside {
        display: block;
        width: 100%;
    }
}

.home-masthead-meta {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: 0;
    font-family: var(--dispatch-mono);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    color: var(--dispatch-text-muted);
    text-transform: uppercase;
    padding: 0.55rem 0.85rem;
    margin-bottom: 1.5rem;
    border: 1px solid var(--dispatch-border);
    border-left: 3px solid #1e90ff;
    border-radius: 2px;
    background: var(--dispatch-surface);
}
.home-masthead-est { margin-left: auto; color: var(--dispatch-text-faint); }

.home-title {
    font-family: var(--dispatch-editorial);
    font-weight: 500;
    font-size: clamp(2.8rem, 7vw, 5rem);
    line-height: 1.02;
    letter-spacing: -0.025em;
    color: var(--dispatch-text-strong);
    margin: 0 0 1.5rem;
    text-wrap: balance;
}

/* Storm gradient text on the one quotable word. The accent makes the
   motto pop without animating anything; the rest of the title stays
   editorial. */
.home-title-accent {
    background: linear-gradient(90deg, #1e90ff 0%, #00d4ff 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    font-style: italic;
}

.home-blurb {
    font-family: 'Georgia', 'Times New Roman', serif;
    font-size: clamp(1rem, 1.5vw, 1.15rem);
    line-height: 1.6;
    color: var(--dispatch-text);
    margin: 0 0 1.75rem;
    max-width: 58ch;
    text-wrap: pretty;
}

.home-ctas {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.home-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.75rem 1.3rem;
    font-family: var(--dispatch-mono);
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    border-radius: 2px;
    border: 1px solid transparent;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
    cursor: pointer;
}
/* Primary CTA: dark Storm navy with white text gets a clean ~17:1 contrast,
   with a cyan border + glow signaling the brand. Hover lights up to the
   Storm blue with brighter glow - still readable, more energetic. */
.home-cta--primary {
    background: #0a1929;
    color: #ffffff;
    border: 1px solid #1e90ff;
    font-weight: 700;
    box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.15),
                0 4px 14px rgba(30, 144, 255, 0.25);
}
.home-cta--primary:hover {
    background: #11243a;
    border-color: #00d4ff;
    color: #ffffff;
    box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.4),
                0 6px 22px rgba(0, 212, 255, 0.4);
}
.home-cta--secondary {
    background: transparent;
    color: var(--dispatch-text-strong);
    border-color: var(--dispatch-border-strong);
}
.home-cta--secondary:hover {
    color: #00d4ff;
    border-color: #1e90ff;
}


/* ============================================================
   Trust strip - single monospace row of receipts
   ============================================================ */

/* Trust strip - borrows the Dispatch reading-tag-pill / masthead-meta
   patterns. Meta bar at top (context), bordered pills below (proof). */
.home-trust {
    margin: 2.5rem 0 3rem;
    background: none;
    border: none;
    padding: 0;
}

.home-trust-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.55rem;
}

.home-trust-pill {
    display: inline-flex; align-items: center;
    gap: 0.55rem;
    padding: 0.6rem 0.95rem;
    font-family: var(--dispatch-mono);
    font-size: 0.78rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    color: var(--dispatch-text-strong);
    background: var(--dispatch-surface);
    border: 1px solid var(--dispatch-border-strong);
    border-radius: 2px;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.home-trust-pill:hover {
    border-color: #00d4ff;
    background: rgba(0, 212, 255, 0.05);
}
.home-trust-check {
    color: #00d4ff;
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1;
    margin-top: -1px;
}

/* Live pills use the Dispatch teal - same color the blog uses for the
   "dispatch" category, so it reads as "active feed" to anyone who knows
   the site. */
.home-trust-pill--live {
    border-color: rgba(29, 158, 117, 0.55);
    color: #5DCAA5;
}
.home-trust-pill--live:hover {
    border-color: #5DCAA5;
    background: rgba(29, 158, 117, 0.07);
}
.home-trust-livedot {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: #5DCAA5;
    box-shadow: 0 0 8px rgba(93, 202, 165, 0.7);
    flex-shrink: 0;
}


/* ============================================================
   Story block - two flat-surface cards side by side
   ============================================================ */

/* The dispatches block wraps both the cards row and the "more" link
   underneath them, so the link reads as the cards' footer rather than
   floating below as a sibling of the platforms-operated line. */
.home-dispatches {
    margin-bottom: 3rem;
    border-top: 1px solid var(--dispatch-border);
    border-bottom: 1px solid var(--dispatch-border);
}

.home-cards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0;
}

.home-dispatches-more {
    display: flex;
    justify-content: flex-end;
    padding: 0.75rem 1.25rem;
    border-top: 1px solid var(--dispatch-border);
    background: rgba(20, 20, 20, 0.4);
}
.home-dispatches-more a {
    font-family: var(--dispatch-mono);
    font-size: 0.74rem;
    letter-spacing: 0.04em;
    color: var(--dispatch-text-muted);
    text-decoration: none;
    transition: color 0.15s;
}
.home-dispatches-more a:hover { color: #00d4ff; }

.home-cards--single {
    grid-template-columns: minmax(0, 1fr);
}

.home-card {
    display: flex;
    flex-direction: column;
    padding: 1.75rem 1.75rem 2rem;
    border-right: 1px solid var(--dispatch-border);
    border-left: 2px solid transparent;
    margin-left: -2px;
    transition: background 0.15s, border-left-color 0.15s;
}
.home-card:last-child { border-right: 0; }
.home-card:hover {
    background: rgba(30, 144, 255, 0.04);
    border-left-color: #1e90ff;
}

.home-card-role {
    font-family: var(--dispatch-mono);
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--dispatch-gold);
    margin-bottom: 0.6rem;
}
.home-card-role--latest  { color: #00d4ff; }
.home-card-role--featured { color: var(--dispatch-gold); }

.home-card-meta {
    display: flex; align-items: baseline; flex-wrap: wrap;
    font-family: var(--dispatch-mono);
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    color: var(--dispatch-text-muted);
    margin-bottom: 0.9rem;
}

.home-card-title {
    font-family: var(--dispatch-editorial);
    font-weight: 500;
    font-size: clamp(1.5rem, 2.6vw, 1.95rem);
    line-height: 1.18;
    letter-spacing: -0.015em;
    color: var(--dispatch-text-strong);
    margin: 0 0 1rem;
    text-wrap: balance;
}

.home-card-excerpt {
    font-family: 'Georgia', 'Times New Roman', serif;
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--dispatch-text);
    margin: 0 0 1.25rem;
    max-width: 50ch;
}

.home-card-readmore {
    margin-top: auto;
    font-family: var(--dispatch-mono);
    font-size: 0.74rem;
    color: var(--dispatch-text-muted);
    letter-spacing: 0.04em;
    transition: color 0.15s;
}
.home-card:hover .home-card-readmore { color: var(--dispatch-text-strong); }

.home-card-cat {
    font-family: var(--dispatch-mono);
    font-weight: 600;
    letter-spacing: 0.08em;
}
.home-card-cat--dispatch  { color: var(--dispatch-teal); }
.home-card-cat--release   { color: var(--dispatch-gold); }
.home-card-cat--incident  { color: var(--dispatch-red); }
.home-card-cat--deep-dive { color: var(--dispatch-blue); }

/* Full-bleed thumbnail at the top of the card. Negative margins break
   out of the .home-card padding (1.75rem). max-height caps the banner
   so a single full-width card doesn't render a giant image. */
.home-card-image {
    margin: -1.75rem -1.75rem 1.5rem;
    aspect-ratio: 16 / 9;
    max-height: 260px;
    overflow: hidden;
    background: var(--dispatch-sunken);
}
.home-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
/* Fallback when a post has no featured_image - a category-tinted
   block with the category name, mirroring .reading-rec-image. */
.home-card-image--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--dispatch-mono);
    font-size: 0.78rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}
.home-card-image--dispatch  { background: rgba(29, 158, 117, 0.16); color: var(--dispatch-teal-bright); }
.home-card-image--release   { background: rgba(212, 164, 55, 0.16); color: var(--dispatch-gold); }
.home-card-image--incident  { background: rgba(229, 72, 77, 0.16); color: var(--dispatch-red); }
.home-card-image--deep-dive { background: rgba(123, 143, 219, 0.16); color: var(--dispatch-blue); }


/* ============================================================
   Footer-style single-line mentions - platforms + dispatch link
   ============================================================ */

/* "Open-source server agent" - section pointing at the Storm Pulse
   repo. Terminal-prompt treatment carries the code-look that matches
   the audience the section is for. */
.home-opensource {
    margin: 0 0 2.5rem;
    padding: 1.75rem 1.75rem 2rem;
    background: var(--dispatch-surface);
    border: 1px solid var(--dispatch-border);
    border-left: 3px solid var(--dispatch-gold);
    border-radius: 2px;
    position: relative;
    overflow: hidden;
}
/* Ambient gold radial glow on the right - same depth-trick the
   newsletter card uses with cyan. Tints the section without competing
   with the content. */
.home-opensource::before {
    content: '';
    position: absolute;
    top: -50%; right: -20%;
    width: 60%; height: 200%;
    background: radial-gradient(ellipse, rgba(212, 164, 55, 0.07) 0%, transparent 60%);
    pointer-events: none;
}
.home-opensource > * { position: relative; }

/* Two-column row: main pitch on the left, live-stats panel on the
   right. Stats stack below the pitch on narrow viewports. */
.home-opensource-row {
    display: flex;
    align-items: flex-start;
    gap: 1.75rem;
    flex-wrap: wrap;
}
.home-opensource-main {
    flex: 1 1 420px;
    min-width: 0;
}

.home-opensource-meta {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: 0;
    font-family: var(--dispatch-mono);
    font-size: 0.7rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--dispatch-text-muted);
    margin-bottom: 1rem;
}
.home-opensource-meta-tail {
    margin-left: auto;
    color: var(--dispatch-gold);
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0.02em;
}

.home-opensource-title {
    font-family: var(--dispatch-editorial);
    font-weight: 500;
    font-size: clamp(1.6rem, 3vw, 2.1rem);
    line-height: 1.15;
    letter-spacing: -0.015em;
    color: var(--dispatch-text-strong);
    margin: 0 0 0.85rem;
}

.home-opensource-body {
    font-family: 'Georgia', 'Times New Roman', serif;
    font-size: 1rem;
    line-height: 1.6;
    color: var(--dispatch-text);
    margin: 0 0 1.25rem;
    max-width: 64ch;
}

.home-opensource-cmd {
    margin: 0 0 1.25rem;
    padding: 0.85rem 1rem;
    background: var(--dispatch-sunken);
    border: 1px solid var(--dispatch-border);
    border-radius: 2px;
    font-family: var(--dispatch-mono);
    font-size: 0.8rem;
    line-height: 1.4;
    color: var(--dispatch-text-strong);
    overflow-x: auto;
    white-space: pre;
}
.home-opensource-prompt {
    color: var(--dispatch-gold);
    margin-right: 0.55em;
    user-select: none;
}

.home-opensource-ctas {
    display: flex;
    flex-wrap: wrap;
    gap: 0.55rem;
}

.home-opensource-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.65rem 1.1rem;
    font-family: var(--dispatch-mono);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    color: var(--dispatch-gold);
    background: rgba(212, 164, 55, 0.06);
    border: 1px solid rgba(212, 164, 55, 0.5);
    border-radius: 2px;
    text-decoration: none;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.home-opensource-cta:hover {
    background: rgba(212, 164, 55, 0.14);
    border-color: var(--dispatch-gold);
    color: var(--dispatch-text-strong);
}

/* Secondary - outlined ghost variant, same gold accent vocabulary but
   lighter weight so it reads as the secondary action. */
.home-opensource-cta--secondary {
    background: transparent;
    color: var(--dispatch-text-muted);
    border-color: var(--dispatch-border-strong);
}
.home-opensource-cta--secondary:hover {
    color: var(--dispatch-gold);
    border-color: var(--dispatch-gold);
    background: rgba(212, 164, 55, 0.04);
}

/* Live-stats panel - sits at the right of the open-source row. Reads
   like a device's status pane: monospace numeric values, mono labels,
   a live indicator at the top. */
.home-pulse-stats {
    /* border-box so the mobile `width: 100%` rule below stays inside the
       row instead of overflowing right by its own padding + border. No
       global box-sizing reset exists, so each width+padding box opts in. */
    box-sizing: border-box;
    flex: 0 0 220px;
    align-self: stretch;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    padding: 1rem 1.1rem;
    background: var(--dispatch-sunken);
    border: 1px solid var(--dispatch-border);
    border-radius: 2px;
}

/* Aside-row that pairs the floating Storm Pulse glyph with the CRT
   panel. Same shape the masthead uses for bucket-logo + welcome-back:
   bare glyph on the left (no chrome), panel on the right. */
.home-pulse-aside {
    flex: 0 0 auto;
    display: flex;
    align-items: stretch;
    gap: 1.25rem;
    min-width: 0;
}
.home-pulse-aside-glyph {
    width: 88px;
    height: 88px;
    flex: 0 0 auto;
    align-self: center;
    opacity: 0.95;
    filter: drop-shadow(0 0 18px rgba(93, 202, 165, 0.45));
}

.home-pulse-stats-head {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid var(--dispatch-border);
    min-width: 0;
}
.home-pulse-stats-title {
    font-family: var(--dispatch-mono);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--dispatch-text-strong);
}
.home-pulse-stats-version {
    font-family: var(--dispatch-mono);
    font-size: 0.68rem;
    color: var(--dispatch-text-faint);
    letter-spacing: 0.05em;
}
/* CRT phosphor screen - retro-futuristic body matching the Fleet
   Pulse hero in the internal developer overview wall (see
   _ts/internal_developer_ui/lib/overview_wall/Ekg.svelte).

   Stack, bottom-up: radial-bulge body + faint phosphor grid +
   scanlines + vignette + the scrolling trace + a readout overlay.
   The trace is CSS-driven here (no WS on the public home page), but
   the visual chrome is identical to the canvas version. */
.home-pulse-stats-screen {
    box-sizing: border-box;
    position: relative;
    flex: 1 1 auto;
    min-height: 200px;
    margin-top: auto;
    border-radius: 9px;
    overflow: hidden;
    background:
        linear-gradient(0deg, rgba(93, 202, 165, 0.06) 1px, transparent 1px) 0 0 / 24px 24px,
        linear-gradient(90deg, rgba(93, 202, 165, 0.06) 1px, transparent 1px) 0 0 / 24px 24px,
        radial-gradient(120% 130% at 50% 0%, #0a1512 0%, #050807 70%, #030403 100%);
    border: 1px solid #14201b;
    box-shadow: inset 0 0 24px rgba(0, 0, 0, 0.35),
                inset 0 0 60px rgba(0, 40, 30, 0.4);
}

/* Scanlines - 3px stripes for the CRT banding. */
.home-pulse-stats-screen::before {
    content: '';
    position: absolute;
    inset: 0;
    background: repeating-linear-gradient(
        0deg,
        rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 2px,
        rgba(0, 0, 0, 0.18) 3px, rgba(0, 0, 0, 0.18) 3px
    );
    mix-blend-mode: multiply;
    pointer-events: none;
    z-index: 2;
}

/* Vignette - corners fall off so the screen reads as bulged glass. */
.home-pulse-stats-screen::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(
        100% 100% at 50% 50%,
        transparent 55%,
        rgba(0, 0, 0, 0.45) 100%
    );
    pointer-events: none;
    z-index: 1;
}

/* No-JS fallback trace - a looped SVG, predictable but better than an
   empty screen. home-pulse-crt.js replaces this span with a canvas
   driven by a synthetic Pulse event stream the moment JS runs. */
.home-pulse-stats-ekg {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 3;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 40' preserveAspectRatio='none'><path d='M0 20 H100 L104 17 L108 20 H114 L116 23 L118 4 L120 36 L122 20 H128 L132 17 L136 20 H200' fill='none' stroke='%237ce7c0' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' vector-effect='non-scaling-stroke'/></svg>");
    background-repeat: repeat-x;
    background-size: 200px 60%;
    background-position: 0 center;
    filter:
        drop-shadow(0 0 3px rgba(124, 231, 192, 1))
        drop-shadow(0 0 6px rgba(124, 231, 192, 0.55))
        drop-shadow(0 0 10px rgba(124, 231, 192, 0.25));
    animation: home-pulse-ekg var(--ekg-cycle, 15s) linear infinite;
}

@keyframes home-pulse-ekg {
    to { background-position-x: -200px; }
}

/* JS-driven trace - same shape vocabulary as the dev-dash Fleet Pulse
   CRT (see _ts/internal_developer_ui/lib/overview_wall/Ekg.svelte).
   Glow comes from the CSS filter, not per-frame canvas shadow. */
.home-pulse-stats-canvas {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 3;
    filter: drop-shadow(0 0 5px rgba(124, 231, 192, 0.55));
}

/* Readout overlay - mirrors the overview wall's CRT HUD: cycle stat
   on the left, blinking LIVE SIGNAL pill on the right. */
.home-pulse-stats-readout {
    position: absolute;
    top: 0.65rem;
    left: 0.8rem;
    right: 0.8rem;
    z-index: 4;
    display: flex;
    justify-content: space-between;
    align-items: center;
    pointer-events: none;
}
.home-pulse-stats-bpm {
    font-family: var(--dispatch-mono);
    font-size: 1.05rem;
    font-weight: 700;
    color: #7ce7c0;
    text-shadow: 0 0 10px rgba(124, 231, 192, 0.6);
    font-feature-settings: 'tnum' 1, 'zero' 1;
}
.home-pulse-stats-bpm small {
    font-size: 0.58rem;
    color: var(--dispatch-text-faint);
    margin-left: 0.25rem;
    font-weight: 600;
    letter-spacing: 0.05em;
}
.home-pulse-stats-live {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-family: var(--dispatch-mono);
    font-size: 0.58rem;
    letter-spacing: 0.14em;
    color: #7ce7c0;
}
.home-pulse-stats-live-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #7ce7c0;
    box-shadow: 0 0 7px #7ce7c0;
    animation: home-pulse-live-blink 2.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes home-pulse-live-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

/* Respect prefers-reduced-motion - hold the trace + dot still. */
@media (prefers-reduced-motion: reduce) {
    .home-pulse-stats-ekg,
    .home-pulse-stats-live-dot {
        animation: none;
    }
}

/* Mobile - when the open-source row wraps, let the stats panel take
   the full width of the section so it doesn't sit as a tiny island.
   The EKG screen inside keeps its desktop width and aligns left so
   the visual rhythm matches. Width is explicit because the EKG
   inside is `width: 100%`; relying on align-self alone makes the
   screen collapse to zero. */
@media (max-width: 1024px) {
    .home-opensource-row {
        flex-direction: column;
    }
    .home-opensource-main {
        flex: 0 0 auto;
        width: 100%;
    }
    .home-pulse-aside {
        flex: 1 1 100%;
        width: 100%;
        align-items: center;
    }
    .home-pulse-stats {
        flex: 1 1 auto;
        min-width: 0;
    }
    .home-pulse-stats-screen {
        flex: 0 0 auto;
        width: 280px;
        max-width: 100%;
        align-self: flex-start;
    }
}

/* ============================================================
   Welcome-back / Get-started widget (.hwb)

   Shared shell between the Svelte-driven authed Resume widget and
   the Django-rendered cold-visitor 1-2-3 variant. Single source of
   truth here so both states have identical chrome - only the body
   content differs.
   ============================================================ */
.hwb {
    display: flex;
    flex-direction: column;
    padding: 0;
    background: var(--dispatch-surface, #141414);
    border: 1px solid var(--dispatch-border-strong, #333);
    border-left: 3px solid #00d4ff;
    border-radius: 2px;
    width: 100%;
    max-width: 440px;
    min-height: 440px;
    font-family: var(--dispatch-mono, 'JetBrains Mono', monospace);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}

.hwb-header {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.85rem 1.1rem;
    border-bottom: 1px solid var(--dispatch-border, #222);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--dispatch-text-muted, #6B7772);
    background: #0d0d0d;
}
.hwb-dot {
    display: inline-block;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: #5DCAA5;
    box-shadow: 0 0 8px rgba(93, 202, 165, 0.75);
    flex-shrink: 0;
}
.hwb-product { color: var(--dispatch-text-strong, #ECEFED); font-weight: 700; }
.hwb-greeting { color: var(--dispatch-text-muted, #6B7772); margin-left: auto; }

.hwb-screen {
    flex: 1 1 auto;
    background: #0d0d0d;
    border-top: 1px solid var(--dispatch-border, #222);
    border-bottom: 1px solid var(--dispatch-border, #222);
    box-shadow: inset 0 0 24px rgba(0, 0, 0, 0.35);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.75rem 1.25rem;
}
.hwb-screen-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1.1rem;
    width: 100%;
}

.hwb-label {
    margin: 0;
    font-size: 0.68rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--dispatch-text-faint, #4B5550);
}

.hwb-bucket-block {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.65rem;
    width: 100%;
    min-width: 0;
}
.hwb-bucket-tag {
    padding: 0.22rem 0.5rem;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: #00d4ff;
    border: 1px solid rgba(0, 212, 255, 0.5);
    border-radius: 2px;
    background: rgba(0, 212, 255, 0.06);
    line-height: 1;
}
.hwb-bucket-name {
    margin: 0;
    font-family: var(--dispatch-editorial, 'Georgia', 'Times New Roman', serif);
    font-size: clamp(1.85rem, 4vw, 2.4rem);
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: var(--dispatch-text-strong, #ECEFED);
    word-break: break-word;
    overflow-wrap: break-word;
    max-width: 100%;
}
.hwb-tab-row {
    margin: 0;
    font-family: var(--dispatch-mono, 'JetBrains Mono', monospace);
    font-size: 0.82rem;
    color: var(--dispatch-text-muted, #6B7772);
    line-height: 1.4;
}
.hwb-tab-name {
    color: var(--dispatch-text-strong, #ECEFED);
    font-weight: 600;
}

/* Cold-visitor 1-2-3 steps - fills the screen panel like the Resume
   body does, but as a numbered list instead of bucket/tab. */
.hwb-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 0.95rem;
}
.hwb-step {
    display: flex;
    align-items: baseline;
    gap: 0.85rem;
}
.hwb-step-n {
    flex-shrink: 0;
    font-family: var(--dispatch-mono, 'JetBrains Mono', monospace);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: #00d4ff;
    min-width: 1.6em;
}
.hwb-step-label {
    font-family: var(--dispatch-editorial, 'Georgia', 'Times New Roman', serif);
    font-size: 1.05rem;
    line-height: 1.3;
    color: var(--dispatch-text-strong, #ECEFED);
}
.hwb-step--done .hwb-step-n {
    color: #5DCAA5;
    font-size: 0.95rem;
}
.hwb-step--upcoming .hwb-step-n { color: var(--dispatch-text-faint, #4B5550); }
.hwb-step--upcoming .hwb-step-label { color: var(--dispatch-text-muted, #6B7772); }

.hwb-action {
    padding: 1.1rem 1.1rem 0.6rem;
}
.hwb-resume {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding: 0.8rem 1rem;
    background: #0a1929;
    color: #ffffff;
    border: 1px solid #1e90ff;
    border-radius: 2px;
    font-family: var(--dispatch-mono, 'JetBrains Mono', monospace);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-decoration: none;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
    box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.15),
                0 4px 14px rgba(30, 144, 255, 0.25);
}
.hwb-resume:hover {
    background: #11243a;
    border-color: #00d4ff;
    box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.4),
                0 6px 22px rgba(0, 212, 255, 0.4);
}
.hwb-resume-arrow {
    font-size: 1rem;
    line-height: 1;
    transition: transform 0.15s;
}
.hwb-resume:hover .hwb-resume-arrow { transform: translateX(3px); }

.hwb-status {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.7rem 1.1rem;
    border-top: 1px solid var(--dispatch-border, #222);
    background: #0d0d0d;
    font-size: 0.64rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--dispatch-text-muted, #6B7772);
}
.hwb-status-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: #00d4ff;
    box-shadow: 0 0 6px rgba(0, 212, 255, 0.65);
}
.hwb-status-region { color: #00d4ff; }
.hwb-status-sep { color: var(--dispatch-text-faint, #4B5550); }
.hwb-status-text { color: var(--dispatch-text-faint, #4B5550); }

@media (max-width: 1024px) {
    .hwb {
        max-width: none;
        width: 100%;
        min-height: 0;
    }
    .hwb-screen {
        padding: 1.5rem 1.25rem;
    }
}

.home-aside {
    font-family: var(--dispatch-mono);
    font-size: 0.74rem;
    color: var(--dispatch-text-muted);
    letter-spacing: 0.02em;
    padding: 0.5rem 0;
}
.home-aside a {
    color: var(--dispatch-text);
    border-bottom: 1px dotted var(--dispatch-text-faint);
    transition: color 0.15s, border-color 0.15s;
}
.home-aside a:hover {
    color: #00d4ff;
    border-bottom-color: #00d4ff;
}
.home-aside-label {
    color: var(--dispatch-text-faint);
    margin-right: 0.4em;
}


/* ============================================================
   Newsletter - Dispatch-styled signup
   ============================================================ */

.home-news {
    margin-top: 3.5rem;
    padding: 2rem;
    background: var(--dispatch-surface);
    border: 1px solid var(--dispatch-border);
    border-left: 3px solid #1e90ff;
    border-radius: 2px;
    position: relative;
    overflow: hidden;
}
/* Subtle Storm-cyan corner glow on the newsletter card. */
.home-news::before {
    content: '';
    position: absolute;
    top: -50%; right: -20%;
    width: 60%; height: 200%;
    background: radial-gradient(ellipse, rgba(0, 212, 255, 0.06) 0%, transparent 60%);
    pointer-events: none;
}
.home-news > * { position: relative; }

.home-news-label {
    font-family: var(--dispatch-mono);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--dispatch-text-muted);
    margin: 0 0 0.6rem;
}

.home-news-title {
    font-family: var(--dispatch-editorial);
    font-weight: 500;
    font-size: clamp(1.6rem, 3vw, 2.1rem);
    line-height: 1.15;
    letter-spacing: -0.015em;
    color: var(--dispatch-text-strong);
    margin: 0 0 0.85rem;
}

.home-news-body {
    font-family: 'Georgia', 'Times New Roman', serif;
    font-size: 1rem;
    line-height: 1.6;
    color: var(--dispatch-text);
    margin: 0 0 1.25rem;
    max-width: 60ch;
}

.home-news-form {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    max-width: 480px;
}
.home-news-input {
    flex: 1 1 220px;
    min-width: 0;
    padding: 0.7rem 0.9rem;
    background: var(--dispatch-bg);
    border: 1px solid var(--dispatch-border-strong);
    border-radius: 2px;
    color: var(--dispatch-text-strong);
    font-family: var(--dispatch-mono);
    font-size: 0.85rem;
    outline: none;
    transition: border-color 0.15s;
}
.home-news-input:focus { border-color: #1e90ff; }
/* Subscribe button - matches .home-cta--primary so the page has one
   consistent primary-action treatment. */
.home-news-submit {
    padding: 0.7rem 1.5rem;
    background: #0a1929;
    color: #ffffff;
    border: 1px solid #1e90ff;
    border-radius: 2px;
    font-family: var(--dispatch-mono);
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
    box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.15),
                0 4px 14px rgba(30, 144, 255, 0.25);
}
.home-news-submit:hover {
    background: #11243a;
    border-color: #00d4ff;
    box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.4),
                0 6px 22px rgba(0, 212, 255, 0.4);
}
.home-news-finepoint {
    margin-top: 0.85rem;
    font-family: var(--dispatch-mono);
    font-size: 0.68rem;
    color: var(--dispatch-text-faint);
    letter-spacing: 0.04em;
}
/* Two-column row for the subscribe card - form on the left, recent
   broadcasts widget on the right. Stacks under the breakpoint. */
.home-news-row {
    display: flex;
    align-items: flex-start;
    gap: 1.75rem;
    flex-wrap: wrap;
}
.home-news-main {
    flex: 1 1 380px;
    min-width: 0;
}
.home-news-aside {
    flex: 0 0 240px;
    padding: 1rem 1.1rem;
    background: var(--dispatch-sunken);
    border: 1px solid var(--dispatch-border);
    border-radius: 2px;
}
.home-news-aside-label {
    margin: 0 0 0.75rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid var(--dispatch-border);
    font-family: var(--dispatch-mono);
    font-size: 0.64rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--dispatch-text-muted);
}
.home-news-aside-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.home-news-aside-item {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
}
.home-news-aside-date {
    font-family: var(--dispatch-mono);
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    color: var(--dispatch-text-faint);
}
.home-news-aside-subject {
    font-family: 'Georgia', 'Times New Roman', serif;
    font-size: 0.92rem;
    line-height: 1.3;
    color: var(--dispatch-text-strong);
    word-break: break-word;
}

/* Empty state - shown when no broadcasts have been sent. Keeps the
   widget visible (visitors learn that subscribing actually leads to
   something) without faking a list. */
.home-news-aside-empty {
    margin: 0;
    font-family: 'Georgia', 'Times New Roman', serif;
    font-size: 0.95rem;
    line-height: 1.45;
    color: var(--dispatch-text);
}
.home-news-aside-empty span {
    display: inline-block;
    margin-top: 0.35rem;
    font-family: var(--dispatch-mono);
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    color: var(--dispatch-text-faint);
}

/* Mobile - when the subscribe row wraps, let the aside take the full
   width of the section. The list inside keeps its natural size and
   aligns left so the rhythm matches the desktop look (same trick the
   pulse-stats panel uses). */
@media (max-width: 1024px) {
    .home-news-row {
        flex-direction: column;
    }
    /* Reset flex basis on BOTH columns - without this, the basis values
       from the desktop layout (380px main, 240px aside) bleed into the
       column axis and create phantom vertical gaps. */
    .home-news-main,
    .home-news-aside {
        flex: 0 0 auto;
        width: 100%;
    }
    /* Drop the desktop separator treatment - border-left/padding-left
       only make sense when the aside is to the right of the main. On
       mobile they read as a stray indent and a phantom vertical bar. */
    .home-news-aside {
        border-left: 0;
        padding-left: 0;
    }
    .home-news-aside-list,
    .home-news-aside-empty {
        max-width: 320px;
    }
}

.home-news-confirm {
    padding: 1rem 1.25rem;
    border: 1px solid #1e90ff;
    border-left: 3px solid #00d4ff;
    border-radius: 2px;
    background: rgba(30, 144, 255, 0.06);
    font-family: var(--dispatch-mono);
    font-size: 0.85rem;
    color: #00d4ff;
    max-width: 480px;
}


/* ============================================================
   Responsive - collapse the two-card grid below 720px
   ============================================================ */

@media (max-width: 1024px) {
    .home {
        padding: 0 0 3rem;
    }
    .home-content {
        padding: 0 0.5rem;
    }
    .home-cards {
        grid-template-columns: minmax(0, 1fr);
    }
    .home-card {
        border-right: 0;
        border-bottom: 1px solid var(--dispatch-border);
    }
    .home-card:last-child { border-bottom: 0; }
    .home-trust {
        font-size: 0.68rem;
    }
}
