/* Шрифты лежат рядом со страницей: наружу она не ходит вовсе. */
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/manrope-700-cyrillic.95a493061fe0.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/manrope-700-latin.e310b55a7fd9.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: 'Manrope';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(fonts/manrope-800-cyrillic.95a493061fe0.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(fonts/manrope-800-latin.e310b55a7fd9.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: 'PT Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/pt-sans-400-cyrillic.9503de4dcabf.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/pt-sans-400-latin.5f81586551e5.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: 'PT Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/pt-sans-700-cyrillic.3259cd13d982.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/pt-sans-700-latin.38d3aa3b6c9c.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: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/jetbrains-mono-400-cyrillic.4995a9a43ac6.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/jetbrains-mono-400-latin.2c32b9b3ee35.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: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/jetbrains-mono-600-cyrillic.4995a9a43ac6.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/jetbrains-mono-600-latin.2c32b9b3ee35.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;
}
/* Отчёт «Активность по проектам» — стили страницы.
   Ни одного встроенного стиля в разметке: всё оформление живёт здесь, поэтому правила
   содержимого страницы (CSP) запрещают встроенные стили и сценарии целиком. */

/* ---- темы оформления ----
   Тем две, и они заведомо разные: песочная (цвета ПК:Форм) и тёмная. Песочная — по умолчанию.
   Прежней «светлой» и отдельной кнопки «как в системе» нет намеренно: светлая почти не
   отличалась от песочной по назначению, а «как в системе» на светлом устройстве давала ровно
   тот же вид, что и светлая, — две кнопки с одинаковым результатом.

   Значения каждой палитры объявлены ровно ОДИН раз (наборы --sand-*, --d-*), а темы только
   присваивают их рабочим именам: иначе одна и та же палитра жила бы в двух местах и однажды
   они бы разошлись. */
:root{
  /* тёмная */
  --d-bg:#0d0f15; --d-paper:#161922; --d-ink:#e7e9f0; --d-dim:#8a90a6; --d-line:#262b38;
  --d-accent:#7c93ff; --d-soft:#1c2340; --d-accent-ink:#7c93ff;
  --d-shadow: 0 1px 2px rgba(0,0,0,.35), 0 14px 34px -18px rgba(0,0,0,.6);
  --d-p1:#7c93ff; --d-p1-rgb:124,147,255;
  --d-p2:#4fc9bd; --d-p2-rgb:79,201,189;
  --d-p3:#a793ff; --d-p3-rgb:167,147,255;
  --d-p4:#d9a94a; --d-p4-rgb:217,169,74;
  --d-alarm:#ff4a33; --d-alarm-rgb:255,74,51;      /* перегруз: красный по тёмному фону */

  /* песочная — цвета ПК:Форм, оформление «editorial», включённое в самом приложении по умолчанию
     (`<html data-skin="editorial">` в его разметке): тёплый бежевый фон, белые карточки,
     песочные границы, золотой акцент. Тёмного варианта у него там нет, поэтому и здесь
     эта тема всегда светлая. Линии графиков подобраны к бежевому фону. */
  --sand-bg:#f3efe8; --sand-paper:#ffffff; --sand-ink:#1f1f1f; --sand-dim:#6f6350; --sand-line:#d9cfbf;
  --sand-accent:#ba9258; --sand-soft:#e8e0d2;
  /* Золото хорошо как заливка, но как текст по бежевому даёт 2,5:1 — для надписей
     и следа фокуса берётся тёмный вариант того же цвета: 5,4:1 на фоне. */
  --sand-accent-ink:#7a5c28;
  --sand-shadow: 0 1px 2px rgba(50,40,25,.06), 0 10px 28px -16px rgba(50,40,25,.20);
  --sand-p1:#3f5f7a; --sand-p1-rgb:63,95,122;      /* глубокий сине-серый */
  --sand-p2:#6b7a3a; --sand-p2-rgb:107,122,58;     /* олива */
  --sand-p3:#7a4a6b; --sand-p3-rgb:122,74,107;     /* сливовый */
  --sand-p4:#ba9258; --sand-p4-rgb:186,146,88;     /* золото */
  --sand-alarm:#e01b0c; --sand-alarm-rgb:224,27,12; /* перегруз: красный по бежевому фону */

  /* Действующая тема по умолчанию — песочная. Настройка устройства её не отменяет:
     так решил Хозяин, и это единственный способ, чтобы «по умолчанию песочная» значило
     ровно то, что сказано, а не «песочная, если у тебя светлая система». */
  color-scheme: light;
  --bg:var(--sand-bg); --paper:var(--sand-paper); --ink:var(--sand-ink); --dim:var(--sand-dim);
  --line:var(--sand-line); --accent:var(--sand-accent); --soft:var(--sand-soft);
  --accent-ink:var(--sand-accent-ink); --shadow:var(--sand-shadow);
  --p1:var(--sand-p1); --p1-rgb:var(--sand-p1-rgb);
  --p2:var(--sand-p2); --p2-rgb:var(--sand-p2-rgb);
  --p3:var(--sand-p3); --p3-rgb:var(--sand-p3-rgb);
  --p4:var(--sand-p4); --p4-rgb:var(--sand-p4-rgb);
  --alarm:var(--sand-alarm); --alarm-rgb:var(--sand-alarm-rgb);
}

/* Песочная, выбранная руками: то же самое, что по умолчанию. Нужна отдельным правилом,
   чтобы человек мог вернуться к ней после тёмной — тогда в хранилище ляжет явный выбор. */
:root[data-skin="sand"]{
  color-scheme: light;
  --bg:var(--sand-bg); --paper:var(--sand-paper); --ink:var(--sand-ink); --dim:var(--sand-dim);
  --line:var(--sand-line); --accent:var(--sand-accent); --soft:var(--sand-soft);
  --accent-ink:var(--sand-accent-ink); --shadow:var(--sand-shadow);
  --p1:var(--sand-p1); --p1-rgb:var(--sand-p1-rgb);
  --p2:var(--sand-p2); --p2-rgb:var(--sand-p2-rgb);
  --p3:var(--sand-p3); --p3-rgb:var(--sand-p3-rgb);
  --p4:var(--sand-p4); --p4-rgb:var(--sand-p4-rgb);
  --alarm:var(--sand-alarm); --alarm-rgb:var(--sand-alarm-rgb);
}

:root[data-skin="dark"]{
  color-scheme: dark;
  --bg:var(--d-bg); --paper:var(--d-paper); --ink:var(--d-ink); --dim:var(--d-dim);
  --line:var(--d-line); --accent:var(--d-accent); --soft:var(--d-soft);
  --accent-ink:var(--d-accent-ink); --shadow:var(--d-shadow);
  --p1:var(--d-p1); --p1-rgb:var(--d-p1-rgb);
  --p2:var(--d-p2); --p2-rgb:var(--d-p2-rgb);
  --p3:var(--d-p3); --p3-rgb:var(--d-p3-rgb);
  --p4:var(--d-p4); --p4-rgb:var(--d-p4-rgb);
  --alarm:var(--d-alarm); --alarm-rgb:var(--d-alarm-rgb);
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0; background:var(--bg); color:var(--ink);
     font:16px/1.55 "PT Sans","Helvetica Neue",Arial,sans-serif;}
/* Резиновая раскладка: ширина следует за окном, а не задана числом. Верхняя граница нужна,
   чтобы на очень широком мониторе строки текста не растягивались на весь экран. */
.wrap{width:100%; max-width:min(1600px, 96vw); margin:0 auto;
      padding:clamp(20px, 3vw, 44px) clamp(10px, 2vw, 22px) 90px;}
.tabular{font-variant-numeric:tabular-nums; font-family:"JetBrains Mono","SF Mono",ui-monospace,monospace;}

/* ---- цвета проектов, единый источник ---- */
.c-qrci{--c:var(--p1); --rgb:var(--p1-rgb)}
.c-pkforms{--c:var(--p2); --rgb:var(--p2-rgb)}
.c-dms{--c:var(--p3); --rgb:var(--p3-rgb)}
.c-shareholder{--c:var(--p4); --rgb:var(--p4-rgb)}
.swatch{width:10px; height:10px; border-radius:3px; display:inline-block; background:var(--c); flex:none;}

/* Предупреждение о том, что страница не отрисовалась. Видно ровно до тех пор, пока сценарий
   не снимет его сам: если он не выполнился, человек увидит причину, а не пустые разделы. */
.broken{background:var(--soft); border:1px solid var(--line); border-radius:12px;
        padding:14px 16px; margin:0 0 22px; font-size:14px; color:var(--ink);}

/* ---- переключатель темы ---- */
.topline{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
         gap:12px; margin-bottom:10px;}
.skins{display:inline-flex; gap:4px; background:var(--paper); border:1px solid var(--line);
       border-radius:10px; padding:3px;}
.skins button{font:inherit; font-family:"PT Sans",sans-serif; font-size:12.5px; border:none;
       background:transparent; color:var(--dim); padding:5px 11px; border-radius:7px; cursor:pointer;}
.skins button:hover{color:var(--ink)}
.skins button:focus-visible{outline:2px solid var(--accent-ink); outline-offset:2px}
.skins button[aria-pressed="true"]{background:var(--soft); color:var(--ink); font-weight:700}

/* ---- шапка ---- */
.eyebrow{font-family:"JetBrains Mono",ui-monospace,monospace; font-size:12px; letter-spacing:.08em;
         text-transform:uppercase; color:var(--accent-ink); font-weight:600; margin:0 0 10px;}
h1{font-family:"Manrope",sans-serif; font-weight:800; font-size:clamp(27px,4vw,38px); line-height:1.1;
   letter-spacing:-.01em; margin:0 0 12px; text-wrap:balance;}
.dek{color:var(--dim); max-width:66ch; margin:0 0 10px;}
.dek b{color:var(--ink)}
.source{color:var(--dim); font-size:12.5px; margin:0 0 30px;}

h2{font-family:"Manrope",sans-serif; font-weight:700; font-size:20px; margin:0 0 6px;}
.verdict{color:var(--dim); font-size:14px; margin:0 0 18px; max-width:64ch;}

/* ---- сводные числа ---- */
.totals{display:grid; grid-template-columns:repeat(4, 1fr); gap:14px; margin:0 0 30px;}
@media (max-width:760px){.totals{grid-template-columns:repeat(2, 1fr)}}
.tile{background:var(--paper); border:1px solid var(--line); border-radius:14px;
      padding:16px 18px; box-shadow:var(--shadow);}
.tile b{display:block; font-family:"Manrope",sans-serif; font-weight:800; font-size:26px;
        line-height:1.1; letter-spacing:-.01em; font-variant-numeric:tabular-nums;}
.tile span{display:block; color:var(--dim); font-size:12.5px; margin-top:6px;}

section.candidate{background:var(--paper); border:1px solid var(--line); border-radius:14px;
                  padding:22px 22px 24px; box-shadow:var(--shadow); margin-bottom:32px;}

.legend{display:flex; flex-wrap:wrap; gap:14px; margin:0 0 26px; font-size:13px; color:var(--dim);}
.legend span{display:inline-flex; align-items:center; gap:7px;}

/* ---- A: спарклайны ---- */
.spark-head, .spark-row{display:grid; grid-template-columns:minmax(120px,150px) 1fr 1fr; gap:16px;}
.spark-head{font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--dim);
            padding-bottom:10px; border-bottom:1px solid var(--line); margin-bottom:4px;}
