/* ── Project page colour tokens — injected from data/colors.yaml › code ──────── */

/* Code-block + article tokens — injected from data/style.yaml › code
   (single source of truth, same as the global tokens in style.css). */
:root{
    --page-color: #ffffff;
    --page-border: #22222222;
    --code-color: #fbfbf9;
    --punctuation: #1d70dd;
    --string: #009b00;
    --keyword: #b400b4;
    --function: #ff0099;
    --number: #ff9900;
    --operation: #eb791c;
    --comment: #999999;
    --subtitle-color: #555555;
    --abstract-bg: #f5f5f5;
}

html[data-bs-theme="dark"] {
    --page-color: #111111;
    --page-border: #fbfbfb22;
    --code-color: #181818;
    --punctuation: #6cb6ff;
    --string: #7ee787;
    --keyword: #ff7b72;
    --function: #d2a8ff;
    --number: #ffa657;
    --operation: #ffa657;
    --comment: #8b949e;
    --subtitle-color: #bbbbbb;
    --abstract-bg: #222222;
}

/* ── Base code styles, page-nav button, chapter-strip panel ─────────────────── */


pre, code {
    font-family: var(--my-font-code);
}

pre{
    background-color: var(--my-white);
}

.btn.page-nav{
    color:var(--my-gray-1);
    background-color: var(--bs-body-bg);
}
.btn.page-nav:hover{
    color:var(--my-black);
}

.btn.page-nav.active{
    background-color: var(--my-white);
    border:none;
}

.btn.page-nav.active:hover{
    color:var(--my-gray-1);
}

/* ── Breadcrumb row — clear the fixed signature pill ──────────────────────────
   The signature pill (#signature-panel) is fixed in a top corner (top-left by
   default) at top/left:2.5vw with height var(--signature-height). Below lg the
   breadcrumb row is full-width (col-12) and its first crumb ("Projects") would sit
   under that footprint. Rather than indent the whole row to the right of the pill
   (which read as a large, awkward inset on phones), drop it below the pill's bottom
   edge with a top margin — the row stays flush-left and full-width. At lg+ the row
   is centered (col-lg-6) and already clears the pill, so this is scoped below lg.
   Margin lives on the wrapper (.breadcrumb-row), not the inner col. */
@media (max-width: 991.98px) {
  .breadcrumb-row {
    margin-top: 1.25rem;
  }
}

/* ── Chapter-strip panel (lives inside #page-console, below #pg-head-panel) ──
   Always visible when console is expanded; has its own collapse toggle
   that shrinks it to pg-head-panel-shape. Inherits .pg-summoned base
   (background, blur, shadow, radius) plus existing visibility rules
   (hidden when console is contracted). */
.pg-chapter-strip-panel {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-width: calc(2.25 * var(--signature-height));
    max-width: calc(3.5 * var(--signature-height));
    padding: calc(0.25 * var(--signature-height));
    font-family: var(--my-font-ui);
    transition:
        min-width var(--motion-base) ease,
        max-width var(--motion-base) ease,
        height var(--motion-base) ease,
        padding var(--motion-base) ease;
}

.pg-chapter-strip-toggle {
    align-self: flex-start;
    width: calc(0.45 * var(--signature-height));
    height: calc(0.45 * var(--signature-height));
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    padding: 0;
    margin-bottom: 0.25rem;
    cursor: pointer;
    color: var(--bs-body-color);
    transition: color var(--motion-fast) ease, text-shadow var(--motion-fast) ease;
}
.pg-chapter-strip-toggle:hover {
    text-shadow: var(--glow-sm);
}
.pg-chapter-strip-toggle .bi {
    transition: transform var(--motion-base) ease;
}

.pg-chapter-strip-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.pg-chapter-strip__item {
    padding-left: 0.4rem;
    border-left: 2px solid transparent;
    transition: border-color var(--motion-fast) ease;
}
.pg-chapter-strip__item.active {
    border-left-color: var(--my-black);
}

