/* =========================================================================
   No Talent, No Alpha
   Tokens lifted from the live site so the custom theme reproduces it exactly.
   ========================================================================= */

:root {
    --brand: #001944;
    --brand-ink: #f5f9ff;
    --highlight: #2563eb;
    --amber: #c9852b;

    --bg: #fdfdfc;
    --bg-tone: #f9f8f6;
    --border: #ebe8e0;

    --text: #262626;
    --text-content: #404040;
    --text-muted: #4d4d4d;
    --text-faint: #767676;

    --radius: 8px;
    --radius-lg: 16px;
    --radius-btn: 30px;

    /* one vertical rhythm for every top-level section, so gaps between them
       are identical instead of ad-hoc (they ran 104/56/68/12/80/128) */
    --section-y: 56px;

    --container: 1180px;
    --content: 680px;
    --gutter: 24px;

    /* Ghost injects --gh-font-body / --gh-font-heading when a font is chosen
       in Admin > Design. The fallbacks are the live site's current faces. */
    --font-body: var(--gh-font-body, 'Nunito', system-ui, -apple-system, 'Segoe UI', sans-serif);
    --font-head: var(--gh-font-heading, system-ui, -apple-system, 'Segoe UI', 'Helvetica Neue', sans-serif);
    --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;

    --shadow-sm: 0 1px 2px rgba(0, 25, 68, .05);
    --shadow: 0 10px 40px -10px rgba(0, 0, 0, .18);
}

/* ---------- reset ---------- */

*, *::before, *::after { box-sizing: border-box; }

/* the hidden attribute must win over any display rule below */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
    margin:0;
    background: var(--bg);
    color: var(--text-content);
    font-family: var(--font-body);
    font-size:16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-head);
    color: var(--text);
    line-height: 1.25;
    margin:0;
    letter-spacing: -0.011em;
}

p { margin:0 0 1.2em; }
p:last-child { margin-bottom:0; }

a { color: inherit; text-decoration-color: rgba(0, 25, 68, .28); text-underline-offset: 3px; }
a:hover { text-decoration-color: currentColor; }

button, input, select, textarea { font: inherit; color: inherit; }

hr { border: 0; border-top: 1px solid var(--border); margin:40px 0; }

.sr-only {
    position: absolute; width: 1px; height: 1px; padding:0; margin:-1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

:focus-visible { outline: 2px solid var(--highlight); outline-offset: 2px; border-radius: 4px; }

/* ---------- layout ---------- */

.container {
    width: 100%;
    max-width: var(--container);
    margin:0 auto;
    padding:0 var(--gutter);
}

.site-main { display: block; min-height: 50vh; }

/* ---------- buttons ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap:8px;
    padding:8px 20px;
    border: 1px solid transparent;
    border-radius: var(--radius-btn);
    font-family: var(--font-body);
    font-size:15px;
    font-weight: 600;
    line-height: 1.45;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease, transform .15s ease;
}

.btn:active { transform: translateY(1px); }

.btn--brand { background: var(--brand); color: var(--brand-ink); }
.btn--brand:hover { background: #00286a; }

.btn--ghost {
    background: transparent;
    color: var(--text);
    border-color: var(--border);
}
.btn--ghost:hover { background: var(--bg-tone); border-color: #ddd8cc; }

.btn--invert { background: #ffffff; color: var(--brand); }
.btn--invert:hover { background: #eef3fb; }

.btn--lg { padding:12px 32px; font-size:15px; }
.btn--block { display: flex; width: 100%; }

/* ---------- header ---------- */

.site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: rgba(253, 253, 252, .88);
    backdrop-filter: saturate(180%) blur(12px);
    transition: box-shadow .2s ease, border-color .2s ease;
    /* Always drawn, faintly, so the nav is separated from the page even at the
       top of the scroll. It deepens to the full border colour once stuck. */
    border-bottom: 1px solid rgba(0, 25, 68, .07);
}

.site-header.is-stuck { border-bottom-color: var(--border); }

.header-inner {
    display: flex;
    align-items: center;
    gap:24px;
    min-height: 76px;
}

.site-logo { display: inline-flex; align-items: center; text-decoration: none; }
.site-logo img { height: 32px; width: auto; }

.site-logo-text {
    font-family: var(--font-head);
    font-weight: 800;
    font-size:18px;
    color: var(--brand);
    letter-spacing: -0.02em;
}

.site-nav { margin-left:auto; }

.nav-list {
    display: flex;
    align-items: center;
    gap:24px;
    list-style: none;
    margin:0;
    padding:0;
}

.nav-item a {
    font-size:15px;
    font-weight: 600;
    color: var(--text);
    text-decoration: none;
    opacity: .85;
    transition: opacity .15s ease;
}
.nav-item a:hover { opacity: 1; }
.nav-item--current a { opacity: 1; text-decoration: underline; text-underline-offset: 5px; }

.header-actions { display: flex; align-items: center; gap:12px; }

.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding:0;
    background: transparent;
    border: 0;
    border-radius: 50%;
    color: var(--text);
    cursor: pointer;
}
.icon-btn:hover { background: var(--bg-tone); }

.nav-toggle { display: none; }

@media (max-width: 860px) {
    .site-logo { flex: 0 1 auto; min-width: 0; }
    .site-logo img { max-height: 28px; width: auto; }

    .site-nav {
        display: none;
        order: 3;
        width: 100%;
        margin:0 -24px;
        padding:4px 24px 8px;
        border-top: 1px solid var(--border);
    }

    .site-header.is-open .site-nav { display: block; }
    .site-header.is-open .header-inner { flex-wrap: wrap; }

    .site-nav .nav-list { flex-direction: column; align-items: stretch; gap:0; }

    .site-nav .nav-item { border-bottom: 1px solid var(--border); }
    .site-nav .nav-item:last-child { border-bottom: 0; }

    .site-nav .nav-item a {
        display: block;
        padding:12px 0;
        font-size:15px;
    }

    .header-actions { margin-left:auto; gap:4px; }
    .nav-toggle { display: inline-flex; }
    .icon-btn { width: 40px; height: 40px; }

    .header-actions .btn {
        padding:8px 16px;
        font-size:14px;
    }
}

/* The header CTA used to be hidden outright below 520px on the grounds that
   Portal floats its own button. That left the mobile header with no way to
   join, and the floating bubble is the easiest thing on a page to ignore.
   The button stays, the label shortens and the logo gives up a few pixels, so
   search survives alongside it. Measured at 390px before shipping. */
/* [stated] Kane, 25 Aug 2026: "lets get rid of that CTA coz its squashing the
   logo." So below 520px the header is the wordmark, search and the menu, and
   nothing competes with the mark. Portal's floating button remains the mobile
   route to joining.

   Worth knowing before anyone tries to make the logo bigger to fill the space
   this frees: it cannot. The logo file is 9:1, so at the narrowest phone width
   worth designing for (360px) the wordmark, the search icon, the menu and the
   gutter cap it at about 29px tall. What removing the CTA buys is room around
   the mark, not a larger one. A stacked, two-line logo is the only thing that
   makes it genuinely bigger. */
@media (max-width: 520px) {
    .header-actions .btn { display: none; }
}

/* ---------- hero ---------- */

.hero { padding: 72px 0 var(--section-y); }

.hero-title {
    max-width: none;
    font-size:clamp(32px, 5.6vw, 56px);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.025em;
    margin:0;
    text-wrap: balance;
}

.hero-title-accent,
.hero-title-rest { display: block; }
.hero-title-accent { color: var(--highlight); }
.hero-title-rest { color: var(--text); }

.hero-inner { display: block; }
.hero-copy { max-width: 1080px; }

.hero-lede {
    max-width: 58ch;
    margin:24px 0 32px;
    font-size:18px;
    line-height: 1.6;
    color: var(--text-content);
}

/* The one link in the hero lede. Underlined rather than coloured alone: the
   lede is running prose and a colour change mid-sentence is easy to read
   straight past. */
.hero-lede-link {
    color: var(--brand);
    font-weight: 600;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

.hero-lede-link:hover { color: var(--highlight); }

.hero .subscribe-form { max-width: 480px; }

.hero-fineprint {
    margin:12px 0 0;
    font-size:14px;
    color: var(--text-muted);
}

/* ---------- live band ---------- */

.band { padding: var(--section-y) 0; }

.band-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap:12px;
    margin-bottom:20px;
}

.band-title {
    font-size:clamp(20px, 3vw, 27px);
    font-weight: 700;
    letter-spacing: -0.025em;
    margin:0;
}

.band-updated { margin:0; font-size:14px; color: var(--text-muted); }
.band-updated:empty { display: none; }

.band-grid {
    display: grid;
    /* The map column is deliberately wider so the map's natural height lands
       within ~20px of the list beside it. Stretching a short card to match
       only moves the empty space inside the card, where the border makes it
       obvious; leaving the list slightly longer hides it, since that column
       has no background. */
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    gap: 32px;
    align-items: start;
}

.band-map { min-width: 0; }
.band-map .dr-map { margin: 0; }
.band-side { min-width: 0; display: flex; flex-direction: column; gap: 20px; }

.band-figures {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 12px;
}

.band-figure {
    background: var(--bg-tone);
    border-radius: var(--radius);
    padding:20px 20px;
}

.band-value {
    font-family: var(--font-head);
    font-size:32px;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.03em;
    color: var(--text);
    margin:0 0 4px;
}

.band-label { margin:0; font-size:14px; color: var(--text-muted); }

.band-feed {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--border);
}

/* below this the figure tiles wrap in the narrow column and the list shoots
   past the map, so stack instead of living with a 150px mismatch */
@media (max-width: 1080px) {
    .band-grid { grid-template-columns: minmax(0, 1fr); gap: 24px; }
}

.band-row {
    display: grid;
    grid-template-columns: 8px minmax(0, 1fr) auto;
    align-items: baseline;
    column-gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
}

.band-row-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    align-self: center;
}

.band-row-dot.is-layoff { background: var(--highlight); }
.band-row-dot.is-closure { background: var(--amber); }

.band-row-co {
    font-family: var(--font-head);
    font-size: 16px;
    font-weight: 700;
    color: var(--text);
    letter-spacing: -0.012em;
    grid-column: 2;
}

.band-row-meta {
    grid-column: 2;
    font-size: 14px;
    color: var(--text-muted);
}

.band-row-n {
    grid-column: 3;
    grid-row: 1 / span 2;
    align-self: center;
    font-family: var(--font-head);
    font-size: 20px;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}

.band-feed-empty {
    padding: 16px 0;
    border-bottom: 1px solid var(--border);
    font-size: 15px;
    color: var(--text-faint);
}