.spark-row{align-items:center; padding:13px 0; border-top:1px solid var(--line);}
.spark-row:first-child{border-top:none}
.spark-name{display:flex; align-items:center; gap:9px; font-family:"Manrope",sans-serif;
            font-weight:700; font-size:14px;}
.spark-metric{display:flex; align-items:center; gap:clamp(6px, 1vw, 12px); min-width:0;}
/* График тянется за шириной колонки, а не держит своё число точек: иначе он распирает ряд. */
.spark-metric svg{flex:1 1 80px; min-width:0; width:auto; height:44px; overflow:visible;}
.spark-latest{flex:none}
.spark-metric .line{fill:none; stroke:var(--c); stroke-width:2; stroke-linejoin:round; stroke-linecap:round;}
.spark-metric .dot{fill:var(--c)}
.spark-metric .area{stroke:none}
.spark-metric stop.a{stop-color:var(--c); stop-opacity:.28}
.spark-metric stop.b{stop-color:var(--c); stop-opacity:0}
.spark-latest b{font-size:16.5px; display:block; line-height:1.15;}
.spark-latest span{color:var(--dim); font-size:11px; text-transform:uppercase; letter-spacing:.04em;}
/* Подпись величины нужна только там, где шапка колонок не помещается. */
.metric-label{display:none; font-size:11px; text-transform:uppercase; letter-spacing:.04em;
              color:var(--dim); flex-basis:100%;}