.pg-chapter-strip__link {
    color: var(--my-gray-1);
    text-decoration: none;
    font-size: 0.9rem;
    transition: color var(--motion-fast) ease;
}
.pg-chapter-strip__link:hover {
    color: var(--my-black);
}
.pg-chapter-strip__item.active .pg-chapter-strip__link {
    color: var(--my-black);
    font-weight: 600;
}

/* Collapsed: shrink to pg-head-panel-shape pill — only toggle visible */
.pg-chapter-strip-panel.collapsed {
    min-width: var(--signature-height);
    max-width: var(--signature-height);
    height: var(--signature-height);
    align-items: center;
    justify-content: center;
}
.pg-chapter-strip-panel.collapsed .pg-chapter-strip-toggle .bi {
    transform: rotate(180deg);
}
.pg-chapter-strip-panel.collapsed .pg-chapter-strip-list {
    display: none;
}

/* Right-corner mirror: align contents flush to the right edge */
#page-console.right .pg-chapter-strip-toggle {
    align-self: flex-end;
}

#page-console.right .pg-chapter-strip__item {
    padding-left: 0;
    padding-right: 0.4rem;
    border-left: none;
    border-right: 2px solid transparent;
    text-align: right;
}
#page-console.right .pg-chapter-strip__item.active {
    border-right-color: var(--my-black);
}

/* Spacing alongside pg-head-panel — match existing .pg-summoned pattern */
#page-console:not(.bottom) #pg-chapter-strip-panel {
    margin-top: calc(0.25 * var(--signature-height));
}
#page-console.bottom #pg-chapter-strip-panel {
    margin-bottom: calc(0.25 * var(--signature-height));
}
/* ── Project card, article layout, figures, headings, syntax, responsive ──────── */


/* ── Project card (entire card surface is the link) ─────────────────────── */
.project-card {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    padding: 0;
    /* White surface + soft hairline lift (mirrors the credentials cards), so the
       card reads as a distinct object against the page background. overflow:hidden
       clips the media image to the rounded top corners. */
    background-color: var(--my-white);
    border: 1px solid var(--my-border-color);
    border-radius: var(--radius-md);
    overflow: hidden;
    box-shadow: var(--shadow-panel);
    transition: transform var(--motion-fast) ease, box-shadow var(--motion-base) ease;
}
/* Lift (transform + shadow) comes from the central .card:hover/:focus-visible
   rule in 40-motion.css; this keeps only the anchor-specific resets. */
.project-card:hover,
.project-card:focus-visible {
    text-decoration: none;
    color: inherit;
}
.project-card .card-title {
    background: transparent;
    color: var(--my-black);
    font-family: var(--my-font-title);
    margin: 0 0 0.4em 0;
    transition: color var(--motion-fast) ease;
}
.project-card:hover .card-title {
    color: var(--my-black);
}

/* Flex-center + overflow + img object-fit come from the .icon-frame utility;
   this keeps the bespoke aspect-ratio and hairline divider. */
.project-card__media {
    aspect-ratio: 4 / 3;
    width: 100%;
    padding: 0;
    margin:0;
    border-bottom: 1px solid var(--my-border-color);
}

.project-card__media .card-img-top {
    border-radius: 0;
    margin: 0;
}

/* Inline GitHub icon button in article footer (Ellipsoidal Channel) */
.my-btn-icon {
    border-color: transparent !important;
    font-size: 1em;
    width: 1.25em;
    height: 1.25em;
    padding: 0;
}

.page {
    position: relative;
    font-size: 1.1rem;
    display: flex;
    width: 100%;
    flex-direction: column;
    max-width: 98vw;
    justify-content: center;
    align-items: center;
    padding: 2em 1em;
}

.katex-display {
    overflow-x: auto;
    font-size: 1.15em;
    overflow-y: hidden;
    max-width: 100%;
    display: block;
    text-align: center;
}

.katex {
    font-size: 0.8em;
    white-space: normal !important;
}

.header {
    text-align: center;
    max-width: 80%;
    margin-bottom: 1em;
}

.header .title {
    font-family: var(--my-font-title);
    font-size: clamp(2rem, 4vw, 3rem);
    text-align: center;
    font-weight: bold;
}