.band-foot {
    margin: 16px 0 0;
    font-size: 15px;
    color: var(--text-muted);
}

.band-foot a { color: var(--brand); font-weight: 600; }

.band.is-unavailable .dr-map,
.band.is-unavailable .band-figures { display: none; }

/* ---------- audience paths ---------- */

.paths {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap:20px;
    padding-top: var(--section-y);
    padding-bottom: var(--section-y);
}

.path-card {
    display: flex;
    flex-direction: column;
    padding:32px 32px 32px;
    background: var(--bg-tone);
    border-radius: var(--radius-lg);
}

.path-card--alt { background: var(--brand); }
.path-card--alt .section-label { color: rgba(245, 249, 255, .7); }
.path-card--alt .path-title { color: #fff; }
.path-card--alt .path-body { color: rgba(245, 249, 255, .84); }

.path-title {
    font-size:20px;
    font-weight: 700;
    letter-spacing: -0.022em;
    margin:0 0 12px;
}

.path-body {
    font-size:15px;
    line-height: 1.6;
    color: var(--text-content);
    margin:0 0 24px;
}

.path-card .btn { align-self: flex-start; margin-top:auto; }
.path-card--alt .btn--brand { background: #fff; color: var(--brand); }
.path-card--alt .btn--brand:hover { background: #eef3fb; }

/* ---------- reader logos ---------- */

.readers { padding-top: var(--section-y); padding-bottom: var(--section-y); text-align: center; }

.readers-label {
    font-family: var(--font-head);
    font-size:12px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--text-faint);
    /* the section is full-bleed so the row can run edge to edge; the label is
       the only thing in it that needs gutters */
    margin:0 auto 20px;
    padding:0 24px;
    max-width: 640px;
}

/* The track is the window; the two lists inside it are identical, so shifting
   the pair left by exactly one list width lands the second set where the first
   one began and the reset is invisible. Edges are masked rather than cut so
   marks fade out instead of being sliced. */
.readers-track {
    display: flex;
    width: 100%;
    overflow: hidden;
    /* wide enough that a mark is fully faded before it reaches the edge; at 8%
       the fade was shorter than a logo and they read as clipped instead */
    -webkit-mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
    mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
}

/* The fade is a percentage, so on a phone 14% is about 55px, far shorter than
   a wordmark, and the logos read as clipped instead of faded. */
@media (max-width: 720px) {
    .readers-track {
        -webkit-mask-image: linear-gradient(to right, transparent, #000 24%, #000 76%, transparent);
        mask-image: linear-gradient(to right, transparent, #000 24%, #000 76%, transparent);
    }
}

.readers-list {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 64px;
    list-style: none;
    margin: 0;
    /* has to equal the gap: this is the space where the two sets meet, and if
       it is not the same the loop shows a hitch once every pass */
    padding: 0 64px 0 0;
    animation: readers-scroll 46s linear infinite;
}

.readers-list > li { flex: 0 0 auto; }

.readers-track:hover .readers-list { animation-play-state: paused; }

@keyframes readers-scroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-100%); }
}

.readers-list img {
    display: block;
    height: 40px;
    width: auto;
    object-fit: contain;
    filter: grayscale(1);
    opacity: .55;
    transition: opacity .15s ease, filter .15s ease;
}

.readers-list img:hover { filter: grayscale(0); opacity: 1; }

/* No motion: hold the row still and let it be scrolled by hand instead. The
   duplicate set is hidden so a screen reader and a scrollbar both see one set. */
@media (prefers-reduced-motion: reduce) {
    .readers-track { overflow-x: auto; scrollbar-width: none; }
    .readers-track::-webkit-scrollbar { display: none; }
    .readers-list { animation: none; }
    .readers-list[aria-hidden="true"] { display: none; }
}

/* ---------- plans strip ---------- */

.plans { padding-top: var(--section-y); padding-bottom: var(--section-y); }

.plan-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap:12px;
}

.plan {
    background: var(--bg-tone);
    border: 1px solid transparent;
    border-radius: var(--radius);
    padding:20px 24px;
}

.plan--free { background: transparent; border-color: var(--border); }

.plan-name {
    font-size:13px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin:0 0 8px;
}

.plan-price {
    font-family: var(--font-head);
    font-size:27px;
    font-weight: 700;
    letter-spacing: -0.03em;
    color: var(--text);
    margin:0 0 8px;
    line-height: 1.1;
}

.plan-period { font-size:15px; font-weight: 400; color: var(--text-muted); letter-spacing: 0; }
.plan-desc { margin:0; font-size:15px; line-height: 1.45; color: var(--text-content); }
.plans-foot { margin:16px 0 0; font-size:15px; }
.plans-foot a { color: var(--brand); font-weight: 600; }

/* figures are read in columns, so they take tabular numerals everywhere */
.band-value, .dr-hero-value, .dr-tile-value, .plan-price,
.dr-num, .ds-asof, .band-updated, .dr-count {
    font-variant-numeric: tabular-nums;
}

/* ---------- section label ---------- */

.section-label {
    font-family: var(--font-head);
    font-size:13px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text);
    margin:0 0 12px;
}

/* ---------- feed ---------- */

.feed-layout {
    padding-top: var(--section-y);
    padding-bottom: var(--section-y);
    display: grid;
    grid-template-columns: minmax(0, 1fr) 350px;
    gap: 32px;
    align-items: start;
}

.feed-layout--wide { grid-template-columns: minmax(0, 1fr); }

.post-list {
    background: var(--bg-tone);
    border-radius: var(--radius-lg);
    padding:8px 24px;
}

.feed-layout--wide .post-list { padding:8px 24px; }

.post-card {
    display: grid;
    grid-template-columns: 240px minmax(0, 1fr);
    gap:24px;
    align-items: start;
    padding:24px 0;
    border-bottom: 1px solid var(--border);
}

.post-card:last-child { border-bottom: 0; }
.post-card--no-image { grid-template-columns: minmax(0, 1fr); }

.post-card-thumb {
    display: block;
    overflow: hidden;
    border-radius: var(--radius);
    background: #fff;
    border: 1px solid var(--border);
}

.post-card-thumb img {
    width: 100%;
    aspect-ratio: 2 / 1;
    object-fit: cover;
}

.post-card-title {
    font-size:18px;
    font-weight: 700;
    line-height: 1.25;
    margin:0 0 8px;
}

.post-card-title a { text-decoration: none; }
.post-card-title a:hover { color: var(--highlight); }

.post-card-excerpt {
    font-size:15px;
    line-height: 1.6;
    color: var(--text-content);
    margin:0 0 12px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.post-meta {
    font-size:14px;
    color: var(--text-muted);
    margin:0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap:8px;
}

.post-meta .dot { opacity: .55; }
.post-meta-tag { text-decoration: none; font-weight: 600; }
.post-meta-tag:hover { color: var(--highlight); }

.lock { font-weight: 600; color: var(--brand); }

.feed-more { display: flex; justify-content: center; padding:24px 0 0; }

/* ---------- sidebar ---------- */

.feed-side { position: sticky; top: 100px; }

.side-card {
    background: var(--bg-tone);
    border-radius: var(--radius-lg);
    padding:24px;
}

.side-card-lede {
    font-size:15px;
    line-height: 1.6;
    color: var(--text-content);
    margin:0 0 16px;
}

/* ---------- subscribe form ---------- */

.subscribe-form {
    display: flex;
    flex-wrap: wrap;
    gap:8px;
    position: relative;
    margin:0;
}

.subscribe-input {
    flex: 1 1 220px;
    min-width: 0;
    padding:12px 16px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-btn);
    font-size:15px;
    color: var(--text);
}

.subscribe-input::placeholder { color: var(--text-faint); }
.subscribe-input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px rgba(0, 25, 68, .08); }

.subscribe-button { flex: 0 0 auto; }

.side-card .subscribe-form { flex-direction: column; align-items: stretch; }
.side-card .subscribe-input,
.side-card .subscribe-button { flex: 0 0 auto; width: 100%; }

.subscribe-message {
    flex: 1 0 100%;
    margin:0;
    font-size:14px;
    min-height: 0;
}

.subscribe-message--error { color: #b3261e; }
.subscribe-message--error:empty { display: none; }
.subscribe-message--success { display: none; color: var(--brand); font-weight: 600; }

.subscribe-form.success .subscribe-message--success { display: block; }
.subscribe-form.success .subscribe-input,
.subscribe-form.success .subscribe-button { display: none; }
.subscribe-form.loading .subscribe-button,
.subscribe-form.is-loading .subscribe-button { opacity: .6; pointer-events: none; }

/* ---------- article ---------- */

.reading-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: 60;
    pointer-events: none;
}

.reading-progress span {
    display: block;
    height: 100%;
    background: var(--highlight);
    transform: scaleX(0);
    transform-origin: 0 50%;
    transition: transform .1s linear;
}

.article-wrap {
    max-width: var(--container);
    margin:0 auto 80px;
    padding:0 var(--gutter);
}

/* No tone panel behind reading. It boxed every post and page in grey, which
   made the text look like a pull quote inside the site rather than the site
   itself, and it fought the plain left-aligned heroes on the home and pricing
   pages. Content now sits on the page. */
/* The top padding is doing the job the grey panel used to do. With the panel
   gone and padding at 0, a post's date line began about nine pixels under a
   sticky header, so the headline read as part of the nav rather than the start
   of the piece. 72px matches the breathing room .page-hero already gives the
   about and pricing pages, so every top-of-page on the site now starts on the
   same line. */
.article {
    background: transparent;
    border-radius: 0;
    padding:72px 0 64px;
}

/* Except where a hero already supplied it: about and pricing lead with
   .page-hero, which carries its own 72px. Doubling it there would open a hole. */
.page-hero + .article-wrap .article { padding-top:0; }

.article > * {
    max-width: calc(var(--content) + 124px);
    margin-left:auto;
    margin-right:auto;
    padding:0 32px;
}

.article-header { margin-bottom:24px; }

.article-title {
    font-size:clamp(27px, 4.4vw, 38px);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.025em;
    margin:8px 0 0;
}

.article-header .post-meta { margin-bottom:4px; }

.article-series {
    font-family: var(--font-head);
    font-size:12px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    margin:0 0 12px;
}

.article-series a {
    color: var(--brand);
    text-decoration: none;
}

.article-series a:hover { color: var(--highlight); }

/* The end-of-post card. Navy, matching .path-card--alt on the home page, so
   the two asks read as one deliberate destination rather than two stray
   paragraphs. Note the auto side margins: `.article > *` centres its children
   with them, and a `margin: 40px 0 0` shorthand silently cancels that. */