@media (max-width:760px){
  .spark-head{display:none}
  .spark-row{grid-template-columns:1fr; gap:10px; padding:16px 0}
  .spark-metric{flex-wrap:wrap; gap:8px 12px}
  .spark-metric svg{width:auto; flex:1 1 140px; min-width:0}
  .metric-label{display:block}
}

/* ---- B: тепловая карта ---- */
.toggle{display:inline-flex; gap:4px; background:var(--bg); border:1px solid var(--line);
        border-radius:10px; padding:3px; margin-bottom:16px;}
.toggle button{font:inherit; font-family:"PT Sans",sans-serif; font-size:13.5px; border:none;
        background:transparent; color:var(--dim); padding:6px 14px; border-radius:7px; cursor:pointer;}
.toggle button:focus-visible{outline:2px solid var(--accent-ink); outline-offset:2px}
.toggle button[aria-pressed="true"]{background:var(--paper); color:var(--ink); font-weight:700;
        box-shadow:var(--shadow);}
/* Тепловая карта тоже резиновая: доли ширины и размеры от окна, поэтому прокрутка не нужна. */
table.heat{border-collapse:collapse; width:100%; table-layout:fixed}
table.heat th{color:var(--dim); text-transform:uppercase; letter-spacing:.04em; font-weight:600;
        text-align:center; font-size:clamp(8.5px, 0.9vw, 11px); padding:0 2px 8px;}