.header .subtitle {
    font-family: var(--my-font-subtitle);
    font-size: clamp(1.25rem, 2.5vw, 1.5rem);
    color: var(--subtitle-color);
}

.header .author {
    margin-top: 8px;
    font-size: clamp(0.9rem, 1.5vw, 1rem);
    font-weight: 500;
}

.article {
    font-family: var(--my-font-article);
    font-size: var(--rj-article-fs, 1.1rem);
    text-align: justify;
    hyphens: auto; /* justify without hyphenation opens word-spacing rivers */
    color:var(--my-black);
    overflow-x: auto;
    word-wrap: break-word;
    white-space: normal;
    background-color: var(--page-color);
    background-clip: border-box;
    border: 1px solid var(--my-border-color);
    border-radius: 0.25em;
    padding: 2em;
    margin: 4px;
    max-width: 85%;
}

.abstract {
    font-size: 1em;
    padding: 2em;
    background: var(--abstract-bg);
    border-radius: 0.5rem;
}

.abstract > .title {
    width: 100%;
    text-align: center;
    font-size: clamp(1.5rem, 3vw, 2rem);
    font-weight: bold;
    border-bottom: 2px solid var(--my-border-color);
    padding-bottom: 0.5rem;
}

.section {
    margin-block: 2em;
    padding: 1.5em;
}

.section > .title {
    width: 100%;
    text-align: left;
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    font-weight: bold;
    border-bottom: 2px solid var(--my-border-color);
    padding-bottom: 0.4em;
    margin-bottom: 1em;
}

.sub-section > .title {
    width: 100%;
    text-align: left;
    font-size: clamp(1.5rem, 2.5vw, 1.75rem);
    font-weight: bold;
    margin-top: 1em;
    padding-bottom: 0.3em;
    border-bottom: 1px groove var(--my-border-color);
}

.figure {
    width: calc(100% + 2rem);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    padding: 12px 12px;
    margin-left: -1em;
    margin-right: -1em;
    margin-block: 2em;
    border: 1px solid var(--my-border-color);
    border-radius: 0.45em;
}

.figure__media {
    width: var(--rj-article-figure-width, 75%);
    max-width: 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    padding: 0.75rem;
    border-radius: 0.35rem;
    background: transparent;
    transition: width var(--motion-base) ease;
}

.figure__image {
    --rj-figure-image-basis: 75%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 1 var(--rj-figure-image-basis);
    max-width: 100%;
}

.figure__image--small  { --rj-figure-image-basis: calc(33% - 0.5rem); }
.figure__image--medium { --rj-figure-image-basis: calc(50% - 0.5rem); }
.figure__image--large  { --rj-figure-image-basis: 85%; }
.figure__image--full   { --rj-figure-image-basis: 100%; }

.figure__image img {
    display: block;
    width: 100%;
    max-width: 100%;
    max-height: min(72vh, 42rem);
    height: auto;
    object-fit: contain;
    background: transparent;
    border-radius: 0.25rem;
}

.figure figcaption,
.figure p {
    width:100%;
    font-size: 0.9em;
    text-align: center;
    margin-top: 0.25em;
    padding: 0;
    margin-bottom:-6px;
    color: var(--my-gray-1);
}

ul,td{
    text-align: left;
}

/* ── Markdown-generated headings inside .article ───────────────────────── */
.article h2 {
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    font-weight: bold;
    border-bottom: 2px solid var(--my-border-color);
    padding-bottom: 0.4em;
    margin-top: 2em;
    margin-bottom: 1em;
}

.article h3 {
    font-size: clamp(1.5rem, 2.5vw, 1.75rem);
    font-weight: bold;
    margin-top: 1.5em;
    padding-bottom: 0.3em;
    border-bottom: 1px groove var(--my-border-color);
    margin-bottom: 0.75em;
}

/* Markdown lists: match original list-unstyled appearance */
.article ul {
    list-style-type: none;
    padding-left: 0;
}
td{
    padding-inline: 8px;
    border: 1px dashed var(--my-border-color);
}