.article > .post-endcap {
    margin:48px auto 0;
    padding:30px 32px;
    background: var(--brand);
    border-radius: var(--radius-lg);
    color: var(--brand-ink);
}

.post-endcap-lede {
    margin:0 0 14px;
    font-size:17px;
    font-weight: 600;
    line-height: 1.45;
    color: #fff;
}

.post-endcap-links {
    margin:0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap:22px;
    font-family: var(--font-head);
    font-size:14px;
    font-weight: 700;
    letter-spacing: .04em;
}

.post-endcap-links a,
.post-endcap-links .post-share-copy {
    color: #fff;
    text-decoration: none;
    border-bottom:1px solid rgba(245, 249, 255, .45);
    padding-bottom:2px;
    transition: border-color .15s ease, color .15s ease;
}

.post-endcap-links .post-share-copy {
    border-left:0;
    border-right:0;
    border-top:0;
    background: none;
    padding-left:0;
    padding-right:0;
    font: inherit;
    letter-spacing: inherit;
    cursor: pointer;
}

.post-endcap-links a:hover,
.post-endcap-links .post-share-copy:hover {
    color: #fff;
    border-bottom-color: #fff;
}

.post-endcap-links a:focus-visible,
.post-endcap-links .post-share-copy:focus-visible {
    outline:2px solid #fff;
    outline-offset:4px;
}

.post-endcap-bridge {
    margin:22px 0 0;
    padding-top:20px;
    border-top:1px solid rgba(245, 249, 255, .2);
    font-size:15px;
    line-height: 1.65;
    color: rgba(245, 249, 255, .82);
}

.post-endcap-bridge a {
    color: #fff;
    font-weight: 600;
    white-space: nowrap;
}

/* `.article > *` sets `padding: 0 16px` further down the file at the same
   specificity, so a bare `.post-endcap` rule loses and the card ends up with
   no vertical padding at all. The child selector is what makes this stick. */
@media (max-width: 720px) {
    .article > .post-endcap { padding:26px 22px 28px; border-radius: var(--radius); }
    .post-endcap-lede { font-size:16px; }
    .post-endcap-links { gap:18px; }
    .post-endcap-bridge { margin-top:20px; padding-top:18px; }
}


.article-lede {
    font-size:18px;
    line-height: 1.6;
    color: var(--text-content);
    margin:16px 0 0;
}

.article-byline {
    margin:20px 0 0;
    font-size:15px;
    color: var(--text-muted);
}

.article-image { margin:32px auto; }

.article-image img {
    width: 100%;
    border-radius: var(--radius);
    background: #fff;
}

.article-image figcaption {
    margin-top:8px;
    font-size:14px;
    color: var(--text-muted);
    text-align: center;
}

.article-content { font-size:16px; line-height: 1.75; }

.article--page .article-title { text-align: center; }
.article--page .article-lede { text-align: center; }
.article-wrap--flush { margin-bottom:40px; }
.article-wrap--flush .article { padding-bottom:40px; }

/* ---------- Ghost content ---------- */

.gh-content > * { margin:0 0 1.35em; }
.gh-content > :last-child { margin-bottom:0; }

.gh-content h2 {
    font-size:23px;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin:1.9em 0 .55em;
}

.gh-content h3 {
    font-size:18px;
    font-weight: 700;
    margin:1.6em 0 .5em;
}

.gh-content a { color: var(--brand); font-weight: 600; }

.gh-content ul, .gh-content ol { padding-left:1.3em; margin:0 0 1.35em; }
.gh-content li { margin-bottom:.5em; }

.gh-content blockquote {
    margin:1.6em 0;
    padding:4px 0 4px 20px;
    border-left: 3px solid var(--brand);
    font-size:18px;
    color: var(--text);
}

.gh-content img,
.gh-content .kg-image { border-radius: var(--radius); }

.gh-content figcaption {
    margin-top:8px;
    font-size:14px;
    color: var(--text-muted);
    text-align: center;
}

.gh-content code {
    font-family: var(--font-mono);
    font-size:.88em;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 5px;
    padding:1px 4px;
}

.gh-content pre {
    background: var(--brand);
    color: #e8eefb;
    padding:16px 20px;
    border-radius: var(--radius);
    overflow-x: auto;
    font-size:15px;
    line-height: 1.6;
}

.gh-content pre code { background: none; border: 0; padding:0; color: inherit; }

.gh-content table {
    width: 100%;
    border-collapse: collapse;
    font-size:15px;
}

.gh-content th, .gh-content td {
    text-align: left;
    padding:8px 12px;
    border-bottom: 1px solid var(--border);
}

.gh-content th { font-family: var(--font-head); font-weight: 700; color: var(--text); }

.kg-width-wide { max-width: calc(var(--content) + 200px); margin-left:auto; margin-right:auto; }
.kg-width-full { max-width: 100%; }

.kg-card { margin-left:auto; margin-right:auto; }