table.heat th.proj{text-align:left; padding-left:2px; width:19%}
table.heat td{padding:0; text-align:center}
table.heat .projcell{text-align:left; text-transform:none; letter-spacing:0; font-family:"Manrope",sans-serif; font-weight:700;
        font-size:clamp(10px, 1.05vw, 13px); padding-right:clamp(4px, 1vw, 14px);
        overflow-wrap:break-word; line-height:1.25;}
.hcell{display:flex; align-items:center; justify-content:center; border-radius:8px;
       height:clamp(30px, 3.4vw, 40px); margin:clamp(1.5px, 0.3vw, 3px);
       font-size:clamp(8px, 0.95vw, 12px); background:rgba(var(--rgb), var(--a, 0));}
.m-commits{--rgb:var(--p1-rgb)}
.m-lines{--rgb:var(--p2-rgb)}
.m-tokens{--rgb:var(--p3-rgb)}
/* Насыщенность заливки доведена до 0,50, а не до 0,92: дальше надпись обычным цветом
   перестаёт проходить норму читаемости (посчитано по WCAG для всех четырёх цветов в
   обеих темах, худший случай — 4,5:1 при 0,51). Раньше здесь надпись переключалась на
   белую с шестой ступени, где заливка ещё светлая, и семь клеток из девяти читались
   как 2,3-2,9:1 — то есть не читались вовсе. Отдельный цвет надписи больше не нужен. */
.h0{--a:0}.h1{--a:.05}.h2{--a:.10}.h3{--a:.15}.h4{--a:.20}.h5{--a:.25}
.h6{--a:.30}.h7{--a:.35}.h8{--a:.40}.h9{--a:.45}.h10{--a:.50}
/* Верхние ступени дополнительно выделены начертанием, а не цветом. */
.hcell.top{font-weight:700}
/* «Нет данных» — не ноль: клетка остаётся пустой по цвету и подписана точкой. */
.hcell.nodata{color:var(--dim); opacity:.65}
/* Незавершённая неделя: столбец в карте и последняя колонка таблицы помечены штриховкой,
   иначе неполная неделя сравнивается с полными как равная. */
.week-open{position:relative}
.week-open::after{content:""; position:absolute; inset:0; pointer-events:none; border-radius:6px;
  background:repeating-linear-gradient(135deg, transparent 0 5px, rgba(127,127,127,.14) 5px 10px);}

/* ---- C: линии ---- */
.linegrid{display:grid; grid-template-columns:1fr 1fr; gap:22px}
@media (max-width:680px){.linegrid{grid-template-columns:1fr}}
.linecard h3{font-family:"Manrope",sans-serif; font-size:12.5px; font-weight:700; margin:0 0 10px;
        color:var(--dim); text-transform:uppercase; letter-spacing:.04em;}
.linecard svg{width:100%; height:auto; overflow:visible}
.axislabel{font-family:"JetBrains Mono",ui-monospace,monospace; font-size:10px; fill:var(--dim)}
.grid-line{stroke:var(--line); stroke-width:1}
.series{fill:none; stroke:var(--c); stroke-width:2.2; stroke-linejoin:round; stroke-linecap:round}
.series-dot{fill:var(--c)}

/* ---- D: таблица с полосами ----
   Правки и токены — в своих колонках, как и было. Ширина колонок задана долями, размеры
   букв и отступов считаются от ширины окна, поэтому таблица укладывается в страницу на любом
   экране и прокрутка не нужна вовсе. */
table.bartable{border-collapse:collapse; width:100%; table-layout:fixed;
        font-size:clamp(8px, 1.05vw, 13px);}
/* Длинное название обязано переноситься внутри своей колонки: иначе оно вылезает на соседнюю
   и наезжает на её заголовок. */
table.bartable th{color:var(--dim); font-weight:600; text-align:left; white-space:normal;
        overflow-wrap:break-word; line-height:1.25; vertical-align:bottom;
        font-size:clamp(9px, 0.95vw, 11px); padding:0 clamp(2px, 0.5vw, 8px) 6px;}
table.bartable th.proj{text-transform:uppercase; letter-spacing:.04em}
table.bartable th.sub{font-weight:400; text-transform:none; letter-spacing:0; padding-bottom:9px;
        font-size:clamp(8.5px, 0.8vw, 10px);}