/* Matches both raw-HTML .code-block (legacy .html pages) and Prism-processed
   pre[class*="language-"] (generated from fenced code blocks in .md pages) */
pre.code-block,
pre[class*="language-"] {
    background-color: var(--code-color);
    border-radius: 0.5rem;
    overflow-x: auto;
    font-size: 0.7em;
    text-shadow: none;
}
code[class*="language-"], :not(pre)>code[class*="language-"]{
    padding-inline: 4px;
    background-color: var(--code-color);
    color:var(--my-black);
}

.token{
    text-shadow: none;
}

/* Article width token — updated at each Bootstrap breakpoint.
   Consumers: .header and .article. Set once here, used everywhere. */
@media (max-width: 992px) {
    :root { --rj-article-width: 95%; }

    .header  { max-width: var(--rj-article-width); }
    .article { max-width: var(--rj-article-width); }

    .abstract {
        padding: 1.5rem;
    }
}

@media (max-width: 768px) {
    .article {
        padding: 1.5rem;
        /* Below ~40ch per line, justification spaces out unevenly even with
           hyphenation — ragged right reads better on phones. */
        text-align: left;
    }

    .abstract {
        padding: 1rem;
    }

    .section {
        padding: 1rem;
    }

    .figure__media { gap: 0.75rem; }
    .figure__image--small  { --rj-figure-image-basis: calc(50% - 0.375rem); }
    .figure__image--medium { --rj-figure-image-basis: 75%; }
    .figure__image--large,
    .figure__image--full   { --rj-figure-image-basis: 100%; }
}

@media (max-width: 576px) {
    :root { --rj-article-width: 100%; }

    .page {
        font-size: 0.7rem;
        width: 100%;
        padding: 1rem;
    }

    .article {
        max-width: var(--rj-article-width);
        padding: 0.5rem;
    }

    .header {
        width: 100%;
    }

    .header .title {
        font-size: 1.25rem;
    }

    .header .subtitle {
        font-size: 1rem;
    }

    .header .author {
        margin-top: 0.5rem;
        font-size: 0.9rem;
    }

    .figure { width: 100%; margin-left: 0; margin-right: 0; }
    .figure__media { width: min(var(--rj-article-figure-width, 75%), 100%); }
}

/* ── Code-block toolkit — copy button + language chip ─────────────────────
   Injected by projectScript.js into each article <pre>. The button reveals
   on hover/focus (always visible on touch, which has no hover). */
.article pre { position: relative; }

.pg-code-lang {
    position: absolute;
    top: 0.45rem;
    right: 2.6rem;
    font-family: var(--my-font-ui);
    font-size: 0.62rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--my-gray-1);
    user-select: none;
    pointer-events: none;
}

.pg-code-copy {
    position: absolute;
    top: 0.3rem;
    right: 0.45rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--my-gray-1);
    cursor: pointer;
    opacity: 0;
    transition: opacity var(--motion-base) ease, color var(--motion-fast) ease;
}

.article pre:hover .pg-code-copy,
.pg-code-copy:focus-visible,
.pg-code-copy.copied { opacity: 1; }

.pg-code-copy:hover { color: var(--my-black); text-shadow: var(--glow-sm); }
.pg-code-copy.copied { color: var(--my-theme-accent); }

@media (pointer: coarse) {
    .pg-code-copy { opacity: 1; }
}
/* ── Gallery page — filter toggle, filter panel, project groups, filter chips ─── */


/* ── Filter toggle button ───────────────────────────────────────────────── */
.filter-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    background: none;
    border: none;
    padding: 0.3rem 0.5rem 0.3rem 0.25rem;
    color: var(--my-gray-1);
    font-size: 1rem;
    cursor: pointer;
    transition: color var(--motion-fast) ease, transform var(--motion-fast) ease;
    flex-shrink: 0;
}

.filter-toggle:hover {
    color: var(--my-black);
}

.filter-toggle.active {
    color: var(--my-black);
}

.filter-toggle.active:not(.has-filter) .bi-funnel::before {
    content: "\F2F1";   /* bi-funnel-fill codepoint */
}

