/* ============================================================
   DRAUP-INSPIRED THEME
   A layer over styles.css, loaded after it; nothing in styles.css is edited.

   The language, borrowed from draup.com: its own body and label faces (Google
   Sans and Google Sans Code, both OFL since 2025) and, for its paid display
   face Sagace, Geist Light:
   - warm off-white surfaces alternating with pure black sections
   - thin display type with tight tracking, bold sans for numbers
   - monospace uppercase eyebrows and step labels
   - a terracotta -> blue shimmer band travelling through headlines

   Structure:
     1. Tokens
     2. Type (applies in both colour modes)
     3. Light-mode colour and surfaces
     4. Dark-mode tokens
     5. Type Lab
   Colour rules are scoped to light mode because the existing dark theme
   styles surfaces its own way; hard-coding cream surfaces here left dark
   mode's light text sitting on a light page.
   ============================================================ */


/* ---------- 1. Tokens ---------- */
:root {
    --dr-cream: #F6F5F3;
    --dr-cream-2: #EFEDE9;
    --dr-ink: #0F1115;
    --dr-ink-soft: #4F4F4F;
    --dr-ink-mute: #8A8780;
    --dr-black: #000000;
    --dr-terracotta: #E8765E;
    --dr-blue: #518DD2;
    --dr-peach: #EDBDAA;
    --dr-salmon: #E9A08C;
    --dr-line: rgba(15, 17, 21, 0.10);
    --dr-line-strong: rgba(15, 17, 21, 0.18);
    --dr-accent-grad: linear-gradient(90deg, #F8D8BD, #F1C2A8 13.69%, #EDBDAA 33.5%, #E9A08C 46.9%, #84BFFF);
    --dr-shimmer: linear-gradient(100deg,
        currentColor 36%, var(--dr-terracotta) 46%, var(--dr-blue) 54%, currentColor 64%);
    --dr-mono: "Google Sans Code", "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
    --dr-sans: "Google Sans", "Geist", -apple-system, BlinkMacSystemFont, sans-serif;
    /* draup.com's slate scale and accents. */
    --dr-slate-20: #E4E7ED;
    --dr-slate-30: #BBC2C9;
    --dr-slate-40: #939BA3;
    --dr-slate-50: #677078;
    --dr-slate-60: #454F58;
    --dr-slate-70: #222E39;
    /* One full shimmer cycle. The sweep is 60% of it; the rest is rest. */
    --dr-shimmer-duration: 4s;

    /* Re-point the existing tokens so every var()-driven rule follows. */
    --bg-main: var(--dr-cream);
    --bg-alt: var(--dr-cream-2);
    --bg-card: #FFFFFF;
    --bg-card-hover: #FBFAF8;
    --text-primary: var(--dr-ink);
    --text-secondary: var(--dr-ink-soft);
    --text-tertiary: var(--dr-ink-mute);
    --accent-primary: var(--dr-ink);
    --accent-secondary: var(--dr-blue);
    --border-color: var(--dr-line);
    --border-hover: var(--dr-line-strong);
    --shadow-sm: none;
    --shadow-md: 0 1px 0 rgba(15, 17, 21, 0.04);
    --shadow-lg: 0 24px 60px -30px rgba(15, 17, 21, 0.18);
    --shadow-hover: 0 24px 60px -28px rgba(15, 17, 21, 0.22);
    --radius: 14px;
    --radius-sm: 10px;
}


/* ---------- 2. Type ---------- */

/* A fourth Type Lab voice, and the new default. */
body[data-font-preset="draup"] {
    --font-display: "Geist", "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
    --font-heading: "Geist", "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
    --font-body: var(--dr-sans);
    font-family: var(--font-body);
    letter-spacing: -0.002em;
    -webkit-font-smoothing: antialiased;
}

/* Headlines: thin and tight. */
body[data-font-preset="draup"] .hero-display-name,
body[data-font-preset="draup"] .stacked-section-title,
body[data-font-preset="draup"] .type-lab-title {
    font-family: var(--font-display);
    font-weight: 300;
    font-style: normal;
}

/* Tracking only, no font-size: styles.css tunes these sizes per breakpoint,
   and a size here would match the specificity of its mobile rules while
   loading later, overriding all of them. Geist already reads larger than the
   old serif at the same size because of its taller x-height. */
body[data-font-preset="draup"] .hero-display-name {
    letter-spacing: -0.045em;
}

body[data-font-preset="draup"] .stacked-section-title {
    letter-spacing: -0.035em;
}

/* Card headlines sit between: light enough not to fight the thin titles. */
body[data-font-preset="draup"] .about-story-title,
body[data-font-preset="draup"] .skills-feature-card h3,
body[data-font-preset="draup"] .writing-feature-copy h3,
body[data-font-preset="draup"] .contact-box h3 {
    font-weight: 400;
    letter-spacing: -0.03em;
    line-height: 1.12;
}

/* Card titles were the section title's size at a heavier weight, so each
   card out-shouted its section. Phones keep styles.css's own size. */
body[data-font-preset="draup"] .showcase-title {
    font-weight: 400;
    letter-spacing: -0.03em;
    text-wrap: balance;
}

@media (min-width: 769px) {
    body[data-font-preset="draup"] .showcase-title {
        font-size: clamp(2rem, 3vw, 2.625rem);
        line-height: 1.1;
    }
}

/* The shimmer: text in its own colour with a narrow warm-to-cool band
   passing through. currentColor keeps it right on light and dark surfaces. */
.dr-shimmer,
body[data-font-preset="draup"] .stacked-section-title,
body[data-font-preset="draup"] .hero-display-name .dn-line {
    background-image: var(--dr-shimmer);
    background-size: 300% 100%;
    background-position: 100% 0;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: dr-shimmer var(--dr-shimmer-duration) cubic-bezier(0.45, 0, 0.2, 1) infinite;
}

body[data-font-preset="draup"] .hero-display-name .dn-line + .dn-line {
    animation-delay: 0.35s;
}

/* The old accent-coloured second line would fight the shimmer. */
body[data-font-preset="draup"] .dn-indent {
    color: var(--text-primary);
}

@keyframes dr-shimmer {
    0%, 12% { background-position: 100% 0; }
    72%, 100% { background-position: 0% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .dr-shimmer,
    body[data-font-preset="draup"] .stacked-section-title,
    body[data-font-preset="draup"] .hero-display-name .dn-line {
        animation: none;
        background: none;
        -webkit-text-fill-color: currentColor;
    }
}

/* Numbers: bold sans, as draup.com sets its stats. */
body[data-font-preset="draup"] .journey-year,
body[data-font-preset="draup"] [class*="stat-value"],
body[data-font-preset="draup"] [class*="stat-number"],
body[data-font-preset="draup"] [class*="metric-value"] {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.02em;
}

/* Eyebrows: monospace, uppercase, no pill. */
.stacked-section-label,
.hero-kicker,
.hero-location-tag {
    font-family: var(--dr-mono);
    font-size: 0.78rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.stacked-section-label {
    padding: 0;
    margin-bottom: 18px;
    background: none;
    border-radius: 0;
}

.stacked-section-label::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 10px;
    border-radius: 50%;
    background: var(--dr-accent-grad);
    vertical-align: middle;
}

/* Numbered steps read as draup.com's monospace step labels. */
.skills-feature-points > div > span {
    font-family: var(--dr-mono);
    font-weight: 500;
    letter-spacing: 0.04em;
}

/* draup.com's button-v2: nearly square, Google Sans, and a terracotta-to-blue
   sheen that sweeps across on hover. */
.btn {
    border-radius: 0.3125rem;
    font-family: var(--dr-sans);
    font-weight: 500;
    letter-spacing: 0.0002em;
}

.btn-primary,
.btn-outline {
    position: relative;
    overflow: hidden;
    isolation: isolate;
}

.btn-primary::after,
.btn-outline::after {
    content: "";
    position: absolute;
    top: -50px;
    left: -150px;
    width: 100px;
    height: 155px;
    background: linear-gradient(100deg, var(--dr-terracotta) 46%, var(--dr-blue) 54%);
    opacity: 0.4;
    transform: rotate(35deg);
    transition: left 550ms cubic-bezier(0.19, 1, 0.22, 1);
    z-index: -1;
    pointer-events: none;
}

.btn-primary:hover::after,
.btn-outline:hover::after {
    left: 120%;
}


/* ---------- 3. Light-mode colour and surfaces ---------- */
body:not([data-theme="dark"]) {
    background: var(--dr-cream);
    color: var(--dr-ink);
}

body:not([data-theme="dark"]) .hero-section,
body:not([data-theme="dark"]) .section:not(.alt-bg) {
    background: var(--dr-cream);
}

/* styles.css pins #about to white with !important; only an equal !important
   later in the cascade can return it to the cream surface. */
body:not([data-theme="dark"]) #about {
    background-color: var(--dr-cream) !important;
}

body:not([data-theme="dark"]) .stacked-section-label {
    color: var(--dr-ink-soft);
}

/* Draup's rhythm: strongest statements on pure black. The existing cards in
   these sections were designed for light surfaces only, so they are left as
   they are and float on the black stage; only the section's own intro text
   flips. Re-scoping the colour tokens instead would turn every card's text
   near-white on its own cream background.
   The #id selectors match the specificity of styles.css's per-section
   overrides, which would otherwise force dark text here. */
body:not([data-theme="dark"]) .section.alt-bg {
    background: var(--dr-black);
}

body:not([data-theme="dark"]) #experience.alt-bg .stacked-section-title,
body:not([data-theme="dark"]) #projects.alt-bg .stacked-section-title {
    color: #F6F5F3;
}