table.bartable td{border-top:1px solid var(--line); padding:clamp(3px, 0.6vw, 7px) clamp(1px, 0.5vw, 8px);}
table.bartable col.week{width:11%}
table.bartable .wk{text-transform:none; letter-spacing:0; font-family:"JetBrains Mono",ui-monospace,monospace; font-weight:600;
        color:var(--dim); white-space:nowrap; font-size:clamp(8px, 0.95vw, 12.5px);}
.wk-short{display:none}
.barcell{position:relative}
.barcell .fill{position:absolute; top:3px; bottom:3px; left:0; border-radius:4px; z-index:0;
        background:rgba(var(--rgb), .10); width:calc(var(--w, 0) * 1%);}
.barcell .num{position:relative; z-index:1; font-family:"JetBrains Mono",ui-monospace,monospace;
        padding-left:clamp(1px, 0.4vw, 6px); white-space:nowrap;}
.barcell.tokens .num{color:var(--dim)}

/* На узком экране полные названия столбцов не помещаются: прописные буквы шире строчных,
   а длинное слово рвётся по слогам. Там показываются короткие написания. */
@media (max-width:620px){
  table.bartable th.proj{text-transform:none; letter-spacing:0}
  .wk-full{display:none}
  .wk-short{display:inline}
}
.w0{--w:0}.w5{--w:5}.w10{--w:10}.w15{--w:15}.w20{--w:20}.w25{--w:25}.w30{--w:30}.w35{--w:35}
.w40{--w:40}.w45{--w:45}.w50{--w:50}.w55{--w:55}.w60{--w:60}.w65{--w:65}.w70{--w:70}.w75{--w:75}
.w80{--w:80}.w85{--w:85}.w90{--w:90}.w95{--w:95}.w100{--w:100}

/* ---- вывод и подвал ---- */
.pick{background:var(--soft); border:1px solid var(--line); border-radius:14px; padding:22px 24px}
.pick .eyebrow{color:var(--ink); opacity:.6}
.pick p{margin:0 0 10px; max-width:66ch}
.pick p:last-child{margin-bottom:0}
footer{margin-top:34px; padding-top:18px; border-top:1px solid var(--line); color:var(--dim);
       font-size:12.5px; line-height:1.7;}

@media (prefers-reduced-motion: reduce){
  *{animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important}
}

/* ---- страница разбора по источникам ---- */
.topline-right{display:flex; flex-wrap:wrap; align-items:center; gap:12px}
.backlink{margin:0; font-size:13.5px}
.backlink a{color:var(--accent-ink); text-decoration:none; border-bottom:1px solid var(--line)}
.backlink a:hover{border-bottom-color:var(--accent-ink)}
.fixed{background:var(--soft); border:1px solid var(--line); border-radius:14px;
       padding:18px 20px; margin:0 0 34px}
.fixed h2{margin:0 0 10px}
.fixed ul{margin:0; padding-left:20px}
.fixed li{margin-bottom:8px; font-size:14.5px}
.fixed li:last-child{margin-bottom:0}
.cards{display:grid; grid-template-columns:repeat(auto-fit, minmax(300px, 1fr)); gap:16px;
       margin-bottom:34px}
.rec{background:var(--paper); border:1px solid var(--line); border-radius:14px;
     padding:16px 18px; box-shadow:var(--shadow); display:flex; flex-direction:column; gap:8px}
.rec h3{margin:0; font-family:"Manrope",sans-serif; font-size:15.5px; font-weight:700; line-height:1.3}
.rec p{margin:0; font-size:13.5px}
.rec .why{color:var(--ink)}
.rec .data{color:var(--dim)}
.rec .src{margin-top:auto; padding-top:8px; border-top:1px solid var(--line);
          font-size:12.5px; color:var(--dim); display:flex; flex-wrap:wrap; gap:8px; align-items:baseline}
.rec .src a{color:var(--accent-ink); text-decoration:none; border-bottom:1px solid var(--line)}
.rec .effort{font-family:"JetBrains Mono",ui-monospace,monospace; font-size:11px;
             text-transform:uppercase; letter-spacing:.04em; background:var(--soft);
             border-radius:100px; padding:2px 9px; color:var(--ink)}
.rec .date{font-family:"JetBrains Mono",ui-monospace,monospace; font-size:11px}

/* ---- страница-образец: все улучшения сразу ---- */
.sub-h{font-family:"Manrope",sans-serif; font-size:12.5px; font-weight:700; margin:18px 0 10px;
       color:var(--dim); text-transform:uppercase; letter-spacing:.04em}
