/* Selfie camera (cam_shutter) — оформление рабочей области.
   Акцентная (индиго) палитра снята ПИПЕТКОЙ из макета — ЛОКАЛЬНЫЕ токены на .cs, сайтовые токены/шапку
   не трогаем (см. .tool_conventions/for_webcam.md + _common.md «Подложка инструмента»). Каркас — Bootstrap,
   кастом (кнопка-затвор, плёнка, оверлеи превью) — согласован категорией for_webcam, поверх Bootstrap. */

.cs {
    --cs-accent:      #5b66e6;
    --cs-accent-2:    #7280f0;  /* светлее — для градиента */
    --cs-accent-dark: #4751c9;  /* hover */
    --cs-soft:        #eceefe;  /* светлая индиго-заливка чипов/иконок */
    --cs-bg:          #f4f4f8;  /* подложка рабочих блоков */
    --cs-card:        #ffffff;
    --cs-stage:       #1f1f2b;  /* фон пустого превью */
    --cs-text:        #2a2a38;
    --cs-muted:       #8a8a9a;
    --cs-line:        #e6e6ef;
    --cs-danger:      #d6483b;
    --cs-radius:      18px;
    --cs-radius-sm:   11px;
    --cs-thumb:       78px;

    max-width: var(--cs-stage-w, 760px);
    margin-inline: auto;
    color: var(--cs-text);
    font-family: 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    background: var(--cs-card);
    border: 1px solid var(--cs-line);
    border-radius: var(--cs-radius);
    box-shadow: 0 2px 10px rgba(40, 40, 90, .05);
    padding: 1.1rem 1.25rem 1.25rem;
}

/* hidden-атрибут скрывает даже элементы с заданным display */
.cs [hidden] { display: none !important; }

/* Снимаем браузерное/bootstrap обрамление фокуса (правило CLAUDE.md) */
.cs input:focus,
.cs button:focus,
.cs select:focus,
.cs .form-check-input:focus,
.cs [tabindex]:focus {
    outline: none;
    box-shadow: none;
}