body:not([data-theme="dark"]) #experience.alt-bg .stacked-section-copy,
body:not([data-theme="dark"]) #projects.alt-bg .stacked-section-copy {
    color: #A8A59F;
}

body:not([data-theme="dark"]) #experience.alt-bg .stacked-section-label,
body:not([data-theme="dark"]) #projects.alt-bg .stacked-section-label {
    color: #8F8C86;
}

body:not([data-theme="dark"]) .section.alt-bg [class*="-card"] {
    border: 1px solid rgba(255, 255, 255, 0.06);
}

/* The hero's drifting glow is .dr-aurora, in section 6. */
.hero-section {
    position: relative;
    overflow: hidden;
}

.hero-section > * {
    position: relative;
    z-index: 1;
}

/* Buttons. */
body:not([data-theme="dark"]) .btn-primary {
    background: var(--dr-ink);
    color: #FFFFFF;
    box-shadow: none;
}

body:not([data-theme="dark"]) .btn-primary:hover {
    background: #26282D;
    color: #FFFFFF;
    transform: translateY(-1px);
    box-shadow: 0 10px 24px -12px rgba(15, 17, 21, 0.45);
}

body:not([data-theme="dark"]) .btn-outline {
    background: #FFFFFF;
    color: var(--dr-ink);
    border: 1px solid var(--dr-line-strong);
}

body:not([data-theme="dark"]) .btn-outline:hover {
    border-color: var(--dr-ink);
    color: var(--dr-ink);
}

/* The one warm call to action, like draup.com's "Book a Demo". Kept in both
   modes: peach reads well on black too. The body prefix matches the
   specificity of the light-mode .btn-primary rule above, which would
   otherwise paint these black. */