.tile .delta{display:block; margin-top:6px; font-size:12.5px; font-weight:700}
.tile .delta.up{color:var(--p2)}
.tile .delta.down{color:var(--p4)}
.tile .note{display:block; margin-top:6px; font-size:12px; color:var(--dim); line-height:1.35}

/* спарклайны образца: подписи краёв и пунктир незакрытой недели */
#d-sparks .spark-metric svg{width:100%; max-width:260px; height:46px}
#d-sparks .line{fill:none; stroke:var(--c); stroke-width:2; stroke-linejoin:round; stroke-linecap:round}
#d-sparks .line.open{stroke-dasharray:3 3}
#d-sparks .dot{fill:var(--c)}
#d-sparks .edge{font-family:"JetBrains Mono",ui-monospace,monospace; font-size:9px; fill:var(--dim)}

/* карта ступенями */
table.heat-bins{border-collapse:collapse; width:100%; table-layout:fixed;
                font-size:clamp(9px, 1vw, 12px)}
table.heat-bins th{color:var(--dim); font-weight:600; text-align:center; padding:0 2px 8px;
                   font-size:clamp(8.5px, .9vw, 11px)}
table.heat-bins th.proj{text-align:left; width:19%; text-transform:none}
table.heat-bins td{padding:0; text-align:center}
table.heat-bins .projcell{text-align:left; font-family:"Manrope",sans-serif; font-weight:700;
                          font-size:clamp(10px, 1vw, 13px); padding-right:8px}
.bin{display:flex; align-items:center; justify-content:center; height:clamp(28px,3.2vw,38px);
     margin:2px; border-radius:7px; background:rgba(var(--fill, var(--p1-rgb)), var(--a,0));
     color:var(--ink)}
.bin.b0{--a:0; color:var(--dim)}
.bin.b1{--a:.12}
.bin.b2{--a:.24}
.bin.b3{--a:.36}
.bin.b4{--a:.48}
/* Тяжёлая неделя красится красным теми же ступенями: карта нарочно ступенчатая, плавную
   заливку глаз не сравнивает. Ступени стоят ПОСЛЕ синих: вес правил одинаковый, и при
   обратном порядке синяя плотность перебивала красную — поймано глазами 08.09.2026.
   Верхняя ступень не гуще 0,62: посчитан контраст надписи с залитой клеткой в обеих темах —
   на 0,80 он падает до 4,2 и 3,9, то есть ниже порога читаемости, а на 0,62 держится 5,6 и
   5,4 (нашёл дипсик). Цвет надписи не подменяется белым по той же причине: в песочной теме
   белым по красному выходит 2,9. */
.bin.h1{--fill:var(--alarm-rgb); --a:.16}
.bin.h2{--fill:var(--alarm-rgb); --a:.27}
.bin.h3{--fill:var(--alarm-rgb); --a:.38}
.bin.h4{--fill:var(--alarm-rgb); --a:.50}
.bin.h5{--fill:var(--alarm-rgb); --a:.62}
.bins-legend{display:flex; align-items:center; gap:6px; margin-top:10px; font-size:11.5px; color:var(--dim)}
.bins-legend i{width:28px; height:14px; border-radius:4px; background:rgba(var(--p1-rgb), var(--a,0));
               border:1px solid var(--line)}
.bins-legend .cap{margin:0 4px}

/* линии образца */
#d-line-commits svg, #d-line-tokens svg, #d-indexed svg{width:100%; height:auto; overflow:visible}
/* Приведённый график стоит один, а не в паре, и без ограничения растягивался вдвое шире
   соседних: подписи внутри рисунка растут вместе с ним и выбивались из общего масштаба. */
#d-indexed{max-width:640px}
.trend{fill:none; stroke:var(--c); stroke-width:1.5; stroke-dasharray:5 4; opacity:.55}

/* Перегруз красит саму линию: поверх линии проекта лежит её красная копия, плотность которой
   ведёт градиент по неделям — от нуля у обычных до полной у перегруженных. Цвет красного
   живёт здесь, в стилях; плотность каждой ступени задаётся свойством самой картинки
   (stop-opacity), потому что встроенные стили запрещены правилами содержимого страницы.
   Ширина красной копии чуть больше линии проекта — иначе по краям остаётся её кайма. */
.heatstop{stop-color:var(--alarm)}
/* У .hotline нарочно НЕ задан stroke: цвет ей приходит свойством самой картинки —
   stroke="url(#…)" на градиент. Пропишешь stroke здесь — стиль перебьёт свойство
   картинки (в SVG стиль всегда сильнее), и красная копия станет одноцветной. */