.filter-toggle__count,
.filter-toggle__divider {
    display: none;
    font-family: var(--my-font-ui);
    font-size: 0.95rem;
    line-height: 1;
}

.filter-toggle.has-filter .filter-toggle__icon {
    display: none;
}

.filter-toggle.has-filter .filter-toggle__count,
.filter-toggle.has-filter .filter-toggle__divider {
    display: inline-flex;
}

/* ── Collapsible filter panel ─────────────────────────────────────────────
   Uses the grid-template-rows 0fr → 1fr trick: composites cheaply, has no
   magic max-height ceiling, and fits arbitrary content. The direct child
   takes the overflow:hidden so its contents clip during the transition. */
.project-filters-wrap {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--motion-base) ease;
}
.project-filters-wrap > * {
    overflow: hidden;
    min-height: 0;
}
.project-filters-wrap.open {
    grid-template-rows: 1fr;
}

/* ── Project groups ─────────────────────────────────────────────────────── */
.project-group {
    margin-bottom: 1rem;
}

/* Grid wrapper — centering via .flex-center utility; this resets the
   container-fluid gutter (was p-0 m-0). */
.project-group__grid {
    padding: 0;
    margin: 0;
}

/* Card row — wraps cards; evenly spaced below lg, space-between at lg+.
   align-items: stretch so cards in the same row share the tallest's height
   (each .project-card carries h-100, which then fills the stretched wrap). */
.project-group__grid-row {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    justify-content: space-evenly;
}
@media (min-width: 992px) {
    .project-group__grid-row { justify-content: space-between; }
}

.project-group.hidden {
    display: none;
}

.project-group__title {
    font-family: var(--my-font-title);
    font-size: clamp(1.25rem, 3vw, 1.75rem);
    font-weight: 300;
    color: var(--bs-body-color);
    margin-bottom: 0.25rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--my-border-color);
}

.project-group__desc {
    font-family: var(--my-font-subtitle-alt);
    font-size: 0.9rem;
    font-style: italic;
    color: var(--my-gray-1);
    margin-top: 0.25rem;
    margin-bottom: 0;
}

/* ── Filter chips ───────────────────────────────────────────────────────── */
.filter-chip {
    font-family: var(--my-font-ui);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 0.3rem 0.85rem;
    border-radius: var(--radius-pill);
    border: 1px solid var(--my-border-color);
    background: var(--my-silver-1);
    color: var(--my-gray-2);
    cursor: pointer;
    transition: background-color var(--motion-fast) ease, color var(--motion-fast) ease, transform var(--motion-fast) ease, border-color var(--motion-fast) ease;
}

.filter-chip:hover {
    transform: scale(1.05);
    border-color: var(--my-gray-2);
}

.filter-chip.active {
    background: var(--my-black);
    color: var(--my-white);
    border-color: var(--my-black);
}

.filter-chip:focus-visible {
    outline: 2px solid var(--my-theme-accent);
    outline-offset: 2px;
}

.filter-chip:active {
    transform: scale(0.96);
}

.project-card-wrap {
    padding: 0;
    margin: 1.5rem;   /* was the m-4 utility on the markup */
    transition: opacity var(--motion-base) ease, transform var(--motion-base) ease;
}
.project-card-wrap.hidden {
    display: none;
}

.project-empty-state {
    font-family: var(--my-font-title);
    font-style: italic;
    color: var(--my-gray-1);
    text-align: center;
    width: 100%;
    padding: 2rem 0;
}
/* ── Project navigation quad (prev/next project + chapter buttons) ──────────── */


/* ── Four-button project navigation (chapter bottom) ─────────────────────
   Outer pair = prev/next project across the gallery (in weight order).
   Inner pair = prev/next chapter within the current bundle.
   Placeholders keep the four slots aligned when a button is absent
   (e.g. first/last project in gallery, single-page projects). */
.project-nav-quad {
    display: flex;
    justify-content: space-between;
    align-items: stretch;
    gap: 0.5rem;
    padding: 2rem 1.5rem 3rem;
    max-width: 56rem;
    margin: 0 auto;
    border-top: 1px solid var(--my-border-color);
}