body .btn-primary.btn-lg,
body .navbar .btn-primary {
    background: var(--dr-accent-grad);
    background-size: 200% 100%;
    color: var(--dr-ink);
    box-shadow: none;
    transition: background-position 0.6s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

body .btn-primary.btn-lg:hover,
body .navbar .btn-primary:hover {
    background: var(--dr-accent-grad);
    background-size: 200% 100%;
    background-position: 100% 0;
    color: var(--dr-ink);
}

/* Navigation: flat, hairline, on cream. */
body:not([data-theme="dark"]) .navbar .nav-container {
    background: rgba(246, 245, 243, 0.78);
    border: 1px solid var(--dr-line);
    box-shadow: none;
}

/* Cards: hairlines instead of shadows. */
body:not([data-theme="dark"]) [class*="-card"] {
    box-shadow: none;
}

body:not([data-theme="dark"]) .section:not(.alt-bg) [class*="-card"] {
    border-color: var(--dr-line);
}

/* Off-palette pieces from the indigo theme. The card family now spans
   Draup's range: warm neutrals (cream/ivory/sand), a warm accent (lilac,
   remapped to peach) and a cool accent (mist). */
body:not([data-theme="dark"]) .showcase-card--lilac {
    background: #F6E5DB;
}

body:not([data-theme="dark"]) .skills-feature-card {
    background: linear-gradient(155deg, #FBEFE8 0%, #F6F5F3 100%);
    border: 1px solid var(--dr-line);
}

body:not([data-theme="dark"]) .skills-feature-points > div {
    background: rgba(255, 255, 255, 0.6);
    border-color: var(--dr-line);
}

body:not([data-theme="dark"]) .skills-feature-points > div > span {
    background: none;
    border: 1px solid rgba(232, 118, 94, 0.35);
    color: var(--dr-terracotta);
}

body:not([data-theme="dark"]) .contact-box {
    background: linear-gradient(150deg, #FBF3EC 0%, #F6E8E1 100%);
}

body:not([data-theme="dark"]) .about-panel {
    background: var(--dr-cream-2);
}

body:not([data-theme="dark"]) ::selection {
    background: rgba(232, 118, 94, 0.22);
    color: var(--dr-ink);
}

:focus-visible {
    outline: 2px solid var(--dr-terracotta);
    outline-offset: 3px;
}


/* ---------- 4. Dark-mode tokens ---------- */
/* The existing dark theme keeps its own component rules. Only its token
   values move to Draup's palette -- true black, warm off-white, peach accent
   in place of indigo -- and every token keeps the same light/dark polarity it
   had, so no existing dark component flips contrast. */
body[data-theme="dark"] {
    --bg-main: #000000;
    --bg-alt: #0A0A0B;
    --bg-card: #121214;
    --bg-card-hover: #19191C;
    --text-primary: #F6F5F3;
    --text-secondary: #B5B2AC;
    --text-tertiary: #7C7973;
    --accent-primary: var(--dr-peach);
    --accent-secondary: #84BFFF;
    --border-color: rgba(255, 255, 255, 0.10);
    --border-hover: rgba(255, 255, 255, 0.22);
    background:
        radial-gradient(circle at top, rgba(232, 118, 94, 0.10), transparent 30%),
        #000000;
}


/* ---------- 5. Type Lab ---------- */
/* Four voices sit as a 2x2. Desktop only: styles.css drops to one column
   below 860px, and an unconditional rule here would override that and
   squeeze the cards into two narrow columns on phones. */
@media (min-width: 861px) {
    .type-lab-options {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

body:not([data-theme="dark"]) .font-choice-card.is-active {
    background: linear-gradient(180deg, #FFFFFF 0%, #FBF0EA 100%);
    border-color: rgba(232, 118, 94, 0.38);
    box-shadow: 0 22px 44px -26px rgba(232, 118, 94, 0.45);
}

.font-choice-card.is-active::after {
    background: var(--dr-accent-grad);
    color: var(--dr-ink);
    font-family: var(--dr-mono);
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Pinned to Geist, like the other previews are pinned to their own faces, so
   the card still shows Signal after a visitor switches to another voice. */
.font-choice-preview--draup span:first-child {
    font-family: "Geist", "Inter", sans-serif;
    font-weight: 300;
    letter-spacing: -0.04em;
}

.font-choice-preview--draup span:last-child {
    font-family: var(--dr-mono);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-size: 0.72rem;
}


/* ---------- Announcement banner ---------- */
.announcement-kicker {
    font-family: var(--dr-mono);
    font-weight: 500;
    letter-spacing: 0.06em;
    color: var(--dr-terracotta);
}

body:not([data-theme="dark"]) .home-announcement-banner {
    background: rgba(255, 255, 255, 0.7);
    border-color: var(--dr-line);
    box-shadow: none;
}

/* styles.css gives this banner a fixed white background and no dark-mode
   rule, while its text follows the (light) dark-mode token -- white on white
   in the original dark theme too. */
body[data-theme="dark"] .home-announcement-banner {
    background: rgba(255, 255, 255, 0.05);
    border-color: rgba(255, 255, 255, 0.10);
}

body[data-theme="dark"] .announcement-action {
    color: var(--dr-peach);
}


/* ---------- Every small uppercase label in mono ---------- */
/* draup.com sets all of its small caps labels in its monospace face; that
   consistency is much of what makes the system read as precise. Sizes are
   left to each component -- mono runs wider, so tracking is tighter here
   than on the section eyebrows. */
.hero-panel-label,
.hero-intro-line,
.hero-availability-note,
.showcase-kicker,
.showcase-side-label,
.showcase-mini-card > span,
.project-surface-card > span,
.project-browser-pill,
.project-browser-column > span,
.writing-mini-card > span,
.writing-quote-card > span,
.writing-note-label,
.font-choice-kicker,
.type-lab-live-label {
    font-family: var(--dr-mono);
    font-weight: 500;
    letter-spacing: 0.04em;
}


/* ---------- Hero eyebrows ---------- */
/* Location and specialties used to sit on one line, told apart by case:
   sentence-case sans against uppercase. With both now uppercase mono they
   read as one string, so on desktop the specialties take their own line.
   Mobile already stacks and centres them. */
@media (min-width: 769px) {
    .hero-availability-note {
        flex-basis: 100%;
    }
}


/* Copy switched by date (script.js) stays hidden even where a component's
   own display rule would otherwise beat the hidden attribute. */
[data-show-until][hidden],
[data-show-from][hidden] {
    display: none !important;
}

/* "Incoming" in the accent colour until its start date passes. */
.showcase-kicker-upcoming {
    color: var(--dr-terracotta);
}


/* ---------- Experience and project cards ---------- */
/* One voice per role, as on draup.com: Geist for titles, Google Sans for
   everything said, Google Sans Code for every label. Google Sans loads at
   400, 500 and 700 only, so the old 600s rendered bold and nearly every line
   in a card was bold; medium carries the emphasis now. Some values were in
   Geist and the terminal in the system's monospace; they join the rest. */
body[data-font-preset="draup"] .showcase-org,
body[data-font-preset="draup"] .showcase-pill-list span,
body[data-font-preset="draup"] .showcase-link,
body[data-font-preset="draup"] .showcase-side-note strong,
body[data-font-preset="draup"] .showcase-mini-card strong,
body[data-font-preset="draup"] .project-surface-card strong,
body[data-font-preset="draup"] .project-browser-column strong {
    font-family: var(--dr-sans);
    font-weight: 500;
    letter-spacing: -0.002em;
}

/* Metrics and themes: the same sans, a step up. */
body[data-font-preset="draup"] .showcase-side-grid--metrics .showcase-mini-card strong,
body[data-font-preset="draup"] .project-surface-card--compact strong {
    font-size: 1.25rem;
    line-height: 1.3;
}

body[data-font-preset="draup"] .project-browser-column strong {
    font-size: 1.0625rem;
    line-height: 1.35;
}

body[data-font-preset="draup"] .project-surface-terminal p {
    font-family: var(--dr-mono);
    font-size: 0.8125rem;
}

/* Google Sans Code loads at 400 and 500; bold would be faked. */
body[data-font-preset="draup"] .project-surface-terminal strong {
    font-weight: 500;
}

/* Two label sizes, not three. */
body[data-font-preset="draup"] .project-browser-pill,
body[data-font-preset="draup"] .project-browser-column > span {
    font-size: 0.72rem;
}

/* Descriptions sat at 19px, above the hero's own 18px lead. */
@media (min-width: 769px) {
    body[data-font-preset="draup"] .showcase-description {
        max-width: 40ch;
        font-size: 1.0625rem;
        line-height: 1.65;
    }
}

/* draup.com's neutrals in place of the old blue-black tints; the labels
   were about 3:1 against their cards, under the 4.5:1 small text needs. */
body:not([data-theme="dark"]) .showcase-org {
    color: var(--dr-ink);
}

body:not([data-theme="dark"]) .showcase-description {
    color: var(--dr-slate-60);
}

body:not([data-theme="dark"]) .showcase-kicker {
    color: var(--dr-ink-soft);
}

body:not([data-theme="dark"]) .showcase-side-label,
body:not([data-theme="dark"]) .showcase-mini-card > span,
body:not([data-theme="dark"]) .project-surface-card > span,
body:not([data-theme="dark"]) .project-browser-column > span {
    color: var(--dr-slate-50);
}

/* Phones: the boxes beside each card's copy kept their desktop size (a
   122-180px floor, 18-28px padding and corners, one to a row), so a card's
   side alone ran 420-720px. Two to a row where the values are short, sized
   to their content, with tighter padding, corners and type. */
@media (max-width: 768px) {
    body .showcase-side,
    body .project-showcase-media,
    body .project-media-stack {
        gap: 10px;
    }

    /* The browser mock's columns stay one to a row: inside its own padding,
       two came out 123px wide and broke words mid-line. */
    body .showcase-side-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    body .showcase-side-grid,
    body .project-surface-browser-body {
        gap: 10px;
    }

    body .showcase-side-note,
    body .showcase-mini-card,
    body .project-surface-card,
    body .project-browser-column {
        min-height: 0;
        padding: 12px 14px;
        border-radius: 14px;
    }

    body .project-surface-terminal,
    body .project-surface-browser {
        padding: 14px;
        border-radius: 16px;
    }

    body .project-surface-terminal-bar,
    body .project-surface-browser-top {
        margin-bottom: 10px;
    }

    body .showcase-side-label,
    body .showcase-mini-card > span,
    body .project-surface-card > span,
    body .project-browser-column > span {
        margin-bottom: 4px;
    }

    body .project-browser-column strong {
        margin-bottom: 6px;
    }

    body[data-font-preset="draup"] .showcase-side-note strong,
    body[data-font-preset="draup"] .showcase-mini-card strong,
    body[data-font-preset="draup"] .project-surface-card strong,
    body[data-font-preset="draup"] .project-browser-column strong {
        font-size: 0.9375rem;
        line-height: 1.4;
    }

    /* The metrics and themes, a step up on desktop, come down with them. */
    body[data-font-preset="draup"] .showcase-side-grid--metrics .showcase-mini-card strong,
    body[data-font-preset="draup"] .project-surface-card--compact strong {
        font-size: 1rem;
        line-height: 1.35;
    }

    body[data-font-preset="draup"] .project-surface-terminal p {
        font-size: 0.75rem;
        line-height: 1.6;
    }
}


/* ---------- Short laptop screens: keep the call to action above the fold ---------- */
/* Most Windows laptops give the page 580-730px of height at 100% zoom
   (1536x864, 1366x768, 1280x720 -- StatCounter's #3-#5 US resolutions), and
   the hero's buttons ended at 740-760px, so visitors saw a name and no way
   in. On short screens the buttons move above the skill tags and the
   spacing tightens. Only the specialties label is dropped; the skill tags
   say the same thing. The name is capped by height, never enlarged: it is
   the smaller of its usual size and 10.5% of the viewport's height. */
@media (min-width: 769px) and (max-height: 800px) {
    .hero-section { padding-top: 86px; }
    .home-announcement-banner { margin-bottom: 16px; }
    .hero-main-top { margin-bottom: 14px; }
    .hero-availability-note { display: none; }
    .hero-main-card { display: flex; flex-direction: column; }
    body[data-font-preset] .hero-display-name {
        font-size: min(clamp(3rem, 5.55vw, 4.72rem), 10.5vh);
        margin-bottom: 16px;
    }
    .hero-lead { margin-bottom: 12px; }
    .hero-bio { margin-bottom: 18px; }
    .hero-focus-pills { order: 1; margin: 18px 0 0; }
}

/* Very short: 110-125% zoom on the smallest laptops leaves 470-535px. The
   second intro sentence goes too; the tagline above it makes the point. */
@media (min-width: 769px) and (max-height: 560px) {
    .hero-bio { display: none; }
}


/* ---------- Phones: readable text and tappable chips ---------- */
/* Tags and the GitHub account chips dropped to 10-11px on phones. Body-ish
   text gets a 12px floor; all-caps labels 11px, the smallest size Apple's
   guidelines allow, since capitals read larger than lower case. */
@media (max-width: 768px) {
    body[data-font-preset] .about-quick-pills span,
    body[data-font-preset] .skill-tags span,
    body[data-font-preset] .showcase-pill-list span,
    body[data-font-preset] .writing-topic-pills span,
    body[data-font-preset] .writing-tag,
    body[data-font-preset] .writing-read-time,
    body[data-font-preset] .prose-gh-link { font-size: 0.75rem; }
    body[data-font-preset] .hero-availability-note,
    body[data-font-preset] .hero-intro-line,
    body[data-font-preset] .announcement-kicker,
    body[data-font-preset] .hero-journey-card .hero-panel-label,
    body[data-font-preset] .live-indicator { font-size: 0.6875rem; }
}

/* The GitHub chips are standalone pills rather than links inside a sentence,
   so WCAG 2.5.8's 24px minimum applies; they were 23px tall. */
.prose-gh-link {
    min-height: 26px;
}


/* ---------- Chat button: lifted clear of important content ---------- */
/* script.js (keepChatButtonClear) measures the layout and sets --chat-lift
   when the button would cover text, icons or buttons on the first screen.
   The separate `translate` property composes with the hover effect's
   `transform` instead of overriding it; the existing transition animates
   the move. */
.chatbot-toggle {
    translate: 0 calc(-1 * var(--chat-lift, 0px));
}

@media (prefers-reduced-motion: reduce) {
    .chatbot-toggle { transition: none; }
}


/* ---------- 6. draup.com's motion and surfaces ---------- */
/* The scroll animations themselves live in draup-motion.js; these are the
   pieces they move, and the states they start from. */

/* Hidden only until draup-motion.js takes over, which the <head> script
   bounds to 3 seconds; with reduced motion they never hide. */
.motion-pending [data-reveal],
.motion-pending .hero-display-name,
.motion-pending .hero-lead,
.motion-pending .hero-bio,
.motion-pending .hero-main-top,
.motion-pending .hero-intro-line,
.motion-pending .hero-focus-pills,
.motion-pending .hero-actions,
.motion-pending .hero-socials {
    opacity: 0;
}

/* The hero's subheading, set as draup.com sets its own. */
body[data-font-preset="draup"] .hero-lead {
    font-family: var(--dr-sans);
    font-size: 1.125rem;
    line-height: 1.625rem;
    font-weight: 400;
    letter-spacing: -0.002em;
    color: var(--dr-ink);
}

body[data-font-preset="draup"] .hero-bio {
    font-family: var(--dr-sans);
    letter-spacing: -0.002em;
}

/* While the name drops in word by word, the shimmer waits: its clip to the
   text doesn't follow words that are moving, so they would be invisible.
   The body[data-font-preset] outranks the preset's own shimmer rule. */
body[data-font-preset] .hero-display-name.dr-intro .dn-line,
.hero-display-name.dr-intro .dn-line {
    animation: none;
    background: none;
    -webkit-text-fill-color: currentColor;
}

/* Gradient call to action: the gradient drifts, as on draup.com. */
body .btn-primary.btn-lg {
    animation: dr-gradient-flow 8s infinite;
}

@keyframes dr-gradient-flow {
    0%, 100% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
}

/* draup.com's "Login": white, a hairline, nearly square. */
body:not([data-theme="dark"]) .btn-outline,
body:not([data-theme="dark"]) .nav-actions .btn-outline {
    background: #FFFFFF;
    color: var(--dr-ink);
    border: 1px solid var(--dr-slate-20);
}

body:not([data-theme="dark"]) .btn-outline:hover,
body:not([data-theme="dark"]) .nav-actions .btn-outline:hover {
    border-color: #313852;
    color: var(--dr-ink);
}

.nav-actions .btn {
    border-radius: 0.3125rem;
}

/* The drifting glow at the foot of the hero and the closing call to action:
   five soft layers on staggered five-second loops. */
.hero-section > .dr-aurora,
.dr-aurora {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
}

.contact-section {
    position: relative;
    overflow: hidden;
}

.contact-section > .container {
    position: relative;
    z-index: 1;
}

.dr-aurora-layer {
    position: absolute;
    will-change: transform, opacity;
}

.dr-aurora-layer.base {
    inset: auto 0 0 0;
    height: 70%;
    opacity: 0.2;
    background:
        radial-gradient(90vw 55vh at 10% 115%, rgba(243, 176, 146, 0.7) 0%, rgba(243, 176, 146, 0) 60%),
        radial-gradient(100vw 55vh at 50% 122%, rgba(246, 232, 205, 0.8) 0%, rgba(246, 232, 205, 0) 62%),
        radial-gradient(90vw 55vh at 94% 116%, rgba(169, 185, 238, 0.6) 0%, rgba(169, 185, 238, 0) 60%);
}

.dr-aurora-layer.coral {
    width: 150vw;
    height: 95vh;
    left: -35vw;
    bottom: -42vh;
    background: radial-gradient(closest-side, rgba(236, 122, 85, 0.32) 0%, rgba(240, 145, 112, 0.26) 38%,
        rgba(243, 176, 146, 0.15) 62%, rgba(243, 176, 146, 0) 78%);
    filter: blur(30px);
    transform-origin: 30% 80%;
    animation: dr-coral-sweep 5s ease-in-out infinite;
}

.dr-aurora-layer.cream {
    width: 130vw;
    height: 85vh;
    left: -10vw;
    bottom: -32vh;
    background: radial-gradient(closest-side, rgba(246, 232, 205, 0.55) 0%, rgba(246, 224, 190, 0.38) 45%, rgba(246, 232, 205, 0) 75%);
    filter: blur(24px);
    animation: dr-cream-bloom 5s ease-in-out infinite;
}

.dr-aurora-layer.lavender {
    width: 100vw;
    height: 92vh;
    right: -45vw;
    bottom: -36vh;
    background: radial-gradient(closest-side, rgba(179, 166, 233, 0.45) 0%, rgba(169, 185, 238, 0.3) 48%, rgba(169, 185, 238, 0) 76%);
    filter: blur(30px);
    transform-origin: 75% 80%;
    animation: dr-lavender-breathe 5s ease-in-out infinite;
}

.dr-aurora-layer.peach {
    width: 95vw;
    height: 65vh;
    left: 5vw;
    bottom: -28vh;
    background: radial-gradient(closest-side, rgba(243, 176, 146, 0.4) 0%, rgba(243, 176, 146, 0) 72%);
    filter: blur(36px);
    animation: dr-peach-drift 5s ease-in-out infinite;
}

body[data-theme="dark"] .dr-aurora-layer.base { opacity: 0.45; }
body[data-theme="dark"] .dr-aurora-layer.coral {
    background: radial-gradient(closest-side, rgba(230, 92, 51, 0.5) 0%, rgba(236, 122, 85, 0.35) 38%,
        rgba(243, 176, 146, 0.18) 62%, rgba(243, 176, 146, 0) 78%);
}

@keyframes dr-coral-sweep {
    0% { transform: translate(-28vw, 22vh) rotate(-8deg) scale(1.05); opacity: 0; }
    16% { transform: translate(-4vw, 6vh) rotate(-2deg) scale(1.15); opacity: 1; }
    34% { transform: translate(14vw, 0) rotate(2deg) scale(1.05); opacity: 0.85; }
    56% { transform: translate(32vw, 10vh) rotate(6deg) scale(0.9); opacity: 0; }
    75%, 100% { transform: translate(-28vw, 22vh) rotate(-8deg) scale(1.05); opacity: 0; }
}

@keyframes dr-cream-bloom {
    0% { transform: translate(-6vw, 14vh) scale(0.85); opacity: 0; }
    22% { transform: translate(-2vw, 10vh) scale(0.9); opacity: 0.15; }
    45% { transform: translate(6vw, 0) scale(1.12); opacity: 1; }
    62% { transform: translate(10vw, -3vh) scale(1.18); opacity: 0.9; }
    82% { transform: translate(14vw, 6vh) scale(1); opacity: 0.2; }
    100% { transform: translate(-6vw, 14vh) scale(0.85); opacity: 0; }
}

@keyframes dr-lavender-breathe {
    0% { transform: translate(30vw, 16vh) scale(0.8); opacity: 0; }
    35% { transform: translate(22vw, 12vh) scale(0.85); opacity: 0.1; }
    58% { transform: translate(-4vw, 2vh) scale(1.15); opacity: 1; }
    74% { transform: translate(-12vw, 0) scale(1.22); opacity: 0.9; }
    92% { transform: translate(14vw, 10vh) scale(0.9); opacity: 0.1; }
    100% { transform: translate(30vw, 16vh) scale(0.8); opacity: 0; }
}

@keyframes dr-peach-drift {
    0% { transform: translate(-24vw, 4vh) scale(1); opacity: 0; }
    20% { transform: translate(-10vw, -2vh) scale(1.1); opacity: 0.8; }
    50% { transform: translate(10vw, -5vh) scale(1.05); opacity: 0.55; }
    78% { transform: translate(26vw, 0) scale(0.9); opacity: 0.75; }
    100% { transform: translate(-24vw, 4vh) scale(1); opacity: 0; }
}

/* Off screen, the glow stops costing anything. */
.dr-aurora.is-paused .dr-aurora-layer {
    animation-play-state: paused;
}

/* The two strips under the hero, like draup.com's "Trusted by..." and
   "Loved by analysts": monospace eyebrows, logos greyed out. */
.dr-strip-label {
    margin: 48px 0 18px;
    text-align: center;
    font-family: var(--dr-mono);
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #4F4F4F;
}

.marquee-multi-wrapper .mq-logo {
    filter: grayscale(1);
    opacity: 0.55;
}

.marquee-multi-wrapper .mq-logo:hover {
    filter: none;
    opacity: 1;
}

/* OpenAI's mark is solid black. Dark mode's skill chips are nearly clear,
   so there it turns white; the strip's logos get white tiles instead. */
body[data-theme="dark"] .skill-logo[src$="openai.svg"] {
    filter: invert(1);
}

/* Phones: the strip kept its desktop size, 36px logos 116px apart, so a row
   showed two and a half. Smaller marks, closer together; the loop stays
   seamless because script.js measures its length from the layout. */
@media (max-width: 768px) {
    .marquee-multi-wrapper {
        padding: 20px 0 22px;
        gap: 16px;
    }

    .marquee-multi-track {
        gap: 56px;
    }

    .mq-logo {
        width: 24px;
        height: 24px;
    }

    body[data-theme="dark"] .mq-logo {
        width: 34px;
        height: 34px;
        padding: 6px;
        border-radius: 10px;
    }
}

.dr-worked {
    padding: 8px 20px 64px;
    text-align: center;
}

.dr-worked .dr-strip-label {
    margin-top: 40px;
}

.dr-worked-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: stretch;
    gap: 1.5rem 3rem;
    padding-top: 1rem;
}

.dr-worked-item {
    display: flex;
    flex-flow: row-reverse;
    justify-content: flex-end;
    align-items: center;
    gap: 2rem;
    padding: 0.75rem;
}

.dr-worked-item--reverse {
    flex-flow: row;
    gap: 1rem;
}

.dr-worked-logo {
    height: 28px;
    width: auto;
    filter: grayscale(1);
    opacity: 0.6;
}

/* Northeastern's homepage wordmark is white: shown in ink here instead.
   Its artwork has more room around it, so it is drawn larger. */
.dr-worked-logo--ink {
    height: 40px;
    filter: grayscale(1) brightness(0);
    opacity: 0.55;
}

.dr-worked-caption {
    font-family: var(--dr-sans);
    font-size: 0.875rem;
    line-height: 1.375rem;
    letter-spacing: -0.2px;
    color: var(--dr-slate-50);
}

body[data-theme="dark"] .dr-strip-label,
body[data-theme="dark"] .dr-worked-caption {
    color: var(--dr-slate-40);
}

body[data-theme="dark"] .dr-worked-logo { filter: grayscale(1) invert(1); }
body[data-theme="dark"] .dr-worked-logo--ink { filter: grayscale(1) brightness(0) invert(1); }

/* Black sections carry draup.com's dot matrix, brightest at the top. */
.dr-dark,
body:not([data-theme="dark"]) .section.alt-bg {
    isolation: isolate;
}

.dr-dark::before,
body:not([data-theme="dark"]) .section.alt-bg::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image: radial-gradient(rgba(255, 255, 255, 0.085) 1px, transparent 1.2px);
    background-size: 24px 24px;
    -webkit-mask-image: radial-gradient(130% 70% at 50% 0%, #000 0%, rgba(0, 0, 0, 0.55) 45%, transparent 80%);
    mask-image: radial-gradient(130% 70% at 50% 0%, #000 0%, rgba(0, 0, 0, 0.55) 45%, transparent 80%);
}

.dr-dark {
    position: relative;
    background: #000000;
    color: #F5F5F5;
}

/* The habits band as draup.com's numbers: gradient figures that count up,
   captions underneath, slate rules with a "+" at each join. The selector
   outranks section 3's cream for every .section. */
body .profile-signals-section.dr-dark,
body:not([data-theme="dark"]) .section.profile-signals-section.dr-dark {
    padding: 96px 0;
    background: #000000;
}

.profile-signals-section.dr-dark .stacked-section-label {
    color: var(--dr-slate-40);
}

.profile-signals-section.dr-dark .stacked-section-copy {
    color: var(--dr-slate-30);
}

.profile-signals-section.dr-dark .profile-signals-grid {
    border-top: 1px solid var(--dr-slate-70);
    border-bottom: 1px solid var(--dr-slate-70);
}

.profile-signals-section.dr-dark .profile-signal-card {
    position: relative;
    padding: 2rem;
    border-right: 1px solid var(--dr-slate-70);
}

.profile-signals-section.dr-dark .profile-signal-card:last-child {
    border-right: none;
}

.profile-signals-section.dr-dark .profile-signal-card:not(:last-child)::before,
.profile-signals-section.dr-dark .profile-signal-card:not(:last-child)::after {
    content: "+";
    position: absolute;
    right: -9px;
    width: 17px;
    height: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--dr-mono);
    font-size: 16px;
    color: var(--dr-slate-60);
    z-index: 2;
}

.profile-signals-section.dr-dark .profile-signal-card:not(:last-child)::before { top: -9px; }
.profile-signals-section.dr-dark .profile-signal-card:not(:last-child)::after { bottom: -8px; }

.profile-signals-section.dr-dark .prose-stat {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    color: inherit;
}

/* draup.com's numbers-style-2. Its gradient spans the figure's full-width
   box, so a figure like "~$240M" (177px of a 566px box) only ever shows the
   first 31%: salmon easing to sand, never the blue end. Sizing the gradient
   at 320% of the figure gives every figure that same stretch, whatever its
   width. #lc-total: an old ID rule in styles.css set it in Geist 800. */
.profile-signals-section.dr-dark .prose-stat-num,
.profile-signals-section.dr-dark #lc-total {
    display: inline-flex;
    font-family: var(--dr-sans);
    font-size: 2.875rem;
    line-height: 2.875rem;
    font-weight: 700;
    letter-spacing: -0.004em;
    background-image: linear-gradient(90deg, #EDA389, #9FE2EA 81%);
    background-size: 320% 100%;
    background-repeat: no-repeat;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* Phones: draup.com sets the same figures at 1.25rem. */
@media (max-width: 768px) {
    .profile-signals-section.dr-dark .prose-stat-num,
    .profile-signals-section.dr-dark #lc-total {
        font-size: 1.25rem;
        line-height: 1.75rem;
    }
}

.profile-signals-section.dr-dark .prose-stat-desc {
    font-family: var(--dr-sans);
    font-weight: 400;
    color: #FFFFFF;
}

.profile-signals-section.dr-dark .prose-stat-sub,
.profile-signals-section.dr-dark .prose-stat-sub * {
    color: var(--dr-slate-40);
}

.profile-signals-section.dr-dark .prose-gh-link {
    color: var(--dr-slate-30);
    border-color: var(--dr-slate-70);
    background: transparent;
}

/* The footer on black, as draup.com closes. */
.site-footer.dr-dark {
    padding: 56px 0 48px;
}

.site-footer.dr-dark .footer-content {
    margin-top: 0;
    background: transparent;
    border: 1px solid var(--dr-slate-70);
    box-shadow: none;
    color: var(--dr-slate-30);
}

.site-footer.dr-dark .footer-copy p { color: #FFFFFF; }
.site-footer.dr-dark .footer-copy span { color: var(--dr-slate-40); }

.site-footer.dr-dark .footer-socials a {
    background: #373634;
    border-color: #373634;
    color: #FFFFFF;
}

/* draup.com's navigation type: links in Google Sans 14px regular, slate-70;
   buttons 14px medium; nothing heavier than medium. styles.css also shrinks
   links and buttons once the page scrolls; draup.com's stay put, so the
   .navbar here outranks those .scrolled rules. */
body[data-font-preset="draup"] .navbar .nav-links a {
    font-family: var(--dr-sans);
    font-size: 0.875rem;
    font-weight: 400;
    letter-spacing: normal;
}

body[data-font-preset="draup"] .navbar .nav-actions .btn {
    font-size: 0.875rem;
    font-weight: 500;
}

body[data-font-preset="draup"] .navbar .nav-brand-copy strong {
    font-weight: 500;
}

body:not([data-theme="dark"]) .navbar .nav-links a {
    color: var(--dr-slate-70);
}

body:not([data-theme="dark"]) .navbar .nav-links a:hover,
body:not([data-theme="dark"]) .navbar .nav-links a.active {
    color: var(--dr-ink);
}

/* Over a black section the navigation turns dark, as draup.com's does. */
.navbar .nav-container,
.navbar .nav-link-shell,
.navbar .nav-links a,
.navbar .nav-brand-copy,
.navbar .nav-actions .btn,
.navbar .mobile-toggle {
    transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

body:not([data-theme="dark"]) .navbar[data-nav-variant="dark"] .nav-container {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.1);
}

body:not([data-theme="dark"]) .navbar[data-nav-variant="dark"] .nav-link-shell {
    background: rgba(255, 255, 255, 0.06);
}

body:not([data-theme="dark"]) .navbar[data-nav-variant="dark"] .nav-links a,
body:not([data-theme="dark"]) .navbar[data-nav-variant="dark"] .nav-brand-copy strong {
    color: #FFFFFF;
}

body:not([data-theme="dark"]) .navbar[data-nav-variant="dark"] .nav-brand-copy span {
    color: var(--dr-slate-30);
}

body:not([data-theme="dark"]) .navbar[data-nav-variant="dark"] .nav-links a:hover,
body:not([data-theme="dark"]) .navbar[data-nav-variant="dark"] .nav-links a.active {
    color: #FFFFFF;
    background: rgba(255, 255, 255, 0.12);
}

body:not([data-theme="dark"]) .navbar[data-nav-variant="dark"] .nav-actions .btn-outline,
body:not([data-theme="dark"]) .navbar[data-nav-variant="dark"] .mobile-toggle {
    background: #373634;
    border-color: #373634;
    color: #FFFFFF;
}

/* On phones the bar itself is solid cream (styles.css), so it turns too,
   or the white name would vanish into it. */
@media (max-width: 768px) {
    body:not([data-theme="dark"]) .navbar[data-nav-variant="dark"] {
        background: #000000;
        border-bottom-color: rgba(255, 255, 255, 0.1);
    }
}

/* The journey draws itself: a line across each stop, in turn. */
.journey-stop {
    position: relative;
}

.journey-line {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 1px;
    background: linear-gradient(90deg, #E9A08C, #84BFFF);
    transform-origin: left center;
    pointer-events: none;
}

/* "Where Draup's research makes headlines": the section pins, the backdrop
   zooms past, the stage turns black and the picks arrive. */
.dr-press {
    position: relative;
    height: 320vh;
}

.dr-press-sticky {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #FFFFFF;
    background-image:
        radial-gradient(circle at 18% 25%, rgba(255, 205, 171, 0.4) 0%, rgba(255, 205, 171, 0) 45%),
        radial-gradient(circle at 88% 10%, rgba(173, 201, 255, 0.4) 0%, rgba(173, 201, 255, 0) 45%);
}

.dr-press-scene {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    will-change: transform;
}

/* An image backdrop: the glows on the stage show until it arrives. */
.dr-press-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 0.6s ease;
}

.dr-press-image.is-loaded {
    opacity: 1;
}

/* The other backdrop: a grid of cards from the work itself. */
.dr-press-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: flex-start;
    gap: 40px 32px;
    width: min(1480px, 120vw);
    padding: 24px 0;
}

.dr-press-grid[hidden] {
    display: none;
}

.dr-press-card {
    display: flex;
    flex-direction: column;
    flex: none;
    gap: 14px;
    min-width: 240px;
    max-width: 300px;
    padding: 20px 24px;
    background: #FFFFFF;
    border: 1px solid rgba(20, 20, 20, 0.08);
    border-radius: 12px;
    box-shadow: 0 10px 30px rgba(15, 23, 42, 0.07);
}

.dr-press-card:nth-child(odd) {
    transform: translateY(-10px);
}

.dr-press-card p {
    margin: 0;
    color: #1C2430;
    font-family: var(--dr-sans);
    font-size: 14px;
    line-height: 1.45;
}

.dr-press-card span {
    font-family: var(--dr-mono);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--dr-slate-50);
}

/* Keeps the headline readable over the backdrop until the stage goes black. */
.dr-press-heading::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.97), rgba(255, 255, 255, 0.88) 28%,
        rgba(255, 255, 255, 0.4) 52%, rgba(255, 255, 255, 0) 76%);
    opacity: var(--dr-press-glow, 1);
    pointer-events: none;
}

.dr-press-overlay {
    position: absolute;
    inset: 0;
    z-index: 2;
    background: #000000;
    opacity: 0;
    pointer-events: none;
}

.dr-press-heading {
    position: absolute;
    inset: 0;
    z-index: 3;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 0 24px;
    text-align: center;
}

.dr-press-title {
    max-width: 700px;
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(2.25rem, 5vw, 3.5rem);
    line-height: 1.14;
    font-weight: 300;
    letter-spacing: -0.03em;
    text-wrap: balance;
    color: var(--dr-ink);
}

/* One step up from the Light around it, as draup.com sets "headlines" in
   Sagace Regular against Sagace Light; Medium read as bold. */
.dr-press-title span {
    font-weight: 400;
}

.dr-press-picks {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 20px;
    width: min(1100px, 92vw);
    margin-top: 44px;
    opacity: 0;
    transform: scale(0.5);
    pointer-events: none;
}

.dr-press-picks.is-live {
    pointer-events: auto;
}

/* draup.com's press cards: a centred column on a dusty-rose-to-navy
   gradient (the stops sampled from their card image) under a faint dot
   grid. Where they set a publication's logo, the topic stands in. */
.dr-press-pick {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    min-height: min(320px, 42vh);
    padding: 28px 24px 22px;
    text-align: center;
    text-decoration: none;
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    background: linear-gradient(180deg, #A77D83 0%, #8B7483 15%, #5B637A 30%, #2E4A6A 45%,
        #193353 60%, #112038 75%, #0B1120 90%, #080C17 100%);
    transition: transform 0.25s ease, border-color 0.25s ease;
}

.dr-press-pick::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image: radial-gradient(circle, rgba(255, 255, 255, 0.16) 1px, transparent 1.5px);
    background-size: 14px 14px;
    -webkit-mask-image: linear-gradient(180deg, transparent 10%, #000 40%, #000 70%, transparent 95%);
    mask-image: linear-gradient(180deg, transparent 10%, #000 40%, #000 70%, transparent 95%);
}

/* On hover the warm top glows a little brighter. */
.dr-press-pick::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: radial-gradient(120% 55% at 50% 0%, rgba(248, 216, 189, 0.32), transparent 70%);
    opacity: 0;
    transition: opacity 0.25s ease;
}

.dr-press-pick:hover,
.dr-press-pick:focus-visible {
    transform: translateY(-4px);
    border-color: rgba(255, 255, 255, 0.22);
}

.dr-press-pick:hover::after,
.dr-press-pick:focus-visible::after {
    opacity: 1;
}

/* Every topic gets two lines' room, set from the bottom, so the topics and
   headlines line up across the row; the call to action keeps the foot. */
.dr-press-pick-topic {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    min-height: 2.24em;
    margin-top: 1.75rem;
    max-width: 11ch;
    color: #FFFFFF;
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 300;
    line-height: 1.12;
    letter-spacing: -0.02em;
    text-wrap: balance;
}

.dr-press-pick-title {
    max-width: 26ch;
    color: rgba(255, 255, 255, 0.84);
    font-family: var(--dr-sans);
    font-size: 0.875rem;
    line-height: 1.375rem;
    letter-spacing: -0.2px;
}

.dr-press-pick-cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: auto;
    color: var(--dr-slate-30);
    font-family: var(--dr-mono);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    transition: color 0.25s ease, gap 0.25s ease;
}

.dr-press-pick:hover .dr-press-pick-cta,
.dr-press-pick:focus-visible .dr-press-pick-cta {
    gap: 12px;
    color: #FFFFFF;
}

/* Small screens and reduced motion: no pinning, just the black finale. */
.dr-press.is-static {
    height: auto;
}

.dr-press.is-static .dr-press-sticky {
    position: relative;
    height: auto;
    padding: 96px 0;
    background: #000000;
}

.dr-press.is-static .dr-press-scene,
.dr-press.is-static .dr-press-overlay,
.dr-press.is-static .dr-press-heading::before {
    display: none;
}

/* Exactly the column's width: the picks' own 92vw plus this padding ran
   9px past each edge of a phone screen. */
.dr-press.is-static .dr-press-heading {
    position: relative;
    width: 100%;
}

.dr-press.is-static .dr-press-title {
    color: #FFFFFF;
}

.dr-press.is-static .dr-press-pick {
    min-height: 220px;
}

.dr-press.is-static .dr-press-picks {
    width: 100%;
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

@media (max-width: 900px) {
    .dr-press-picks {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .dr-press-pick {
        min-height: min(240px, 30vh);
    }
}

@media (max-width: 560px) {
    .dr-press-picks {
        grid-template-columns: 1fr;
    }

    .dr-worked-item,
    .dr-worked-item--reverse {
        flex-direction: column;
        gap: 0.75rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .dr-aurora-layer,
    body .btn-primary.btn-lg {
        animation: none !important;
    }
}

/* ---------- The chat: Luma thinking, and replies written in ---------- */
.chatbot-messages .message {
    animation: chat-message-in 0.28s ease-out both;
}

@keyframes chat-message-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}

.thinking {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

.thinking-dots {
    display: inline-flex;
    gap: 4px;
}

.thinking-dots i {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: linear-gradient(135deg, #E9A08C, #84BFFF);
    animation: thinking-dot 1.2s ease-in-out infinite;
}

.thinking-dots i:nth-child(2) { animation-delay: 0.15s; }
.thinking-dots i:nth-child(3) { animation-delay: 0.3s; }

@keyframes thinking-dot {
    0%, 70%, 100% { opacity: 0.35; transform: translateY(0); }
    35% { opacity: 1; transform: translateY(-4px); }
}

/* The label, with the headlines' warm-to-cool band passing through it. */
.thinking-label {
    color: var(--text-secondary);
    font-size: 0.82rem;
    background-image: var(--dr-shimmer);
    background-size: 300% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: thinking-shimmer 1.8s linear infinite;
}

@keyframes thinking-shimmer {
    from { background-position: 100% 0; }
    to { background-position: 0% 0; }
}

.reveal-word {
    opacity: 0;
    animation: reveal-word 0.35s ease-out forwards;
}

@keyframes reveal-word {
    from { opacity: 0; filter: blur(2px); }
    to { opacity: 1; filter: none; }
}

@media (prefers-reduced-motion: reduce) {
    .chatbot-messages .message,
    .thinking-dots i,
    .thinking-label,
    .reveal-word {
        animation: none;
    }

    .thinking-dots i { opacity: 0.6; }
    .reveal-word { opacity: 1; }

    .thinking-label {
        background: none;
        -webkit-text-fill-color: currentColor;
    }
}

/* Counted figures are <data>, so the cards' small-label rules for <span>
   leave them in the line they belong to. */
data[data-count] {
    font: inherit;
    color: inherit;
    font-variant-numeric: tabular-nums;
}