.kg-callout-card {
    display: flex;
    gap:12px;
    padding:16px 20px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

/* ---------- paywall ---------- */

/* Ghost injects its own upgrade card inside {{content}} for any member
   without access. The theme renders its own, so without this every gated post
   showed two stacked asks with two different headlines. Ours stays. */
.gh-post-upgrade-cta { display: none !important; }

/* The gated text used to stop mid-sentence against a hard edge. The fade sits
   over the last lines so the piece dissolves into the offer rather than
   hitting a wall, which is also the honest signal: there is more here. */
/* How much of a paid piece a non-member gets to read.

   Ghost hands the browser a long preview: about 600 words on a recent weekly,
   which rendered to over 3,000 pixels of scrolling before the card appeared.
   That is most of the argument, and a reader who has already had the argument
   has no reason to pay for it.

   Clamped here rather than by editing the posts, which is a deliberate trade.
   The full preview still reaches the page, so Google still indexes those 600
   words and the piece keeps competing in search; only the reader is stopped
   early. If the preview should genuinely not leave the server, that is a
   paywall card in each post and a different job.

   The cut lands mid-sentence on purpose. A preview that ends cleanly reads as
   a short post; one that stops in the middle of a thought reads as a door.

   Both heights were measured rather than guessed. Across four recent paid
   posts these are the values that end on a paragraph AND cut into the middle
   of the next one every time. 340 looked reasonable and was wrong: on three of
   the four it stopped exactly on a section heading with nothing underneath,
   which reads as a broken page rather than a paywall. */
.article-content.is-preview {
    max-height: 260px;
    overflow: hidden;
}

/* A narrower column takes more vertical space for the same words, so the phone
   value is not a scaled-down desktop one. Measured the same way. */
@media (max-width: 720px) {
    .article-content.is-preview { max-height: 400px; }
}

/* The fade was built for a preview thousands of pixels long, where 160px of
   gradient was a tail. Over a 260px preview it would wash out most of what is
   left. Shorter, so it signals the cut without eating the copy. */
.article-content.is-preview + .paywall-fade {
    height: 88px;
    margin:-88px auto -40px;
}

.paywall-fade {
    position: relative;
    z-index: 1;
    height: 160px;
    /* the negative top pulls the gradient over the tail of the preview; the
       negative bottom cancels the card's own top margin so the two meet.

       The auto sides are load-bearing and were missing: .article-content is
       centred inside the article and this was not, so the gradient sat 164px
       to the left of the text and the right-hand end of every line stayed
       crisp. Invisible while the fade was a tail on a 3,000px preview,
       obvious the moment the preview got short. */
    margin:-160px auto -40px;
    padding:0;
    pointer-events: none;
    background: linear-gradient(to bottom, rgba(253, 253, 252, 0) 0%, var(--bg) 78%);
}

/* A post with no paywall divider gives non-members no body text at all: Ghost
   renders the content block containing nothing but its own upgrade card. There
   is then nothing to fade, and the gradient lands on the feature image and
   washes it out. Only fade when a preview actually exists. */
.article-content:has(> .gh-post-upgrade-cta:only-child) + .paywall-fade { display: none; }

.paywall {
    margin:40px auto 0;
    padding:0;
    background: var(--brand);
    color: var(--brand-ink);
    border-radius: var(--radius-lg);
    text-align: center;
    overflow: hidden;
}

/* Padding lives on the inner element so the card can keep the same outer
   width as the reading column while the copy inside sits on a shorter measure
   than the body text. Centred text needs the narrower line to stay readable. */
.paywall-inner {
    max-width: 46ch;
    margin:0 auto;
    padding:52px 32px 44px;
}

.paywall--page { margin:0 0 80px; }

.paywall-eyebrow {
    margin:0 0 14px;
    font-family: var(--font-head);
    font-size:12px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: rgba(245, 249, 255, .62);
}

.paywall-title {
    color: #fff;
    font-family: var(--font-head);
    font-size:clamp(22px, 3.4vw, 29px);
    font-weight: 700;
    line-height: 1.18;
    margin:0 0 14px;
    letter-spacing: -0.02em;
    text-wrap: balance;
}

.paywall-copy {
    margin:0 0 24px;
    font-size:16px;
    line-height: 1.6;
    color: rgba(245, 249, 255, .82);
}

/* Left-aligned inside a centred card: a centred list has no common edge for
   the eye to run down, which is what makes three short lines read as a blur
   rather than as three things you get. */
.paywall-list {
    display: inline-block;
    margin:0 0 28px;
    padding:0;
    list-style: none;
    text-align: left;
}

.paywall-list li {
    position: relative;
    margin:0 0 9px;
    padding-left:26px;
    font-size:15px;
    line-height: 1.5;
    color: rgba(245, 249, 255, .95);
}

.paywall-list li:last-child { margin-bottom:0; }

.paywall-list li::before {
    content: "";
    position: absolute;
    left:2px;
    top:7px;
    width:9px;
    height:5px;
    border-left:2px solid #8fb4ff;
    border-bottom:2px solid #8fb4ff;
    transform: rotate(-45deg);
}

.paywall-btn { min-width:200px; }

.paywall-price {
    margin:14px 0 0;
    font-size:14px;
    color: rgba(245, 249, 255, .68);
}

.paywall-alt {
    margin:26px auto 0;
    padding-top:22px;
    border-top:1px solid rgba(245, 249, 255, .16);
    font-size:14px;
    line-height: 1.55;
    color: rgba(245, 249, 255, .7);
}

.paywall-alt a { color: #fff; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }

/* Free gate: the ask is an email field, not a link out to Portal. Every step
   between the reader and the article is a place to lose them, and Portal is a
   modal, a form and a redirect. Ghost's Portal script binds
   [data-members-form] and sets loading / success / error on the FORM element,
   so the three states below are pure CSS and the theme ships no JS for this. */
.paywall-form {
    display: flex;
    gap:10px;
    max-width:420px;
    margin:0 auto;
}

.paywall-input {
    flex:1 1 auto;
    min-width:0;
    padding:11px 16px;
    border:1px solid rgba(245, 249, 255, .28);
    border-radius: var(--radius-btn);
    background: rgba(255, 255, 255, .08);
    color: #fff;
    font-family: var(--font-body);
    font-size:15px;
    line-height: 1.45;
}

.paywall-input::placeholder { color: rgba(245, 249, 255, .5); }

.paywall-input:focus {
    outline: none;
    border-color: rgba(255, 255, 255, .85);
    background: rgba(255, 255, 255, .14);
}

.paywall-submit { flex:0 0 auto; }

.paywall-form.loading .paywall-submit { opacity:.55; pointer-events: none; }

/* On success the form is replaced by the confirmation, because leaving a
   filled field on screen next to "check your inbox" invites a second submit. */
.paywall-form.success { display: none; }

.paywall-msg {
    display: none;
    margin:16px auto 0;
    font-size:15px;
    line-height: 1.55;
}

.paywall-form.success ~ .paywall-msg--ok { display: block; color: #fff; font-size:16px; }

/* The instruction paragraph is the ask, so leaving it above "check your inbox"
   tells someone who has already acted to act again. :has() looks backwards up
   the card, which a sibling selector cannot do. */
.paywall-inner:has(.paywall-form.success) .paywall-copy { display: none; }

.paywall-msg--err { color:#ffc7c7; font-size:14px; }
.paywall-msg--err:not(:empty) { display: block; }

@media (max-width: 720px) {
    .paywall-form { flex-direction: column; }
    .paywall-submit { width:100%; }
}

.paywall-signin { margin:18px 0 0; font-size:14px; color: rgba(245, 249, 255, .7); }
.paywall-signin a { color: #fff; font-weight: 600; }

@media (max-width: 720px) {
    .paywall-inner { padding:40px 24px 36px; }
    .paywall-fade { height:120px; margin-top:-120px; }
    .paywall-btn { width:100%; min-width:0; }
}

/* ---------- data room preview gate ----------
   Signed out, the page shows real rows and dissolves into the upgrade card
   rather than stopping at a wall. The visitor gets to check our work first,
   which is the whole argument for paying. */

/* Controls that would tease a capability the visitor does not have yet. The
   markup stays so the script can read its defaults without a null check. */
.dr-app.is-preview .dr-toolbar,
.dr-app.is-preview .dr-more { display: none; }

/* Signed out, the panel body is capped and dissolved almost immediately. The
   tabs and each dataset's header stay fully legible, so the range of what is
   here is obvious, but nothing below is usable: no filters, no full table, no
   export. Measured in CSS rather than positioned by script, because the start
   is now a fixed fraction of a fixed height rather than the midpoint of
   whatever chart happened to render. */
.dr-app.is-preview .ds-body {
    position: relative;
    max-height: 300px;
    overflow: hidden;
}

.dr-app.is-preview .ds-body::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(
        to bottom,
        rgba(253, 253, 252, 0)    0,
        rgba(253, 253, 252, 0)    26%,
        rgba(253, 253, 252, 0.72) 62%,
        var(--bg)                 92%
    );
}

/* the inner zones are the member-side grouping; in preview the body-level fade
   above replaces them entirely, so they must not paint a second gradient */
.dr-app.is-preview .dr-fade-zone::after { content: none; }

.dr-app.is-preview .dr-count { color: var(--text-faint); }

.dr-gate {
    /* Deliberately NOT pulled up under the fade: the sourcing caveat sits
       between the table and this card, and overlapping it hid the one piece
       of copy that admits what the dataset is missing. */
    margin: 32px 0 0;
    padding: 36px 32px 40px;
    background: var(--brand);
    color: var(--brand-ink);
    border-radius: var(--radius-lg);
    text-align: center;
    position: relative;
}

.dr-gate-label {
    font-family: var(--font-head);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: rgba(245, 249, 255, .6);
    margin: 0 0 8px;
}

.dr-gate-title {
    color: #fff;
    font-size: clamp(20px, 3.2vw, 27px);
    font-weight: 700;
    letter-spacing: -0.02em;
    margin: 0 0 12px;
}

.dr-gate-copy {
    max-width: 46ch;
    margin: 0 auto 24px;
    font-size: 15px;
    line-height: 1.6;
    color: rgba(245, 249, 255, .85);
}

.dr-gate-list {
    display: grid;
    gap: 8px;
    max-width: 46ch;
    margin: 0 auto 28px;
    padding: 0;
    list-style: none;
    text-align: left;
    font-size: 15px;
    line-height: 1.45;
    color: rgba(245, 249, 255, .92);
}

.dr-gate-list li { padding-left: 26px; position: relative; }

.dr-gate-list li::before {
    content: "";
    position: absolute;
    left: 4px;
    top: .5em;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--highlight, #2563eb);
}

.dr-gate-signin { margin: 16px 0 0; font-size: 15px; color: rgba(245, 249, 255, .85); }
.dr-gate-signin a { color: #fff; font-weight: 600; }

.dr-gate-note {
    max-width: 56ch;
    margin: 26px auto 0;
    padding-top: 18px;
    border-top: 1px solid rgba(245, 249, 255, .16);
    font-size: 13.5px;
    line-height: 1.55;
    color: rgba(245, 249, 255, .6);
}

@media (max-width: 640px) {
    .dr-gate { padding: 28px 20px 32px; margin-top: 24px; }
}


/* ---------- featured tier ----------
   Levav: an unmarked list of three makes the reader do the choosing, and the
   default wins because it is the default. One tier carries the flag; the rest
   are unchanged so the mark reads as a recommendation, not a hard sell. */

.plan.is-featured,
.tier-card.is-featured {
    border-color: var(--highlight);
    box-shadow: 0 0 0 1px var(--highlight);
}

.plan-flag,
.tier-flag {
    font-family: var(--font-head);
    font-size:11px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--highlight);
    margin:0 0 6px;
}

/* ---------- archive / error ---------- */

.archive-header { padding:64px 0 32px; }

.archive-title {
    font-size:clamp(27px, 5vw, 46px);
    font-weight: 700;
    letter-spacing: -0.028em;
    margin:0;
}

.archive-lede {
    max-width: 60ch;
    margin:12px 0 0;
    font-size:16px;
    color: var(--text-content);
}

.archive-count { margin:12px 0 0; font-size:15px; color: var(--text-muted); }

.read-next { padding-bottom:80px; }

.error-page { padding:110px 0 130px; }
.error-page .btn { margin-top:24px; }

/* ---------- pricing ---------- */

.tier-toggle {
    display: inline-flex;
    gap:4px;
    padding:4px;
    margin:0 auto 32px;
    background: var(--bg-tone);
    border-radius: var(--radius-btn);
    position: relative;
    left: 50%;
    transform: translateX(-50%);
}

.tier-toggle-btn {
    padding:8px 20px;
    border: 0;
    border-radius: var(--radius-btn);
    background: transparent;
    font-size:15px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
}

.tier-toggle-btn.is-active { background: #fff; color: var(--text); box-shadow: var(--shadow-sm); }

.tier-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap:20px;
    padding-bottom:80px;
}

.tier-card {
    display: flex;
    flex-direction: column;
    padding:32px 24px;
    background: var(--bg-tone);
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
}

.tier-card--free { background: transparent; border-color: var(--border); }

/* The Data Room card, which carries no price.

   Given the border treatment rather than the filled one so it reads as a
   different kind of offer next to the two self-serve cards, not as a third
   rung on the same ladder. */
.tier-card--talk { background: transparent; border-color: var(--border); }

.tier-name {
    font-size:15px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    margin:0 0 12px;
}

.tier-price { display: flex; align-items: baseline; gap:4px; margin:0 0 12px; }

.tier-amount {
    font-family: var(--font-head);
    font-size:32px;
    font-weight: 700;
    letter-spacing: -0.03em;
    color: var(--text);
    line-height: 1.1;
}

/* "Talk to us" at the 32px price size shouts, and it is not a number, so it
   does not need to anchor anything. Sized to sit on the same baseline as the
   prices beside it so the cards still line up row for row. */
.tier-amount--talk {
    font-size: 22px;
    /* 22 x 1.6 matches 32 x 1.1, so this row is exactly as tall as a price
       row and the three cards stay aligned line for line. */
    line-height: 1.6;
    letter-spacing: -0.02em;
    color: var(--text-muted);
}

.tier-period { font-size:15px; color: var(--text-muted); }

.tier-description { font-size:15px; line-height: 1.6; color: var(--text-content); margin:0 0 16px; }

.tier-benefits { list-style: none; margin:0 0 24px; padding:0; }

.tier-benefits li {
    display: flex;
    gap:8px;
    align-items: flex-start;
    font-size:15px;
    line-height: 1.45;
    margin-bottom:8px;
}

.tier-benefits svg { flex: 0 0 auto; margin-top:4px; color: var(--highlight); }

.tier-card .btn { margin-top:auto; }

/* ---------- footer ---------- */

.site-footer { margin-top:0; }

.footer-cta {
    position: relative;
    overflow: hidden;
    container-type: inline-size;
    max-width: var(--container);
    margin: 0 auto;
    background: var(--bg-tone);
    border-radius: var(--radius-lg);
    padding: var(--section-y) 24px 80px;
    text-align: center;
}

/* Sized to the block rather than the viewport, so the whole title is visible.
   Cropped letters read as a rendering fault, not as a deliberate watermark. */
.footer-watermark {
    position: absolute;
    left: 50%;
    bottom: 0;
    transform: translateX(-50%);
    display: block;
    max-width: 100%;
    font-family: var(--font-head);
    font-size:clamp(40px, 8.5cqw, 128px);
    font-weight: 800;
    letter-spacing: -0.04em;
    line-height: 1.1;
    white-space: nowrap;
    color: rgba(0, 25, 68, .04);
    pointer-events: none;
    user-select: none;
}

.footer-cta-inner { position: relative; z-index: 1; max-width: 560px; margin:0 auto; }

.footer-logo { display: inline-flex; margin-bottom:20px; }
.footer-logo img { height: 30px; width: auto; }

.footer-lede {
    font-size:16px;
    line-height: 1.6;
    color: var(--text-content);
    margin:0 0 24px;
}

.footer-cta .subscribe-form { justify-content: center; }

.footer-bottom {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap:8px;
    padding-top:24px;
    padding-bottom:40px;
}

.footer-nav .nav-list { gap:20px; flex-wrap: wrap; justify-content: center; }
.footer-nav .nav-item a { font-size:14px; font-weight: 600; }

/* One line, measured rather than hoped. The four labels are 320px of text at
   14px, and a 393px screen leaves 345px inside the container gutter, so a
   single row needs gaps under 9px, which reads as one run-on word. Dropping
   to 12px and pulling the gutter to 16px leaves 316px of text and gaps inside
   328px at 360px wide, the narrowest phone worth designing for. Wrap stays on
   so anything narrower than that breaks gracefully instead of overflowing. */
@media (max-width: 520px) {
    .footer-bottom {
        padding-left:16px;
        padding-right:16px;
        padding-bottom:32px;
        gap:14px;
    }

    .footer-nav .nav-list { gap:14px; }
    .footer-nav .nav-item a { font-size:12px; }
    .footer-social a { font-size:12px; }
    .footer-copy { font-size:12px; }
}

.footer-social {
    display: flex;
    gap:16px;
    list-style: none;
    margin:0;
    padding:0;
}

.footer-social a { font-size:14px; font-weight: 600; color: var(--text-muted); text-decoration: none; }
.footer-social a:hover { color: var(--text); text-decoration: underline; }

.footer-copy { margin:0; font-size:14px; color: var(--text-muted); }
.footer-copy a { font-weight: 600; }

/* =========================================================================
   Data Room
   ========================================================================= */

.dr-band {
    background: var(--brand);
    color: var(--brand-ink);
    padding:56px 0 64px;
    margin-bottom:32px;
}

.dr-eyebrow {
    font-family: var(--font-head);
    font-size:12px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: rgba(245, 249, 255, .65);
    margin:0 0 12px;
}

.dr-title {
    color: #fff;
    font-size:clamp(27px, 5vw, 46px);
    font-weight: 700;
    letter-spacing: -0.028em;
    margin:0;
}

.dr-lede {
    max-width: 60ch;
    margin:12px 0 0;
    font-size:16px;
    line-height: 1.6;
    color: rgba(245, 249, 255, .82);
}

/* ---------------------------------------------------------------------------
   The Data Room, explained to somebody who has not paid for it.

   Rendered only when there is no access. A subscriber already knows what this
   page is and does not need a sales panel above their data.
   --------------------------------------------------------------------------- */

.dr-intro { padding: 0 0 44px; }

.dr-intro-inner {
    display: grid;
    /* The copy column is wider because it carries the argument. Collapses to
       one column early: three feature blocks squeezed beside a paragraph is
       worse than three feature blocks under one. */
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: 40px 56px;
    align-items: start;
}

.dr-intro-title {
    margin: 0 0 14px;
    font-size: clamp(21px, 3vw, 28px);
    font-weight: 700;
    letter-spacing: -0.025em;
}

.dr-intro-lede {
    margin: 0;
    max-width: 54ch;
    font-size: 17px;
    line-height: 1.65;
    color: var(--text-content);
}

.dr-intro-cta { margin: 26px 0 0; }

.dr-intro-points {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 20px;
}

/* The rule sits on the left of each point rather than a bullet, so the three
   read as a short spec sheet rather than as a list of claims. */
.dr-intro-points li {
    padding-left: 16px;
    border-left: 2px solid var(--border);
}

.dr-intro-points h3 {
    margin: 0 0 5px;
    font-size: 16px;
    font-weight: 700;
    letter-spacing: -0.012em;
    color: var(--brand);
}

.dr-intro-points p {
    margin: 0;
    font-size: 15px;
    line-height: 1.55;
    color: var(--text-muted);
}

@media (max-width: 860px) {
    .dr-intro-inner { grid-template-columns: 1fr; gap: 32px; }
    .dr-intro { padding-bottom: 32px; }
    .dr-intro-lede { font-size: 16px; }
    .dr-intro-cta .btn { width: 100%; text-align: center; }
}

.dr-app { padding-bottom:80px; }

.dr-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap:12px;
    padding:80px 0;
    color: var(--text-muted);
}

.dr-spinner {
    width: 26px;
    height: 26px;
    border: 2px solid var(--border);
    border-top-color: var(--brand);
    border-radius: 50%;
    animation: dr-spin .8s linear infinite;
}

@keyframes dr-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .dr-spinner { animation-duration: 2.4s; }
    html { scroll-behavior: auto; }
}

/* summary */

.dr-summary {
    display: grid;
    grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
    gap:20px;
    align-items: stretch;
    margin-bottom:32px;
}

.dr-hero {
    background: var(--bg-tone);
    border-radius: var(--radius-lg);
    padding:24px 24px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.dr-hero-label {
    font-size:15px;
    color: var(--text-muted);
    margin:0 0 4px;
}

.dr-hero-value {
    font-family: var(--font-head);
    font-size:46px;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.035em;
    color: var(--text);
    margin:0;
}

.dr-hero-note { margin:8px 0 0; font-size:14px; color: var(--text-muted); }

.dr-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap:12px;
}

.dr-tile {
    display: flex;
    flex-direction: column;
    justify-content: center;
    background: var(--bg-tone);
    border-radius: var(--radius);
    padding:16px 20px;
}

.dr-tile-label { font-size:14px; color: var(--text-muted); margin:0 0 4px; }

.dr-tile-value {
    font-family: var(--font-head);
    font-size:23px;
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--text);
    margin:0;
    line-height: 1.1;
}

.dr-tile-sub {
    margin:4px 0 0;
    font-size:13px;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* tabs */

.dr-tabs {
    display: flex;
    gap:4px;
    border-bottom: 1px solid var(--border);
    margin-bottom:20px;
}

.dr-tab {
    padding:12px 16px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    font-family: var(--font-head);
    font-size:15px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    margin-bottom:-1px;
}

.dr-tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--brand); }