.project-nav-quad__btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.9rem;
    font-family: var(--my-font-ui);
    font-size: 0.85rem;
    color: var(--my-gray-1);
    text-decoration: none;
    border: 1px solid var(--my-border-color);
    border-radius: var(--radius-pill);
    transition:
        color var(--motion-fast) ease,
        border-color var(--motion-fast) ease,
        box-shadow var(--motion-base) ease,
        transform var(--motion-fast) ease;
}
.project-nav-quad__btn:hover {
    color: var(--my-black);
    border-color: var(--my-gray-2);
    box-shadow: var(--shadow-sm);
    transform: translateY(-1px);
    text-decoration: none;
}

/* Outer pair (cross-project): visually heavier so the boundary reads */
.project-nav-quad__btn--outer-prev,
.project-nav-quad__btn--outer-next {
    color: var(--my-gray-2);
    font-weight: 500;
}

.project-nav-quad__arrow {
    font-size: 1rem;
    line-height: 1;
}

.project-nav-quad__label {
    /* Hidden on narrow viewports; visible on desktop. Clipping (overflow +
       ellipsis + nowrap) comes from the .truncate utility; this caps the
       width at 12em (overrides .truncate's max-width:100% — loads later). */
    display: none;
    max-width: 12em;
}

/* Placeholder slot — preserves layout when a button is absent */
.project-nav-quad__btn--placeholder {
    border-color: transparent;
    pointer-events: none;
    visibility: hidden;
}

@media (min-width: 768px) {
    .project-nav-quad__label {
        display: inline;
    }
}

@media (max-width: 576px) {
    .project-nav-quad {
        padding: 1.5rem 0.75rem 2.5rem;
        gap: 0.35rem;
    }
    .project-nav-quad__btn {
        padding: 0.4rem 0.65rem;
    }
}
/* ── Page-console panels — text-size slider, figure-width slider, ToC ─────── */


/* ═══════════════════════════════════════════════════════════════════════════
   Page-console content (project-page-specific):
     • #pg-text-size-toggle — active state when its panel is open
     • #pg-text-size-panel  — slider container summoned by the toggle
     • #pg-toc-toggle       — 3-state cycle icon swap
     • #pg-toc-panel        — table-of-contents list rendering
   The generic skeleton (#page-console positioning, #pg-head-panel pill,
   .pg-head__item base styling, .pg-summoned card template, contraction)
   lives in style.css.
   ═══════════════════════════════════════════════════════════════════════════ */

/* pg-head-panel sized to fit the three project buttons + arc */
#pg-head-panel { width: calc(2.25 * var(--signature-height)); }

/* Active state of pg-text-size toggle (panel open) */
#pg-text-size-toggle.active { color: var(--my-black); }

/* 3-state ToC toggle: cycles none → l1 → l2; active states use full-contrast ink */
#pg-toc-toggle[data-mode="l1"],
#pg-toc-toggle[data-mode="l2"] { color: var(--my-black); }

/* Lucide icon visibility: one icon shown per data-mode state.
   Lucide's createIcons() replaces each <i data-lucide> with an <svg> that
   inherits all original classes, so these selectors work both before and
   after icon rendering. */
#pg-toc-toggle .pg-toc-icon {
  display: none;
  width: 1em;
  height: 1em;
  pointer-events: none;     /* let clicks fall through to the button */
  transition: filter var(--motion-fast) ease;
}
#pg-toc-toggle:hover .pg-toc-icon {
  filter: drop-shadow(0 0 1px color-mix(in srgb, var(--my-theme-accent) 60%, transparent));
}
#pg-toc-toggle[data-mode="none"] .pg-toc-icon--none,
#pg-toc-toggle[data-mode="l1"]   .pg-toc-icon--l1,
#pg-toc-toggle[data-mode="l2"]   .pg-toc-icon--l2  { display: block; }

