/*
 * talk.css — стили контентных слайдов ЭТОГО доклада
 * («Подходы к работе над информационными системами», глава 1).
 * Общий «хром» дека живёт в deck.css и правится только в шаблоне; всё, что
 * относится к слайдам спикера, — здесь: пересборка «хром»-слайдов
 * (scripts/rebuild-talk.mjs) этот файл не трогает.
 */

/* Отступы и рамки — внутрь заданной ширины: глобального box-sizing в deck.css
   нет, а без него width: 100% с padding вылезает за контейнер слайда. */
.content-slide,
.content-slide *,
.content-slide *::before,
.content-slide *::after {
    box-sizing: border-box;
}

/* ===== Каркас контентного слайда =====
   Шапка (заголовок + лид) прижата к верху, всё остальное центрировано в
   остатке высоты: автоотступы у первого блока после шапки и у хвостового
   элемента делят свободное место поровну. */
.content-slide {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    height: 100%;
    padding: 52px 100px;
}
.content-slide > h2 {
    font-size: 52px;
    margin: 0;
    line-height: 1.1;
    flex-shrink: 0;
}
.content-slide > h2 + .slide-lead {
    margin-top: 14px;
}
.content-slide > .slide-lead + *,
.content-slide > h2 + *:not(.slide-lead) {
    margin-top: auto !important;
}
.content-slide::after {
    content: '';
    margin-top: auto;
}
.slide-lead {
    font-size: 21px;
    line-height: 1.55;
    color: var(--text-muted);
    margin: 0;
    max-width: 1400px;
}
.slide-lead b {
    color: #ededed;
    font-weight: 600;
}
.section-label {
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #71717a;
    margin: 0;
}
/* Инлайновый термин — тем же моно-шрифтом, что листинги. */
.content-slide code {
    font-family: var(--font-mono);
    font-size: 0.92em;
    color: #93c5fd;
}

/* Вывод внизу слайда — широкая строка за левой чертой. */
.wide-accent {
    margin: 30px 0 0;
    padding: 18px 26px;
    border-left: 3px solid #3f3f46;
    border-radius: 0 14px 14px 0;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0));
    font-size: 20px;
    line-height: 1.55;
    color: #d4d4d8;
    flex-shrink: 0;
}
.wide-accent.is-strong {
    border-left-color: #fff;
    font-size: 23px;
    color: #ededed;
}
.wide-accent b {
    color: #fff;
    font-weight: 600;
}
.dotted {
    text-decoration: underline dotted;
    text-decoration-color: #a1a1aa;
    text-decoration-thickness: 2px;
    text-underline-offset: 7px;
    color: #ededed;
}

/* Цитата из книги — одинаковая на всех слайдах, со ссылкой на раздел. */
.book-quote {
    border-left: 2px solid #3f3f46;
    padding: 4px 0 4px 22px;
    margin: 0;
    font-size: 18px;
    line-height: 1.6;
    color: #d4d4d8;
}
.book-quote cite {
    display: block;
    margin-top: 8px;
    font-style: normal;
    font-size: 14px;
    color: #71717a;
    font-family: var(--font-mono);
}