/* ---------- Шапка карточки ---------- */
.cs__head { display: flex; align-items: center; gap: .6rem; margin-bottom: 1rem; }
.cs__logo {
    display: inline-grid; place-items: center;
    width: 36px; height: 36px; border-radius: 10px;
    background: linear-gradient(135deg, var(--cs-accent), var(--cs-accent-2));
    color: #fff; font-size: 1.05rem;
}
.cs__title { font-weight: 700; font-size: 1.15rem; }
.cs__head-actions { margin-left: auto; display: flex; gap: .5rem; }
.cs__headbtn {
    display: inline-flex; align-items: center; gap: .35rem;
    background: 0; border: 1px solid var(--cs-line); border-radius: var(--cs-radius-sm);
    color: var(--cs-muted); font-size: .85rem; padding: .4rem .75rem; cursor: pointer;
    transition: color .12s, border-color .12s, background .12s;
}
.cs__headbtn:hover { color: var(--cs-accent); border-color: #c7ccf5; background: var(--cs-soft); }
.cs__headbtn[aria-expanded="true"] { color: var(--cs-accent); border-color: var(--cs-accent); background: var(--cs-soft); }
/* Settings бессмысленны до доступа к камере — показываем только когда камера открыта */
.cs[data-state="idle"] #cs-settings-btn { display: none; }

/* ---------- Панель настроек ---------- */
.cs__settings {
    background: var(--cs-bg); border: 1px solid var(--cs-line); border-radius: var(--cs-radius-sm);
    padding: .9rem 1rem; margin-bottom: 1rem;
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: 1rem 1.4rem; align-items: start;
}
.cs__setting { display: flex; flex-direction: column; gap: .4rem; margin: 0; }
.cs__setting-cap { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--cs-muted); }
.cs__device-sel { border-color: var(--cs-line); }
.cs__setting-toggle { gap: .3rem; }
.cs__switch { padding-left: 2.6em; min-height: auto; margin: 0; }
.cs__switch .form-check-input { width: 2.1em; height: 1.1em; margin-left: -2.6em; cursor: pointer; background-color: #d3d3e2; border-color: #d3d3e2; }
.cs__switch .form-check-input:checked { background-color: var(--cs-accent); border-color: var(--cs-accent); }
.cs__switch .form-check-label { font-weight: 600; font-size: .92rem; cursor: pointer; }
.cs__setting-hint { font-size: .82rem; color: var(--cs-muted); margin: 0; }

/* ====================================================================
   Рабочая область: превью + стрелки
   ==================================================================== */
/* z-index создаёт у stage СОБСТВЕННЫЙ stacking-контекст — видео-слой заперт внутри него и не может
   «всплыть» поверх кнопки-затвора (controls, z-index:10). Без этого живое <video> в Chrome перекрывало
   кольцо затвора то появляясь, то пропадая (GPU-композиция). */
/* место снизу под выступающую кнопку-затвор и подпись (кнопка нависает за нижний край превью);
   замер: подпись уходит ~69px ниже превью → резерв с запасом, чтобы не наезжать на плёнку */
.cs__stage { position: relative; z-index: 1; margin-bottom: 84px; }
.cs__preview {
    position: relative;
    aspect-ratio: 16 / 9;
    background: var(--cs-stage);
    border-radius: var(--cs-radius);
    /* overflow VISIBLE — нижняя половина кнопки-затвора выступает за край. Скруглённые углы держат сами
       медиа-слои (видео/карусель/вспышка клипуются своим border-radius), а не превью. */
    overflow: visible;
    /* в review листаем фото горизонтальным свайпом; вертикальный скролл страницы оставляем браузеру */
    touch-action: pan-y;
}
/* клип-обёртка: скруглённые углы + горизонтальный клип карусели (родитель НЕ движется, клип стабилен).
   Сам трек двигать overflow:hidden НЕЛЬЗЯ — клип едет вместе с ним и виден только первый слайд. */
.cs__media {
    position: absolute; inset: 0;
    overflow: hidden; border-radius: var(--cs-radius);
}
.cs__video {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover; display: block;
    background: var(--cs-stage);
}
/* Зеркалим ТОЛЬКО живое видео (сырой поток). Снятые кадры уже сохранены в нужной ориентации при съёмке
   (canvas рисуется с учётом зеркала), поэтому в карусели показываются КАК ЕСТЬ — без повторного scaleX,
   иначе было бы двойное зеркало (миниатюра норм, большое фото перевёрнуто). */
.cs[data-mirror="1"] .cs__video { transform: scaleX(-1); }

/* ---- карусель снятых кадров ---- */
.cs__track {
    position: absolute; inset: 0; display: flex;
    touch-action: pan-y; will-change: transform;
}
.cs__track.is-anim { transition: transform .28s ease; }
.cs__slide { position: relative; flex: 0 0 100%; height: 100%; }
.cs__slide img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    background: var(--cs-stage);
    -webkit-user-drag: none; user-select: none; -webkit-user-select: none;
}
.cs[data-state="review"] .cs__preview { cursor: grab; }
.cs[data-state="review"].cs--dragging .cs__preview { cursor: grabbing; }

/* видимость слоёв по состоянию */
.cs[data-state="idle"]   .cs__video,
.cs[data-state="review"] .cs__video { display: none; }
.cs[data-state="idle"]   .cs__track,
.cs[data-state="live"]   .cs__track { display: none; }
.cs[data-state="live"]   .cs__placeholder,
.cs[data-state="review"] .cs__placeholder { display: none; }

