/*
 * Токены и экраны почтового клиента.
 *
 * Тёмная тема — отдельный набор значений, не инверсия светлой. Базовые цвета
 * фона и текста берём из темы Telegram (переменные --tg-theme-*), чтобы
 * приложение не спорило с клиентом, а свои акценты держим постоянными.
 */

:root {
  /* шаг 4 px */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px;
  --r1: 6px; --r2: 10px; --r3: 16px;

  --accent: #0DB8A5;          /* заливка, только для главного действия */
  --accent-text: #077668;     /* тот же смысл, но читаемый как текст */
  --accent-quiet: rgba(13, 184, 165, .12);

  --bg: var(--tg-theme-bg-color, #ffffff);
  --bg-elev: var(--tg-theme-secondary-bg-color, #f3f4f6);
  --fg: var(--tg-theme-text-color, #111827);
  --fg-muted: var(--tg-theme-hint-color, #6b7280);
  --line: rgba(0, 0, 0, .10);
  --line-strong: rgba(0, 0, 0, .22);
  --danger: #b3261e;
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .08);
  --shadow-2: 0 6px 24px rgba(0, 0, 0, .16);

  /* Одна кривая на всё приложение: с ней движение читается как физическое,
     а не как равномерный сдвиг. Три длительности, больше не нужно. */
  --ease: cubic-bezier(.32, .72, 0, 1);
  --dur-1: 160ms;   /* отклик на нажатие */
  --dur-2: 300ms;   /* появление блока */
  --dur-3: 420ms;   /* переход между экранами */
}

/* Класс темы вешаем на <html>, а не на <body>: фон холста берётся с корневого
   элемента, и при классе на body тёмная краска заканчивалась ровно на высоте
   экрана, а дальше проступал белый. */
html.dark {
  /* Telegram обычно подставляет свои --tg-theme-*, но если их нет (старый
     клиент, предпросмотр), тёмная тема должна остаться тёмной, а не съехать
     на белый фон из светлых значений по умолчанию. */
  --bg: var(--tg-theme-bg-color, #17212b);
  --bg-elev: var(--tg-theme-secondary-bg-color, #232e3c);
  --fg: var(--tg-theme-text-color, #f1f4f7);
  --fg-muted: var(--tg-theme-hint-color, #91a3b5);
  --line: rgba(255, 255, 255, .12);
  --line-strong: rgba(255, 255, 255, .28);
  --accent-text: #35D6C3;     /* на тёмном читается светлая ступень */
  --accent-quiet: rgba(13, 184, 165, .16);
  --danger: #f2b8b5;
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .5);
  --shadow-2: 0 6px 24px rgba(0, 0, 0, .6);
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0; min-height: 100%;
  background: var(--bg); color: var(--fg);
  font: 15px/1.45 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  -webkit-text-size-adjust: 100%;
}
body { overscroll-behavior-y: none; }

.app { display: flex; flex-direction: column; min-height: 100vh; max-width: 100%; overflow-x: hidden; }
.tnum { font-variant-numeric: tabular-nums; }

/* --- полоса заголовка ---------------------------------------------------- */
.bar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s3) var(--s4);
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.bar h1 { font-size: 17px; font-weight: 600; margin: 0; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar .sub { font-size: 12px; color: var(--fg-muted); font-weight: 400; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; min-width: 40px;
  border: 0; border-radius: var(--r2); background: transparent; color: var(--fg);
  cursor: pointer; padding: 0;
}
.icon-btn:active { background: var(--bg-elev); }
.icon-btn:focus-visible, .btn:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.ic { width: 22px; height: 22px; display: block; }
.ic-sm { width: 16px; height: 16px; }

/* --- кнопки -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: var(--s2); justify-content: center;
  min-height: 44px; padding: 0 var(--s4);
  border: 1px solid var(--line-strong); border-radius: var(--r2);
  background: transparent; color: var(--fg); font: inherit; font-weight: 500; cursor: pointer;
}
.btn:active { background: var(--bg-elev); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #052e2a; }
.btn-quiet { border-color: transparent; color: var(--accent-text); }
.btn-danger { border-color: transparent; color: var(--danger); }
.btn-wide { width: 100%; }
.btn[disabled] { opacity: .5; pointer-events: none; }

/* --- список писем -------------------------------------------------------- */
.list { flex: 1; }
.row {
  display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; gap: var(--s3);
  align-items: start;
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line);
  cursor: pointer; background: transparent;
  width: 100%; text-align: left; border-left: 0; border-right: 0; border-top: 0;
  color: inherit; font: inherit;
}
.row:active { background: var(--bg-elev); }
.row.unseen { background: var(--accent-quiet); }
.row-mark { padding-top: 3px; color: var(--fg-muted); }
.row.unseen .row-mark { color: var(--accent-text); }
/* Обрезка длинных строк работает только на блочных элементах: у инлайновых
   span игнорируются и overflow, и min-width, и строка растягивает всю сетку. */
.row-main { display: block; min-width: 0; }
.row-from, .row-subject {
  display: block; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.row-from { font-weight: 600; font-size: 14px; }
.row.unseen .row-from { font-weight: 700; }
.row-subject { font-size: 14px; color: var(--fg-muted); }
.row.unseen .row-subject { color: var(--fg); }
.row-mark { display: block; }
.row-meta { display: flex; gap: var(--s2); align-items: center;
  font-size: 12px; color: var(--fg-muted); margin-top: 2px; }
.row-meta:empty { display: none; }
.row-side { display: flex; flex-direction: column; align-items: flex-end; gap: var(--s1);
  font-size: 12px; color: var(--fg-muted); white-space: nowrap; }

/* --- письмо -------------------------------------------------------------- */
.msg { padding: var(--s4); min-width: 0; }
.msg h2 { font-size: 18px; line-height: 1.3; margin: 0 0 var(--s3); overflow-wrap: anywhere; }
.msg-head { font-size: 13px; color: var(--fg-muted); display: grid; gap: 2px;
  margin-bottom: var(--s4); overflow-wrap: anywhere; }
.msg-head b { color: var(--fg); font-weight: 600; }

.actions { display: flex; gap: var(--s2); flex-wrap: wrap;
  padding: 0 var(--s4) var(--s4); }

/*
 * Тело письма — всегда светлый «лист», в обеих темах.
 *
 * Письма свёрстаны под белый фон и несут свои цвета в inline-стилях: тёмный
 * текст подписи, тёмно-синие заголовки, картинки с белой подложкой. На тёмном
 * фоне приложения такое письмо становится нечитаемым, а перекрасить чужой HTML
 * без потерь нельзя. Поэтому лист светлый — как в Kerio и в почтовых клиентах,
 * а тёмной остаётся оболочка приложения.
 */
.mail-body {
  padding: var(--s4); border-top: 1px solid var(--line);
  font-size: 15px; line-height: 1.5; overflow-x: auto; word-break: break-word;
}
/* Лист включается только для писем со своими цветами — см. paper в API. */
.mail-body.paper {
  --paper: #ffffff;
  --paper-fg: #111827;
  --paper-muted: #4b5563;
  --paper-line: rgba(0, 0, 0, .12);
  background: var(--paper); color: var(--paper-fg);
}
.mail-body img { max-width: 100%; height: auto; }
/* Таблицу не ужимаем: 12 колонок в 390 px превращаются в столбики по букве.
   Пусть будет своей ширины, а .mail-body прокрутится вбок — страница при этом
   стоит на месте, потому что прокрутка живёт внутри контейнера. */
.mail-body table { border-collapse: collapse; }
.mail-body td, .mail-body th { word-break: normal; }
.mail-body a { color: var(--accent-text); }
.mail-body.paper a { color: #0b57d0; }
.mail-body blockquote { color: var(--fg-muted); }
.mail-body.paper blockquote { color: var(--paper-muted); }
.mail-body .plain { white-space: pre-wrap; }
.mail-body blockquote { margin: var(--s3) 0; padding-left: var(--s3);
  border-left: 2px solid var(--line-strong); }
.mail-body.paper blockquote { border-left-color: var(--paper-line); }

.notice {
  display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
  margin: var(--s3) var(--s4); padding: var(--s3);
  border: 1px solid var(--line); border-radius: var(--r1);
  font-size: 13px; color: var(--fg-muted);
}
.notice .btn { min-height: 32px; padding: 0 var(--s3); font-size: 13px; }

.att { display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s4); }
.atts { border-top: 1px solid var(--line); }
.atts-title { padding: var(--s3) var(--s4) 0; font-size: 12px; color: var(--fg-muted); }
.att { min-width: 0; border-top: 0; }
.atts .att + .att { border-top: 1px solid var(--line); }
.att-main { flex: 1 1 auto; min-width: 0; display: block; }
.att-name { display: block; min-width: 0; font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-kind { display: block; font-size: 12px; color: var(--fg-muted); }
.att .ic, .att-size, .att .btn { flex: 0 0 auto; }
.att-size { font-size: 12px; color: var(--fg-muted); }

/* --- формы --------------------------------------------------------------- */
.form { padding: var(--s4); display: grid; gap: var(--s4); }
.field { display: grid; gap: var(--s1); }
.field label { font-size: 13px; color: var(--fg-muted); }
input[type=text], input[type=email], input[type=password], textarea, select {
  width: 100%; padding: var(--s3);
  border: 1px solid var(--line-strong); border-radius: var(--r1);
  background: var(--bg); color: var(--fg); font: inherit;
}
textarea { min-height: 160px; resize: vertical; }
.hint { font-size: 12px; color: var(--fg-muted); }
.tone { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; margin-top: var(--s2); }
.tone .btn { min-height: 34px; padding: 0 var(--s3); font-size: 13px; }
.error { font-size: 13px; color: var(--danger); }

.switch { display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); padding: var(--s3) 0; border-bottom: 1px solid var(--line); }
.switch:last-child { border-bottom: 0; }
.switch-label { font-size: 14px; }
.switch-hint { font-size: 12px; color: var(--fg-muted); }
input[type=checkbox] { width: 22px; height: 22px; accent-color: var(--accent); }

/* --- служебные ----------------------------------------------------------- */
/* --- заставка запуска ----------------------------------------------------
 * Хореография: конверт прочерчивается линией → вспыхивает мягкое свечение →
 * из конверта вылетает письмо → по названию проходит световая волна. На выходе
 * заставка не просто гаснет, а «пропускает сквозь себя»: увеличивается и
 * размывается, а список писем в это же время подаётся из глубины.
 *
 * Движение построено на одной кривой (0.32, 0.72, 0, 1) — с ней разгон и
 * торможение выглядят как у физического предмета, а не как равномерный сдвиг.
 * Значки — из Ionicons, другого набора в проекте нет.
 */
.splash {
  position: fixed; inset: 0; z-index: 30;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--s4);
  background: var(--bg);
  transform-origin: 50% 46%;
  transition: opacity 460ms cubic-bezier(.32, .72, 0, 1),
              transform 520ms cubic-bezier(.32, .72, 0, 1),
              filter 460ms cubic-bezier(.32, .72, 0, 1),
              visibility 520ms;
}
.splash.done {
  opacity: 0; visibility: hidden;
  transform: scale(1.08);
  filter: blur(6px);
}

/* Мягкое свечение за знаком: «вдох» ровно один раз, в момент готовности. */
.splash-glow {
  position: absolute; width: 320px; height: 320px; border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--accent) 26%, transparent) 0%,
    color-mix(in srgb, var(--accent) 8%, transparent) 42%,
    transparent 68%);
  opacity: 0; transform: scale(.6);
  animation: sp-glow 1600ms cubic-bezier(.32, .72, 0, 1) 340ms forwards;
  pointer-events: none;
}

.splash-stage {
  transform: scale(.86); opacity: 0;
  animation: sp-rise 720ms cubic-bezier(.32, .72, 0, 1) forwards;
}
.splash-mark { width: 88px; height: 88px; overflow: visible; display: block; }
.splash-mark rect, .splash-mark path {
  fill: none; stroke: currentColor;
  stroke-width: 26px; stroke-linecap: round; stroke-linejoin: round;
}
.sp-env, .sp-flap { color: var(--fg); }

/* Контур конверта прочерчивается, следом — линия клапана. */
.sp-env {
  stroke-dasharray: 1440; stroke-dashoffset: 1440;
  animation: sp-draw 720ms cubic-bezier(.32, .72, 0, 1) 120ms forwards;
}
.sp-flap {
  stroke-dasharray: 380; stroke-dashoffset: 380;
  animation: sp-draw 420ms cubic-bezier(.32, .72, 0, 1) 620ms forwards;
}

/* Письмо вылетает из конверта и уходит за кадр. */
.sp-plane {
  color: var(--accent);
  stroke-width: 30px;
  opacity: 0; transform-origin: 50% 50%;
  animation: sp-fly 1050ms cubic-bezier(.32, .72, 0, 1) 900ms forwards;
}

/* Световая волна по названию — как блик, проходящий по стеклу. */
.splash-title {
  font-size: 14px; font-weight: 500; letter-spacing: .04em;
  color: var(--fg-muted);
  background-image: linear-gradient(100deg,
    transparent 20%, color-mix(in srgb, var(--fg) 92%, transparent) 42%,
    color-mix(in srgb, var(--fg) 92%, transparent) 50%, transparent 72%);
  background-size: 260% 100%; background-position: 180% 0;
  -webkit-background-clip: text; background-clip: text;
  opacity: 0;
  animation: sp-fade 420ms ease 700ms forwards,
             sp-shine 1500ms cubic-bezier(.4, 0, .2, 1) 980ms 2;
}

.splash-track {
  width: 108px; height: 2px; border-radius: 2px;
  background: color-mix(in srgb, var(--fg) 10%, transparent); overflow: hidden;
  opacity: 0; animation: sp-fade 380ms ease 1000ms forwards;
}
.splash-track span {
  display: block; height: 100%; width: 100%; border-radius: 2px;
  background: linear-gradient(90deg,
    transparent, var(--accent) 30%, var(--accent) 70%, transparent);
  transform-origin: 0 50%;
  animation: sp-progress 1.6s cubic-bezier(.65, 0, .35, 1) 1000ms infinite;
}

@keyframes sp-rise {
  0%   { opacity: 0; transform: scale(.86) translateY(10px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}
@keyframes sp-draw { to { stroke-dashoffset: 0; } }
@keyframes sp-fade { to { opacity: 1; } }
@keyframes sp-glow {
  0%   { opacity: 0; transform: scale(.6); }
  45%  { opacity: 1; transform: scale(1.04); }
  100% { opacity: .55; transform: scale(1); }
}
@keyframes sp-shine { to { background-position: -80% 0; } }
@keyframes sp-fly {
  0%   { opacity: 0; transform: scale(.46) translate(-26px, 26px) rotate(-8deg); }
  22%  { opacity: 1; transform: scale(.40) translate(0, 0) rotate(0deg); }
  70%  { opacity: 1; transform: scale(.30) translate(210px, -190px) rotate(6deg); }
  100% { opacity: 0; transform: scale(.22) translate(320px, -300px) rotate(10deg); }
}
@keyframes sp-progress {
  0%   { transform: translateX(-100%) scaleX(.35); }
  50%  { transform: translateX(0%) scaleX(.6); }
  100% { transform: translateX(100%) scaleX(.35); }
}

/* Список подаётся из глубины ровно тогда, когда заставка расходится. */
.app.enter { animation: app-enter 520ms cubic-bezier(.32, .72, 0, 1) both; }
.app.enter .row, .app.enter .bar { animation: app-row 460ms cubic-bezier(.32, .72, 0, 1) both; }
.app.enter .row:nth-child(1) { animation-delay: 40ms; }
.app.enter .row:nth-child(2) { animation-delay: 80ms; }
.app.enter .row:nth-child(3) { animation-delay: 120ms; }
.app.enter .row:nth-child(4) { animation-delay: 160ms; }
.app.enter .row:nth-child(5) { animation-delay: 200ms; }
.app.enter .row:nth-child(6) { animation-delay: 240ms; }

@keyframes app-enter { from { opacity: 0; transform: scale(.985); } }
@keyframes app-row { from { opacity: 0; transform: translateY(8px); } }

/* Кому анимации мешают — статичный знак и обычное появление. */
@media (prefers-reduced-motion: reduce) {
  .splash-mark rect, .splash-mark path, .splash-stage, .splash-glow,
  .splash-title, .splash-track, .splash-track span,
  .app.enter, .app.enter .row, .app.enter .bar { animation: none; }
  .sp-env, .sp-flap { stroke-dashoffset: 0; }
  .sp-plane { display: none; }
  .splash-stage, .splash-title, .splash-track { opacity: 1; transform: none; }
  .splash-glow { opacity: .4; transform: scale(1); }
  .splash-track span { width: 100%; opacity: .5; }
  .splash.done { transform: none; filter: none; }
}

/* --- движение интерфейса --------------------------------------------------
 * Экраны не подменяются рывком: входящий подаётся из глубины и слегка сбоку —
 * вперёд при переходе вглубь, назад при возврате. Списки появляются лесенкой,
 * догруженные письма — только сами, без перерисовки всего списка.
 */
.view-push > .bar, .view-push > .list, .view-push > .msg, .view-push > .form,
.view-push > .actions, .view-push > .atts, .view-push > .notice, .view-push > .mail-body,
.view-push > .load-more, .view-push > .empty {
  animation: view-in-push var(--dur-3) var(--ease) both;
}
.view-pop > .bar, .view-pop > .list, .view-pop > .msg, .view-pop > .form,
.view-pop > .actions, .view-pop > .atts, .view-pop > .notice, .view-pop > .mail-body,
.view-pop > .load-more, .view-pop > .empty {
  animation: view-in-pop var(--dur-3) var(--ease) both;
}
/* Полоса заголовка трогается чуть раньше содержимого — так переход собран. */
.view-push > .bar, .view-pop > .bar { animation-duration: var(--dur-2); }
.view-push > .msg, .view-pop > .msg { animation-delay: 30ms; }
.view-push > .actions, .view-pop > .actions { animation-delay: 60ms; }
.view-push > .atts, .view-pop > .atts { animation-delay: 90ms; }
.view-push > .mail-body, .view-pop > .mail-body { animation-delay: 120ms; }

@keyframes view-in-push {
  from { opacity: 0; transform: translate3d(16px, 0, 0) scale(.995); }
}
@keyframes view-in-pop {
  from { opacity: 0; transform: translate3d(-16px, 0, 0) scale(.995); }
}

/* Список писем появляется лесенкой: 8 строк, дальше без задержки, иначе
   ожидание растягивается вместо того, чтобы казаться коротким. */
.stagger .row { animation: row-in var(--dur-2) var(--ease) both; }
.stagger .row:nth-child(1) { animation-delay: 20ms; }
.stagger .row:nth-child(2) { animation-delay: 50ms; }
.stagger .row:nth-child(3) { animation-delay: 80ms; }
.stagger .row:nth-child(4) { animation-delay: 110ms; }
.stagger .row:nth-child(5) { animation-delay: 140ms; }
.stagger .row:nth-child(6) { animation-delay: 170ms; }
.stagger .row:nth-child(7) { animation-delay: 200ms; }
.stagger .row:nth-child(8) { animation-delay: 230ms; }

/* Догруженные письма появляются сами по себе — список не мигает целиком. */
.row-new { animation: row-in var(--dur-2) var(--ease) both; }

@keyframes row-in { from { opacity: 0; transform: translate3d(0, 10px, 0); } }

/* Отклик на нажатие: кнопка чуть подаётся, как физическая. */
.btn, .icon-btn, .row, .folder-row { transition: transform var(--dur-1) var(--ease),
  background-color var(--dur-1) var(--ease); }
.btn:active, .icon-btn:active { transform: scale(.97); }
.row:active, .folder-row:active { transform: scale(.995); }

/* Звёздочка «важное» отзывается на нажатие. */
.pop { animation: pop 320ms var(--ease); }
@keyframes pop {
  0% { transform: scale(1); }
  40% { transform: scale(1.28); }
  100% { transform: scale(1); }
}

/* Лист папок выезжает снизу, подложка проявляется. */
.sheet { animation: sheet-up var(--dur-3) var(--ease) both; }
.sheet-backdrop { animation: fade-in var(--dur-2) var(--ease) both; }
@keyframes sheet-up { from { transform: translate3d(0, 100%, 0); } }
@keyframes fade-in { from { opacity: 0; } }

/* Ответ модели и подгруженные подписи проявляются, а не возникают. */
.ai-out, .att-kind { animation: fade-in var(--dur-2) var(--ease) both; }

@media (prefers-reduced-motion: reduce) {
  .view-push > *, .view-pop > *, .stagger .row, .row-new,
  .sheet, .sheet-backdrop, .ai-out, .att-kind, .pop { animation: none; }
  .btn:active, .icon-btn:active, .row:active, .folder-row:active { transform: none; }
}

/* --- скелет загрузки ------------------------------------------------------
 * Пока письма едут, показываем их будущую форму, а не слово «загружаю»:
 * человек сразу видит, что это список писем, и не гадает, чего ждать.
 */
.sk {
  display: inline-block; border-radius: var(--r1);
  background: var(--bg-elev);
  position: relative; overflow: hidden;
}
.sk::after {
  content: ''; position: absolute; inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg,
    transparent, color-mix(in srgb, var(--fg) 8%, transparent), transparent);
  animation: sk-sweep 1.25s ease-in-out infinite;
}
.sk-line { height: 12px; margin: 3px 0; }
.sk-icon { width: 22px; height: 22px; border-radius: var(--r1); }
.sk-dot { width: 16px; height: 16px; border-radius: 50%; margin-top: 3px; }
.sk-row { cursor: default; }
.sk-row .row-main { display: block; }
.sk-row:nth-child(2) .sk::after { animation-delay: .08s; }
.sk-row:nth-child(3) .sk::after { animation-delay: .16s; }
.sk-row:nth-child(4) .sk::after { animation-delay: .24s; }
.sk-row:nth-child(5) .sk::after { animation-delay: .32s; }
.sk-row:nth-child(6) .sk::after { animation-delay: .40s; }

@keyframes sk-sweep { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .sk::after { animation: none; }
}

.boot, .empty {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--s3); padding: var(--s6) var(--s4); color: var(--fg-muted); text-align: center;
}
.empty .ic { width: 32px; height: 32px; }
.center-pad { padding: var(--s4); display: grid; gap: var(--s3); justify-items: center; }
.load-more { padding: var(--s4); display: flex; justify-content: center; }

/* Фильтры списка: активный отмечен чертой, а не заливкой — акцент на экране
   один, и он принадлежит главному действию. */
.chips {
  display: flex; gap: var(--s2); padding: var(--s2) var(--s4) var(--s3);
  overflow-x: auto; border-bottom: 1px solid var(--line);
}
.chip {
  flex: 0 0 auto; padding: var(--s2) var(--s3);
  border: 1px solid var(--line); border-radius: 999px;
  background: transparent; color: var(--fg-muted); font: inherit; font-size: 13px;
  cursor: pointer;
}
.chip.on {
  color: var(--fg); border-color: var(--line-strong);
  box-shadow: inset 0 -2px 0 var(--accent);
}

.folders { padding: var(--s2) 0; }
.folder-line { display: flex; align-items: center; }
.folder-line .folder-row { flex: 1 1 auto; }
.folder-tools { display: flex; gap: var(--s1); padding-right: var(--s3); }
.sheet-actions {
  display: flex; flex-direction: column; align-items: stretch; gap: var(--s1);
  padding: var(--s2) var(--s3) var(--s4); border-top: 1px solid var(--line);
}
.folder-row { display: flex; align-items: center; gap: var(--s3); width: 100%;
  padding: var(--s3) var(--s4); border: 0; background: transparent; color: inherit;
  font: inherit; cursor: pointer; text-align: left; }
.folder-row:active { background: var(--bg-elev); }
.folder-row > span:first-of-type {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.folder-row.current { box-shadow: inset 3px 0 0 var(--accent); font-weight: 600; }
.folder-count { margin-left: auto; font-size: 13px; color: var(--fg-muted); }

.sheet-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: 20; }
.sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 21;
  background: var(--bg); border-radius: var(--r3) var(--r3) 0 0;
  box-shadow: var(--shadow-2); max-height: 80vh; overflow: auto;
  padding-bottom: env(safe-area-inset-bottom); }
.sheet-title { padding: var(--s4) var(--s4) var(--s2); font-weight: 600; }

.ai-out { white-space: pre-wrap; padding: var(--s4); font-size: 14px;
  border-top: 1px solid var(--line); }
.spinner { display: inline-block; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--line-strong); border-top-color: var(--accent);
  animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 2s; } }
