@import url(reset.css);

@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('../fonts/ibm-plex-sans-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('../fonts/ibm-plex-sans-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/ibm-plex-mono-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/ibm-plex-mono-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('../fonts/ibm-plex-mono-600-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('../fonts/ibm-plex-mono-600-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('../fonts/ibm-plex-mono-700-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('../fonts/ibm-plex-mono-700-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

html{
    background-color: var(--page-bg);
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;

}


/* colors  */
@property --primary-color { syntax: "<color>"; inherits: true; initial-value: #FFFFFF; }
@property --secondary-color { syntax: "<color>"; inherits: true; initial-value: #C4C4C4; }
@property --accent-color { syntax: "<color>"; inherits: true; initial-value: #F79030; }
@property --page-bg { syntax: "<color>"; inherits: true; initial-value: #191919; }
@property --panel-bg { syntax: "<color>"; inherits: true; initial-value: rgba(0, 0, 0, 0.45); }
@property --raised-bg { syntax: "<color>"; inherits: true; initial-value: rgba(255, 255, 255, 0.07); }
@property --on-accent { syntax: "<color>"; inherits: true; initial-value: #191919; }

/* The palette is declared exactly once, in the --ink/--surface/--seq/--cat
   variables below and their light-mode counterparts further down. Nothing
   else in the site should hard-code a colour.

   Each of those has a matching *paint* alias (--primary-color, --page-bg,
   ...) that is `transition`ed, so a theme switch cross-fades the page rather
   than snapping. The alias is what CSS paints with; the raw variable is what
   JavaScript reads. That split matters: getComputedStyle on a transitioning
   custom property returns wherever the fade currently is, so anything that
   read --primary-color during a switch got a half-faded grey and froze it
   into the chart it was drawing. The raw variables never transition, so they
   always report the theme the page is actually in. See assets/js/figures.js.

   Rule of thumb: paint from the alias, read from the raw variable. */
:root {
  --ink: white;
  --ink-dim: rgb(196, 196, 196);
  --ink-on-accent: #191919;
  --accent: #F79030;
  --surface: #191919;
  --surface-panel: rgba(0, 0, 0, 0.45);
  /* A raised surface, for something sitting on top of the page rather than
     recessed into it - a table header, say. --surface-panel darkens in dark
     mode and lightens in light mode, which is right for the frosted nav but
     backwards here: a header wants to read as lifted in both themes. This
     one lightens in dark mode and stays the brighter white in light. */
  --surface-raised: rgba(255, 255, 255, 0.07);

  --primary-color: var(--ink);
  --secondary-color: var(--ink-dim);
  --accent-color: var(--accent);
  --page-bg: var(--surface);
  --panel-bg: var(--surface-panel);
  --raised-bg: var(--surface-raised);
  --on-accent: var(--ink-on-accent);

  --theme-fade: 0.3s;
  --page-width: 1024px;
  --nav-font: 21px;
  --nav-pad-y: 14px;
  --nav-item-size: calc(var(--nav-font) + 2 * var(--nav-pad-y));
  --icon-size: 32px;
  --space-xs: 0.35rem;
  --space-sm: 0.75rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --font-body: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: 'IBM Plex Mono', ui-monospace, monospace;
  /* Sequential ramps, quiet end first. A ramp has to be declared per theme
     and not shared: it is read as a distance from the page, and a fixed hex
     cannot hold that distance against two different backgrounds. The light
     values (further down) put the quiet end 1.11:1 off a white page - a
     whisper - and those same hexes were 14.51:1 against this dark one, which
     is why the table glared here while the alpha-blended scatterplot blobs,
     which re-derive themselves from whatever is behind them, looked right in
     both. These dark values reproduce the light ladder - 1.11, 1.61, 3.13,
     4.70, 11.71 - against #191919, so both figures sit at the same weight in
     either theme. Quiet end first means the ramp inverts between themes: on
     a dark page the low end is the dark one.
     --ink-on-*: which ink reads on that ramp's quiet and loud ends. They
     swap between themes, because the ends do. */
  --seq-0: #080D11;
  --seq-25: #253F55;
  --seq-50: #396B97;
  --seq-75: #4E89BC;
  --seq-100: #C2D5E6;
  --warm-0: #3C2517;
  --warm-25: #5D351B;
  --warm-50: #82461F;
  --warm-75: #AC5F2B;
  --warm-100: #D18F62;
  --ink-on-seq-low: #FFFFFF;
  --ink-on-seq-high: #0D1B2A;
  --ink-on-warm-low: #FFFFFF;
  --ink-on-warm-high: #3B1A02;
  /* A separator, not a border: something the eye groups by without reading it
     as a line of its own. --ink-dim is far too loud for that (it sits ~9:1
     against the page in both themes), so this is a step off the surface
     instead - 1.4:1 either way, darker than the page in light mode and
     lighter than it in dark. */
  --hairline: #353535;
  /* the same separator, turned up: used to ring the panel the post is
     singling out. ~2.4:1 against the page either way. */
  --hairline-strong: #555555;
  --cat-1: #3987e5;
  --cat-2: #d95926;
  --cat-3: #199e70;

  transition:
    --primary-color var(--theme-fade) ease,
    --secondary-color var(--theme-fade) ease,
    --page-bg var(--theme-fade) ease,
    --panel-bg var(--theme-fade) ease,
    --raised-bg var(--theme-fade) ease;
}

html{
  color-scheme: dark;
}

/* Every transition on the site is timed off --theme-fade, so turning that
   down is enough to take the motion out of a theme switch - no blanket
   `* { transition: none }` override needed. The animated background is
   handled separately, in assets/js/background.js. */
@media (prefers-reduced-motion: reduce){
  :root{ --theme-fade: 0.001s; }
}

/* Keyboard focus. The browser default is a thin ring that all but disappears
   against both of this site's backgrounds, and the nav links and toggle paint
   their own hover state, so give focus a visible one of its own. :focus-visible
   rather than :focus keeps it off mouse clicks. */
:focus-visible{
  outline: 2px solid var(--accent-color);
  outline-offset: 2px;
}

html[data-theme="light"] {
  color-scheme: light;
  --ink: #0A0A0A;
  --ink-dim: #454545;
  --ink-on-accent: #FFFFFF;
  --accent: #C2410C;
  --seq-0: #DEEBF7;
  --seq-25: #9ECAE1;
  --seq-50: #4292C6;
  --seq-75: #2171B5;
  --seq-100: #08306B;
  --warm-0: #FDD8B3;
  --warm-25: #FDAF6D;
  --warm-50: #F87F2C;
  --warm-75: #DB5108;
  --warm-100: #9F3303;
  --ink-on-seq-low: #0D1B2A;
  --ink-on-seq-high: #FFFFFF;
  --ink-on-warm-low: #3B1A02;
  --ink-on-warm-high: #FFFFFF;
  --hairline: #D2D2D2;
  --hairline-strong: #A0A0A0;
  --cat-1: #2a78d6;
  --cat-2: #eb6834;
  --cat-3: #1baf7a;
  --surface: #F5F5F5;
  --surface-panel: rgba(255, 255, 255, 0.60);
  --surface-raised: rgba(255, 255, 255, 0.60);
}

html[data-theme="light"] canvas{
    filter: invert(1);
}

canvas{
    transition: filter var(--theme-fade) ease;
}

html.theming nav a,
html.theming .nav-toggle{
    transition: background-color var(--theme-fade) ease, backdrop-filter var(--theme-fade) ease;
}

a,
.person-name,
.vega-embed summary svg{
    transition: color var(--theme-fade) ease, border-color var(--theme-fade) ease, fill var(--theme-fade) ease;
}

html.theming a,
html.theming .person-name,
html.theming .vega-embed summary svg{
    transition: none;
}
body {
    font-family: var(--font-body);

}

p {
    line-height: 1.55;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--accent-color);
}

strong, b {
    font-weight: 700;
}

em, i {
    font-style: italic;
}


/* nav bar content */

nav {
    display:flex;
    align-items: center;
    color: var(--primary-color);
    border-bottom: 1px solid var(--primary-color);
    max-width: var(--page-width);
    margin: 0 auto;
    text-align: center;
    justify-content: center;
    padding-top: 2.5rem;
}

nav a {
    display: block;
    font-family: var(--font-display);
    width: 100%;
    padding: var(--nav-pad-y) 12px;
    font-size: var(--nav-font);
    line-height: 1;
    font-weight: 700;
    color: var(--primary-color);
    text-decoration: none;
    text-align: center;
    background-color: transparent;
    backdrop-filter: blur(0px);
    transition: background-color var(--theme-fade) ease, backdrop-filter var(--theme-fade) ease, color var(--theme-fade) ease;
}

nav ul {
    display: flex;
    width: 100%;
    list-style: none;
    margin: 0;
    padding: 0;
    text-align: center;
}

nav ul li.nav-toggle-item{
    flex: 0 0 auto;
}

.nav-toggle{
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--nav-item-size);
    height: var(--nav-item-size);
    padding: 0;
    border: 0;
    background-color: transparent;
    backdrop-filter: blur(0px);
    color: var(--primary-color);
    font-family: var(--font-display);
    font-size: var(--nav-font);
    line-height: 1;
    cursor: pointer;
    transition: background-color var(--theme-fade) ease, backdrop-filter var(--theme-fade) ease, color var(--theme-fade) ease;
}

.nav-toggle::before{
    content: "\2600";
}

html[data-theme="light"] .nav-toggle::before{
    content: "\263D";
}

.nav-toggle:hover{
    background-color: var(--panel-bg);
    backdrop-filter: blur(10px);
    color: var(--accent-color);
}

nav ul li {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    color: var(--primary-color);
    text-align: center;
}

nav a:hover {
    background-color: var(--panel-bg);
    backdrop-filter: blur(10px);
    color: var(--accent-color);
}

/* footer content */
footer {
    max-width: var(--page-width);
    color: var(--primary-color);
    padding: 0 0 2rem;
    margin: 0 auto;

}

.frosted {
    max-width: var(--page-width);
    margin: 0 auto;
    backdrop-filter: blur(10px);
    background-color: var(--panel-bg);
}

.footer-content-grid{
    display: flex;
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
    width: 100%;
    border-top: 1px solid var(--primary-color);
    padding: 0.5rem 2rem;
}
.social-media{
    display: flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--primary-color);
}
.footer-links{
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    line-height: 1;
    list-style: none;
    margin: 0;
    padding: 0;
}
.footer-links a{
    display: block;
    color: var(--primary-color);
}
.icon{
    display: block;
    width: var(--icon-size);
    height: var(--icon-size);
}
svg.icon{
    fill: currentColor;
}
.icon-cmu{
    background: center / contain no-repeat url('../img/icons/cmu-dark.png');
}
html[data-theme="light"] .icon-cmu{
    background-image: url('../img/icons/cmu-light.png');
}
.footer-links a:hover{
    color: var(--accent-color);
}

/* interior page css */
.content-grid{
    display: flex;
    font-size: 24px;
    max-width: var(--page-width);
    margin: 0 auto;
	background-color: transparent;
}
.content{
    flex: 3 1 0;
    padding: 2rem 2.5rem;
}
.content h2{
    font-size: 27px;
    font-weight: 700;
}
.content h3{
    font-size: 18px;
    font-weight: 600;
}
.content p{
    padding: 0 1rem;
    font-size: 16px;
    color: var(--primary-color);
}


/* flow spacing: elements own no vertical space; each gap is one --flow */
.content > * + *,
.entry-card > * + *{
    margin-block-start: var(--flow, var(--space-md));
}
.content > h2{ --flow: var(--space-xl); }
.content > h3{ --flow: var(--space-lg); }
.content > :is(h2, h3) + *{ --flow: var(--space-md); }
.content > h2 + .entry-meta{ --flow: var(--space-xs); }
.content > h2 + .entry-subtitle{ --flow: var(--space-xs); }
.content > .entry-subtitle + .entry-meta{ --flow: var(--space-sm); }
.content > .figure,
.content > .figure + *{ --flow: var(--space-xl); }
.content > .foot-note{ --flow: var(--space-lg); }
.content > .entry-meta + .entry-meta{ --flow: 0.25rem; }
.content > .entry-card + .entry-card{ --flow: var(--space-lg); }
.content li + li{ margin-block-start: var(--space-xs); }
.entry-card > * + *{ --flow: var(--space-xs); }
.entry-card > .entry-links{ --flow: var(--space-sm); }


/* markdown body content on entry pages */
.content a{
    color: var(--primary-color);
    text-decoration: underline;
    text-underline-offset: 3px;
}
.content a:hover{
    color: var(--accent-color);
}
.content ul,
.content ol{
    padding: 0 1rem 0 3rem;
    font-size: 16px;
    line-height: 1.55;
    color: var(--primary-color);
    list-style: disc;
}
.content ol{
    list-style: decimal;
}
.content code{
    font-family: var(--font-display);
    padding: 1px 5px;
    background-color: rgba(255, 255, 255, 0.1);
    font-size: 13px;
}
.content .table-wrap{
    border: 1px solid var(--secondary-color);
    border-radius: 12px;
    overflow: hidden;
}
.content table{
    width: 100%;
    border-collapse: collapse;
    font-size: 15px;
    color: var(--primary-color);
}
.content th,
.content td{
    padding: var(--space-sm) var(--space-md);
    text-align: left;
    vertical-align: top;
    border-right: 1px solid var(--secondary-color);
    border-bottom: 1px solid var(--secondary-color);
}
.content th:last-child,
.content td:last-child{
    border-right: none;
}
.content tr:last-child td{
    border-bottom: none;
}
.content th{
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--primary-color);
    background-color: var(--raised-bg);
}
/* a lighter reading table for prose comparisons: opt in with
   {% include modules/table.html data="..." class="table-soft" %} */
.content .table-soft{
    border: 1px solid var(--hairline-strong);
}
.content .table-soft table{
    font-size: 16px;
    line-height: 1.5;
}
.content .table-soft th,
.content .table-soft td{
    padding: var(--space-md) var(--space-lg);
    border-right: none;
    border-bottom: 1px solid var(--hairline-strong);
}
.content .table-soft tr:last-child td{ border-bottom: none; }
.content .table-soft th{
    font-family: var(--font-body);
    font-size: 15px;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    color: var(--secondary-color);
}
.content .table-soft td:first-child{ white-space: nowrap; }
.content .table-soft th:last-child{ color: var(--accent-color); }
.content .table-soft td:last-child{ box-shadow: inset 3px 0 0 var(--accent-color); }
/* a denser soft table for many columns: class="table-soft table-compact" */
.content .table-compact table{
    font-size: 14px;
    line-height: 1.45;
}
.content .table-compact th,
.content .table-compact td{
    padding: var(--space-sm) var(--space-md);
}
.content .table-compact th{ font-size: 16px; }
.content .table-compact td:first-child{ white-space: normal; }
@media (min-width: 701px){
    .content .table-compact table{ table-layout: fixed; }
    .content .table-compact th:nth-child(1){ width: 16%; }
    .content .table-compact th:nth-child(2){ width: 20%; }
    .content .table-compact th:nth-child(3){ width: 20%; }
    .content .table-compact th:nth-child(4){ width: 44%; }
}
.content > .table-wrap{ --flow: var(--space-lg); }
.content > .table-wrap + *{ --flow: var(--space-lg); }


.vega-embed{
    width: 100%;
}
.vega-embed svg{
    max-width: 100%;
    height: auto;
}

/* --- chart chrome ---------------------------------------------------------
   Vega stamps a role class onto every group it draws, which splits a chart
   cleanly in two: the chrome (axes, legends, chart and facet-panel titles)
   and the data marks. The chrome is page furniture and should follow the
   page's ink exactly the way body text does, so it is coloured here rather
   than through the embed config in figures.js.

   Doing it in CSS is what makes a theme switch instant. The embed config is
   only consulted when a chart is built, so a config-only chart keeps the ink
   it was born with until something re-renders it - which is why axis and
   legend labels used to stay white on the light background after a toggle.
   A CSS rule has no such gap, it cross-fades along with the rest of the page
   because --primary-color is itself a transitioned property, and it applies
   to every chart added later without anyone having to wire it up.

   The `fill` and `stroke` CSS properties outrank the presentational
   fill="..." attributes Vega writes into the SVG, so no !important is needed.
   Data marks (role-mark) are deliberately left alone: their colour is data,
   not decoration. Anything a spec needs to paint itself in theme colours can
   ask for them by name - see the $token note in assets/js/figures.js. */
.vega-embed :is(.role-axis-label, .role-axis-title,
                .role-legend-label, .role-legend-title,
                .role-title-text, .role-title-subtitle) text{
    fill: var(--primary-color);
}
.vega-embed :is(.role-axis-domain, .role-axis-tick) line{
    stroke: var(--secondary-color);
}
.vega-embed .role-axis-grid line{
    stroke: var(--secondary-color);
    opacity: 0.22;
}
.vega-embed .vega-actions a{
    color: var(--primary-color);
    font-family: var(--font-display);
}
.vega-bind select option{
    background-color: var(--page-bg);
    color: var(--primary-color);
}
.vega-embed summary{
    background: none !important;
    border: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    opacity: 0.6 !important;
    color: var(--secondary-color) !important;
}
.vega-embed summary:hover{
    opacity: 1 !important;
}
.vega-embed summary svg{
    fill: var(--secondary-color);
}
.vega-embed summary:hover svg{
    fill: var(--accent-color);
}
.vega-embed .vega-actions{
    background-color: var(--page-bg);
    border: 1px solid var(--secondary-color);
    box-shadow: none;
}
.vega-embed .vega-actions:before,
.vega-embed .vega-actions:after{
    display: none;
}
.vega-embed .vega-actions a{
    color: var(--primary-color);
    font-family: var(--font-display);
    font-size: 12px;
}
.vega-embed .vega-actions a:hover{
    background-color: var(--panel-bg);
    color: var(--accent-color);
}

#vg-tooltip-element{
    background-color: var(--page-bg) !important;
    border: 1px solid var(--secondary-color) !important;
    color: var(--primary-color) !important;
    font-family: var(--font-body) !important;
}
#vg-tooltip-element td.key,
#vg-tooltip-element td.value{
    color: var(--primary-color) !important;
}
.vega-bindings{
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    padding-bottom: 0.75rem;
    font-family: var(--font-display);
    font-size: 12px;
    color: var(--secondary-color);
}
.vega-bind label{
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.vega-bind select{
    padding: 4px 6px;
    border: 1px solid var(--secondary-color);
    background-color: transparent;
    color: var(--primary-color);
    font-family: var(--font-display);
    font-size: 12px;
}
.vega-embed summary{
    color: var(--secondary-color);
}

/* A raster figure is a fixed-size image, not a chart that can lay itself out
   again, so it gets the opposite treatment to a chart's svg: scale down to
   the text column rather than keep its natural width. The screenshots are
   saved at 2x for sharp rendering on dense displays, so their intrinsic
   width is well past the column and this is what brings them back to it. */
.content .figure img{
    display: block;
    max-width: 100%;
    height: auto;
}

.figure-placeholder{
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 180px;
    margin: 1.5rem 0;
    padding: 1rem;
    border: 1px dashed var(--secondary-color);
    font-size: 13px;
    line-height: 1.4;
    text-align: center;
    color: var(--secondary-color);
}

.content p.foot-note{
    padding: 0;
    font-size: 12px;
    line-height: 1.4;
    color: var(--secondary-color);
}

.content p.figure-caption{
    padding: 0;
    font-size: 13px;
    line-height: 1.45;
    color: var(--secondary-color);
}
.content p.figure-caption-lg{
    font-size: 15px;
    line-height: 1.5;
}
.content p.figure-caption-center{
    font-size: 16px;
    line-height: 1.5;
    text-align: center;
}
.content > .figure + .figure-caption{ --flow: var(--space-xs); }
.content > .figure-caption + *{ --flow: var(--space-xl); }

/* optional front-matter subtitle under an entry's title */
.content p.entry-subtitle{
    padding: 0;
    font-size: 18px;
    font-style: italic;
    color: var(--secondary-color);
}

/* light-background raster/SVG figures sit on the page as a rounded card */
.content .figure-image img{
    margin: 0 auto;
    border-radius: 6px;
}

/* a single, compact chart: keep it narrower than the column and centred.
   The spec uses width "container", so it fits this box on a phone too. */
.content .figure-centered .vega-embed{
    display: block;
    width: min(100%, 460px) !important;
    margin: 0 auto;
}

/* a diagram beside the chart of its results; stacks on a phone (see the
   max-width: 700px block) */
.content .figure-pair{
    display: grid;
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    gap: var(--space-lg);
    align-items: center;
}
.content .figure-pair > img{
    width: 100%;
    border-radius: 6px;
}
.content .figure-pair > [data-vega]{
    min-width: 0;
    overflow-x: auto;
}
/* two diagrams compared side by side with a grey rule between them (Fig. 1).
   Column widths follow the images' natural widths (792 and 999 px) so both
   are drawn at the same scale; they stack on a phone (see the max-width:
   700px block) */
.content .figure-compare{
    display: grid;
    grid-template-columns: minmax(0, 792fr) 1px minmax(0, 999fr);
    column-gap: var(--space-lg);
    align-items: start;
}
.content .figure-compare > img{
    width: 100%;
    margin: 0;
}
.content .figure-compare > .figure-divider{
    align-self: stretch;
    background: var(--hairline-strong);
}
/* diagrams drawn for a white page keep their transparent background in light
   mode, but sit on a light card in dark mode so their dark text stays legible */
html:not([data-theme="light"]) .content .figure-card img{
    box-sizing: border-box;
    padding: var(--space-sm);
    background: #f4f3ef;
}
/* a diagram + results pair becomes one white card in dark mode, chart
   included: the chart re-reads its palette from its own element (see css()
   in assets/js/figures.js), so re-declaring the light-theme values here gives
   it dark ink on the card while the rest of the page stays dark */
html:not([data-theme="light"]) .content .figure-pair.figure-card{
    padding: var(--space-md);
    border-radius: 8px;
    background: #ffffff;
}
html:not([data-theme="light"]) .content .figure-pair.figure-card > img{
    padding: 0;
    background: none;
}
html:not([data-theme="light"]) .content .figure-compare.figure-card{
    padding: var(--space-md);
    border-radius: 8px;
    background: #ffffff;
}
html:not([data-theme="light"]) .content .figure-compare.figure-card > img{
    padding: 0;
    background: none;
}
html:not([data-theme="light"]) .content .figure-compare > .figure-divider{
    background: #cccccc;
}
html:not([data-theme="light"]) .content .figure-card [data-vega]{
    color-scheme: light;
    --ink: #0A0A0A;
    --ink-dim: #454545;
    --accent: #C2410C;
    --cat-1: #2a78d6;
    --cat-2: #eb6834;
    --cat-3: #1baf7a;
    --hairline: #D2D2D2;
    --hairline-strong: #A0A0A0;
    --primary-color: var(--ink);
    --secondary-color: var(--ink-dim);
    --accent-color: var(--accent);
    --page-bg: #ffffff;
}

/* call-to-action box */
.content .callout{
    margin-inline: 1rem;
    padding: .9rem 1.1rem;
    border: 1px solid var(--accent-color);
    border-left-width: 4px;
    border-radius: 6px;
    background: var(--panel-bg);
}
.content .callout p{
    padding: 0;
    margin: 0;
}
.content .callout p + p{
    margin-top: .4rem;
}
.content .callout.tldr .tldr-label{
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--accent-color);
    margin-bottom: .3rem;
}
.content .callout.tldr ul{
    margin: 0;
    padding: 0 0 0 1.2rem;
}

/* icon button that copies an address without printing it; see copy-email.js */
.content .copy-email{
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: -3px;
    width: 20px;
    height: 20px;
    padding: 0;
    margin: 0 2px;
    border: 0;
    background: transparent;
    color: var(--primary-color);
    cursor: pointer;
}
.content .copy-email:hover,
.content .copy-email:focus-visible{
    color: var(--accent-color);
}
.content .copy-email-tip{
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    white-space: nowrap;
    font-size: 12px;
    padding: 2px 8px;
    border-radius: 4px;
    background: var(--accent-color);
    color: var(--ink-on-accent);
    opacity: 0;
    pointer-events: none;
    transition: opacity .15s;
}
.content .copy-email-tip.show{
    opacity: 1;
}

/* numbered reference list at the foot of a post; [n] links land on these */
.content ol.references{
    font-size: 14px;
}
.content ol.references li{
    scroll-margin-top: 1rem;
}
.content ol.references li:target{
    color: var(--accent-color);
}


/* entry cards: blog, data, publications */
.entry-title{
    display: block;
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--primary-color);
    text-decoration: none;
}
a.entry-title:hover{
    color: var(--accent-color);
}
.content :is(p.entry-title, p.entry-meta, p.entry-desc, p.entry-links){
    padding: 0;
}
.content p.entry-meta{
    font-size: 13px;
    color: var(--secondary-color);
}
.entry-meta a{
    color: var(--secondary-color);
    text-decoration: underline;
    text-underline-offset: 3px;
}
.entry-meta a:hover{
    color: var(--accent-color);
    text-decoration: underline;
}
.content p.entry-desc{
    font-size: 14px;
    color: var(--primary-color);
}
.entry-links a{
    display: inline-block;
    margin-right: 0.4rem;
    padding: 2px 8px;
    border: 1px solid var(--secondary-color);
    font-size: 12px;
    color: var(--secondary-color);
    text-decoration: none;
}
.entry-links a:hover{
    color: var(--accent-color);
    border-color: var(--accent-color);
}
/* paper titles are long, so set them in the body face rather than bold mono */
.publication-card .entry-title{
    font-family: var(--font-body);
    font-size: 17px;
    font-weight: 600;
    line-height: 1.4;
    margin-top: 0.35rem;
}
.publication-card .entry-meta{
    line-height: 1.6;
}
.venue{
    display: inline-block;
    padding: 2px 8px;
    background-color: var(--accent-color);
    color: var(--on-accent);
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 700;
    text-decoration: none;
}

/* email signup (see _includes/modules/subscribe.html) */
.visually-hidden{
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
.subscribe{
    display: block;
}
.content p.subscribe-label{
    display: block;
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--secondary-color);
}
.content p.subscribe-row,
.subscribe-row{
    display: flex;
    padding: 0;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-block-start: var(--space-sm);
}
.subscribe-input{
    flex: 1 1 14rem;
    min-width: 0;
    padding: 8px 10px;
    border: 1px solid var(--secondary-color);
    background-color: transparent;
    color: var(--primary-color);
    font-family: var(--font-body);
    font-size: 15px;
}
.subscribe-input::placeholder{
    color: var(--secondary-color);
}
a.subscribe-button,
.subscribe-button{
    display: inline-block;
    flex: 0 0 auto;
    text-decoration: none;
    padding: 8px 16px;
    border: 1px solid var(--accent-color);
    background-color: var(--accent-color);
    color: var(--on-accent);
    font-family: var(--font-display);
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
}
.subscribe-button:hover{
    background-color: transparent;
    color: var(--accent-color);
}
.content p.subscribe-note{
    padding: 0;
    margin-block-start: var(--space-xs);
    font-size: 12px;
    line-height: 1.4;
    color: var(--secondary-color);
}

/* sidebar recent list */
.recent-list{
    list-style: none;
    margin: 0;
    padding: 0;
}
.recent-list li{
    line-height: 1.3;
}
.recent-list li + li{
    margin-block-start: var(--space-sm);
}
.recent-list a{
    display: block;
    font-size: 14px;
    color: var(--primary-color);
    text-decoration: underline;
    text-underline-offset: 3px;
}
.recent-list a:hover{
    color: var(--accent-color);
}
.recent-meta{
    display: block;
    margin-block-start: var(--space-xs);
    font-size: 12px;
    line-height: 1;
    color: var(--secondary-color);
}


/* people page css */
.people-grid{
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 1.5rem 1rem;
}
.person a{
    text-decoration: none;
}
.person a:hover .person-name{
    color: var(--accent-color);
    text-decoration: underline;
}
.person img{
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: 50%;
}
.content p.person-name{
    padding: 0.5rem 0 0;
    font-size: 14px;
    line-height: 1.25;
    text-align: center;
    color: var(--primary-color);
}



/* home page css */
/* home content section */

.home-logo{
    display: block;
    width: 100%;
    height: auto;
}


/* home side bar section */
.sidebar{
    flex: 1 1 0;
    gap: 0rem 1rem;
    border-left: 1px solid var(--primary-color);
    padding: 2rem 1rem;
    color: var(--primary-color);
}
.sidebar > * + *{
    margin-block-start: var(--flow, var(--space-md));
}
.sidebar h2{
    font-size: 24px;
}
.sidebar p{
    font-size: 14px;
    color: var(--primary-color);
}


@media (max-width: 700px){
    nav{
        justify-content: flex-start;
    }
    nav ul{
        overflow-x: auto;
    }
    nav ul li{
        flex: 0 0 auto;
    }
    nav ul li.nav-toggle-item{
        order: -1;
    }
    nav a{
        width: auto;
    }

    .content-grid{
        flex-direction: column;
    }
    .sidebar{
        border-left: 0;
        border-top: 1px solid var(--primary-color);
    }
    .content{
        padding: var(--space-lg) var(--space-md);
    }
    .content p{
        padding: 0;
    }
    .content ul,
    .content ol{
        padding: 0 0 0 var(--space-xl);
    }
    .content .table-wrap{
        overflow-x: auto;
    }
    .content table{
        white-space: nowrap;
    }

    /* soft tables stack each row into a card instead of scrolling sideways */
    .content .table-soft table,
    .content .table-soft tbody,
    .content .table-soft tr,
    .content .table-soft td{
        display: block;
        white-space: normal;
    }
    .content .table-soft thead{ display: none; }
    .content .table-soft tr{ border-bottom: 1px solid var(--hairline-strong); }
    .content .table-soft tr:last-child{ border-bottom: none; }
    .content .table-soft td{ border: none; padding: var(--space-xs) var(--space-md); }
    .content .table-soft td:first-child{ padding-top: var(--space-md); font-size: 17px; }
    .content .table-soft td:last-child{ padding-bottom: var(--space-md); }
    .content .table-soft td:not(:first-child)::before{
        content: attr(data-label);
        display: block;
        font-size: 13px;
        font-weight: 600;
        color: var(--secondary-color);
    }
    .content .table-soft td:last-child::before{ color: var(--accent-color); }
    /* charts: let the (now bottom-oriented) legend keep its natural width and
       scroll horizontally instead of forcing the whole chart to shrink to fit,
       which was squashing the legend rather than just widening the figure */
    .content .figure{
        overflow-x: auto;
    }
    .content .figure-pair{
        grid-template-columns: minmax(0, 1fr);
    }
    .content .figure-pair > img{
        width: min(100%, 460px);
        margin: 0 auto;
    }
    /* stacked: the rule turns horizontal, and the narrower free-form diagram
       keeps its 792:999 width ratio so both stay at the same scale */
    .content .figure-compare{
        grid-template-columns: minmax(0, 1fr);
        row-gap: var(--space-md);
    }
    .content .figure-compare > .figure-divider{
        height: 1px;
    }
    .content .figure-compare > img{
        width: min(100%, 460px);
        margin: 0 auto;
    }
    .content .figure-compare > img:first-child{
        width: min(79.3%, 365px);
    }
    .content .figure svg{
        max-width: none;
    }
    /* vega-embed's "..." export button is position:absolute against
       .vega-embed's own box, so that box decides which corner the button
       calls "top right". Letting it hug the chart's real (wider) width rather
       than the scroll container's puts the button on the chart's own top
       right corner - the corner of the image, not of the phone screen. On a
       figure wider than the viewport that means scrolling the figure across
       to reach it, which is the trade: the button belongs to the image.

       has-actions' reserved 38px gutter stays, and now does its job: with the
       box hugging the chart, that gutter is 38px of clear space added to the
       chart's right edge, so the button sits beside the last column label
       instead of on top of it. (It was briefly set to 0 while the box was
       pinned to the viewport - there the gutter could not help, since the
       chart scrolled underneath the button whatever the padding was, and all
       it bought was empty space to scroll past.) The chip below is belt and
       braces for a chart whose content does reach under the button. */
    .content .figure .vega-embed{
        width: max-content;
    }
    /* ...except a chart that sizes itself to its container ("width":
       "container", which vega-embed marks with .fit-x) and has no
       _minMobileWidth to fall back on: hugging its content and filling its
       box would wait on each other and collapse the chart to 0px wide */
    .content .figure .vega-embed:has(> .chart-wrapper.fit-x){
        width: 100%;
    }
    .content .figure .vega-embed summary{
        padding: 2px 4px;
        border-radius: 4px !important;
        background-color: var(--page-bg) !important;
        opacity: 0.85 !important;
    }

    .people-grid{
        grid-template-columns: repeat(2, 1fr);
    }
    .footer-content-grid{
        padding: 0.5rem var(--space-md);
    }
}