.hotline{fill:none; stroke-width:3.2; stroke-linejoin:round; stroke-linecap:round}
.hotline.open{stroke-dasharray:4 4}
#d-sparks .hotline{stroke-width:2.8}
#d-sparks .hotline.open{stroke-dasharray:3 3}
.series.open{stroke-dasharray:4 4}
.endlabel{font-family:"PT Sans",sans-serif; font-size:11px; fill:var(--c); font-weight:700}
.endlead{fill:none; stroke:var(--c); stroke-width:1; opacity:.45}
.grid-line.base{stroke:var(--dim); stroke-dasharray:2 3}

/* назначение правок */
.kind-row{padding:14px 0; border-top:1px solid var(--line)}
.kind-row:first-child{border-top:none}
.kind-head{display:flex; flex-wrap:wrap; gap:10px; align-items:baseline; margin-bottom:8px}
.kind-head b{font-family:"Manrope",sans-serif; font-size:14.5px}
.kind-head span{color:var(--dim); font-size:12.5px}
.kind-bar{display:flex; height:16px; border-radius:6px; overflow:hidden; background:var(--soft)}
.kind-bar .seg{height:100%; width:calc(var(--w,0) * 1%)}
.seg.k-0{background:var(--p4)}
.seg.k-1{background:var(--p1)}
.seg.k-2{background:var(--p2)}
.seg.k-3{background:var(--p3)}
.seg.k-4{background:var(--dim); opacity:.75}
.seg.k-5{background:var(--line)}
.seg.k-6{background:var(--line); opacity:.6}
.kind-legend{display:flex; flex-wrap:wrap; gap:12px; margin-top:8px; font-size:12px; color:var(--dim)}
.kind-legend span::before{content:""; display:inline-block; width:9px; height:9px; border-radius:2px;
                          margin-right:5px; vertical-align:middle}
.kind-legend .k-0::before{background:var(--p4)}
.kind-legend .k-1::before{background:var(--p1)}
.kind-legend .k-2::before{background:var(--p2)}
.kind-legend .k-3::before{background:var(--p3)}
.kind-legend .k-4::before{background:var(--dim)}
.kind-legend .k-5::before{background:var(--line)}
.kind-legend .k-6::before{background:var(--line)}

/* таблица качества */
/* Шесть колонок с числами на телефон не влезают, а прятать их за прокруткой всей страницы
   нельзя: у таблицы своя прокрутка, и она подписана для чтения с экрана. */
#d-quality{overflow-x:auto}
/* Широкая таблица прокручивается сама, а не тянет вбок всю страницу; у каждой такой обёртки
   подписана роль, чтобы прокрутку нашли и с клавиатуры, и чтением с экрана. */
.scrollx, .barwrap{overflow-x:auto}
/* Расход в клетке пишется словами («1,2 млрд»), и на телефоне такой строке нужна своя ширина —
   иначе цифры налезают на соседние клетки. */
table.heat-bins.m-tokens{min-width:540px}
.bin.nodata{color:var(--dim); font-weight:400}
table.quality{border-collapse:collapse; width:100%; min-width:520px;
              font-size:clamp(11px,1.05vw,13.5px)}
table.quality th{text-align:left; color:var(--dim); font-weight:600; font-size:11px;
                 text-transform:uppercase; letter-spacing:.04em; padding:0 8px 9px}
table.quality td{padding:8px; border-top:1px solid var(--line); white-space:nowrap}
table.quality .projcell{display:flex; align-items:center; gap:8px; font-family:"Manrope",sans-serif;
                        font-weight:700; text-align:left; padding:8px; border-top:1px solid var(--line);
                        text-transform:none; letter-spacing:0; font-size:13px}

/* расход */
.spend{display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px}
.spend-item{background:var(--soft); border-radius:12px; padding:14px 16px}
.spend-item b{display:block; font-family:"Manrope",sans-serif; font-size:20px; font-weight:800}
.spend-item span{display:block; color:var(--dim); font-size:12.5px; margin-top:4px}
.models{display:flex; flex-direction:column; gap:6px}
.model-item{display:flex; gap:12px; align-items:baseline; padding:7px 10px; border-radius:8px;
            background:var(--soft); font-size:13px}
.model-item code{font-family:"JetBrains Mono",ui-monospace,monospace; font-size:12px; flex:1}
.model-item b{font-family:"Manrope",sans-serif}
.model-item span{color:var(--dim); font-size:12px; min-width:44px; text-align:right}

/* очаги правок */
.hot-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:14px}
.hot-card{background:var(--soft); border-radius:12px; padding:14px 16px}
.hot-card h3{margin:0 0 10px; font-family:"Manrope",sans-serif; font-size:14px; display:flex;
             align-items:center; gap:8px}
.hot-card ul{margin:0; padding:0; list-style:none}
.hot-card li{display:flex; justify-content:space-between; gap:10px; padding:5px 0;
             border-top:1px solid var(--line); font-size:12.5px}