/* плейсхолдер */
.cs__placeholder {
    position: absolute; inset: 0; z-index: 2;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .65rem;
    text-align: center; padding: 1.25rem; color: #e8e8f2;
}
.cs__cam-circle {
    display: inline-grid; place-items: center;
    width: 72px; height: 72px; border-radius: 50%;
    background: linear-gradient(135deg, var(--cs-accent), var(--cs-accent-2));
    color: #fff; font-size: 1.9rem; box-shadow: 0 8px 22px rgba(91, 102, 230, .45);
}
.cs__start {
    display: inline-flex; align-items: center; gap: .5rem;
    background: #fff; color: var(--cs-accent); font-weight: 600;
    border: 0; border-radius: var(--cs-radius-sm); padding: .6rem 1.4rem;
}
.cs__start:hover { background: var(--cs-soft); color: var(--cs-accent-dark); }
.cs__placeholder-text { margin: 0; font-size: .95rem; }
.cs__placeholder-note { margin: 0; font-size: .8rem; color: #b9b9cc; display: flex; flex-direction: column; }

/* вспышка */
.cs__flash { position: absolute; inset: 0; z-index: 5; background: #fff; opacity: 0; pointer-events: none; }
.cs__flash.is-on { animation: cs-flash .32s ease-out; }
@keyframes cs-flash { 0% { opacity: .9; } 100% { opacity: 0; } }

/* оверлеи поверх превью */
.cs__ovl {
    position: absolute; z-index: 3;
    display: inline-flex; align-items: center; gap: .35rem;
    background: rgba(20, 18, 36, .55); color: #fff;
    border: 0; border-radius: 999px; padding: .4rem .7rem; font-size: .82rem; cursor: pointer;
    backdrop-filter: blur(2px);
}
.cs__ovl:hover { background: rgba(20, 18, 36, .72); }
.cs__mirror { top: .7rem; right: .7rem; }
.cs__mirror[aria-pressed="true"] { background: var(--cs-accent); }
.cs__flip { bottom: .7rem; right: .7rem; width: 42px; height: 42px; justify-content: center; padding: 0; font-size: 1.1rem; }
/* mirror/flip — только в live (поверх живого видео) */
.cs[data-state="idle"]   .cs__mirror,
.cs[data-state="review"] .cs__mirror,
.cs[data-state="idle"]   .cs__flip,
.cs[data-state="review"] .cs__flip { display: none; }
/* Settings-оверлей — по умолчанию (десктоп) скрыт: там настройки в шапке. Включается на мобайле,
   в правом верхнем углу превью (справа от Mirror). */
.cs__settings-ovl { display: none; top: .7rem; right: .7rem; width: 42px; height: 42px; justify-content: center; padding: 0; font-size: 1.05rem; }
.cs__settings-ovl[aria-expanded="true"] { background: var(--cs-accent); }
/* «Снять ещё» — полупрозрачный оверлей в левом нижнем углу, только в review */
.cs__more { left: .7rem; bottom: .7rem; }
.cs[data-state="idle"] .cs__more,
.cs[data-state="live"] .cs__more { display: none; }

/* счётчик «фото N из M» — только в review */
.cs__counter {
    position: absolute; top: .7rem; left: .7rem; z-index: 3;
    background: rgba(20, 18, 36, .55); color: #fff;
    border-radius: 999px; padding: .3rem .7rem; font-size: .8rem;
    font-variant-numeric: tabular-nums; backdrop-filter: blur(2px);
}

/* стрелки навигации по бокам stage — только в review */
.cs__nav {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 4;
    width: 44px; height: 44px; border-radius: 50%;
    background: rgba(255, 255, 255, .92); border: 1px solid var(--cs-line);
    color: var(--cs-text); font-size: 1.3rem; display: grid; place-items: center; cursor: pointer;
    box-shadow: 0 4px 14px rgba(40, 30, 90, .18);
}
.cs__nav:hover { color: var(--cs-accent); }
.cs__nav:disabled { opacity: .4; cursor: default; }
.cs__nav-prev { left: .55rem; }
.cs__nav-next { right: .55rem; }
.cs[data-state="idle"] .cs__nav,
.cs[data-state="live"] .cs__nav { display: none; }

/* ====================================================================
   Кнопка-затвор + «Снять ещё»
   ==================================================================== */
/* Кнопка-затвор «сидит» на нижней кромке превью (верхняя половина — на фото), как на макете.
   shoot-wrap позиционируется поверх стыка; «Take more» — справа на уровне кнопки. */
/* Кнопка-затвор — внутри превью, в одном слое с видео (как оверлеи), её центр на нижней кромке.
   z-index выше видео/оверлеев; видео НЕ может её перекрыть (тот же stacking-контекст превью). */
.cs__shoot-wrap {
    position: absolute; top: calc(100% - 42px); left: 50%; transform: translateX(-50%); z-index: 6;
    display: flex; flex-direction: column; align-items: center; gap: .35rem;
}
.cs__shoot {
    position: relative;
    width: 84px; height: 84px; border-radius: 50%; border: 0; cursor: pointer;
    background: linear-gradient(135deg, var(--cs-accent), var(--cs-accent-2));
    color: #fff; font-size: 1.9rem; display: grid; place-items: center;
    transition: transform .08s ease;
}
/* Белый ореол — ОТДЕЛЬНЫЙ НЕПРОЗРАЧНЫЙ круг-подложка, а НЕ box-shadow. Причина: над живым <video> в Chrome
   box-shadow пропадает (видео-overlay не блендит полупрозрачную тень), а непрозрачный элемент компонуется
   поверх видео — ровно как тело кнопки. Воспроизведено в headed Chrome (repro_*.png). Тонкий контур держит
   читаемость на светлом фоне, мягкая тень снизу — на белой карточке. */
.cs__shoot::before {
    content: ""; position: absolute; inset: -7px; z-index: -1;
    border-radius: 50%; background: #fff;
    border: 1px solid rgba(54, 54, 84, .18);
    box-shadow: 0 6px 18px rgba(20, 20, 50, .30);
}
.cs__shoot:hover { background: linear-gradient(135deg, var(--cs-accent-dark), var(--cs-accent)); }
.cs__shoot:active { transform: scale(.93); }
.cs__shoot-cap { font-size: .82rem; color: var(--cs-muted); margin-top: .1rem; }

/* ====================================================================
   Лента-фотоплёнка (перфорация сверху/снизу, новый кадр слева)
   ==================================================================== */
/* Лента и нижние действия нужны только когда есть хотя бы одно фото — до съёмки их не показываем */
.cs:not(.has-frames) .cs__filmstrip,
.cs:not(.has-frames) .cs__actions { display: none; }

.cs__filmstrip {
    position: relative; margin-top: 1rem;
    background: #e9eaf0; border-radius: var(--cs-radius-sm);
    padding: 14px 12px; min-height: calc(var(--cs-thumb) + 28px);
}
/* перфорация — ряды светлых «прорезей» сверху и снизу */
.cs__filmstrip::before,
.cs__filmstrip::after {
    content: ""; position: absolute; left: 8px; right: 8px; height: 7px;
    background-image: repeating-linear-gradient(90deg, var(--cs-card) 0 9px, transparent 9px 17px);
    background-size: 17px 7px;
}
.cs__filmstrip::before { top: 4px; }
.cs__filmstrip::after { bottom: 4px; }

.cs__strip-empty { margin: 0; color: #7a7a8c; font-size: .88rem; text-align: center; padding: calc((var(--cs-thumb) - 18px) / 2) 0; }
.cs:not([data-state="idle"]) .cs__strip-empty,
.cs.has-frames .cs__strip-empty { display: none; }

.cs__strip { display: flex; gap: .6rem; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin;
    cursor: grab; -webkit-overflow-scrolling: touch; }
.cs__strip.is-grabbing { cursor: grabbing; }
.cs:not(.has-frames) .cs__strip { display: none; }

.cs__frame {
    flex: none; position: relative; width: var(--cs-thumb); height: var(--cs-thumb);
    border-radius: var(--cs-radius-sm); overflow: hidden; cursor: pointer; padding: 0; border: 2px solid transparent;
    background: #fff;
}
.cs__frame img { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; }
.cs__frame.is-current { border-color: var(--cs-accent); }
.cs__frame-check {
    position: absolute; top: 4px; right: 4px;
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--cs-accent); color: #fff;
    display: none; place-items: center; font-size: .9rem; box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
}
.cs__frame.is-current .cs__frame-check { display: grid; }

.cs__addtile {
    flex: none; width: var(--cs-thumb); height: var(--cs-thumb);
    border: 2px dashed #c7ccf5; border-radius: var(--cs-radius-sm); background: #fff;
    color: var(--cs-accent); font-size: 1.5rem; display: grid; place-items: center; cursor: pointer;
}
.cs__addtile:hover { background: var(--cs-soft); }

/* ====================================================================
   Нижние действия
   ==================================================================== */
.cs__actions { display: flex; gap: .8rem; margin-top: 1rem; }
.cs__dlgroup { position: relative; flex: 1 1 auto; display: flex; }
.cs__download {
    flex: 1 1 auto;
    background: linear-gradient(135deg, var(--cs-accent), var(--cs-accent-2));
    border: 0; color: #fff; font-weight: 600; border-radius: var(--cs-radius-sm);
    padding: .8rem 1.4rem; display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
}
.cs__download:hover { background: linear-gradient(135deg, var(--cs-accent-dark), var(--cs-accent)); color: #fff; }
.cs__download:disabled { background: #c8cbe6; color: #fff; cursor: default; }
/* стрелка split-кнопки — видна, только когда «Download all» доступен (JS снимает hidden + ставит .has-more).
   ВАЖНО: обрезаем правое скругление только у ОСНОВНОЙ кнопки (прямой ребёнок), а не у копии в меню. */
.cs__dlgroup.has-more > .cs__download { border-radius: var(--cs-radius-sm) 0 0 var(--cs-radius-sm); }
.cs__download-more {
    flex: 0 0 auto; width: 46px; padding: 0;
    background: linear-gradient(135deg, var(--cs-accent), var(--cs-accent-2));
    border: 0; border-left: 1px solid rgba(255, 255, 255, .35); color: #fff;
    border-radius: 0 var(--cs-radius-sm) var(--cs-radius-sm) 0;
    display: inline-flex; align-items: center; justify-content: center; font-size: 1rem;
}
.cs__download-more:hover:not(:disabled) { background: linear-gradient(135deg, var(--cs-accent-dark), var(--cs-accent)); }
/* стрелка неактивна вместе с основной кнопкой */
.cs__download-more:disabled { background: #c8cbe6; cursor: default; }
/* выпадающая альтернатива = КОПИЯ основной кнопки (большая фиолетовая «Download all»),
   поповером ВНИЗ из-под split-кнопки, по её ширине, со всеми скруглёнными углами */
.cs__dlmenu {
    position: absolute; left: 0; right: 0; top: calc(100% + 8px); z-index: 20;
    padding: 0; background: transparent; border: 0;
}
.cs__dlmenu-item { width: 100%; border-radius: var(--cs-radius-sm); box-shadow: 0 12px 28px rgba(40, 30, 90, .24); }
.cs__clear {
    flex: 0 0 auto;
    background: #fff; border: 1px solid #f0c9c5; color: var(--cs-danger);
    border-radius: var(--cs-radius-sm); padding: .8rem 1.3rem;
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
}
.cs__clear:hover:not(:disabled) { background: #fdecea; border-color: var(--cs-danger); color: var(--cs-danger); }
.cs__clear:disabled { opacity: .5; cursor: default; }

/* ошибка / предупреждение */
.cs__error { margin: .85rem 0 0; min-height: 0; color: var(--cs-danger); font-size: .9rem; text-align: center; }
.cs__error:empty { margin: 0; }
.cs__error.is-warn { color: #8a6d1a; }

/* ====================================================================
   Модалка подтверждения (по центру приложения, вместо нативного confirm)
   ==================================================================== */
.cs__modal {
    position: fixed; inset: 0; z-index: 1090;
    display: grid; place-items: center; padding: 1rem;
    background: rgba(20, 18, 40, .5); backdrop-filter: blur(2px);
}
.cs__modal-card {
    background: #fff; border-radius: var(--cs-radius);
    padding: 1.5rem 1.4rem 1.2rem; max-width: 360px; width: 100%; text-align: center;
    box-shadow: 0 20px 50px rgba(20, 15, 50, .35);
}
.cs__modal-ic {
    display: inline-grid; place-items: center; width: 50px; height: 50px; border-radius: 50%;
    background: #fdecea; color: var(--cs-danger); font-size: 1.45rem; margin-bottom: .8rem;
}
.cs__modal-text { font-size: 1rem; color: var(--cs-text); margin: 0 0 1.3rem; }
.cs__modal-actions { display: flex; gap: .7rem; }
.cs__modal-btn {
    flex: 1 1 0; border-radius: var(--cs-radius-sm); padding: .7rem 1rem;
    font-weight: 600; font-size: .95rem; cursor: pointer; border: 1px solid var(--cs-line);
}
.cs__modal-cancel { background: #fff; color: var(--cs-text); }
.cs__modal-cancel:hover { background: var(--cs-bg); }
.cs__modal-ok { background: var(--cs-danger); color: #fff; border-color: var(--cs-danger); }
.cs__modal-ok:hover { background: #bf3b2f; }

/* «How it works» — общий блок движка (.tool-explain), стили в assets/css/app.css. */

/* ====================================================================
   Мобайл — упрощённый интерфейс «как камера телефона»: крупное превью, минимум текста.
   Форма превью — ПО ОРИЕНТАЦИИ устройства (портрет стоя / горизонталь лёжа).
   ==================================================================== */
@media (max-width: 640px) {
    .cs { padding: .7rem .6rem .8rem; }
    /* минимализм: убираем верхнюю шапку целиком (Settings уезжает оверлеем в угол превью),
       подпись под затвором, длинный плейсхолдер */
    .cs__head { display: none; }
    .cs__shoot-cap { display: none; }
    /* Settings — оверлеем в ВЕРХНЕМ правом углу превью, справа от Mirror (в live/review) */
    .cs[data-state="live"]   .cs__settings-ovl,
    .cs[data-state="review"] .cs__settings-ovl { display: inline-flex; }
    /* Mirror на мобайле — круглая иконка БЕЗ подписи, левее Settings */
    .cs__mirror { right: calc(.7rem + 50px); width: 42px; height: 42px; padding: 0; gap: 0; justify-content: center; font-size: 1.05rem; }
    .cs__mirror span { display: none; }
    .cs__placeholder-text, .cs__placeholder-note { display: none; }
    .cs__settings { grid-template-columns: 1fr; gap: .8rem; }
    .cs__headbtn span { display: none; }
    .cs__headbtn { padding: .45rem .6rem; }
    /* крупное превью; ПОРТРЕТ когда телефон стоя */
    .cs__preview { aspect-ratio: 3 / 4; max-height: 62vh; }
    .cs__stage { margin-bottom: 54px; }            /* подпись убрана → меньше резерв под выступ кнопки */
    .cs__nav { width: 38px; height: 38px; font-size: 1.15rem; }
    .cs__nav-prev { left: .35rem; } .cs__nav-next { right: .35rem; }
    .cs__actions { flex-direction: column; }
    .cs__clear { width: 100%; }
}
/* телефон/планшет ЛЁЖА — широкое превью */
@media (max-width: 900px) and (orientation: landscape) {
    .cs__logo, .cs__title { display: none; }
    .cs__shoot-cap { display: none; }
    .cs__placeholder-text, .cs__placeholder-note { display: none; }
    .cs__preview { aspect-ratio: 16 / 9; max-height: 78vh; }
}
@media (max-width: 380px) {
    .cs { --cs-thumb: 66px; }
    .cs__shoot { width: 60px; height: 60px; font-size: 1.3rem; }
    .cs__shoot-wrap { top: calc(100% - 30px); }   /* кнопка 60px → половина 30px на кромке */
    .cs__stage { margin-bottom: 44px; }
    .cs__more { padding: .5rem .8rem; font-size: .85rem; }
}