/* ── Text size & figure width panel (summoned by #pg-text-size-toggle) ──────── */
#pg-text-size-panel {
  display: none;
  flex-direction: column;
  gap: calc(0.12 * var(--signature-height));
  padding: calc(0.25 * var(--signature-height));
  width: calc(2.25 * var(--signature-height));
}
#pg-text-size-panel.open { display: flex; }

.pg-size-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: calc(0.15 * var(--signature-height));
  width: 100%;
}

/* ── Slider reset dot ─────────────────────────────────────────────────────
   Tiny visible affordance — clicking resets the row's slider to default
   and clears its localStorage key. Right-click on the slider still works
   as a power-user shortcut (both bind to the same reset function in JS). */
.pg-size-reset-dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--my-gray-1);
  cursor: pointer;
  position: relative;
  transition: background-color var(--motion-fast) ease, transform var(--motion-fast) ease, box-shadow var(--motion-fast) ease;
}
.pg-size-reset-dot::before {
  content: "";
  position: absolute;
  inset: -8px;            /* extend hit area to ~24px square */
}
.pg-size-reset-dot:hover {
  background: var(--my-black);
  transform: scale(1.4);
  box-shadow: 0 0 6px var(--my-theme-accent);
}

.pg-text-size-label {
  font-family: var(--my-font-ui);
  font-weight: 600;
  color: var(--my-gray-1);
  line-height: 1;
  user-select: none;
}
.pg-text-size-label--sm { font-size: 0.65rem; }
.pg-text-size-label--lg { font-size: 1rem; }

.pg-img-size-label {
  color: var(--my-gray-1);
  line-height: 1;
  user-select: none;
  font-variation-settings: 'FILL' 1, 'wght' 200, 'GRAD' 0, 'opsz' 20;
}
.pg-img-size-label--sm { font-size: 0.7rem; }
.pg-img-size-label--lg { font-size: 1.05rem; }

#pg-text-size-slider,
#pg-img-size-slider {
  -webkit-appearance: none;
  appearance: none;
  flex: 1;
  min-width: 0;
  width: 100%;
  height: 2px;
  background: var(--my-border-color);
  border-radius: 1px;
  outline: none;
  cursor: pointer;
  margin: 0;
  padding: 0;
}
#pg-text-size-slider::-webkit-slider-thumb,
#pg-img-size-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--my-black);
  cursor: pointer;
  transition: transform var(--motion-fast) ease;
}
#pg-text-size-slider::-moz-range-thumb,
#pg-img-size-slider::-moz-range-thumb {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--my-black);
  border: none;
  cursor: pointer;
  transition: transform var(--motion-fast) ease;
}
#pg-text-size-slider::-webkit-slider-thumb:hover,
#pg-img-size-slider::-webkit-slider-thumb:hover { transform: scale(1.5); }
#pg-text-size-slider::-moz-range-thumb:hover,
#pg-img-size-slider::-moz-range-thumb:hover     { transform: scale(1.5); }

#pg-text-size-slider:focus-visible,
#pg-img-size-slider:focus-visible {
    outline: 2px solid var(--my-theme-accent);
    outline-offset: 4px;
    border-radius: var(--radius-sm);
}

/* ── Floating ToC panel (summoned by #pg-toc-toggle) ────────────────────────── */
#pg-toc-panel {
  width: calc(2.25 * var(--signature-height));
  max-height: 60vh;
  overflow-y: auto;
  padding: calc(0.2 * var(--signature-height));
  position: relative;
}

/* Sliding active indicator — mirrors #navigation-panel::before, sits at panel edge */
#pg-toc-panel::before {
  content: "";
  position: absolute;
  left: 0;
  top: var(--toc-active-y, 0px);
  width: 2px;
  height: var(--toc-active-h, 2em);
  background: var(--my-black);
  border-radius: 2px;
  pointer-events: none;
  opacity: var(--toc-indicator-shown, 0);
  transition: top var(--motion-slow) cubic-bezier(0.22, 1, 0.36, 1),
              height var(--motion-slow) cubic-bezier(0.22, 1, 0.36, 1),
              opacity var(--motion-fast) ease;
}
#pg-toc-panel.hide { display: none !important; }