/* ---------- dataset library ---------- */

/* The line between asking and reading. Without it the tabs sat directly under
   the ask panel and the two read as one block, so nothing told you where the
   conversation ended and the evidence began. The note beside it states a fact
   about the datasets rather than counting them: the count only goes up, and
   copy naming a number is stale the week after it is written. */
.ds-divider {
    display: flex;
    align-items: center;
    gap:16px;
    margin:40px 0 22px;
}

.ds-divider::after {
    content: "";
    flex:1;
    height:1px;
    background: var(--border);
}

.ds-divider-text {
    font-family: var(--font-head);
    font-size:12px;
    font-weight:700;
    letter-spacing:.13em;
    text-transform: uppercase;
    color: var(--text-faint);
    white-space: nowrap;
}

.ds-divider-note {
    font-size:12px;
    font-weight:600;
    letter-spacing:.04em;
    color: var(--text-faint);
    opacity:.72;
    white-space: nowrap;
}

.ds-nav { margin-bottom:32px; }

.ds-cats {
    display: flex;
    flex-wrap: wrap;
    gap:7px;
    margin-bottom:18px;
}

.ds-cat {
    display: inline-flex;
    align-items: baseline;
    gap:7px;
    padding:8px 16px;
    font-family: var(--font-head);
    font-size:14px;
    font-weight:600;
    color: var(--text-muted);
    background: var(--bg);
    border:1px solid var(--border);
    border-radius: var(--radius-btn);
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease, background-color .15s ease;
}

.ds-cat:hover { border-color: var(--highlight); color: var(--highlight); }

.ds-cat[aria-pressed="true"] {
    background: var(--brand);
    border-color: var(--brand);
    color:#fff;
}

.ds-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap:8px;
}

.ds-cards .ds-tab[hidden] { display: none; }

.ds-tab {
    display: block;
    text-align: left;
    padding:16px 16px;
    background: var(--bg-tone);
    border: 1px solid transparent;
    border-radius: var(--radius);
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}

.ds-tab:hover { border-color: var(--border); }

.ds-tab[aria-selected="true"] {
    background: var(--brand);
    border-color: var(--brand);
}

.ds-tab-name {
    display: block;
    font-family: var(--font-head);
    font-size:15px;
    font-weight: 700;
    letter-spacing: -0.015em;
    color: var(--text);
}

.ds-tab-note {
    display: block;
    margin-top:3px;
    font-size:13px;
    color: var(--text-muted);
}

.ds-tab[aria-selected="true"] .ds-tab-name { color: #fff; }
.ds-tab[aria-selected="true"] .ds-tab-note { color: rgba(245, 249, 255, .72); }

.ds-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap:20px 40px;
    padding-bottom:20px;
    margin-bottom:24px;
    border-bottom: 1px solid var(--border);
}

.ds-head-copy { flex: 1 1 420px; min-width: 0; }

.ds-title {
    font-size:23px;
    font-weight: 700;
    letter-spacing: -0.024em;
    margin:0 0 8px;
}

.ds-desc {
    max-width: 62ch;
    margin:0;
    font-size:15px;
    line-height: 1.6;
    color: var(--text-content);
}

.ds-meta {
    display: flex;
    flex-wrap: wrap;
    gap:16px 24px;
    margin:4px 0 0;
    flex: 0 1 400px;
}

.ds-meta div { min-width: 0; max-width: 22ch; }

.ds-meta dt {
    font-family: var(--font-head);
    font-size:12px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--text-faint);
    margin-bottom:3px;
}

.ds-meta dd { margin:0; font-size:14px; font-weight: 600; color: var(--text); }
.ds-meta dd a { color: var(--brand); }

.ds-asof { margin:0 0 16px; font-size:14px; color: var(--text-muted); }

.ds-caveat {
    margin:20px 0 0;
    padding:16px 20px;
    background: var(--bg-tone);
    border-radius: var(--radius);
    font-size:15px;
    line-height: 1.6;
    color: var(--text-muted);
}

.ds-chart {
    margin:0 0 20px;
    padding:16px 20px 12px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}

.ds-chart-title {
    font-family: var(--font-head);
    font-size:14px;
    font-weight: 700;
    color: var(--text);
    margin:0 0 8px;
}

/* ---------- dataset lead statement ----------
   A sentence with a number in it, rather than a stat tile. These datasets have
   no single headline figure worth a tile, but they do have a fact worth
   stating, and a sentence carries the comparison that a bare number cannot. */

.ds-lead { margin:0 0 24px; }

/* Deliberately NOT a flex row. This is a sentence with a large number inside
   it, and flex gap inserts space around every inline span, which shows up as a
   double space either side of the interpolated name. Normal text flow, with the
   figure aligned on the baseline, keeps the spacing the sentence's own. */
.ds-lead-line {
    margin:0 0 4px;
    font-family: var(--font-head);
    font-size:20px;
    line-height: 1.35;
    color: var(--text);
    letter-spacing: -0.015em;
    text-wrap: pretty;
}

.ds-lead-line--muted { color: var(--text-muted); font-size:18px; }