/* ===== Аккордеон (об авторе, вопросы преподавателя) ===== */
.acc {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.acc-item {
    border: 1px solid #232323;
    border-radius: 16px;
    background: #080808;
    transition: border-color 0.2s ease, background 0.2s ease;
}
.acc-item:hover {
    border-color: #3f3f46;
}
.acc-item.is-open {
    border-color: #3f3f46;
    background: #0a0a0a;
}
.acc-head {
    display: flex;
    align-items: center;
    gap: 16px;
    width: 100%;
    padding: 18px 24px;
    background: none;
    border: none;
    color: #ededed;
    font: inherit;
    font-size: 21px;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
}
.acc-mark {
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: 1px solid #3f3f46;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #71717a;
    transition: transform 0.3s ease, color 0.2s ease, border-color 0.2s ease;
}
.acc-mark svg {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    stroke-width: 2;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.acc-item.is-open .acc-mark {
    transform: rotate(180deg);
    color: #fff;
    border-color: #fff;
}
.acc-head b {
    flex: 1 1 auto;
    font-weight: 500;
}
/* Раскрытие без магических max-height: строка грида растёт с 0fr до 1fr. */
.acc-body {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}
.acc-item.is-open .acc-body {
    grid-template-rows: 1fr;
}
.acc-inner {
    overflow: hidden;
}
/* Всплывашки внутри раскрытого пункта иначе обрезались бы по его границе. */
.acc-item.is-done .acc-inner {
    overflow: visible;
}
.acc-body ul {
    margin: 0;
    padding: 0 28px 22px 70px;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.acc-body li {
    position: relative;
    font-size: 18px;
    line-height: 1.55;
    color: #a1a1aa;
}
.acc-body li::before {
    content: '';
    position: absolute;
    left: -22px;
    top: 13px;
    width: 8px;
    height: 1px;
    background: #52525b;
}
.acc-body li b,
.acc-body p b {
    color: #ededed;
    font-weight: 600;
}
.acc-body p {
    margin: 0;
    padding: 0 28px 22px 70px;
    font-size: 18px;
    line-height: 1.6;
    color: #a1a1aa;
}
/* Обложка слева на всю высоту блока, пункты справа. Высота задана явно:
   иначе колонка с текстом оказывалась ниже обложки, и contain ужимал её
   до трети размера. Ширина держит пропорции обложки (248×351). */
.acc-book {
    display: grid;
    grid-template-columns: 187px minmax(0, 1fr);
    gap: 30px;
    align-items: stretch;
    min-height: 264px;
    margin: 0 28px 22px 70px;
}
.acc-book img {
    width: 187px;
    height: 100%;
    object-fit: contain;
    border-radius: 10px;
}
.acc-book-text > p {
    margin: 0 0 16px;
    padding: 0;
    font-size: 18px;
    line-height: 1.6;
    color: #d4d4d8;
}
.acc-book-text > p b {
    color: #fff;
    font-weight: 600;
}
.acc-book-text > ul {
    padding: 0;
}

/* Всплывающее пояснение к термину: висит над ссылкой, показывается по наведению. */
.pop-host {
    position: relative;
}
.pop-link {
    color: #93c5fd;
    text-decoration: none;
    border-bottom: 1px dashed #3f3f46;
    transition: color 0.2s ease, border-color 0.2s ease;
}
.pop-link:hover {
    color: #fff;
    border-bottom-color: #fff;
}
.pop {
    position: absolute;
    bottom: calc(100% + 12px);
    left: -16px;
    width: 470px;
    padding: 14px 18px;
    border: 1px solid #3f3f46;
    border-radius: 14px;
    background: #0a0a0a;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.9);
    /* Носитель бывает моноширинным и с nowrap (метка версии) — во всплывашке
       и то и другое сбрасываем, иначе она вытягивалась в одну строку
       через весь слайд. */
    font-family: var(--font-sans);
    font-weight: 400;
    font-size: 16px;
    line-height: 1.5;
    color: #d4d4d8;
    white-space: normal;
    opacity: 0;
    visibility: hidden;
    transform: translateY(6px);
    transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
    z-index: 30;
}
.pop b {
    color: #fff;
    font-weight: 600;
}
.pop-host:hover .pop {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.acc-body .acc-quote {
    margin: 0 28px 22px 70px;
    padding: 2px 0 2px 18px;
    border-left: 2px solid #3f3f46;
    font-size: 17px;
    line-height: 1.55;
    color: #d4d4d8;
}
.acc-body .acc-quote cite {
    display: block;
    margin-top: 6px;
    font-style: normal;
    font-family: var(--font-mono);
    font-size: 13px;
    color: #71717a;
}

/* ===== Слайд «Об авторе» ===== */
.author-hero {
    display: grid;
    grid-template-columns: 340px minmax(0, 1fr);
    gap: 48px;
    align-items: start;
}
.author-hero .author-photo {
    width: 340px;
    height: 340px;
    border-radius: 24px;
    object-fit: cover;
    border: 1px solid #3f3f46;
    display: block;
}
.author-hero .author-name {
    margin: 22px 0 4px;
    font-size: 30px;
    font-weight: 600;
    color: #fff;
}
.author-hero .author-role {
    margin: 0 0 18px;
    font-size: 16px;
    line-height: 1.5;
    color: #71717a;
}
.author-hero .author-links {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.author-hero .author-links a {
    font-size: 15px;
    color: #a1a1aa;
    text-decoration: none;
    font-family: var(--font-mono);
    transition: color 0.2s ease;
}
.author-hero .author-links a:hover {
    color: #fff;
}

/* ===== Цитата автора: ящик выезжает снизу слайда ===== */
.quote-caller {
    position: absolute;
    bottom: 36px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    background: none;
    border: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
    z-index: 6;
}
.quote-caller-arrow {
    width: 22px;
    height: 22px;
    stroke: #fff;
    stroke-width: 2;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
    animation: callerArrow 1.6s ease-in-out infinite;
}
@keyframes callerArrow {
    0%, 100% { opacity: 0.25; transform: translateY(4px); }
    50% { opacity: 1; transform: translateY(-2px); }
}
.quote-caller img {
    width: 54px;
    height: 54px;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid #3f3f46;
    transition: border-color 0.2s ease, transform 0.2s ease;
}
.quote-caller:hover img {
    border-color: #fff;
    transform: scale(1.04);
}
.quote-drawer-inner > img {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid #3f3f46;
    flex-shrink: 0;
}
.quote-caller-name {
    font-size: 15px;
    color: #a1a1aa;
}
.quote-caller:hover .quote-caller-name {
    color: #fff;
}
.quote-drawer {
    position: absolute;
    /* Спрятан не только сдвигом: сцена масштабируется, и под ней остаётся
       свободное место — сдвинутый ящик было видно на узком экране. */
    visibility: hidden;
    left: 0;
    right: 0;
    bottom: 0;
    background: #0a0a0a;
    border-top: 1px solid #3f3f46;
    border-radius: 24px 24px 0 0;
    padding: 40px 100px 44px;
    box-shadow: 0 -24px 60px rgba(0, 0, 0, 0.9);
    transform: translateY(100%);
    transition: transform 0.45s cubic-bezier(0.16, 1, 0.3, 1), visibility 0.45s;
    z-index: 7;
}
.quote-drawer.open {
    transform: translateY(0);
    visibility: visible;
}
.quote-drawer-inner {
    display: flex;
    gap: 28px;
    align-items: flex-start;
    max-width: 1500px;
    margin: 0 auto;
}
.quote-drawer blockquote {
    margin: 0;
    font-size: 24px;
    line-height: 1.6;
    color: #ededed;
}
.quote-drawer cite {
    display: block;
    margin-top: 12px;
    font-style: normal;
    font-family: var(--font-mono);
    font-size: 14px;
    color: #71717a;
}
.quote-close {
    flex-shrink: 0;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 1px solid #333;
    background: #0a0a0a;
    color: #a1a1aa;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: color 0.2s ease, border-color 0.2s ease;
}
.quote-close:hover {
    color: #fff;
    border-color: #fff;
}

/* ===== Слайд «Виды приложений» ===== */
/* Две колонки: слева вид, которому посвящена книга, — ему и две трети ширины. */
.kinds {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 48px;
    align-items: start;
}
.kind.is-side {
    border-left: 1px solid #232323;
    padding-left: 48px;
}
.kind h3 {
    margin: 0 0 14px;
    font-size: 34px;
    font-weight: 600;
    line-height: 1.2;
    color: #a1a1aa;
}
.kind.is-main h3 {
    color: #fff;
}
.kind h3 em {
    display: block;
    margin-top: 6px;
    font-style: normal;
    font-family: var(--font-mono);
    font-size: 17px;
    letter-spacing: 0.02em;
    color: #52525b;
}
.kind .section-label {
    margin-bottom: 12px;
}
.kind-desc {
    margin: 0;
    font-size: 20px;
    line-height: 1.55;
    color: #a1a1aa;
}
.kind-desc b {
    color: #ededed;
    font-weight: 600;
}
/* Узкое место — то, во что упирается вид приложений. Красный блок внимания. */
.warn {
    margin-top: 22px;
    padding: 16px 22px;
    border: 1px solid #5f1e1e;
    border-left-width: 3px;
    border-radius: 0 14px 14px 0;
    background: rgba(248, 113, 113, 0.06);
}
.warn-label {
    display: block;
    margin-bottom: 8px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #f87171;
}
.warn p {
    margin: 0;
    font-size: 19px;
    line-height: 1.55;
    color: #d4d4d8;
}
.warn p b {
    color: #fff;
    font-weight: 600;
}

/* ===== Слайд «Спойлер»: главная мысль доклада =====
   Без карточек и рамок — только крупная типографика и волосяная линия
   между двумя мыслями. */
.ideas {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0 80px;
}
.idea + .idea {
    border-left: 1px solid #232323;
    padding-left: 80px;
}
.idea-num {
    display: block;
    font-family: var(--font-mono);
    font-size: 22px;
    letter-spacing: 0.12em;
    color: #3f3f46;
    margin-bottom: 18px;
}
.idea h3 {
    margin: 0 0 24px;
    font-size: 46px;
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.02em;
    color: #fff;
}
.idea p {
    margin: 0 0 16px;
    font-size: 21px;
    line-height: 1.55;
    color: #a1a1aa;
    max-width: 640px;
}
.idea p:last-child {
    margin-bottom: 0;
}
.idea b {
    color: #ededed;
    font-weight: 600;
}

/* ===== Слайд «Нет одного правильного инструмента»: круги категорий =====
   Сцена размечена в пикселях (доклад живёт на 1920×1080), круги двигает
   скрипт: он же считает середину пересечения для метки с версией. */
/* ===== Три категории инструментов: круги съезжаются в диаграмму Венна =====
   Слайд состоит из одной сцены на всю ширину. В исходном состоянии круги
   стоят раздельно и внутри каждого — список инструментов со ссылками
   и пояснением по наведению. Клик по слайду сводит круги: инструменты
   гаснут, а в зонах пересечений проявляются версии, которыми инструмент
   зашёл на соседнюю территорию. Координаты кругов и меток считает скрипт —
   в CSS только внешний вид и переходы. */
.venn-slide {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 26px;
}
.venn {
    position: relative;
    width: 1720px;
    height: 700px;
}
.venn-circle {
    position: absolute;
    width: 420px;
    height: 420px;
    border-radius: 50%;
    border: 1px solid;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    transition: left 0.75s cubic-bezier(0.16, 1, 0.3, 1), top 0.75s cubic-bezier(0.16, 1, 0.3, 1);
}
.venn-circle.c-db {
    border-color: rgba(96, 165, 250, 0.55);
    background: rgba(96, 165, 250, 0.08);
}
.venn-circle.c-cache {
    border-color: rgba(248, 113, 113, 0.55);
    background: rgba(248, 113, 113, 0.08);
}
.venn-circle.c-queue {
    border-color: rgba(251, 191, 36, 0.55);
    background: rgba(251, 191, 36, 0.08);
}
/* Подпись — над кругом. Когда круги сведены, нижним двум она мешала бы
   накладываться на верхний круг, поэтому уезжает под них. */
.venn-cap {
    position: absolute;
    top: -34px;
    left: 50%;
    transform: translateX(-50%);
    white-space: nowrap;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #a1a1aa;
    transition: top 0.75s cubic-bezier(0.16, 1, 0.3, 1);
}
.venn.is-tight .c-cache .venn-cap,
.venn.is-tight .c-queue .venn-cap {
    top: 440px;
}
.venn-tools {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    transition: opacity 0.4s ease, visibility 0.4s ease;
}
.venn.is-tight .venn-tools {
    opacity: 0;
    visibility: hidden;
}
/* Инструмент внутри круга: логотип, название-ссылка и пояснение по наведению. */
.tool {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 16px;
    border-radius: 9999px;
    border: 1px solid #3f3f46;
    background: #0a0a0a;
    text-decoration: none;
    color: #fff;
    font-size: 18px;
    font-weight: 600;
    transition: border-color 0.2s ease, transform 0.2s ease;
}
.tool:hover {
    border-color: #fff;
    transform: translateY(-1px);
}
/* Официальные логотипы лежат локально в assets/logos (см. комментарий
   в index.html). Логотип Kafka одноцветно-чёрный — на тёмном слайде его
   выворачиваем в белый. У Redis официальный знак — это шрифтовое
   начертание названия, поэтому подписи рядом с ним нет. Для инструментов
   без локального логотипа — монограмма. */
.tool-mark {
    width: 24px;
    height: 24px;
    object-fit: contain;
    flex-shrink: 0;
}
.tool-mono {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border: 1px solid #3f3f46;
    border-radius: 7px;
    background: #18181b;
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 600;
    color: #d4d4d8;
}
.tool .tool-go {
    font-size: 13px;
    color: #71717a;
}
/* Зона диаграммы: логотипы инструментов, которые эту роль закрывают.
   Появляются, когда круги сведены; что именно умеет инструмент — в подсказке
   по наведению на его знак. */
.zone {
    position: absolute;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 10px;
    border-radius: 9999px;
    border: 1px solid #52525b;
    background: #0a0a0a;
    transform: translate(-50%, -50%);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.45s ease, visibility 0.45s ease,
        left 0.75s cubic-bezier(0.16, 1, 0.3, 1), top 0.75s cubic-bezier(0.16, 1, 0.3, 1);
    z-index: 5;
}
.zone.is-all {
    border-color: #fff;
    background: #111;
}
.zone-item {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    cursor: help;
    transition: background 0.2s ease;
}
.zone-item:hover {
    background: #1c1c1c;
}
.zone-item img {
    width: 28px;
    height: 28px;
    object-fit: contain;
}
.venn.is-tight .zone {
    opacity: 1;
    visibility: visible;
    transition-delay: 0.5s, 0.5s, 0s, 0s;
}
.zone-item:hover > .pop {
    opacity: 1;
    visibility: visible;
}

/* Всплывашка по центру носителя — для меток и кружков, где сдвиг влево
   вывел бы её за край сцены. */
.pop.is-center {
    left: 50%;
    transform: translateX(-50%) translateY(6px);
}
.pop-host:hover .pop.is-center,
.zone-item:hover > .pop.is-center {
    transform: translateX(-50%) translateY(0);
}

/* Подсказка под сценой. */
.venn-hint {
    margin: 0;
    font-family: var(--font-mono);
    font-size: 14px;
    color: #52525b;
}

/* ===== Схема из книги (рис. 1.1): информационная система из компонентов =====
   Вся схема — один SVG на 1720×620: у неё десяток узлов и полтора десятка
   подписей вдоль стрелок, и раскладывать их вёрсткой пришлось бы вслепую.
   Здесь координаты заданы явно и повторяют рисунок книги. */
.fig {
    position: relative;
    width: 1720px;
    margin: 0 auto;
}
/* Накладка над подписью инструмента в SVG: сама невидима, нужна только
   как носитель всплывашки — в SVG-тексте её не подвесить. */
.svg-tip {
    position: absolute;
    height: 22px;
    transform: translate(-50%, -50%);
    border-bottom: 1px dashed #3f3f46;
    cursor: help;
    transition: border-color 0.2s ease;
}
.svg-tip:hover {
    border-bottom-color: #fff;
}
.svg-tip:hover .pop {
    opacity: 1;
    visibility: visible;
}
.svg-tip:hover .pop.is-center {
    transform: translateX(-50%) translateY(0);
}
.fig svg {
    display: block;
    width: 1720px;
    height: 620px;
}
.fig .s-box {
    fill: #0a0a0a;
    stroke: #3f3f46;
    stroke-width: 1.5;
}
.fig .s-fill {
    fill: #0a0a0a;
    stroke: none;
}
.fig .s-bound {
    fill: none;
    stroke: #3f3f46;
    stroke-width: 1.5;
    stroke-dasharray: 9 8;
}
.fig .s-line {
    fill: none;
    stroke: #52525b;
    stroke-width: 1.5;
}
.fig .s-thin {
    fill: none;
    stroke: #3f3f46;
    stroke-width: 1.5;
}
.fig .s-actor {
    fill: none;
    stroke: #a1a1aa;
    stroke-width: 1.6;
    stroke-linecap: round;
}
.fig .s-api {
    fill: #a1a1aa;
}
.fig text {
    font-family: var(--font-sans);
}
.fig .t-node {
    fill: #ededed;
    font-size: 17px;
    font-weight: 600;
}
.fig .t-tool {
    fill: #71717a;
    font-size: 12px;
    font-family: var(--font-mono);
}
.fig .t-edge {
    fill: #a1a1aa;
    font-size: 13px;
}
.fig .t-mini {
    fill: #71717a;
    font-size: 12px;
    letter-spacing: 0.08em;
}

/* ===== Схемы на фиксированной сцене (архитектура, рассинхрон) ===== */
.scene {
    position: relative;
    width: 1720px;
    margin: 0 auto;
}
.scene-wires {
    position: absolute;
    left: 0;
    top: 0;
}
.scene-wires path {
    stroke: #3f3f46;
    stroke-width: 2;
    fill: none;
}
.scene-wires text {
    fill: #52525b;
    font-family: var(--font-sans);
    font-size: 16px;
}
.node {
    position: absolute;
    border: 1px solid #232323;
    border-radius: 18px;
    background: #0a0a0a;
    padding: 16px 22px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 6px;
}
.node b {
    font-size: 26px;
    color: #fff;
    font-weight: 600;
}
.node span {
    font-size: 18px;
    line-height: 1.45;
    color: #a1a1aa;
}
.scene.is-big .node {
    padding: 20px 26px;
    gap: 10px;
}
.scene.is-big .node.is-hub b {
    font-size: 30px;
}
.node em {
    font-style: normal;
    font-family: var(--font-mono);
    font-size: 13px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #52525b;
}
.node.is-hub {
    border-color: #fff;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0));
}
.node.is-hub b { font-size: 26px; }
/* Цвет закреплён за ролью компонента и повторяется на всех схемах доклада. */
.node.c-db { border-color: #1e3a5f; }
.node.c-db b { color: #60a5fa; }
.node.c-cache { border-color: #5f1e1e; }
.node.c-cache b { color: #f87171; }
.node.c-search { border-color: #1e5f34; }
.node.c-search b { color: #4ade80; }
.node.c-queue { border-color: #5f4a1e; }
.node.c-queue b { color: #fbbf24; }

/* ===== Слайд «Компоненты нужно связать»: демонстрация рассинхрона ===== */
.sync-value {
    align-self: flex-start;
    font-family: var(--font-mono);
    font-size: 22px;
    color: #ededed;
    padding: 8px 16px;
    border-radius: 10px;
    background: #111;
    border: 1px solid #232323;
    transition: color 0.3s ease, border-color 0.3s ease;
}
.sync-value.is-fresh {
    color: #4ade80;
    border-color: #1e5f34;
}
.sync-value.is-stale {
    color: #f87171;
    border-color: #5f1e1e;
}
.sync-bar {
    display: flex;
    align-items: center;
    gap: 24px;
    margin-top: 24px;
}
.sync-btn {
    padding: 13px 26px;
    border-radius: 9999px;
    border: 1px solid #3f3f46;
    background: #0a0a0a;
    color: #ededed;
    font: inherit;
    font-size: 17px;
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease;
    flex-shrink: 0;
}
.sync-btn:hover {
    border-color: #fff;
    color: #fff;
}
.sync-hint {
    margin: 0;
    font-size: 18px;
    line-height: 1.5;
    color: #a1a1aa;
}
.sync-hint b {
    color: #ededed;
    font-weight: 600;
}

/* ===== Цепочка рассуждения: горизонтальная линия со звеньями =====
   Звенья стоят на одной линии и открываются кликом по слайду. Описание
   текущего звена — панель под линией с уголком, который скрипт двигает
   под активный узел: всплывашка у каждого звена уезжала бы за край слайда,
   а панель у края — нет. */
.road {
    display: flex;
    flex-direction: column;
}
.road-line {
    position: relative;
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 12px;
}
.road-track {
    position: absolute;
    top: 8px;
    left: 8.333%;
    right: 8.333%;
    height: 2px;
    background: #232323;
    border-radius: 2px;
}
.road-fill {
    display: block;
    width: 0;
    height: 100%;
    border-radius: 2px;
    background: linear-gradient(90deg, #3f3f46, #fff);
    transition: width 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}
.road-node {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 6px;
    padding-top: 34px;
    opacity: 0.25;
    transition: opacity 0.45s ease;
}
.road-node.is-on {
    opacity: 1;
}
.road-dot {
    position: absolute;
    top: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #0a0a0a;
    border: 2px solid #3f3f46;
    transform: translateX(-50%);
    left: 50%;
    margin-left: 0;
}
.road-node {
    position: relative;
}
.road-node.is-on .road-dot {
    border-color: #a1a1aa;
}
.road-node.is-now .road-dot {
    background: #fff;
    border-color: #fff;
}
.road-num {
    font-family: var(--font-mono);
    font-size: 13px;
    color: #52525b;
}
.road-node b {
    font-size: 20px;
    line-height: 1.3;
    font-weight: 600;
    color: #a1a1aa;
    transition: color 0.3s ease;
}
.road-node.is-now b {
    color: #fff;
}
.road-note {
    position: relative;
    margin-top: 34px;
    min-height: 100px;
    padding: 0 40px;
    font-size: 26px;
    line-height: 1.5;
    color: #a1a1aa;
    text-align: center;
}
.road-note b {
    color: #ededed;
    font-weight: 600;
}
.road-hint {
    margin: 16px 0 0;
    font-family: var(--font-mono);
    font-size: 14px;
    color: #52525b;
}

/* ===== Три свойства системы (надёжность, масштабируемость, сопровождение) ===== */
.props {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 28px;
    margin-top: 28px;
}
.prop {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 28px 32px;
    border: 1px solid #232323;
    border-radius: 18px;
    background: #080808;
}
.prop b {
    font-size: 27px;
    color: #fff;
    font-weight: 600;
}
.prop p {
    margin: 0;
    font-size: 18px;
    line-height: 1.55;
    color: #a1a1aa;
}
/* Низ карточки: раздел книги и спикер, который читает про него доклад. */
.prop-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px dashed #232323;
}
.prop-foot em {
    font-style: normal;
    font-family: var(--font-mono);
    font-size: 13px;
    color: #52525b;
}
.prop-speaker {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 12px 6px 6px;
    border: 1px solid #232323;
    border-radius: 9999px;
    background: #0a0a0a;
    text-decoration: none;
    color: #d4d4d8;
    font-size: 15px;
    transition: border-color 0.2s ease, color 0.2s ease;
}
.prop-speaker:hover {
    border-color: #fff;
    color: #fff;
}
.prop-speaker img {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    object-fit: cover;
}
.prop-go {
    font-size: 12px;
    color: #71717a;
}

/* ===== Итог: четыре карточки-вывода и главная мысль под ними =====
   Описание видно сразу, без наведения: на итоговом слайде докладчику
   некогда наводиться, а зрителю нужно увидеть всю цепочку целиком. */
.sums {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 30px;
}
.sum {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 22px 24px;
    border: 1px solid #232323;
    border-radius: 18px;
    background: #080808;
}
.sum::after {
    content: '→';
    position: absolute;
    top: 42px;
    right: -30px;
    width: 30px;
    text-align: center;
    color: #3f3f46;
    font-size: 20px;
}
.sum.is-last::after {
    content: '';
}
.sum.is-last {
    border-color: #3f3f46;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0));
}
.sum-num {
    font-family: var(--font-mono);
    font-size: 13px;
    color: #52525b;
}
.sum > b {
    font-size: 21px;
    line-height: 1.3;
    font-weight: 600;
    color: #fff;
}
.sum p {
    margin: 0;
    font-size: 16px;
    line-height: 1.5;
    color: #a1a1aa;
}
.sum p b {
    color: #ededed;
    font-weight: 600;
}

/* Главная мысль доклада: круглый портрет автора и крупная фраза —
   без рамок и вертикальных черт, чтобы она читалась как финальный титр. */
.verdict {
    display: grid;
    grid-template-columns: 132px minmax(0, 1fr);
    gap: 36px;
    align-items: center;
    margin: 40px 0 0;
    padding: 0;
}
.verdict img {
    width: 132px;
    height: 132px;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid #3f3f46;
}
.verdict-text {
    margin: 0;
    font-size: 40px;
    line-height: 1.25;
    letter-spacing: -0.02em;
    color: #52525b;
}
.verdict-text b {
    font-weight: 600;
    color: #fff;
    text-shadow: 0 0 40px rgba(255, 255, 255, 0.25);
}
.verdict cite {
    display: block;
    margin-top: 16px;
    font-style: normal;
    font-family: var(--font-mono);
    font-size: 14px;
    line-height: 1.5;
    color: #71717a;
}