#pg-toc-panel .pg-toc-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.pg-toc-list__item {
  font-family: var(--my-font-title);
  line-height: 1.25;
  padding: 0.35em 0.6em;
  transition: color var(--motion-fast) ease, transform var(--motion-fast) ease;
}
.pg-toc-list__item a {
  display: block;
  color: var(--my-gray-2);
  text-decoration: none;
  white-space: nowrap;
  text-wrap: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pg-toc-list__item:hover     { transform: translateX(2px); }
.pg-toc-list__item:hover a   { color: var(--my-black); }
.pg-toc-list__item--h2       { font-size: 0.95rem; padding-top: 1em; font-weight: 500; }
.pg-toc-list__item--h3       { font-size: 0.7rem;  padding-top: 0.35em; }
.pg-toc-list__item--active a { color: var(--my-black); font-weight: 600; }
.pg-toc-list__item a:focus-visible {
    outline: 2px solid var(--my-theme-accent);
    outline-offset: 2px;
    border-radius: 2px;
}

/* Spacing: only when a panel is actually visible alongside pg-head-panel */
#pg-text-size-panel.open,
#pg-toc-panel:not(.hide) { margin-top: calc(0.25 * var(--signature-height)); }
#page-console.bottom #pg-text-size-panel.open,
#page-console.bottom #pg-toc-panel:not(.hide) {
  margin-top: 0;
  margin-bottom: calc(0.25 * var(--signature-height));
}

/* Text-align + indent flip based on which side #page-console is anchored to */
#page-console.left  #pg-toc-panel            { text-align: left;  }
#page-console.left  .pg-toc-list__item--h3   { padding-left: 1.4em; }
#page-console.right #pg-toc-panel            { text-align: right; }
#page-console.right .pg-toc-list__item--h3   { padding-right: 1.4em; }
#page-console.right #pg-toc-panel::before { left: auto; right: 0; }

@media (prefers-reduced-motion: reduce) {
  /* Snap the TOC active-indicator to its new position instantly so it
     doesn't slide across the panel under reduced-motion preferences. */
  #pg-toc-panel::before { transition-duration: 0.01ms !important; }
}
/* ── Print stylesheet (C6) — project articles on paper ────────────────────────
   Strips interactive chrome, forces paper colours (theme tokens resolve to
   white-on-white in dark mode, so absolute black/white keywords are the correct
   choice here — the one place raw colours are intentional), and tames page
   breaks. Loads as the last part of the projectstyle bundle, so it only ships
   on project pages — the print target. */

@media print {
  /* Drop all fixed/interactive chrome */
  #command-console,
  #page-console,
  #scroll-arc,
  #toast,
  #nav-arc,
  #spotlight-overlay,
  #shortcuts-overlay,
  .project-nav-quad,
  .pg-code-copy,
  .pg-code-lang,
  .skip-link {
    display: none !important;
  }

  html, body {
    background: white;
    color: black;
  }

  /* Article surface → plain page, full width, no card framing */
  .page {
    padding: 0;
    max-width: 100%;
  }
  .header {
    max-width: 100%;
    margin-bottom: 1.5rem;
  }
  .article {
    max-width: 100%;
    margin: 0;
    padding: 0;
    border: none;
    background: transparent;
    color: black;
    font-size: 11pt;
    line-height: 1.5;
    text-align: left;
  }
  .abstract {
    background: transparent;
    border: 1px solid gray;
  }

  /* Keep atomic blocks whole; don't strand headings at a page foot */
  figure, .figure, pre, table, img, .katex-display {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  h1, h2, h3,
  .article h2, .article h3,
  .section > .title, .sub-section > .title {
    break-after: avoid;
    page-break-after: avoid;
  }

  /* Expose link targets as footnotes — but only real external URLs, not
     in-page anchors (#…) or javascript: handlers. */
  .article a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    color: dimgray;
    word-break: break-all;
  }

  /* Comfortable margins; let the browser print backgrounds off by default */
  @page {
    margin: 2cm;
  }
}