.ds-lead-fig {
    display: inline-block;
    margin-right:4px;
    font-size:38px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--highlight);
    font-variant-numeric: tabular-nums;
}

.ds-lead-line--muted .ds-lead-fig { color: var(--text-muted); font-size:30px; }

.ds-lead .ds-asof { margin-top:10px; }

/* ---------- ranked bars ---------- */

.bars { list-style: none; margin:0; padding:0; display: grid; gap:6px; }

.bar-row {
    display: grid;
    grid-template-columns: minmax(120px, 15em) 1fr auto;
    align-items: center;
    gap:12px;
    font-size:14px;
}

.bar-label { color: var(--text-muted); line-height: 1.3; }

.bar-track {
    position: relative;
    height: 16px;
    background: var(--bg-tone);
    border-radius: 3px;
    overflow: hidden;
}

.bar-fill {
    display: block;
    height: 100%;
    background: var(--highlight);
    opacity: .45;
    border-radius: 3px;
}

.bar-row.is-lead .bar-fill { opacity: 1; }
.bar-row.is-lead .bar-label { color: var(--text); font-weight: 600; }

.bar-value {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--text);
    min-width: 3.6em;
    text-align: right;
}

/* Labels and bars stop sharing a row once there is no room for both to be
   readable; the label sits above its own bar instead of being squeezed. */
@media (max-width: 560px) {
    .bar-row {
        grid-template-columns: 1fr auto;
        gap:4px 10px;
    }
    .bar-label { grid-column: 1 / -1; font-size:13px; }
    .ds-lead-line { font-size:17px; }
    .ds-lead-fig { font-size:30px; }
    .ds-lead-line--muted { font-size:16px; }
    .ds-lead-line--muted .ds-lead-fig { font-size:25px; }
}

.ds-desc--inline { margin:-8px 0 20px; font-size:15px; line-height:1.6; color: var(--text-muted); }

.ds-next { padding:48px 0 0; margin-top:40px; border-top: 1px solid var(--border); }

.ds-next-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap:16px;
    list-style: none;
    margin:0 0 16px;
    padding:0;
}

.ds-next-list li {
    padding:16px 20px;
    border: 1px dashed var(--border);
    border-radius: var(--radius);
}

.ds-next-list h3 { font-size:15px; font-weight: 700; margin:0 0 4px; }
.ds-next-list p { margin:0; font-size:15px; line-height: 1.6; color: var(--text-muted); }
.ds-next-foot { margin:0; font-size:14px; color: var(--text-faint); }

/* ---------- charts ---------- */

.ch-stage { position: relative; }
.ch { display: block; width: 100%; height: auto; overflow: visible; }

.ch-grid { stroke: var(--border); stroke-width: 1; }

.ch-tick {
    font-family: var(--font-body);
    font-size:calc(12px * var(--k, 1));
    fill: var(--text-faint);
    font-variant-numeric: tabular-nums;
}

.ch-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.ch-end { stroke: #fff; stroke-width: 2; }

.ch-endlabel {
    font-family: var(--font-head);
    font-size:calc(12px * var(--k, 1));
    font-weight: 700;
    fill: var(--text);
    font-variant-numeric: tabular-nums;
}

.ch-hit rect { fill: transparent; }
.ch-cross { stroke: var(--text-faint); stroke-width: 1; stroke-dasharray: 3 3; }

.ch-legend {
    display: flex;
    flex-wrap: wrap;
    gap:8px 20px;
    list-style: none;
    margin:8px 0 0;
    padding:0;
    font-size:13px;
    color: var(--text-muted);
}

.ch-legend li { display: flex; align-items: center; gap:8px; }
.ch-key { width: 11px; height: 11px; border-radius: 50%; }

.ch-tip {
    position: absolute;
    z-index: 5;
    padding:8px 12px;
    background: var(--brand);
    color: var(--brand-ink);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    pointer-events: none;
    font-size:13px;
    line-height: 1.45;
    white-space: nowrap;
}

.ch-tip strong { display: block; color: #fff; margin-bottom:4px; font-family: var(--font-head); }
.ch-tip span { display: flex; align-items: center; gap:8px; color: rgba(245, 249, 255, .85); }
.ch-tip b { color: #fff; font-variant-numeric: tabular-nums; }
.ch-tip i { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }

/* toolbar */

.dr-toolbar--right { justify-content: flex-end; }

.dr-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap:8px;
    align-items: center;
    margin-bottom:12px;
}

.dr-field { display: flex; }
.dr-field--grow { flex: 1 1 260px; min-width: 0; }

.dr-input, .dr-select {
    width: 100%;
    padding:8px 12px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size:15px;
    color: var(--text);
}

.dr-select { padding-right:32px; cursor: pointer; }
.dr-input:focus, .dr-select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px rgba(0, 25, 68, .08); }

.dr-export { margin-left:auto; }

/* map */

.dr-map {
    margin:0 0 20px;
    padding:12px 12px 12px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}

.dr-map--compact { padding:8px 8px 8px; margin:0; }
.dr-map--compact .dr-map-stage { max-width: 900px; margin:0 auto; }

.dr-map-stage { position: relative; }

.dr-map-land,
.dr-map-dots {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 975 / 610;
}

.dr-map-dots { position: absolute; inset: 0; overflow: visible; }

.dr-dot {
    stroke: #fff;
    stroke-width: 2;
    vector-effect: non-scaling-stroke;
    fill-opacity: .82;
    cursor: pointer;
    transition: fill-opacity .12s ease;
}

.dr-dot.is-layoff { fill: var(--highlight); }
.dr-dot.is-closure { fill: var(--amber); }

/* an outlined mark means the city was not published and the filing sits
   on the state centre, so the position is indicative rather than exact */
.dr-dot.is-approx { fill-opacity: .28; }
.dr-dot.is-layoff.is-approx { stroke: var(--highlight); }
.dr-dot.is-closure.is-approx { stroke: var(--amber); }

.dr-dot:hover { fill-opacity: 1; stroke-width: 3; }

.dr-map-tip {
    position: absolute;
    z-index: 5;
    min-width: 170px;
    max-width: 260px;
    padding:8px 12px;
    background: var(--brand);
    color: var(--brand-ink);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    pointer-events: none;
    font-size:13px;
    line-height: 1.45;
}

.dr-map-tip strong { display: block; color: #fff; font-family: var(--font-head); font-size:14px; margin-bottom:3px; }
.dr-map-tip span { display: block; color: rgba(245, 249, 255, .82); }

.dr-map-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap:8px 20px;
    padding-top:12px;
    margin-top:8px;
    border-top: 1px solid var(--border);
}

.dr-legend {
    display: flex;
    flex-wrap: wrap;
    gap:16px;
    list-style: none;
    margin:0;
    padding:0;
    font-size:13px;
    color: var(--text-muted);
}

.dr-legend li { display: flex; align-items: center; gap:8px; }

.dr-key {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: var(--text-faint);
}

.dr-key.is-layoff { background: var(--highlight); }
.dr-key.is-closure { background: var(--amber); }
.dr-key.is-approx { background: transparent; border: 2px solid var(--text-faint); }

.dr-map-note { margin:0 0 0 auto; font-size:13px; color: var(--text-faint); }
.dr-map-note:empty { display: none; }

.dr-count {
    margin:0 0 12px;
    font-size:14px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* table */

.dr-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: #fff;
}

.dr-table {
    width: 100%;
    border-collapse: collapse;
    font-size:15px;
}

.dr-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--bg-tone);
    font-family: var(--font-head);
    font-size:12px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-muted);
    text-align: left;
    padding:12px 16px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

.dr-table tbody th,
.dr-table td {
    padding:12px 16px;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
    text-align: left;
    font-weight: 400;
}

.dr-table tbody tr:last-child th,
.dr-table tbody tr:last-child td { border-bottom: 0; }

