/*
    Оформление кабинета.

    Цвет один и приглушённый — сине-зелёный, тот же, что в приложении пациента
    (android/…/ui/Theme.kt). Это дневник здоровья, а не приборная панель:
    яркость принадлежит отклонениям, а не оформлению.

    Отклонения — единственное, что выделяется: янтарный для превышения, синий
    для снижения. Красный не используется намеренно: показатель вне интервала
    не является тревогой, трактовка результатов лежит вне границ продукта
    (docs/01-product.md). Красным окрашены только отказы самого кабинета —
    то, что сломалось в нём, а не в человеке.
*/

:root {
    --teal: #1f6f6b;
    --teal-container: #cdedea;
    --on-teal-container: #06322f;
    --bg: #f7faf9;
    --surface: #ffffff;
    --surface-variant: #edf3f2;
    --on-surface: #1a1c1c;
    --on-surface-variant: #3f4947;
    --outline: #d5e0de;
    --above: #b26a00;
    --below: #2a5db0;
    --failure: #8c1d18;
    /* Поле ввода: заметно темнее карточки, но не темнее текста. */
    --field: #f2f7f6;
    --field-border: #b9c8c6;
    --radius: 12px;
    --gap: 16px;
}

@media (prefers-color-scheme: dark) {
    :root {
        --teal: #7fd1cb;
        --teal-container: #00504a;
        --on-teal-container: #9ff2ea;
        --bg: #0e1513;
        --surface: #151d1c;
        --surface-variant: #283331;
        --on-surface: #e0e3e2;
        --on-surface-variant: #bfc9c7;
        --outline: #3a4644;
        --above: #ffb86b;
        --below: #9cc0ff;
        --failure: #f2b8b5;
        --field: #1e2827;
        --field-border: #4a5654;
    }
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--on-surface);
    font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/*
    Числа сравнивают глазами по столбцу: «110,3» и «98,7» должны стоять ровно
    друг под другом, иначе взгляд спотыкается на каждой строке.
*/
.num {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

h1 { font-size: 22px; margin: 0; }
h2 { font-size: 18px; margin: 0 0 12px; }
h3 { font-size: 15px; margin: 0 0 8px; color: var(--on-surface-variant); }
p { margin: 0 0 8px; }

a { color: var(--teal); }

header.top {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 14px 20px;
    background: var(--surface);
    border-bottom: 1px solid var(--outline);
    position: sticky;
    top: 0;
    z-index: 5;
}

/*
    Логотип — кнопка, но выглядит заголовком: он всегда был заголовком, нажимать
    на него пробовали и раньше. Обводка при обходе с клавиатуры оставлена: это
    единственное, что отличает его от текста для того, кто мышью не пользуется.
*/
header.top .logo {
    background: none;
    border: none;
    color: inherit;
    font-size: 22px;
    font-weight: 600;
    padding: 0 4px 0 0;
    cursor: pointer;
}
header.top .logo:hover { color: var(--teal); }

/*
    Кто вошёл — лицом и именем.

    Прежде здесь стояло слово «Пациент»: оно отвечало на вопрос, который человек
    про себя и так знает, и молчало о том, который он задаёт, садясь за чужой
    компьютер. Роль осталась второй строкой, мелко: она объясняет, почему экран
    выглядит так, а не иначе.
*/
header.top .who {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

header.top .who-text {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
    min-width: 0;
}

header.top .who-name {
    font-size: 14px;
    font-weight: 600;
    /* Длинное имя не должно выталкивать «Выйти» за край экрана. */
    max-width: 30ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

header.top .who-role { font-size: 12px; }

/* На узком экране от подписи остаётся лицо: имя там некуда положить. */
@media (max-width: 560px) {
    header.top .who-text { display: none; }
}

main {
    max-width: 1080px;
    margin: 0 auto;
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: var(--gap);
}

.card {
    background: var(--surface);
    border: 1px solid var(--outline);
    border-radius: var(--radius);
    padding: 16px;
}

.grid {
    display: grid;
    gap: var(--gap);
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.tile .value { font-size: 26px; }
.tile .label { color: var(--on-surface-variant); font-size: 13px; }
.tile .when { color: var(--on-surface-variant); font-size: 12px; margin-top: 4px; }

.above { color: var(--above); }
.below { color: var(--below); }
.muted { color: var(--on-surface-variant); }
.small { font-size: 13px; }

button {
    font: inherit;
    border: 1px solid var(--teal);
    background: var(--teal);
    color: var(--surface);
    border-radius: 8px;
    padding: 9px 14px;
    cursor: pointer;
}

button.ghost { background: transparent; color: var(--teal); }
button.link {
    background: none;
    border: none;
    color: var(--teal);
    padding: 0;
    text-decoration: underline;
}
button:disabled { opacity: .55; cursor: default; }

/*
    Поля ввода видно без наведения мышью.

    Прежде они были белыми на белой карточке с бледной рамкой: на экране
    оставалась одна подпись, и куда нажимать, приходилось угадывать. Поле
    отличается от карточки заливкой, рамка темнее фона, а при вводе добавляется
    обводка цветом — иначе в длинной форме теряется место, где стоит курсор.
*/
input, select, textarea {
    font: inherit;
    color: inherit;
    background: var(--field);
    border: 1px solid var(--field-border);
    border-radius: 8px;
    padding: 9px 10px;
    width: 100%;
}

input:hover, select:hover, textarea:hover { border-color: var(--teal); }

input:focus, select:focus, textarea:focus {
    outline: 2px solid var(--teal);
    outline-offset: -1px;
    border-color: var(--teal);
    background: var(--surface);
}

input::placeholder, textarea::placeholder { color: var(--on-surface-variant); opacity: .7; }

/* Отключённое поле не должно выглядеть как обычное: нажимать в него незачем. */
input:disabled, select:disabled, textarea:disabled { opacity: .6; background: var(--surface-variant); }

textarea { min-height: 90px; resize: vertical; }

label { display: block; font-size: 13px; color: var(--on-surface-variant); margin-bottom: 12px; }
label > input, label > select, label > textarea { margin-top: 4px; }

form.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
form.row label { flex: 1 1 160px; margin-bottom: 0; }

table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--outline); }
th { font-size: 13px; color: var(--on-surface-variant); font-weight: 600; }
tr.clickable { cursor: pointer; }
tr.clickable:hover { background: var(--surface-variant); }

.list-item {
    padding: 12px 0;
    border-bottom: 1px solid var(--outline);
}
.list-item:last-child { border-bottom: none; }
.list-item .head { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.list-item .actions { margin-top: 8px; display: flex; gap: 12px; }

.chip {
    display: inline-block;
    font-size: 12px;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--surface-variant);
    color: var(--on-surface-variant);
}
.chip.attention { background: var(--teal-container); color: var(--on-teal-container); }
/* Карточка, требующая действия: то же выделение, что у ждущего подтверждения
   назначения, — оба говорят «от тебя чего-то ждут», и выглядеть должны одинаково. */
.card.attention { border-color: var(--teal); border-width: 2px; }

.problem {
    border: 1px solid var(--failure);
    color: var(--failure);
    border-radius: 8px;
    padding: 10px 12px;
    margin-bottom: 12px;
}

.notice {
    background: var(--teal-container);
    color: var(--on-teal-container);
    border-radius: 8px;
    padding: 12px;
}

.placeholder { padding: 40px 20px; color: var(--on-surface-variant); text-align: center; }

/* Вход — единственный экран без шапки: показывать в нём нечего и некого. */
.login {
    max-width: 380px;
    margin: 8vh auto;
    padding: 24px;
}
.login h1 { margin-bottom: 4px; }
.login .sub { color: var(--on-surface-variant); font-size: 14px; margin-bottom: 20px; }
.login button { width: 100%; }

.code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 22px;
    letter-spacing: 2px;
    user-select: all;
}

.tabs { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 4px; }
.tabs button {
    background: transparent;
    border: 1px solid transparent;
    color: var(--on-surface-variant);
    border-radius: 999px;
}
.tabs button[aria-current="true"] {
    background: var(--teal-container);
    color: var(--on-teal-container);
    border-color: transparent;
}

/*
    Слева — разделы, справа — сам раздел.

    Прежде карта была одним длинным столбцом, и всё лежало в куче: чтобы дойти
    до анализов, приходилось проматывать дневник. Разделы теперь открываются по
    одному — и это не только про глаза: каждый раздел читает данные пациента и
    пишет строку в журнал доступа. Открывать все семь ради одного означало
    отмечать в журнале чтение того, на что никто не смотрел.
*/
.layout {
    display: grid;
    grid-template-columns: 210px minmax(0, 1fr);
    gap: var(--gap);
    align-items: start;
}

.sidebar {
    position: sticky;
    top: 72px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    background: var(--surface);
    border: 1px solid var(--outline);
    border-radius: var(--radius);
    padding: 8px;
}

.sidebar button {
    background: transparent;
    border: 1px solid transparent;
    color: var(--on-surface);
    text-align: left;
    padding: 9px 12px;
    border-radius: 8px;
    font-size: 15px;
}
.sidebar button:hover { background: var(--surface-variant); }
.sidebar button[aria-current="true"] {
    background: var(--teal-container);
    color: var(--on-teal-container);
    font-weight: 600;
}

.content { display: flex; flex-direction: column; gap: var(--gap); min-width: 0; }

/* На узком экране разделы становятся строкой поверх содержимого. */
@media (max-width: 720px) {
    .layout { grid-template-columns: 1fr; }
    .sidebar { position: static; flex-direction: row; overflow-x: auto; }
    .sidebar button { white-space: nowrap; }
}

/*
    Календарь: месяц целиком, отмеченные дни — те, на которые что-то назначено.

    Сетка нужна не ради вида: «раз в две недели по вторникам» на списке не
    читается, а на месяце видно сразу — и видно, что три напоминания сошлись в
    один день.
*/
.month {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 4px;
}
.month .dow { font-size: 12px; color: var(--on-surface-variant); text-align: center; padding: 4px 0; }
.month .day {
    border: 1px solid var(--outline);
    border-radius: 8px;
    min-height: 62px;
    padding: 4px 6px;
    font-size: 13px;
    background: var(--surface);
}
.month .day.other { opacity: .4; }
.month .day.today { border-color: var(--teal); border-width: 2px; }
.month .day .n { color: var(--on-surface-variant); }
.month .day .mark {
    display: block;
    font-size: 11px;
    line-height: 1.3;
    margin-top: 2px;
    color: var(--on-teal-container);
    background: var(--teal-container);
    border-radius: 4px;
    padding: 1px 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Отметка выполнения — приглушённее срока: сделанное уже не требует внимания. */
.month .day .mark.done {
    color: var(--on-surface-variant);
    background: var(--surface-variant);
}

/*
 * Фотография в профиле и в списке людей.
 *
 * Квадрат с обрезкой по центру, а не свободный размер: снимки приходят
 * какие угодно, и ряд карточек разной высоты читается как сбор случайных
 * картинок, а не как список людей.
 *
 * Пустое место занято словом или инициалами. Пустой серый круг в списке
 * людей выглядит как не загрузившееся изображение, то есть как поломка.
 */
.photo {
    width: 160px;
    height: 160px;
    flex: 0 0 auto;
    border-radius: 12px;
    overflow: hidden;
    background: var(--surface-variant);
    border: 1px solid var(--outline);
    display: flex;
    align-items: center;
    justify-content: center;
}
.photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-empty { color: var(--on-surface-variant); font-size: 13px; }

.avatar {
    width: 44px;
    height: 44px;
    flex: 0 0 auto;
    border-radius: 50%;
    overflow: hidden;
    background: var(--surface-variant);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--on-surface-variant);
    font-size: 15px;
    font-weight: 600;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* В шапке лицо меньше: рядом с ним строка имени, а не карточка человека. */
.avatar.small { width: 34px; height: 34px; font-size: 13px; }

/*
    В шапке карты — среднее: меньше, чем в профиле, где снимок разглядывают, и
    больше, чем в шапке кабинета, где он лишь метка вошедшего. Рамка отделяет
    светлый снимок от светлой карточки: без неё лицо на белом фоне выглядит
    вырезанным, а не вставленным.
*/
.avatar.large {
    width: 56px;
    height: 56px;
    font-size: 19px;
    border: 1px solid var(--outline);
}

/*
    Микрографик.

    Линия одна и всегда одного цвета. Отклонение от нормы и от цели сказано
    рядом словами: янтарный и синий в кабинете уже значат «выше» и «ниже», и
    третий смысл у тех же красок читался бы как тревога — а тревоги здесь нет,
    трактовка лежит вне границ продукта (docs/01-product.md).

    Заливка под линией бледная, сетки и осей нет вовсе: на ста тридцати
    пикселях они съели бы место, а ответ дают не они, а форма кривой. Точные
    числа стоят подписью — они же и есть то, что останется, если график не
    виден.
*/
.spark { display: block; overflow: visible; }
.spark-line {
    fill: none;
    stroke: var(--teal);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.spark-area { fill: var(--teal); opacity: .1; stroke: none; }
.spark-last { fill: var(--teal); }

/* Цель — пунктиром и приглушённо: это опора для взгляда, а не ещё один ряд. */
.spark-goal {
    stroke: var(--on-surface-variant);
    stroke-width: 1;
    stroke-dasharray: 3 3;
    opacity: .55;
}

.spark-box { margin: 8px 0 2px; }
.spark-caption { display: block; margin-top: 2px; }

.spark-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.spark-pair { display: flex; flex-direction: column; gap: 2px; margin: 8px 0 2px; }

.spark-grid {
    display: grid;
    gap: 12px;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
}
.spark-cell { display: flex; flex-direction: column; gap: 2px; }

/*
    Разбор цели под плиткой.

    Он длиннее подписи с датой и переносится на две строки — поэтому не `.when`:
    у той однострочная высота, и перенос ломал бы ряд плиток по высоте.
*/
.goal-line {
    margin-top: 6px;
    font-size: 12px;
    line-height: 1.35;
    color: var(--on-surface-variant);
}
.goal-line.above { color: var(--above); }
.goal-line.below { color: var(--below); }

/* Файловое поле: у него своя высота, и общая рамка ввода ему только мешает. */
input[type=file] {
    padding: 8px 0;
    border: none;
    background: transparent;
}

/*
    Сообщения. Свои — справа на цвете контейнера, чужие — слева на поверхности:
    сторона и цвет дублируют друг друга, чтобы диалог читался и без цвета.
*/
.chat { display: flex; flex-direction: column; gap: 10px; }
.chat-feed {
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 60vh;
    min-height: 160px;
    overflow-y: auto;
    padding: 4px 2px;
}
.chat-day { align-self: center; margin: 8px 0 2px; }
.bubble {
    max-width: 78%;
    padding: 8px 12px;
    border-radius: 14px;
    border: 1px solid var(--outline);
    background: var(--surface-variant);
    align-self: flex-start;
}
.bubble.mine {
    align-self: flex-end;
    background: var(--teal-container);
    color: var(--on-teal-container);
    border-color: transparent;
}
.bubble .stamp { display: block; margin-top: 4px; text-align: right; }
.bubble.mine .stamp { color: var(--on-teal-container); opacity: .75; }
.chat-form { display: flex; gap: 8px; align-items: flex-end; }
.chat-form textarea { flex: 1; min-height: 44px; }
button.unread {
    text-decoration: none;
    background: var(--teal-container);
    color: var(--on-teal-container);
    border-radius: 999px;
    padding: 4px 12px;
    font-weight: 600;
}

/* Черновик отчёта: утверждения списком, у каждого — источник и переход к записи. */
ul.report { margin: 0; padding-left: 20px; }
ul.report li { margin: 4px 0; line-height: 1.5; }
ul.report .chip { vertical-align: middle; }
button.link.small { font-size: 13px; }

/* Отчёт языковой модели: Markdown, отрисованный в узлы. Таблицы шире карточки
   прокручиваются внутри себя, страница вбок не едет. */
.markdown h2, .markdown h3, .markdown h4, .markdown h5 { margin: 18px 0 8px; }
.markdown h2 { font-size: 20px; }
.markdown h3 { font-size: 17px; }
.markdown h4, .markdown h5 { font-size: 15px; }
.markdown p { margin: 8px 0; line-height: 1.55; }
.markdown ul, .markdown ol { margin: 6px 0; padding-left: 22px; }
.markdown li { margin: 3px 0; line-height: 1.5; }
.markdown table { margin: 8px 0; font-size: 14px; }
.markdown td, .markdown th { vertical-align: top; }
.markdown blockquote { margin: 8px 0; padding: 4px 12px; border-left: 3px solid var(--outline); color: var(--on-surface-variant); }
.markdown hr { border: none; border-top: 1px solid var(--outline); margin: 14px 0; }
.markdown code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