.hot-card li:first-child{border-top:none}
.hot-card code{font-family:"JetBrains Mono",ui-monospace,monospace; font-size:11.5px;
               overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.hot-card span{color:var(--dim); white-space:nowrap}

/* строка текущей недели в таблице */
tr.week-open-row td, tr.week-open-row th{background:repeating-linear-gradient(135deg,
  transparent 0 6px, rgba(127,127,127,.10) 6px 12px)}
.bartable td.dim{color:var(--dim)}

/* словесная расшифровка */
.words p{margin:0 0 12px; font-size:14px; max-width:78ch}
.words p:last-child{margin-bottom:0}

/* ---- выжимка «что сделано» ---- */
/* Темы правок длинные и чужие: строка рвётся по словам, а слово-путь — по знакам, поэтому
   горизонтальной прокрутки у раздела не бывает и на телефоне. */
.chg-period{border-top:1px solid var(--line); padding:10px 0;}
.chg-period:first-of-type{border-top:0}
.chg-period > summary{cursor:pointer; font-weight:700; overflow-wrap:anywhere;}
.chg-row{margin:14px 0 6px; padding-left:12px; border-left:3px solid var(--c);}
.chg-head{display:flex; flex-wrap:wrap; align-items:center; gap:4px 10px; min-width:0; overflow-wrap:anywhere;}
.chg-counts{color:var(--dim); font-size:14px;}
.chg-src{color:var(--dim); font-size:12.5px; flex-basis:100%;}
.chg-row h4{margin:10px 0 4px; font-size:13px; text-transform:uppercase; letter-spacing:.04em; color:var(--dim);}
.chg-list{list-style:none; margin:0; padding:0;}
.chg-list li{display:grid; grid-template-columns:auto 1fr; gap:2px 10px; padding:4px 0; min-width:0;}
.chg-id{white-space:nowrap; font-size:12.5px; color:var(--dim); padding-top:2px;}
.chg-body{min-width:0; overflow-wrap:anywhere;}
.chg-sub{display:block; color:var(--ink);}
.chg-tail{display:block; color:var(--dim); font-size:12px;}
.chg-flag{display:inline-block; margin-left:8px; font-style:normal; font-size:12px;
          padding:0 6px; border:1px solid var(--line); border-radius:6px; color:var(--dim);}
.chg-more{margin-top:8px;}
.chg-more > summary{cursor:pointer; color:var(--dim); font-size:14px;}
.chg-note{color:var(--dim); font-size:13px;}
@media (max-width:620px){.chg-list li{grid-template-columns:1fr}}
/* Вторая и следующие темы одной задачи — с тире, чтобы не читались продолжением первой. */
.chg-sub::before{content:"— "; color:var(--dim);}

/* ---- вход и выход ---- */
.logout{margin:0}
.logout button{font:inherit; font-family:"PT Sans",sans-serif; font-size:12.5px; color:var(--dim);
       background:var(--paper); border:1px solid var(--line); border-radius:10px; padding:7px 14px;
       cursor:pointer}
.logout button:hover{color:var(--ink); border-color:var(--accent-ink)}
.logout button:focus-visible{outline:2px solid var(--accent-ink); outline-offset:2px}
.login{width:100%; max-width:400px; margin:12vh auto 40px; padding:0 16px}
.login h1{margin-bottom:22px}
.login-form{display:flex; flex-direction:column; gap:6px; background:var(--paper);
       border:1px solid var(--line); border-radius:14px; padding:22px 20px; box-shadow:var(--shadow)}
.login-form label{font-size:14px; font-weight:700; margin-top:8px}
.login-form label:first-child{margin-top:0}
.login-form input{font:inherit; color:var(--ink); background:var(--bg); border:1px solid var(--line);
       border-radius:9px; padding:10px 12px; width:100%}
.login-form input:focus{outline:2px solid var(--accent-ink); outline-offset:1px; border-color:transparent}
.login-form button{font:inherit; font-weight:700; margin-top:18px; padding:11px 14px; border:none;
       border-radius:9px; background:var(--accent-ink); color:var(--paper); cursor:pointer}
.login-form button:hover{filter:brightness(1.12)}
.login-form button:focus-visible{outline:2px solid var(--ink); outline-offset:2px}
/* Сообщение видно, только когда его якорь стоит в адресе. */
.login-msg{display:none; margin:0 0 16px; padding:12px 14px; border-radius:10px; font-size:14.5px;
       background:var(--soft); border:1px solid var(--line)}
.login-msg:target{display:block}
.login-bad{border-color:var(--alarm); color:var(--ink)}