.dr-table tbody tr:hover { background: #fbfaf8; }

.dr-co { font-weight: 700; color: var(--text); max-width: 320px; }
.dr-table td.dr-num,
.dr-table thead th.dr-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dr-date { white-space: nowrap; font-variant-numeric: tabular-nums; }
.dr-muted { color: var(--text-faint); }
.dr-src a { font-weight: 600; text-decoration: none; color: var(--brand); }
.dr-src a:hover { text-decoration: underline; }

.dr-badge {
    display: inline-block;
    padding:3px 8px;
    border-radius: var(--radius-btn);
    font-size:13px;
    font-weight: 700;
    white-space: nowrap;
    border: 1px solid transparent;
}

.dr-badge.is-layoff { background: rgba(37, 99, 235, .10); color: #1a49b8; border-color: rgba(37, 99, 235, .22); }
.dr-badge.is-closure { background: rgba(201, 133, 43, .13); color: #8a5a14; border-color: rgba(201, 133, 43, .3); }

.dr-flag {
    display: inline-block;
    margin-left:4px;
    padding:1px 8px;
    border-radius: var(--radius-btn);
    background: var(--brand);
    color: var(--brand-ink);
    font-size:12px;
    font-weight: 700;
    letter-spacing: .03em;
    vertical-align: middle;
}

.dr-empty { padding:48px 0; text-align: center; color: var(--text-muted); }
.dr-more { display: flex; justify-content: center; padding:20px 0 0; }

/* news */

.dr-news { list-style: none; margin:0; padding:0; display: grid; gap:12px; }

.dr-news-item {
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding:16px 20px;
}

.dr-news-head { display: flex; align-items: baseline; gap:12px; justify-content: space-between; }

.dr-news-co { font-size:16px; font-weight: 700; margin:0; }

.dr-news-n {
    font-family: var(--font-head);
    font-size:15px;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.dr-news-why { margin:8px 0 0; font-size:15px; line-height: 1.6; color: var(--text-content); }

.dr-news-meta {
    margin:8px 0 0;
    font-size:14px;
    color: var(--text-muted);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap:8px;
}

.dr-news-meta a { font-weight: 600; color: var(--brand); }

/* notes */

.dr-note {
    margin-top:32px;
    padding:24px 24px;
    background: var(--bg-tone);
    border-radius: var(--radius-lg);
    font-size:15px;
    line-height: 1.6;
    color: var(--text-muted);
}

.dr-note strong { color: var(--text); }
.dr-note p { margin-bottom:.9em; }

.dr-body { padding-bottom:80px; }

/* ---------- responsive ---------- */

@media (max-width: 1000px) {
    .feed-layout { grid-template-columns: minmax(0, 1fr); }
    .feed-side { position: static; }
    .dr-summary { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 720px) {
    body { font-size:15px; }
    .hero { padding:40px 0 32px; }
    .post-card { grid-template-columns: minmax(0, 1fr); gap:12px; }
    .post-card-thumb img { aspect-ratio: 16 / 9; }
    .post-list { padding:4px 16px; }
    .article { padding:44px 0 24px; }
    .article > * { padding:0 20px; }

    /* 120px of air between the end of a piece and the next-piece rail reads on
       a phone as the page having finished, and readers stop scrolling. */
    .article-wrap { margin-bottom:40px; }
    .read-next { padding-bottom:48px; }

    /* Read next, compact. A full-width 16:9 thumbnail per card made three next
       pieces about 1,180px of scrolling. A square 96px thumb makes the same
       three roughly 420px, so the rail can be taken in rather than swiped past.
       The excerpt stays: it is the reason to click. */
    .read-next .post-card {
        grid-template-columns: 96px minmax(0, 1fr);
        gap:14px;
        padding:16px 0;
        align-items: start;
    }
    .read-next .post-card--no-image { grid-template-columns: minmax(0, 1fr); }
    .read-next .post-card-thumb img { aspect-ratio: 1 / 1; }
    .read-next .post-card-title { font-size:16px; }
    .read-next .post-card-excerpt { font-size:14px; margin-bottom:8px; }
    .dr-export { margin-left:0; width: 100%; }
    .dr-hero-value { font-size:38px; }
    .footer-cta { border-radius: 0; }

    /* hero: the desktop floor was far too large for a phone */
    .hero-title { font-size:clamp(23px, 8.4vw, 32px); line-height: 1.1; }
    .hero-lede { font-size:16px; line-height: 1.6; margin:16px 0 20px; }
    .hero-fineprint { font-size:13px; }

    /* one clear action rather than a stranded half-width button.
       flex:1 on the input fills the cross axis once stacked, so reset it */
    .subscribe-form { flex-direction: column; align-items: stretch; gap:8px; }
    .subscribe-form > * { flex: 0 0 auto; }
    .subscribe-form input { width: 100%; }
    .subscribe-form .btn { width: 100%; justify-content: center; }

    .band-title { font-size:20px; }
    .band-value { font-size:27px; }
    .band-figures { gap:8px; }
    .band-figure { padding:16px 16px; }

    .path-card { padding:24px 20px 24px; }
    .path-title { font-size:20px; }
    .path-body { font-size:15px; }

    .article-lede { font-size:16px; }

    .ds-title { font-size:20px; }
    .ds-desc { font-size:15px; }
    .ds-meta { flex: 1 1 100%; gap:12px 20px; }
    .ds-meta dt { font-size:12px; }
    .ds-chart { padding:12px 12px 8px; }
    .ds-tab { padding:12px 16px; }

    /* Narrow screens are where categories pay off most: two cards at a time
       instead of one long wall of cards. The row itself scrolls sideways rather than
       wrapping to three lines and pushing the data off the screen. */
    .ds-divider { margin:28px 0 18px; }
    .ds-cats {
        flex-wrap: nowrap;
        overflow-x: auto;
        margin-right: calc(var(--gutter) * -1);
        padding-right: var(--gutter);
        scrollbar-width: none;
    }
    .ds-cats::-webkit-scrollbar { display: none; }
    .ds-cat { flex:0 0 auto; padding:7px 14px; font-size:13.5px; }

    /* Still one row on a phone, just tighter and a little quicker, since the
       track is narrower and a slow scroll on a short row reads as stalled. */
    .readers-list { gap: 40px; padding-right: 40px; animation-duration: 32s; }
    .readers-list img { height: 30px; }

    /* the oversized watermark is decoration; it overflows a phone */
    .footer-watermark { display: none; }
}

/* ---------- home page exhibits ---------- */

/* Tabs rather than four stacked charts. A reader gets the whole range of what
   we track inside one screen, and meets the same interaction they will use in
   the Data Room, so the home page teaches the product. */
.ex-tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 24px;
    overflow-x: auto;
    scrollbar-width: none;
}
.ex-tabs::-webkit-scrollbar { display: none; }

.ex-tab {
    flex: 0 0 auto;
    padding: 12px 18px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    font-family: var(--font-head);
    font-size: 15px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    margin-bottom: -1px;
    white-space: nowrap;
}
.ex-tab:hover { color: var(--text); }
.ex-tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--brand); }

.ex-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
    gap: 32px;
    align-items: start;
}

.ex-read { min-width: 0; }

.ex-q {
    font-family: var(--font-head);
    font-size: 17px;
    font-weight: 600;
    color: var(--text-muted);
    margin: 0 0 14px;
}

.ex-value {
    font-family: var(--font-head);
    font-size: clamp(40px, 6vw, 56px);
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.035em;
    color: var(--text);
    margin: 0 0 8px;
}

.ex-unit {
    margin: 0 0 16px;
    font-size: 15px;
    line-height: 1.45;
    color: var(--text-muted);
}

.ex-say {
    margin: 0 0 18px;
    font-size: 15px;
    line-height: 1.6;
    color: var(--text);
    max-width: 46ch;
}
.ex-say:empty { display: none; }

.ex-link {
    display: inline-block;
    color: var(--brand);
    font-weight: 600;
    font-size: 15px;
}

.ex-list {
    list-style: none;
    margin: 0 0 18px;
    padding: 0;
    border-top: 1px solid var(--border);
}

.ex-row {
    display: grid;
    grid-template-columns: 8px minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
}

.ex-row-co {
    font-family: var(--font-head);
    font-size: 15px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ex-row-n {
    font-family: var(--font-head);
    font-size: 15px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

.ex-row--empty {
    grid-template-columns: 1fr;
    color: var(--text-muted);
    font-size: 14px;
}

.ex-visual { min-width: 0; }
.ex-visual .dr-map { margin: 0; }

.ex-note {
    margin: 10px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--text-faint);
}
.ex-note:empty { display: none; }

/* The chart column carries the weight on wide screens; below this the two
   columns are both too narrow to read, so stack and let the number lead. */
@media (max-width: 900px) {
    .ex-grid { grid-template-columns: minmax(0, 1fr); gap: 24px; }
}

/* The eyebrow answers "what is this site" before the headline gets to be
   interesting. A rule rather than a bullet or a badge: the headline already
   carries the accent color, so the eyebrow borrows a stroke of it and stays
   quiet in muted text. */
.hero-eyebrow {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0 0 20px;
    font-family: var(--font-head);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.hero-eyebrow::before {
    content: "";
    flex: 0 0 auto;
    width: 28px;
    height: 2px;
    background: var(--highlight);
}

/* ---------- hero latest issue ---------- */

.hero-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 350px);
    gap: 56px;
    align-items: start;
}

.hero-latest {
    background: var(--bg-tone);
    border-radius: var(--radius);
    padding: 24px 24px 22px;
    min-width: 0;
}

.hero-latest-label {
    font-family: var(--font-head);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin: 0 0 10px;
}

.hero-latest-title {
    font-size: 20px;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.02em;
    margin: 0 0 8px;
}

.hero-latest-title a { color: var(--text); }
.hero-latest-title a:hover { color: var(--brand); }

.hero-latest-meta {
    margin: 0 0 12px;
    font-size: 13px;
    color: var(--text-faint);
}

.hero-latest-excerpt {
    margin: 0 0 16px;
    font-size: 15px;
    line-height: 1.55;
    color: var(--text-muted);
}

.hero-latest-link {
    font-family: var(--font-head);
    font-size: 15px;
    font-weight: 600;
    color: var(--brand);
}

/* The card is a companion to the headline, not a second column of reading.
   Below this the headline needs the full width, so it drops underneath. */
@media (max-width: 980px) {
    .hero-inner { grid-template-columns: minmax(0, 1fr); gap: 32px; }
    .hero-latest { max-width: 520px; }
}

/* ---------- page hero, shared by pricing and about ---------- */

.page-hero { padding: 72px 0 40px; }

.page-hero .hero-eyebrow { margin-bottom: 18px; }

.page-hero-title {
    font-size: clamp(30px, 4.6vw, 46px);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.03em;
    margin: 0;
    max-width: 20ch;
    text-wrap: balance;
}

.page-hero-lede {
    margin: 20px 0 0;
    max-width: 54ch;
    font-size: 18px;
    line-height: 1.6;
    color: var(--text-content);
}

.tier-foot {
    margin: 28px 0 0;
    text-align: center;
    font-size: 14px;
    color: var(--text-faint);
}

/* Where a page leads with the hero, the body has to start on the same left
   edge as the headline. The old grey panel justified centring the column
   inside it; without the panel the text just began 200px to the right of the
   title for no reason a reader could see. Posts keep their centred measure. */
.page-hero + .article-wrap .article > * {
    max-width: calc(var(--content) + 60px);
    margin-left: 0;
    margin-right: 0;
    padding: 0;
}

/* Jump nav on the about page, in the manner of a masthead: the page is a
   reference document as much as a pitch, so the sections are addressable. */
.about-jump {
    margin: 0 0 8px;
    padding: 0 0 20px;
    border-bottom: 1px solid var(--border);
    font-family: var(--font-head);
    font-size: 14px;
    font-weight: 600;
    color: var(--text-faint);
}

.about-jump a { color: var(--text-muted); }
.about-jump a:hover { color: var(--brand); }
.about-jump span { margin: 0 10px; opacity: .5; }

/* ---------- Data Room, promoted in the nav ---------- */

/* The Data Room is the product, not a page, so it should not sit in the nav
   looking like About and Contact. It gets a pill rather than a solid button
   because the header already has one solid button on the right, and two
   competing calls to action would leave the reader choosing between them.
   The dot is the honest part: it marks the one destination in the nav that
   has been rebuilt since the reader last visited. */
@media (min-width: 861px) {
    .nav-list .nav-data-room a {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        padding: 7px 15px 7px 13px;
        border: 1px solid var(--border);
        border-radius: 999px;
        background: var(--bg-tone);
        opacity: 1;
        transition: border-color .15s ease, background-color .15s ease;
    }

    .nav-list .nav-data-room a::before {
        content: "";
        flex: 0 0 auto;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: var(--highlight);
    }

    .nav-list .nav-data-room a:hover {
        border-color: var(--brand);
        background: #fff;
    }

    /* The underline that marks the current page reads as a mistake inside a
       pill, so the border carries that job here instead. */
    .nav-list .nav-item--current.nav-data-room a {
        text-decoration: none;
        border-color: var(--brand);
        background: #fff;
    }
}

@media (max-width: 860px) {
    .nav-list .nav-data-room a {
        display: flex;
        align-items: center;
        gap: 10px;
    }

    .nav-list .nav-data-room a::before {
        content: "";
        flex: 0 0 auto;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: var(--highlight);
    }
}

/* Wide cards inside an article have to break out of the reading measure, or a
   chart lands the same width as a paragraph and the axis labels stop being
   readable. Every issue carries at least one chart, so this matters more here
   than the usual Koenig defaults allow. */
@media (min-width: 900px) {
    .gh-content .kg-width-wide {
        width: calc(100% + 160px);
        max-width: none;
        margin-left: -80px;
        margin-right: -80px;
    }

    .gh-content .kg-width-full {
        width: calc(100% + 260px);
        max-width: none;
        margin-left: -130px;
        margin-right: -130px;
    }
}

.gh-content .kg-image-card img { width: 100%; height: auto; display: block; }

/* ---------------------------------------------------------------------------
   The Data Room ask bar.

   Deliberately the heaviest thing on the page above the tabs. A reader who
   arrives with a question in mind should not have to work out which
   panel holds the answer, and the bar only earns that position if it reads as
   the primary way in rather than as a filter box bolted on top.
   --------------------------------------------------------------------------- */

.ask {
    margin: 0 0 40px;
    padding: 30px 32px 26px;
    background: var(--bg-tone);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}

.ask-label {
    display: block;
    margin: 0 0 12px;
    font-family: var(--font-head);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--text-faint);
}

.ask-row { display: flex; gap: 10px; align-items: stretch; }

.ask-input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 14px 18px;
    font-family: var(--font-body);
    font-size: 17px;
    line-height: 1.4;
    color: var(--text);
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-btn);
    transition: border-color .15s ease, box-shadow .15s ease;
}

.ask-input::placeholder { color: var(--text-faint); }

.ask-input:focus {
    outline: none;
    border-color: var(--highlight);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, .14);
}

.ask-send { flex: 0 0 auto; min-width: 104px; }
.ask-send[disabled] { opacity: .6; cursor: default; }

.ask-note {
    margin: 12px 0 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--text-faint);
}

/* Example questions. These are the feature demo: an empty box says nothing
   about what the thing can do, and three specific questions say most of it. */
.ask-examples {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 16px 0 0;
    padding: 0;
    list-style: none;
}

.ask-example {
    /* Explicit, because the home page specimen renders these as spans rather
       than buttons. An inline span that wraps draws its border in pieces. */
    display: inline-block;
    padding: 7px 15px;
    font-family: var(--font-body);
    font-size: 14px;
    line-height: 1.3;
    text-align: left;
    color: var(--text-muted);
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-btn);
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}

.ask-example:hover { border-color: var(--highlight); color: var(--highlight); }

/* ---- the answer ---- */

.ask-answer {
    margin: 26px 0 0;
    padding: 24px 0 0;
    border-top: 1px solid var(--border);
}

.ask-answer-head {
    display: flex;
    gap: 16px;
    align-items: baseline;
    justify-content: space-between;
    margin: 0 0 14px;
}

.ask-asked {
    margin: 0;
    font-family: var(--font-head);
    font-size: 17px;
    font-weight: 700;
    line-height: 1.35;
    color: var(--brand);
}

.ask-clear {
    flex: 0 0 auto;
    padding: 0;
    font-family: var(--font-body);
    font-size: 14px;
    color: var(--text-faint);
    background: none;
    border: 0;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.ask-clear:hover { color: var(--text); }

/* The answer is prose, so it reads at the article measure rather than the full
   width of the Data Room, which is laid out for tables. */
.ask-body { max-width: 68ch; font-size: 17px; line-height: 1.68; color: var(--text-content); }
.ask-body p { margin: 0 0 1em; }
.ask-body p:last-child { margin-bottom: 0; }
.ask-body ul,
.ask-body ol { margin: 0 0 1em; padding-left: 1.3em; }
.ask-body li { margin: 0 0 .4em; }
.ask-body strong { color: var(--brand); font-weight: 700; }

/* Answers cite our own pieces now, so they contain links. Underlined rather
   than coloured alone, because an answer is running prose and a colour change
   mid-sentence is easy to read straight past. */
.ask-link {
    color: var(--brand);
    font-weight: 600;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}

.ask-link:hover { color: var(--highlight); }

/* The locked answer.

   Deliberately the loudest thing inside the bar. Written as prose it inherited
   .ask-body and looked identical to a real answer, so somebody scanning the
   page read text under their question and concluded the feature had answered.

   Navy on purpose: the same treatment as the paywall card on a paid post, so a
   reader who has met one recognises the other instead of having to work it out
   a second time. */
.ask-locked {
    margin: 4px 0 0;
    padding: 26px 28px 28px;
    background: var(--brand);
    color: var(--brand-ink);
    border-radius: var(--radius-lg);
}

.ask-locked-label {
    margin: 0 0 10px;
    font-family: var(--font-head);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--amber);
}

.ask-locked-title {
    margin: 0 0 10px;
    font-family: var(--font-head);
    font-size: clamp(19px, 2.4vw, 23px);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.02em;
    color: #fff;
}

.ask-locked-copy {
    max-width: 52ch;
    margin: 0 0 22px;
    font-size: 16px;
    line-height: 1.6;
    color: rgba(245, 249, 255, .86);
}

.ask-locked-btn { min-width: 210px; }

.ask-locked-team {
    margin: 16px 0 0;
    font-size: 14px;
    color: rgba(245, 249, 255, .7);
}

.ask-locked-team a { color: #fff; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }

/* Enterprise replaces the three-card grid with one card, so it must not
   stretch to a third of the row, and it centres under the toggle rather than
   sitting alone on the left. */
.tier-grid--enterprise {
    grid-template-columns: minmax(0, 420px);
    justify-content: center;
}

@media (max-width: 720px) {
    .ask-locked { padding: 22px 20px 24px; }
    .ask-locked-copy { font-size: 15px; }
    .ask-locked-btn { width: 100%; text-align: center; }
}

.ask-upgrade { margin-top: 6px; }

.ask-thinking {
    display: flex;
    gap: 10px;
    align-items: center;
    margin: 6px 0 0;
    font-size: 15px;
    color: var(--text-faint);
}

.ask-error {
    margin: 6px 0 0;
    padding: 12px 16px;
    font-size: 15px;
    line-height: 1.5;
    color: var(--text);
    background: var(--bg);
    border: 1px solid var(--border);
    border-left: 3px solid var(--amber);
    border-radius: var(--radius);
}

@media (max-width: 720px) {
    .ask { margin-bottom: 28px; padding: 22px 20px 20px; }
    .ask-row { flex-direction: column; }
    .ask-send { width: 100%; }
    .ask-input { font-size: 16px; }
    .ask-body { font-size: 16px; }
}

/* ---------------------------------------------------------------------------
   The home page look at the Data Room.

   A live specimen of the ask bar rather than an image of one. It reuses the
   .ask-* rules above, so it can never fall out of step with the real thing,
   and these rules only do two jobs: neutralize the controls that are not
   wired to anything, and give the block the breathing room a section needs
   that the in-page bar does not.
   --------------------------------------------------------------------------- */

.peek-lede {
    max-width: 62ch;
    margin: 0 0 24px;
    font-size: 17px;
    line-height: 1.65;
    color: var(--text-content);
}

/* The frame. A specimen that sits flush on the page looks like a control,
   and a control that does nothing looks broken, which is exactly what
   happened. A title bar, a tag and a lifted edge say "picture of an app"
   before the reader's hand reaches the mouse. */
.peek-frame {
    max-width: 880px;
    margin: 0;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: 0 18px 40px -24px rgba(0, 25, 68, .28);
    overflow: hidden;
}

.peek-chrome {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 11px 18px;
    background: var(--brand);
    color: var(--brand-ink);
}

.peek-chrome-name {
    font-family: var(--font-head);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .04em;
}

/* Says the quiet part out loud. Cheap, and it is the sentence that stops
   someone concluding the product does not work. */
.peek-chrome-tag {
    padding: 3px 10px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--brand-ink);
    background: rgba(245, 249, 255, .16);
    border-radius: var(--radius-btn);
}

.ask--demo {
    /* The frame above carries the width and the edge now, so the bar itself
       gives both up. Two borders and two radii nested inside each other read
       as a mistake. */
    max-width: none;
    margin: 0;
    border: 0;
    border-radius: 0;
}

/* .ask-label is a <label> in the real bar and a <p> here, because there is no
   field for it to label. Same rule, so it needs no styling of its own. */

/* A paragraph wearing the input's clothes. Not an <input readonly>, which
   still takes focus and still invites typing into a box that goes nowhere. */
.ask-input--static {
    display: flex;
    align-items: center;
    margin: 0;
    cursor: default;
    /* Matches the focused state of the real input, because the specimen is
       showing a question that has just been asked. */
    border-color: var(--highlight);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, .14);
}

.ask--demo .ask-send {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: default;
}

/* Nothing in the specimen responds to the pointer, so nothing in it should
   look like it does. A button that lights up and then does nothing is a worse
   advertisement than a button that sits still. */
.ask--demo .ask-send:hover { background: var(--brand); }
.ask--demo .ask-send:active { transform: none; }

.ask--demo .ask-example { cursor: default; }
.ask--demo .ask-example:hover { border-color: var(--border); color: var(--text-muted); }

/* The real answer wraps at the article measure because the Data Room around
   it is much wider. The specimen is already narrow, so the measure would only
   put a ragged column of white down the right of the box. */
.ask--demo .ask-body { max-width: none; }

.ask-demo-source {
    margin: 18px 0 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--text-faint);
}

.peek-cta { display: flex; align-items: center; gap: 18px; margin: 28px 0 0; }

.peek-replay {
    padding: 0;
    font-family: var(--font-body);
    font-size: 15px;
    color: var(--text-faint);
    background: none;
    border: 0;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.peek-replay:hover { color: var(--text); }

/* ---- the replay ----
   The markup ships in the FINISHED state so a reader with no JavaScript sees
   the whole thing. These classes are added by peek.js, so everything below is
   inert until the script runs. */

.ask-input--static.is-typing::after {
    content: '';
    display: inline-block;
    width: 2px;
    height: 1.05em;
    margin-left: 1px;
    vertical-align: -0.14em;
    background: var(--highlight);
    animation: peek-caret 1s steps(1, end) infinite;
}

@keyframes peek-caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

.ask--demo .ask-send.is-busy { opacity: .6; }

/* Collapsed rather than display:none, so the block fades in where it already
   is instead of shoving the page down as it appears. peek.js pins the height
   first, so nothing below this section moves during the replay. */
.ask-answer.is-hidden { opacity: 0; visibility: hidden; }

.ask-answer { transition: opacity .45s ease; }

@media (max-width: 720px) {
    .peek-lede { font-size: 16px; }
    .ask-input--static { font-size: 16px; }
    .ask--demo .ask-send { width: 100%; }
}
