/* ==== ШРИФТЫ: собрано tools/build_fonts.py, вручную не править ==== */
@font-face{font-family:'Inter';font-style:italic;font-weight:300;font-display:swap;src:url('/static/fonts/inter-300i-cyrillic.woff2') format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Inter';font-style:italic;font-weight:300;font-display:swap;src:url('/static/fonts/inter-300i-latin.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:'Inter';font-style:italic;font-weight:400;font-display:swap;src:url('/static/fonts/inter-400i-cyrillic.woff2') format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Inter';font-style:italic;font-weight:400;font-display:swap;src:url('/static/fonts/inter-400i-latin.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:'Inter';font-style:italic;font-weight:900;font-display:swap;src:url('/static/fonts/inter-900i-cyrillic.woff2') format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Inter';font-style:italic;font-weight:900;font-display:swap;src:url('/static/fonts/inter-900i-latin.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:'Inter';font-style:normal;font-weight:300;font-display:swap;src:url('/static/fonts/inter-300-cyrillic.woff2') format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Inter';font-style:normal;font-weight:300;font-display:swap;src:url('/static/fonts/inter-300-latin.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:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('/static/fonts/inter-400-cyrillic.woff2') format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('/static/fonts/inter-400-latin.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:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/inter-500-cyrillic.woff2') format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/inter-500-latin.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:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('/static/fonts/inter-600-cyrillic.woff2') format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('/static/fonts/inter-600-latin.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:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url('/static/fonts/inter-700-cyrillic.woff2') format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url('/static/fonts/inter-700-latin.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:'Inter';font-style:normal;font-weight:900;font-display:swap;src:url('/static/fonts/inter-900-cyrillic.woff2') format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Inter';font-style:normal;font-weight:900;font-display:swap;src:url('/static/fonts/inter-900-latin.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:'Space Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/space-grotesk-500-latin.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:'Space Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url('/static/fonts/space-grotesk-700-latin.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}
/* ==== конец шрифтов ==== */
/* Namiko — единая таблица стилей.
 *
 * Разметка одна на оба устройства, различается только оформление:
 *   1. базовый макет — рабочий стол (исходник дизайна, _design/style-desktop.css);
 *   2. прикладной слой — то, чего в статичном макете не было;
 *   3. мобильный макет — до 899px, переложен на ту же разметку.
 *
 * Исходники дизайна лежат в _design/ и не подключаются — они справочные.
 */

/* ═══ 1. БАЗОВЫЙ МАКЕТ (рабочий стол) ═══ */
:root{--bg:#111214;--panel:#1a1b1e;--panel-deep:#16171a;--text:#fff;--warn:#ffb020;--muted:rgba(255,255,255,.42);--faint:rgba(255,255,255,.22);--border:rgba(255,255,255,.08);--coral:#f55555;--coral-hover:#ff6b6b;--blue:#60a5fa;--max:1240px}
*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:var(--bg);color:var(--text);font-family:Inter,system-ui,sans-serif;-webkit-font-smoothing:antialiased;overflow-x:hidden}a{color:inherit;text-decoration:none}button,input{font:inherit}.container{width:min(var(--max),calc(100% - 48px));margin-inline:auto}.site-nav{position:sticky;top:0;z-index:10;background:rgba(17,18,20,.86);border-bottom:1px solid rgba(255,255,255,.05);backdrop-filter:blur(16px)}.nav-inner{height:64px;display:flex;align-items:center;justify-content:space-between}.brand-nav{display:flex;align-items:center;gap:36px}.brand{display:inline-flex;align-items:center;gap:9px;font:700 19px/1 'Space Grotesk',sans-serif;letter-spacing:-.04em}.brand-mark{width:32px;height:32px;display:block;border-radius:8px}.nav-links,.auth-actions{display:flex;align-items:center;gap:26px}.nav-links a,.auth-actions>a:first-child{font-size:13px;font-weight:600;color:rgba(255,255,255,.62);transition:color .2s}.nav-links a:hover,.auth-actions>a:first-child:hover{color:var(--coral)}.auth-actions{gap:18px}.button{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:56px;border:1px solid transparent;border-radius:8px;padding:0 32px;font-size:11px;font-weight:700;letter-spacing:.19em;text-transform:uppercase;transition:transform .2s,background .2s,border-color .2s,box-shadow .2s}.button:hover{transform:translateY(-2px)}.button-small{min-height:34px;padding:0 18px;background:var(--coral);border-radius:6px;font-size:10px}.button-primary{background:var(--coral);box-shadow:0 0 40px -12px rgba(245,85,85,.72)}.button-primary:hover{background:var(--coral-hover);box-shadow:0 0 48px -8px rgba(245,85,85,.72)}.button-ghost{background:rgba(255,255,255,.04);border-color:rgba(255,255,255,.12)}.button-ghost:hover{background:rgba(255,255,255,.09)}.promo-banner{background:var(--panel);border-bottom:1px solid rgba(255,255,255,.05)}.promo-inner{min-height:48px;display:flex;align-items:center;justify-content:center;gap:14px}.eyebrow,.section-subtitle,.site-footer h4{font-size:10px;font-weight:700;letter-spacing:.22em;text-transform:uppercase}.eyebrow{color:rgba(255,255,255,.36)}.promo-inner p{margin:0;color:rgba(255,255,255,.78);font-size:12px;font-weight:500}.pill-button{padding:7px 14px;border:1px solid rgba(255,255,255,.12);border-radius:999px;background:rgba(255,255,255,.04);font-size:10px;font-weight:700;text-transform:uppercase;transition:background .2s}.pill-button:hover{background:rgba(255,255,255,.1)}.hero{position:relative;padding:128px 0 158px;overflow:hidden}.hero-content{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;text-align:center}.hero-glow{position:absolute;border-radius:50%;filter:blur(2px);animation:float 10s ease-in-out infinite;pointer-events:none}.hero-glow-blue{left:22%;top:0;width:700px;height:700px;background:radial-gradient(circle,rgba(59,130,246,.15),transparent 70%)}.hero-glow-violet{right:20%;bottom:-180px;width:800px;height:800px;background:radial-gradient(circle,rgba(139,92,246,.15),transparent 70%);animation-delay:-5s}.live-badge{display:inline-flex;align-items:center;gap:9px;padding:9px 16px;margin-bottom:48px;border:1px solid rgba(255,255,255,.12);border-radius:999px;background:rgba(255,255,255,.04);font-size:10px;font-weight:700;letter-spacing:.28em;text-transform:uppercase;color:rgba(255,255,255,.62)}.live-badge span{width:8px;height:8px;border-radius:50%;background:var(--coral);box-shadow:0 0 12px var(--coral)}.hero-heading{position:relative;margin-bottom:46px}.hero-heading .hero-poster{margin:0;font:700 clamp(64px,8.5vw,128px)/.85 'Space Grotesk',sans-serif;letter-spacing:-.075em}.hero-heading em{font-style:normal;color:var(--coral)}.quote-mark{position:absolute;right:-40px;top:-42px;font-size:88px;color:rgba(255,255,255,.2)}.hero-description{max-width:740px;margin:0 0 64px;color:rgba(255,255,255,.56);font-size:20px;line-height:1.55;font-weight:300}.hero-actions{display:flex;gap:32px}.preview-section,.characters-section,.features-section,.cta-section{margin-bottom:128px}.chat-preview{display:grid;grid-template-columns:256px minmax(0,1fr) 320px;height:700px;overflow:hidden;border:1px solid rgba(255,255,255,.1);border-radius:16px;background:var(--panel);box-shadow:0 24px 80px rgba(0,0,0,.32)}.sidebar{display:flex;flex-direction:column;background:var(--panel-deep);border-right:1px solid var(--border)}.sidebar-title{display:flex;align-items:center;gap:12px;padding:24px;color:rgba(255,255,255,.35);font:700 12px/1 'Space Grotesk',sans-serif;letter-spacing:.16em}.icon-box,.feature-icon{display:grid;place-items:center;background:rgba(255,255,255,.05);border-radius:10px}.icon-box{width:32px;height:32px}.sidebar-links{padding:0 16px;display:flex;flex-direction:column;gap:4px}.sidebar-links a,.sidebar-settings{display:flex;align-items:center;gap:12px;padding:12px;border-radius:8px;color:rgba(255,255,255,.44);font-size:13px;font-weight:500;transition:.2s}.sidebar-links a:hover,.sidebar-links a.active{background:rgba(255,255,255,.06);color:#fff}.sidebar-links i:first-child,.sidebar-settings i{color:var(--coral)}.sidebar-settings{margin-top:auto;margin-bottom:18px;padding-inline:24px;border-top:1px solid var(--border);border-radius:0;padding-top:22px;font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase}.chat-main{display:flex;flex-direction:column;min-width:0;background:var(--panel)}.chat-header{display:flex;align-items:center;justify-content:space-between;padding:20px;border-bottom:1px solid var(--border)}.chat-contact{display:flex;align-items:center;gap:14px}.avatar-initial{display:grid;place-items:center;width:40px;height:40px;border:1px solid rgba(245,85,85,.22);border-radius:50%;background:rgba(245,85,85,.1);color:var(--coral);font-weight:700}.chat-contact strong{display:block;font-size:13px}.chat-contact small{display:flex;align-items:center;gap:6px;margin-top:4px;color:rgba(255,255,255,.38);font-size:10px}.online-dot{width:6px;height:6px;border-radius:50%;background:#22c55e}.chat-badges{display:flex;gap:8px}.chat-badges span{padding:6px 8px;border:1px solid var(--border);border-radius:4px;color:rgba(255,255,255,.36);font-size:9px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;font-style:italic}.message-history{flex:1;padding:24px;display:flex;flex-direction:column;gap:28px;overflow:auto}.message-row{display:flex;gap:14px;max-width:86%}.message-row.sent{justify-content:flex-end;align-self:flex-end}.message-row p{margin:0;padding:16px;border:1px solid rgba(255,255,255,.1);border-radius:16px;background:linear-gradient(rgba(255,255,255,.04),rgba(255,255,255,.04)),rgba(46,48,56,var(--bub-a,.1));color:rgba(255,255,255,.8);font-size:13px;line-height:1.6}.message-row.sent p{border-color:rgba(245,85,85,.2);background:linear-gradient(rgba(245,85,85,.1),rgba(245,85,85,.1)),rgba(46,48,56,var(--bub-a,.1));color:#fff}.message-row em{color:rgba(255,255,255,.38)}.bot-icon{display:grid;place-items:center;flex:0 0 32px;width:32px;height:32px;border-radius:50%;background:rgba(255,255,255,.05);color:rgba(255,255,255,.3)}.composer{display:flex;align-items:flex-end;gap:8px;padding:20px;border-top:1px solid var(--border)}.composer input,.composer textarea{width:100%;min-width:0;outline:0;border:1px solid var(--border);border-radius:10px;background:var(--panel-deep);padding:16px;color:#fff}.composer input::placeholder,.composer textarea::placeholder{color:rgba(255,255,255,.2)}.composer textarea::placeholder{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.composer textarea{resize:none;overflow-y:hidden;font:inherit;line-height:1.45;max-height:none;display:block}.icon-button,.send-button{display:grid;place-items:center;border:0;color:rgba(255,255,255,.4);cursor:pointer}.icon-button{width:36px;height:36px;background:transparent}.send-button{width:40px;height:40px;border-radius:8px;background:var(--coral);color:#fff;box-shadow:0 8px 24px rgba(245,85,85,.22)}.profile-rail{display:flex;flex-direction:column;align-items:center;padding:32px;background:var(--panel-deep);border-left:1px solid var(--border)}.portrait{position:relative;width:100%;aspect-ratio:4/5;overflow:hidden;border:1px solid var(--border);border-radius:12px}.portrait img,.card-image img{width:100%;height:100%;display:block;object-fit:cover;transition:transform .8s}.portrait:hover img,.character-card:hover .card-image img{transform:scale(1.06)}.portrait:after,.card-image:after{content:"";position:absolute;inset:0;background:linear-gradient(to top,rgba(17,18,20,.9),transparent 65%);pointer-events:none}.profile-copy{text-align:center;margin:22px 0}.profile-copy h2{margin:0 0 6px;font:700 24px/1 'Space Grotesk',sans-serif}.profile-copy strong,.card-copy>strong{color:var(--coral);font-size:10px;letter-spacing:.15em;text-transform:uppercase}.tag-list{display:flex;flex-wrap:wrap;gap:8px}.profile-rail .tag-list{justify-content:center}.tag-list span{padding:5px 8px;border:1px solid var(--border);border-radius:5px;background:rgba(255,255,255,.04);color:rgba(255,255,255,.46);font-size:9px;font-style:italic}.profile-bio{margin:24px 0;text-align:center;color:rgba(255,255,255,.4);font-size:12px;line-height:1.65}.profile-button{width:100%;margin-top:auto;min-height:52px}.section-header{display:flex;align-items:flex-end;justify-content:space-between;margin-bottom:38px}.section-title{margin:0 0 10px;padding-left:20px;border-left:4px solid var(--coral);font:700 30px/1 'Space Grotesk',sans-serif}.section-subtitle{margin:0;padding-left:24px;color:rgba(255,255,255,.35)}.section-link{display:flex;align-items:center;gap:8px;color:var(--coral);font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase}.characters-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:32px}.character-card{display:flex;height:190px;overflow:hidden;border:1px solid rgba(255,255,255,.06);border-radius:16px;background:var(--panel);transition:border-color .3s,box-shadow .3s}.character-card:hover{border-color:rgba(245,85,85,.4);box-shadow:0 24px 60px rgba(0,0,0,.3)}.card-image{position:relative;width:192px;flex:0 0 192px;overflow:hidden}.card-copy{position:relative;display:flex;flex:1;flex-direction:column;justify-content:center;padding:26px}.card-copy .status{position:absolute;top:26px;right:26px;width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.18)}.card-copy .status.active{background:var(--coral);box-shadow:0 0 8px var(--coral);animation:pulse 2s infinite}.card-copy h3{margin:0 0 7px;font-size:22px;line-height:1.1}.card-copy .tag-list{margin-top:16px}.feature-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:32px}.feature-card{position:relative;min-height:310px;padding:36px;border:1px solid rgba(255,255,255,.06);border-radius:16px;background:var(--panel);overflow:hidden}.feature-icon{width:56px;height:56px;margin-bottom:28px;font-size:26px}.feature-icon.coral{color:var(--coral)}.feature-icon.blue{color:var(--blue)}.feature-card h3{margin:0 0 16px;font:700 23px/1.1 'Space Grotesk',sans-serif}.feature-card p{margin:0;color:rgba(255,255,255,.32);font-size:13px;line-height:1.7}.feature-highlight{display:flex;flex-direction:column;justify-content:flex-end}.feature-highlight h3{font-size:34px;color:#fff}.feature-highlight p{margin-bottom:28px;color:rgba(255,255,255,.42)}.feature-highlight .button{align-self:flex-start}.background-icon{position:absolute;right:-38px;top:-34px;font-size:190px;color:#fff;opacity:.035;transform:rotate(-12deg)}.cta-inner{position:relative;min-height:456px;display:grid;place-items:center;overflow:hidden;border:1px solid rgba(255,255,255,.06);border-radius:24px;background:var(--panel-deep);text-align:center}.cta-content{position:relative;z-index:1;padding:32px}.cta-content h2{margin:0 0 28px;font:700 clamp(44px,5.5vw,76px)/.95 'Space Grotesk',sans-serif;letter-spacing:-.06em}.cta-content p{max-width:650px;margin:0 auto 56px;color:rgba(255,255,255,.4);font-size:19px;line-height:1.55}.cta-glow{position:absolute;left:50%;top:50%;width:500px;height:500px;border-radius:50%;transform:translate(-50%,-50%);filter:blur(90px);animation:float 10s ease-in-out infinite}.cta-glow.blue{background:rgba(37,99,235,.18)}.cta-glow.violet{width:350px;height:350px;background:rgba(124,58,237,.2);animation-delay:-3s}.site-footer{padding:64px 0 32px;border-top:1px solid rgba(255,255,255,.05);background:var(--bg)}.footer-grid{display:grid;grid-template-columns:1.5fr 1fr 1.2fr 1fr;gap:40px;margin-bottom:64px}.footer-brand{max-width:410px}.footer-brand p{margin:24px 0;color:rgba(255,255,255,.3);font-size:13px;line-height:1.7}.socials{display:flex;gap:14px}.socials a{display:grid;place-items:center;width:40px;height:40px;border-radius:50%;background:rgba(255,255,255,.05);transition:background .2s}.socials a:hover{background:var(--coral)}.site-footer h4{margin:0 0 24px;color:rgba(255,255,255,.2)}.site-footer>div>div:not(.footer-brand)>a{display:block;margin-bottom:18px;color:rgba(255,255,255,.4);font-size:13px}.site-footer>div>div:not(.footer-brand)>a:hover{color:var(--coral)}.footer-bottom{display:flex;justify-content:space-between;padding-top:24px;border-top:1px solid rgba(255,255,255,.05);color:rgba(255,255,255,.2);font-size:10px;font-weight:700;letter-spacing:.13em;text-transform:uppercase}.footer-bottom b{margin-left:28px;color:var(--coral)}.section-reveal{opacity:1;transform:translateY(0)}@keyframes float{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-18px) scale(1.04)}}@keyframes pulse{50%{opacity:.45}}
@media (max-width:980px){.nav-links{display:none}.chat-preview{grid-template-columns:1fr;height:auto}.sidebar{display:none}.chat-main{min-height:620px}.profile-rail{border-top:1px solid var(--border);border-left:0}.feature-grid{grid-template-columns:1fr 1fr}.feature-highlight{grid-column:1/-1;min-height:280px}.characters-grid{gap:20px}.character-card{height:170px}.card-image{width:150px;flex-basis:150px}}
@media (max-width:640px){.container{width:calc(100% - 32px)}.auth-actions>a:first-child{display:none}.promo-inner{flex-wrap:wrap;padding:10px 16px;gap:8px}.promo-inner p{font-size:11px;text-align:center}.hero{padding:90px 0 100px}.live-badge{margin-bottom:34px;font-size:8px;letter-spacing:.18em}.hero-heading .hero-poster{font-size:56px}.hero-description{font-size:16px;margin-bottom:38px}.hero-actions{width:100%;flex-direction:column;gap:12px}.hero-actions .button{width:100%}.preview-section,.characters-section,.features-section,.cta-section{margin-bottom:88px}.chat-header{padding:16px}.chat-badges{display:none}.message-history{padding:16px;gap:18px}.profile-rail{padding:20px}.section-header{align-items:flex-start;gap:16px}.section-title{font-size:25px}.section-link{font-size:9px}.characters-grid{grid-template-columns:1fr}.character-card{height:160px}.card-image{width:130px;flex-basis:130px}.card-copy{padding:18px}.card-copy h3{font-size:19px}.feature-grid{grid-template-columns:1fr}.feature-highlight{grid-column:auto}.cta-inner{min-height:400px}.cta-content h2{font-size:48px}.cta-content p{font-size:16px;margin-bottom:34px}.footer-grid{grid-template-columns:1fr 1fr;gap:36px}.footer-brand{grid-column:1/-1}.footer-bottom{flex-direction:column;gap:16px;line-height:1.6}}

/* ══════════════════════════════════════════════════════════════════════════
   2. ПРИКЛАДНОЙ СЛОЙ
   Живой чат, модалки, список диалогов, память, полноэкранный режим — всё,
   чего не было в статичном макете.
   ══════════════════════════════════════════════════════════════════════════ */

/* Узлы, живущие только в одном из макетов.
   Прятать надо ТОЛЬКО в чужом макете: если оставить .only-mobile{display:none}
   без медиазапроса, а в мобильном слое возвращать display, правило перебьёт
   собственные стили узла — так шторка меню однажды раскрылась во весь экран
   и перехватила все клики. Поэтому в «своём» макете правила нет вовсе. */
@media (min-width:900px){.only-mobile{display:none!important}}
@media (max-width:899px){.only-desktop{display:none!important}}

/* Промо-плашка. Разметка вложена по мобильному макету (строка «режим + кнопка»,
   под ней текст). На широком экране обёртки распускаются, и .eyebrow / p /
   .pill-button снова становятся прямыми детьми флекс-строки — но порядок при
   этом сбивается, поэтому он задан явно. */
.promo-top,.promo-mode{display:contents}
.promo-inner .eyebrow{order:1}
.promo-inner p{order:2}
.promo-inner .pill-button{order:3}

/* нижняя строка подвала: отжимаем правую группу */
.footer-bottom .fb-note{margin-right:auto}

/* липкая шапка перекрывает якорь без этого отступа */
section[id],main[id]{scroll-margin-top:80px}
.is-hidden{display:none!important}

/* ── цвет текста на кнопках ───────────────────────────────────────────────── */
/* <button> не наследует цвет от родителя: браузер подставляет свой системный
   чёрный. В макете все кнопки были ссылками <a>, там цвет наследуется от body,
   поэтому в статике проблема не проявлялась — вылезла на наших настоящих
   кнопках: «Очистить», «Отмена», «Показать всех». */
button{color:inherit}
.button-primary,.button-danger,.button-small{color:#fff}

/* ── аватары вместо букв ──────────────────────────────────────────────────── */
.avatar-initial,.bot-icon{overflow:hidden}
.avatar-initial img,.bot-icon img{width:100%;height:100%;display:block;object-fit:cover;border-radius:50%}
.card-image .letter,.portrait .letter{display:grid;place-items:center;width:100%;height:100%;
  background:linear-gradient(150deg,rgba(245,85,85,.25),rgba(96,165,250,.18));
  font:700 44px/1 'Space Grotesk',sans-serif;color:rgba(255,255,255,.75)}
.portrait .letter{font-size:76px}

/* ── лента сообщений ──────────────────────────────────────────────────────── */
/* pre-line, а не pre-wrap: переносы строк модели сохраняем, но пробелы
   схлопываем. Модель почти всегда ставит пробел после переноса, и pre-wrap
   рисовал его буквально — каждая следующая строка начиналась с отступа. */
.message-row p{white-space:pre-line}
.message-row.system{align-self:center;max-width:94%}
.message-row.system p{border-color:rgba(245,158,11,.35);background:linear-gradient(rgba(245,158,11,.1),rgba(245,158,11,.1)),rgba(46,48,56,var(--bub-a,.1));color:#ffd9a8}
.typing{display:flex;gap:5px;align-self:flex-start;padding:17px;border:1px solid rgba(255,255,255,.1);
  border-radius:16px;background:rgba(255,255,255,.04)}
.typing i{width:7px;height:7px;border-radius:50%;background:rgba(255,255,255,.45);animation:blink 1.3s infinite}
.typing i:nth-child(2){animation-delay:.18s}
.typing i:nth-child(3){animation-delay:.36s}
@keyframes blink{0%,60%,100%{opacity:.25}30%{opacity:1}}
.empty-log{margin:auto;max-width:320px;text-align:center;color:rgba(255,255,255,.3);font-size:13px;line-height:1.7}
.composer input:disabled,.composer textarea:disabled{opacity:.5}
.send-button{border:0;cursor:pointer;transition:transform .15s}
.send-button:disabled,.icon-button:disabled{opacity:.35;cursor:not-allowed}
.send-button:not(:disabled):hover{transform:translateY(-1px)}
/* В шапке чата остались только кнопки режима — счётчик памяти убран, число
   фактов видно в карточке персонажа. Раз это единственные интерактивные
   элементы шапки, они и выглядят как кнопки: коралловый акцент сайта вместо
   серой плашки, размер под палец. Заливка приглушённая — рядом уже есть
   главная коралловая кнопка «Начать», и спорить с ней за внимание незачем. */
.chat-badges a{display:inline-flex;align-items:center;gap:6px;padding:9px 13px;
  border:1px solid rgba(245,85,85,.38);border-radius:8px;
  background:rgba(245,85,85,.12);color:#fff;
  font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  text-decoration:none;transition:background .15s,border-color .15s}
.chat-badges a i{color:var(--coral);font-size:13px}
/* Корзина в шапке чата: та же рамка, что у «Во весь экран», но квадратная и
   без подписи — рядом с текстовой кнопкой вторая надпись загромождает шапку,
   а смысл иконки понятен и так. Цвет спокойный: действие опасное, но не
   основное, и красной заливкой оно перетягивало бы внимание на себя. */
.chat-badges .badge-icon{display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;padding:0;border:1px solid var(--border);border-radius:8px;
  background:rgba(255,255,255,.04);color:rgba(255,255,255,.5);cursor:pointer;
  transition:background .15s,border-color .15s,color .15s}
.chat-badges .badge-icon svg{width:17px;height:17px;display:block}
/* Гаснет, когда стирать нечего: разговор ещё не начат, и в базе пусто. */
.chat-badges .badge-icon:disabled{opacity:.35;cursor:not-allowed}
@media (hover:hover){.chat-badges .badge-icon:hover{background:rgba(245,85,85,.14);
  border-color:rgba(245,85,85,.45);color:#fff}}
@media (hover:hover){.chat-badges a:hover{background:rgba(245,85,85,.22);
  border-color:rgba(245,85,85,.6)}}
/* В приложении (/chat) «во весь экран» не нужен — оно и так на весь экран.
   Правило выше задаёт display, поэтому специфичность повторена. */
body.chat-full .chat-badges a.enter-full{display:none}

/* ── боковая колонка: недавние диалоги ────────────────────────────────────── */
/* Прокручивается всё содержимое колонки: и пункты меню, и список диалогов.
   Их станет больше — разделов в меню и недавних персонажей, — и упереться
   в край не должно ни то, ни другое. Заголовок сверху и «во весь экран»
   снизу закреплены и в прокрутке не участвуют. */
.sidebar-scroll{flex:1;min-height:0;overflow-y:auto;padding:0 16px 12px}
.sidebar-scroll .sidebar-links{padding:0}
.sidebar-title{position:sticky;top:0;z-index:1;background:var(--panel-deep)}
.rail-label{margin:18px 4px 10px;color:rgba(255,255,255,.24);font-size:9px;font-weight:700;
  letter-spacing:.2em;text-transform:uppercase}
/* Строка списка = сама кнопка перехода + крестик поверх неё справа.
   На ПК крестик проявляется по наведению: постоянный ряд крестиков в узкой
   колонке шумит и притягивает случайные клики. На касании наведения нет —
   там он виден всегда, см. мобильный слой. */
.recent-row{position:relative}
/* Подложка свайпа: лежит под карточкой и проявляется, когда её тянут влево.
   На компьютере не показывается — там удаляют крестиком. */
.recent-swipe{position:absolute;top:0;right:0;bottom:4px;display:none;
  align-items:center;padding:0 18px;border-radius:10px;
  background:var(--coral);color:#fff;font-size:10px;
  font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  /* Появляется и исчезает мгновенно, без плавности: видимостью управляет сама
     строка, которая её закрывает. Плавное угасание накладывалось на возврат
     строки и читалось как мигание. */
  white-space:nowrap;pointer-events:none;opacity:0}
.recent-del{position:absolute;right:6px;top:50%;transform:translateY(-50%);
  display:grid;place-items:center;width:26px;height:26px;padding:0;border:0;
  border-radius:7px;background:transparent;color:rgba(255,255,255,.35);
  font-size:14px;line-height:1;cursor:pointer;opacity:0;transition:.16s}
.recent-row:hover .recent-del,.recent-del:focus-visible{opacity:1}
.recent-del:hover{background:rgba(245,85,85,.14);color:var(--coral)}
/* Размеры равняем на списки мессенджеров: строка — это в первую очередь лицо
   и имя, а не подпись мелким шрифтом. На компьютере колонка узкая (256 px),
   поэтому здесь масштаб сдержаннее, а в мобильной вёрстке — как привыкли. */
.recent-item{display:flex;align-items:center;gap:11px;width:100%;padding:10px 12px;margin-bottom:4px;
  border:1px solid transparent;border-radius:10px;background:transparent;text-align:left;
  color:rgba(255,255,255,.62);cursor:pointer;transition:.18s}
/* Место под крестик держим всегда, иначе имя дёргается при наведении.
   Отдельным правилом ПОСЛЕ основного: сокращённый padding выше его перебил бы. */
.recent-item{padding-right:34px}
.recent-item:hover{background:rgba(255,255,255,.05);color:#fff}
.recent-item.active{border-color:rgba(245,85,85,.3);background:rgba(245,85,85,.1);color:#fff}
.recent-item .pic{flex:0 0 38px;width:38px;height:38px;overflow:hidden;border-radius:50%;
  display:grid;place-items:center;background:rgba(255,255,255,.07);font-size:14px;font-weight:700}
.recent-item .pic img{width:100%;height:100%;object-fit:cover}
.recent-item .pic-letter{font-size:14px;font-weight:700}
/* Коллективный чат — лица в ряд внахлёст, тем же приёмом, что в шапке самого
   чата: один язык на весь интерфейс. Кружки мельче одиночного (28 против 38)
   и сильно перекрывают друг друга — иначе тройка съедала бы место у имени,
   которого в колонке и так немного. */
.recent-item .pic.many{flex:none;width:auto;height:auto;overflow:visible;
  display:flex;align-items:center;border-radius:0;background:none}
.recent-item .pic.many>*{flex:none;width:28px;height:28px;overflow:hidden;
  /* Обводка тоньше, чем у лиц в шапке: там кружки крупнее, и та же линия
     здесь читалась жирной рамкой вокруг каждого. */
  border:1.5px solid var(--panel-deep);border-radius:50%;
  background:rgba(255,255,255,.07);display:grid;place-items:center;
  font-size:11px;font-weight:700}
.recent-item .pic.many>*+*{margin-left:-10px}
/* Первое лицо сверху — как в шапке и в списке участников. */
.recent-item .pic.many>*:nth-child(1){z-index:3}
.recent-item .pic.many>*:nth-child(2){z-index:2}
.recent-item .pic.many>*:nth-child(3){z-index:1}
.recent-item .txt{min-width:0;flex:1}
/* Имя и время — в одной строке: время прижато вправо, имя занимает остаток и
   обрезается многоточием, поэтому длинное на время не наезжает. */
.recent-item .line{display:flex;align-items:baseline;gap:8px;margin-bottom:2px}
.recent-item .line b{min-width:0;margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.recent-item time{flex:0 0 auto;margin-left:auto;color:rgba(255,255,255,.26);
  font-size:10.5px;font-variant-numeric:tabular-nums}
.recent-item b{display:block;margin-bottom:2px;font-size:13px;font-weight:600}
.recent-item small{display:block;overflow:hidden;color:rgba(255,255,255,.3);font-size:11.5px;
  text-overflow:ellipsis;white-space:nowrap}
.rail-empty{padding:10px;color:rgba(255,255,255,.24);font-size:11px;line-height:1.6;font-style:italic}

/* ── память персонажа ─────────────────────────────────────────────────────── */
/* Колонка стоит на месте: портрет, имя, теги и кнопки не уезжают при прокрутке.
   Внутри неё едет только список фактов — он один растёт без предела. */
/* Колонка не двигается, когда прокручивают переписку — это отдельный контейнер.
   Собственная прокрутка у неё всё-таки есть: портрет 4:5, имя, теги, описание,
   кнопки и список фактов в 700px не помещаются, а резать портрет до полоски
   ради этого неправильно — он тут главный. Полоса сделана тонкой и приглушённой.
   Шапка колонки закреплена: аватар и имя видно всегда. */
.profile-rail{overflow-y:auto;padding:0 26px 26px}
/* Фон шапки должен быть ПЛОТНЫМ: с полупрозрачным градиентом факты просвечивали
   сквозь имя персонажа.
   Затухающего слоя под шапкой быть не должно: он рисуется поверх содержимого
   всегда, а не только при прокрутке, и приглушал первую же строку под собой —
   теги характера выглядели полустёртыми. Вместо него просто отступ. */
.profile-head{position:sticky;top:0;z-index:2;width:100%;padding:26px 0 18px;
  background:var(--panel-deep)}
.profile-head .profile-copy{margin:22px 0 0}
.portrait{flex:0 0 auto}
.memory-box{width:100%}
.profile-button{margin-top:22px}
.profile-actions{display:flex;gap:8px;width:100%;margin-top:10px}
/* «Во весь экран» осталась только в левой колонке — дублировать её
   в карточке персонажа незачем. Единственная кнопка занимает всю ширину. */
.profile-actions button:only-child{flex:1}
.profile-actions button{flex:1;min-height:38px;border-radius:8px;border:1px solid var(--border);
  background:rgba(255,255,255,.04);color:rgba(255,255,255,.5);font-size:9px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;cursor:pointer;transition:.2s}
.profile-actions button:hover{background:rgba(255,255,255,.09);color:#fff}
.memory-box{width:100%;margin-top:20px;padding-top:18px;border-top:1px solid var(--border)}
.memory-head{display:flex;align-items:center;justify-content:space-between;width:100%;padding:0;
  border:0;background:transparent;color:rgba(255,255,255,.4);cursor:pointer;
  font-size:9px;font-weight:700;letter-spacing:.18em;text-transform:uppercase}
.memory-head:hover{color:#fff}
/* Число прижато вправо своим полем, а не space-between: детей в заголовке
   теперь три (подпись, число, стрелка), и раскладка «по краям» растащила бы
   число с стрелкой в разные концы строки. */
.memory-head .count{color:var(--coral);margin-left:auto}
.memory-arrow{width:14px;height:14px;flex:none;margin-left:6px;opacity:.7;
  transition:transform .18s ease}
.memory-head:hover .memory-arrow{opacity:1}
/* Свёрнут — стрелка смотрит вправо, «дальше». Признак берём с самой кнопки
   (aria-expanded): он и так обязан быть верным для голосовых помощников,
   значит второго состояния заводить не нужно — и стиль не разъедется с ним. */
.memory-head[aria-expanded="false"] .memory-arrow{transform:rotate(-90deg)}
@media (prefers-reduced-motion:reduce){.memory-arrow{transition:none}}
.memory-list{margin-top:14px;text-align:left}
.memory-list.collapsed{display:none}
.fact{padding:8px 10px;margin-bottom:6px;border:1px solid var(--border);border-radius:8px;
  background:rgba(255,255,255,.03);color:rgba(255,255,255,.6);font-size:11px;line-height:1.5}
.fact b{color:var(--coral);font-weight:600}
/* Крестик у факта: память набирается сама, и человек должен мочь снять
   то, что персонажу знать незачем. Пункт становится гнездом, чтобы
   кнопка легла в его угол и не отжимала текст. На наведение проступает,
   на касании видна всегда — постоянная у каждой строки зашумила бы
   список. */
.fact{position:relative;padding-right:26px}
.fact-del{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:grid;place-items:center;width:20px;height:20px;padding:0;border:0;border-radius:50%;background:transparent;color:rgba(255,255,255,.35);font-size:16px;line-height:1;cursor:pointer;opacity:0;transition:opacity .15s,color .15s,background .15s}
.fact:hover .fact-del,.fact:focus-within .fact-del{opacity:1}
.fact-del:hover{background:rgba(255,255,255,.08);color:var(--coral)}
@media (hover:none){.fact-del{opacity:.5}}
/* Страницы памяти — тот же вид, что у страниц кабинета, но мельче: колонка
   узкая, а кнопок здесь самое большее шесть («‹ 1 2 3 4 ›»). */
.memory-pager{display:flex;flex-wrap:wrap;gap:4px;align-items:center;margin-top:10px}
.memory-page{min-width:26px;height:26px;padding:0 6px;border:1px solid var(--border);
  border-radius:6px;background:transparent;color:rgba(255,255,255,.62);
  font:600 11px/1 Inter,sans-serif;cursor:pointer;
  transition:border-color .15s,color .15s,background .15s}
.memory-page:hover:not(:disabled):not(.on){border-color:rgba(255,255,255,.3);color:#fff}
.memory-page.on{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.2);
  color:#fff;cursor:default}
.memory-page:disabled{opacity:.35;cursor:default}
.memory-note{margin:12px 0 0;color:rgba(255,255,255,.24);font-size:10px;line-height:1.6;font-style:italic}

/* ── витрина персонажей ───────────────────────────────────────────────────── */
.character-card{cursor:pointer;text-align:left}
.character-card.current{border-color:rgba(245,85,85,.55);box-shadow:0 0 0 1px rgba(245,85,85,.25)}
.grid-more{margin-top:28px;text-align:center}
.disclaimer{margin:28px 0 0;color:rgba(255,255,255,.22);font-size:11px;line-height:1.7;text-align:center}
.disclaimer a{color:var(--coral)}

/* ── как это работает ─────────────────────────────────────────────────────── */
.steps-section{margin-bottom:128px}
.steps-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:32px}
.step{padding:36px;border:1px solid rgba(255,255,255,.06);border-radius:16px;background:var(--panel)}
.step .num{display:block;margin-bottom:22px;font:700 13px/1 'Space Grotesk',sans-serif;
  letter-spacing:.2em;color:var(--coral)}
.step h3{margin:0 0 14px;font:700 21px/1.15 'Space Grotesk',sans-serif}
.step p{margin:0;color:rgba(255,255,255,.34);font-size:13px;line-height:1.7}

/* ── шторка меню (телефон) ────────────────────────────────────────────────── */
.sheet{position:fixed;inset:0;z-index:30;display:none;overflow-y:auto;padding:88px 24px 32px;
  background:rgba(15,15,19,.97);backdrop-filter:blur(12px)}
.sheet.open{display:block}
.sheet>a{display:block;padding:18px 0;border-bottom:1px solid var(--border);font-size:17px;
  font-weight:600;color:#fff} /* обычный шрифт, как у ссылок шапки на ПК (22.08.2026); прежний курсивный капс снят */
/* Крестик в углу меню. Кнопка-бургер в шапке тоже закрывает его, но она вне
   меню — закрытие ищут внутри, поэтому даём привычный крестик. Верх совпадает
   с шапкой, чтобы он не выглядел приклеенным к первой строке. */
.sheet-close{position:absolute;top:18px;right:18px;display:grid;place-items:center;
  width:38px;height:38px;padding:0;border:0;border-radius:50%;
  background:rgba(255,255,255,.06);color:rgba(255,255,255,.6);
  font-size:15px;line-height:1;cursor:pointer}
.sheet-close:active{background:rgba(255,255,255,.12);color:#fff}
.sheet-note{margin-top:28px;color:rgba(255,255,255,.28);font-size:11px;line-height:1.7}
.menu-button{display:none;width:28px;height:28px;padding:0;border:0;background:transparent;
  color:rgba(255,255,255,.7);font-size:24px;cursor:pointer}
.menu-button.is-open i:before{content:"\ea55"}

/* ── модальные окна ───────────────────────────────────────────────────────── */
.modal{position:fixed;inset:0;z-index:60;display:none;place-items:center;padding:24px;
  background:rgba(8,8,10,.74);backdrop-filter:blur(8px)}
.modal.open{display:grid}
.modal-card{position:relative;width:min(540px,100%);max-height:88vh;overflow-y:auto;padding:34px;
  border:1px solid rgba(255,255,255,.1);border-radius:20px;background:var(--panel);
  box-shadow:0 34px 100px rgba(0,0,0,.6)}
.modal-card h3{margin:0 0 10px;font:700 26px/1.05 'Space Grotesk',sans-serif;letter-spacing:-.04em}
.modal-card>p{margin:0 0 24px;color:rgba(255,255,255,.42);font-size:13px;line-height:1.7}
.modal-close{position:absolute;top:22px;right:24px;width:38px;height:38px;display:grid;place-items:center;
  border:1px solid var(--border);border-radius:50%;background:rgba(255,255,255,.04);
  color:rgba(255,255,255,.5);font-size:18px;cursor:pointer}
.modal-close:hover{background:rgba(255,255,255,.1);color:#fff}
.field{margin-bottom:20px}
/* ── кастомизация персонажа ───────────────────────────────────────────────
   Правила ГЛОБАЛЬНЫЕ. Сначала они по невнимательности попали внутрь
   @media (max-width:899px) — форма выглядела правильно только на узком
   экране, а на десктопе textarea оставалась браузерной. Проверять такие
   вещи надо на обеих ширинах. */
.add-row{display:flex;gap:8px;align-items:center}
.add-row input[type=text]{flex:1;min-width:0}
.field textarea{width:100%;padding:14px 16px;border:1px solid var(--border);border-radius:13px;
  background:rgba(255,255,255,.04);color:#fff;font:inherit;line-height:1.5;resize:vertical;min-height:88px}
.field textarea:focus{outline:0;border-color:rgba(245,85,85,.5)}
.field textarea::placeholder{color:rgba(255,255,255,.2)}
#cu-base button,#cu-extra button,#cu-tone button{cursor:pointer}
/* Приглушённая черта: видно, что она есть в каноне, но сейчас отключена. */
#cu-base button:not(.on){opacity:.45;text-decoration:line-through}
/* Свои черты живут в .tag-list, где стилизованы span'ы, а не кнопки:
   без этого правила чипы получают браузерный вид — белый прямоугольник. */
#cu-extra button{padding:6px 10px;border:1px solid rgba(245,85,85,.38);border-radius:6px;
  background:rgba(245,85,85,.14);color:#fff;font-size:11px;font-weight:600;letter-spacing:.02em}
#cu-extra button:hover{background:rgba(245,85,85,.24)}
/* Предел в три черты: поле гаснет заранее, текст появляется по нажатию. */
.add-row input[type=text]:disabled{opacity:.4;cursor:not-allowed}
.pill-button:disabled{opacity:.35;cursor:not-allowed}
.field-hint.is-warn{color:var(--coral)}
/* Медно-золотой — для правил, а не ошибок: предел числа черт человек не
   нарушил, ему просто надо это увидеть. Фон и рамка едва заметны, чтобы
   строка читалась как табличка, а не как тревога. */
.field-hint.is-note{margin-top:12px;padding:11px 13px;border:1px solid rgba(201,150,79,.3);
  border-radius:9px;background:rgba(201,150,79,.09);color:#d9a95f;
  font-weight:500;letter-spacing:.01em}
/* Дуга от подсказки к чертам. Слой поверх содержимого, но кликов не ловит:
   поля и кнопки под ней должны работать как обычно. Координаты пишет JS. */
.cu-arrow{position:absolute;left:0;top:0;pointer-events:none;overflow:visible;
  color:#c9964f}
/* Страховка от горизонтальной прокрутки в кастомизации: содержимое по ширине
   ограничено, всё лишнее по X (стрелка, длинное прозвище) — режется. */
#custom .modal-card{overflow-x:hidden}
/* Портрет в кастомизации: превью слева, кнопка и пояснение справа. */
.avatar-row{display:flex;gap:16px;align-items:flex-start}
.avatar-preview{flex:0 0 104px;width:104px;height:104px;overflow:hidden;
  border:1px solid var(--border);border-radius:14px;background:var(--panel-deep);
  display:grid;place-items:center}
.avatar-preview img{width:100%;height:100%;object-fit:cover;display:block}
.avatar-preview .letter{font:700 34px/1 'Space Grotesk',sans-serif;color:rgba(255,255,255,.35)}
.avatar-side{flex:1;min-width:0;display:flex;flex-direction:column;gap:10px}
.avatar-side .button{min-height:44px;padding:0 20px;align-self:flex-start}
.avatar-side .button:disabled{opacity:.4;cursor:not-allowed;transform:none}
.avatar-side .field-hint{margin:0}
@media (max-width:520px){.avatar-side .button{width:100%}}
.field label{display:block;margin-bottom:8px;color:rgba(255,255,255,.35);font-size:9px;font-weight:700;
  letter-spacing:.2em;text-transform:uppercase}
.field input[type=text]{width:100%;padding:15px;border:1px solid var(--border);border-radius:10px;
  background:var(--panel-deep);color:#fff;outline:0}
.field input[type=text]:focus{border-color:rgba(245,85,85,.5)}
.check{display:flex;gap:11px;align-items:flex-start;margin-bottom:22px;color:rgba(255,255,255,.5);
  font-size:12px;line-height:1.55;cursor:pointer}
.check input{flex:0 0 auto;width:17px;height:17px;margin-top:2px;accent-color:var(--coral)}
.modal .button{width:100%}
.button:disabled{opacity:.35;cursor:not-allowed;transform:none}
.form-note{margin:26px 0 0;padding:13px 15px;border:1px solid rgba(255,255,255,.08);border-radius:10px;
  background:rgba(255,255,255,.03);color:rgba(255,255,255,.34);font-size:11px;line-height:1.65}
/* `.modal-card>p` выше по специфичности и обнуляет верхний отступ у любого
   абзаца внутри окна — без этой строки плашка липнет к кнопке. */
.modal-card>p.form-note{margin:26px 0 0}
.form-err{margin:16px 0 0;padding:13px 15px;border:1px solid rgba(245,85,85,.4);border-radius:10px;
  background:rgba(245,85,85,.12);color:#ffc9c9;font-size:12px;line-height:1.6}
.legal-body{color:rgba(255,255,255,.5);font-size:13px;line-height:1.8}
.legal-body p{margin:0 0 16px}
.legal-body strong{color:#fff}

/* ── выбор рода обращения ─────────────────────────────────────────────────── */
.choice{display:flex;gap:8px;flex-wrap:wrap}
/* flex:1 — это flex-basis:0: кнопки делят строку поровну, не считаясь с
   длиной надписи, и самое длинное слово («нейтральный») вылезало за рамку.
   basis:auto даёт каждой её собственную ширину, а grow добирает остаток. */
.choice button{flex:1 1 auto;white-space:nowrap;min-width:96px;min-height:44px;padding:0 14px;border:1px solid var(--border);
  border-radius:10px;background:var(--panel-deep);color:rgba(255,255,255,.55);font-size:11px;
  font-weight:700;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;transition:.18s}
.choice button:hover{background:rgba(255,255,255,.06);color:#fff}
.choice button.on{border-color:rgba(245,85,85,.55);background:rgba(245,85,85,.12);color:#fff}
/* Взаимоисключение: кнопка гаснет, но остаётся кликабельной — клик объясняет
   почему (toast). Перечёркнутый курсор подсказывает это до клика. */
.choice button.is-blocked{opacity:.32;cursor:not-allowed;text-decoration:line-through;text-decoration-color:rgba(255,255,255,.5)}
.choice button.is-blocked:hover{background:transparent;color:inherit}
.field-hint{margin:10px 0 0;color:rgba(255,255,255,.28);font-size:11px;line-height:1.6}

/* ── наведение на «во весь экран» / «свернуть» ────────────────────────────── */
/* В базовом макете подсветка была только у пунктов меню: правило
   .sidebar-links a:hover нижнюю кнопку не задевало, и она выглядела неживой.
   Условие hover:hover обязательно — на сенсорных экранах :hover залипает после
   нажатия, и кнопка осталась бы подсвеченной до следующего касания. */
@media (hover: hover) {
  .sidebar-settings:hover{background:rgba(255,255,255,.06);color:#fff}
  .sidebar-settings:hover i{color:var(--coral-hover);transform:translateX(2px)}
}
/* Это <button>, а не ссылка: без сброса он берёт браузерный вид — белый фон
   и рамку, и в тёмной колонке светился белым прямоугольником. Ширину и
   выравнивание тоже задаём сами: у кнопки текст по центру, у пунктов меню слева. */
/* Ширина — вся колонка, нижний отступ снят: кнопка должна стоять на одной
   линии с формой ввода в чате. Замер до правки: низ кнопки 1591, низ формы
   1609, ширина 231 против 256 у колонки. */
/* Кнопок теперь две, и внизу колонки они стоят вместе: margin-top:auto
   переезжает на обёртку, иначе вторая кнопка отрывается от первой. */
.sidebar-actions{margin-top:auto;display:flex;flex-direction:column}

/* ── аниме-радио в левой колонке ────────────────────────────────────────────
   Карточка над кнопками колонки: круглая кнопка «играть», рядом станция,
   число слушателей, бегущая строка с треком и тонкая полоса — сколько трека
   осталось. Пока не играет — приглушённая; в эфире кнопка коралловая, а
   точка «эфир» пульсирует. Громкость появляется только когда есть что
   регулировать. */
.radio{margin:0 12px 10px;padding:10px 12px 10px 10px;border:1px solid var(--border);border-radius:14px;
  background:linear-gradient(160deg,rgba(255,255,255,.05),rgba(255,255,255,.02));
  transition:border-color .25s,background .25s}
.radio[data-state="playing"]{border-color:rgba(245,85,85,.35);
  background:linear-gradient(160deg,rgba(245,85,85,.12),rgba(245,85,85,.03))}
.radio-row{display:flex;align-items:center;gap:11px;min-width:0}
.radio-play{position:relative;flex:none;display:grid;place-items:center;width:40px;height:40px;
  border:1px solid rgba(255,255,255,.14);border-radius:50%;background:rgba(255,255,255,.07);
  color:#fff;cursor:pointer;transition:background .2s,border-color .2s,transform .15s}
.radio-play:hover{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.28)}
.radio-play:active{transform:scale(.94)}
.radio-ico{width:20px;height:20px;grid-area:1/1}
.radio-ico-play{margin-left:2px}
.radio-ico-pause,.radio-spin{display:none}
.radio[data-state="playing"] .radio-play,
.radio[data-state="loading"] .radio-play{background:var(--coral);border-color:var(--coral);
  box-shadow:0 6px 18px rgba(245,85,85,.35)}
.radio[data-state="playing"] .radio-play:hover{background:var(--coral-hover)}
.radio[data-state="playing"] .radio-ico-play{display:none}
.radio[data-state="playing"] .radio-ico-pause{display:block}
/* Пока поток буферизуется — кольцо вокруг кнопки крутится, значок остаётся:
   человек видит, что нажатие принято. */
.radio[data-state="loading"] .radio-spin{display:block;position:absolute;inset:-4px;border-radius:50%;
  border:2px solid transparent;border-top-color:#fff;animation:radio-spin .9s linear infinite}
@keyframes radio-spin{to{transform:rotate(360deg)}}
.radio-body{display:flex;flex-direction:column;gap:4px;min-width:0;flex:1}
.radio-head{display:flex;align-items:center;gap:8px;min-width:0;font-size:10px;line-height:1}
.radio-station{font:800 10.5px/1 'Space Grotesk',Inter,sans-serif;letter-spacing:.08em;color:#fff;
  transition:color .2s}
.radio-station:hover{color:var(--coral)}
.radio-live{display:inline-flex;align-items:center;gap:4px;color:rgba(255,255,255,.42);font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;font-size:9px}
.radio-live i{width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.28)}
.radio[data-state="playing"] .radio-live{color:#f87171}
.radio[data-state="playing"] .radio-live i{background:#f87171;box-shadow:0 0 8px #f87171;
  animation:pulse 1.6s infinite}
.radio-listeners{margin-left:auto;color:rgba(255,255,255,.4);font-size:10px;white-space:nowrap}
.radio-listeners:empty{display:none}
.radio-listeners:before{content:"";display:inline-block;width:9px;height:9px;margin:0 4px -1px 0;
  border-radius:50%;background:radial-gradient(circle at 50% 35%,rgba(255,255,255,.7) 0 30%,transparent 32%),
  radial-gradient(circle at 50% 100%,rgba(255,255,255,.55) 0 60%,transparent 62%)}
/* Строка трека: аниме жирным, название — обычным. Не влезает — едет: класс
   is-long ставит JS, измерив ширину; сдвиг — в переменной. */
.radio-track{position:relative;overflow:hidden;white-space:nowrap;font-size:12px;line-height:1.3;
  color:rgba(255,255,255,.62);
  mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 14px),transparent);
  -webkit-mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 14px),transparent)}
.radio-track b{color:#fff;font-weight:600}
/* Бегущей строке — фейд и слева: уехавшее начало не должно обрубаться. */
.radio-track.is-long{mask-image:linear-gradient(90deg,transparent,#000 12px,#000 calc(100% - 14px),transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12px,#000 calc(100% - 14px),transparent)}
.radio-marquee{display:inline-block;will-change:transform}
.radio-track.is-long .radio-marquee{animation:radio-marquee var(--dur,12s) ease-in-out infinite alternate}
@keyframes radio-marquee{0%,12%{transform:translateX(0)}88%,100%{transform:translateX(var(--shift,0))}}
.radio-bar{height:3px;border-radius:2px;background:rgba(255,255,255,.08);overflow:hidden}
.radio-bar i{display:block;height:100%;width:0;border-radius:2px;background:rgba(255,255,255,.28);
  transition:width 1s linear}
.radio[data-state="playing"] .radio-bar i{background:var(--coral)}
/* Громкость — только когда играет или на паузе после игры. */
.radio-vol{display:none;align-items:center;gap:8px;margin-top:9px;padding-top:9px;
  border-top:1px solid rgba(255,255,255,.06);color:rgba(255,255,255,.4)}
.radio[data-state="playing"] .radio-vol,.radio[data-state="paused"] .radio-vol{display:flex}
.radio-vol svg{width:16px;height:16px;flex:none}
.radio-vol input{flex:1;height:3px;margin:0;appearance:none;-webkit-appearance:none;border-radius:2px;
  background:linear-gradient(90deg,var(--coral) var(--v,70%),rgba(255,255,255,.14) 0);cursor:pointer}
.radio-vol input::-webkit-slider-thumb{appearance:none;-webkit-appearance:none;width:12px;height:12px;
  border-radius:50%;background:#fff;border:0;box-shadow:0 1px 4px rgba(0,0,0,.5)}
.radio-vol input::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:#fff;border:0}
.radio-vol input::-moz-range-track{height:3px;background:transparent}
/* Станция не ответила — карточка тускнеет, но кнопка остаётся: поток и
   статус — разные серверы, поток может играть и без строки «что в эфире». */
.radio.is-off .radio-body{opacity:.55}
.sidebar-settings{cursor:pointer;width:100%;margin-top:0;margin-bottom:0;background:transparent;
  border:0;border-top:1px solid var(--border);text-align:left;font-family:inherit;
  line-height:1.35}
/* Обычный регистр вместо капслока: это действия, а не заголовки разделов, —
   капслоком «Вернуть изначальных персонажей» читалось как рубрика. Без
   разрядки и чуть крупнее: строчные буквы её не требуют. */
.sidebar-settings{text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:600}
.sidebar-settings i{font-size:19px;flex:0 0 auto}
.sidebar-settings .ico{width:19px;height:19px;flex:0 0 auto;color:var(--coral)}
/* Сбрасывать нечего — кнопка гаснет и не отзывается на наведение. */
.sidebar-settings:disabled{opacity:.32;cursor:default}
.sidebar-settings:disabled:hover{background:transparent;color:rgba(255,255,255,.44)}
.sidebar-settings:disabled:hover i{color:var(--coral);transform:none}
.sidebar-settings i{transition:transform .2s,color .2s}
/* В базовом макете у кнопки отступ сверху 22px, а снизу 12px — наследие от
   общего правила с пунктами меню. Пока подсветки не было, перекос не бросался
   в глаза; с фоном при наведении стало видно, что текст сидит не по центру.
   Выравниваем оба отступа, общая высота при этом почти не меняется. */
.sidebar-settings{padding-block:17px}

/* ── подтверждение необратимого действия ──────────────────────────────────── */
/* Своё окно вместо системного confirm(): тот выглядит чужим на тёмной странице
   и в каждом браузере по-разному. */
.ask-actions{display:flex;gap:10px;margin-top:4px}
.ask-actions .button{flex:1;width:auto;min-height:52px;padding:0 18px}
.button-danger{background:var(--coral);border-color:transparent;
  box-shadow:0 0 32px -14px rgba(245,85,85,.9)}
.button-danger:hover{background:var(--coral-hover)}
#ask .modal-card{width:min(440px,100%)}
/* Перенос строки в тексте вопроса. Текст ставится как textContent — так он не
   может принести в окно чужую разметку, — но разделить строки в нём всё же
   нужно: «приглашённые останутся» это не оговорка в конце абзаца, а ответ на
   главный страх перед нажатием. */
#ask-text{white-space:pre-line}

/* ── уведомление ──────────────────────────────────────────────────────────── */
.toast{position:fixed;left:50%;bottom:34px;z-index:70;padding:14px 22px;border-radius:12px;
  border:1px solid rgba(255,255,255,.12);background:rgba(26,27,30,.96);color:#fff;font-size:13px;
  box-shadow:0 20px 50px rgba(0,0,0,.5);transform:translate(-50%,20px);opacity:0;pointer-events:none;
  transition:opacity .25s,transform .25s}
.toast.show{opacity:1;transform:translate(-50%,0)}

/* ── полноэкранный чат (/chat) ────────────────────────────────────────────── */
/* Лендинг и приложение — одна страница: /chat показывает тот же файл, только
   гасит всё вокруг чата. Раньше секции перечислялись по одной, и список
   отставал от разметки: «Сценарии», «Помощники» и «Предложить идею» появились
   позже и в него не попали — на телефоне они вылезали под чатом (на большом
   экране их прятал overflow:hidden, поэтому и не замечали). Считать заново
   каждый раз бессмысленно: правило теперь по строению документа — в main
   лежит ровно лендинг, а приложение живёт в .preview-section. Новая секция
   гасится сама, дописывать ничего не нужно. */
body.chat-full main>section:not(.preview-section),
body.chat-full .promo-banner,body.chat-full .site-footer{display:none}
body.chat-full{overflow:hidden}
body.chat-full .preview-section{width:100%;margin:0}
/* Во весь экран — значит только чат: верхнее меню сайта убираем целиком.
   Выход остаётся кнопкой «Свернуть» в шапке самого чата, она никуда не
   девается. Раз меню больше нет, из высоты вычитать нечего — берём весь
   экран. dvh дышит вместе с адресной строкой мобильного браузера, строка
   выше с vh — запас для старых движков. */
body.chat-full .site-nav{display:none}
/* Заголовок секции — тоже часть страницы, а не чата: «Демонстрация чата» со
   счётчиком объясняют, что это за блок среди других блоков. Во весь экран
   никаких других блоков нет, объяснять нечего. Дело не только в виде: на
   телефоне заголовок занимал 73 пикселя сверху, на компьютере 90 — ровно на
   столько поле ввода уезжало за нижний край экрана. */
body.chat-full .section-header{display:none}
body.chat-full .chat-preview{height:100vh;border-radius:0;border-left:0;border-right:0;
  border-bottom:0;border-top:0}
body.chat-full .chat-preview{height:100dvh}
body.chat-full .enter-full{display:none}

/* ── приложение (/chat): левая колонка про человека ────────────────────────
   Шапки сайта в приложении нет; аватарка с именем (вход в кабинет) и «Выйти»
   стоят наверху левой колонки — там, где в мессенджерах профиль. На лендинге
   блок скрыт: там кабинет и выход в шапке. Заголовок «ДИАЛОГИ» в приложении
   лишний — под панелью сразу пункты меню, и так ясно, что это. */
.side-user{display:none}
body.chat-full .side-user{display:flex;align-items:center;gap:10px;padding:14px 12px 12px 16px;
  border-bottom:1px solid var(--border)}
body.chat-full .sidebar-title{display:none}
.side-user-link{display:flex;align-items:center;gap:12px;min-width:0;flex:1;padding:6px 8px 6px 4px;
  border-radius:12px;transition:background .2s}
.side-user-link:hover{background:rgba(255,255,255,.06)}
.side-user-link:hover .cab-avatar{border-color:var(--coral)}
.side-avatar{width:44px;height:44px}
.side-avatar .letter{font-size:17px}
.side-user-text{display:flex;flex-direction:column;min-width:0;gap:3px}
.side-user-text strong{font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.side-user-text small{font-size:11px;color:rgba(255,255,255,.42);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.side-user-text small.is-pro{color:var(--coral);font-weight:700;letter-spacing:.04em;
  display:inline-flex;align-items:center;gap:5px}
/* «Тариф» белым. Коралловый в этой строке помечает сам тариф, и когда им
   выкрашено всё слово в слово, выделять становится нечем (просьба владельца
   27.08.2026). Красим только подпись, «PRO» и срок остаются коралловыми. */
.side-user-text small.is-pro .plan-word{color:#fff}
/* Подписка на исходе. Отдельный класс, а НЕ .is-soon: то имя уже занято
   значением «скоро появится» (.create-item.is-soon гасит пункт до .6), общего
   у них — одно слово. Из-за этого совпадения подсветка остатка в кабинете
   вообще ничем не красилась: правила для голого .is-soon в файле нет, и
   `<b class="is-soon">осталось 5 дней</b>` был просто жирным текстом. */
.is-ending{color:var(--warn)}
.side-user-text small.is-ending{color:var(--warn)}
.pro-check{width:13px;height:13px;color:#22c55e;flex:none}
.side-logout{display:grid;place-items:center;flex:none;width:38px;height:38px;border:1px solid var(--border);
  border-radius:10px;background:rgba(255,255,255,.04);color:rgba(255,255,255,.55);cursor:pointer;
  transition:background .2s,border-color .2s,color .2s}
.side-logout svg{width:18px;height:18px}
.side-logout:hover{background:rgba(245,85,85,.14);border-color:rgba(245,85,85,.45);color:#fff}
/* Стрелки «назад» — только телефон в приложении (см. мобильный слой). */
.chat-back,.rail-back{display:none}
.side-resize{display:none}
/* На широком экране во весь экран строка сообщения не должна тянуться на
   полтора метра: глазу читать длинные строки тяжело. */
body.chat-full .message-row{max-width:min(86%,820px)}


/* ── высоты колонок ───────────────────────────────────────────────────────── */
/* Без этого лента не прокручивалась, а обрезалась: у элементов сетки и флекса
   min-height по умолчанию auto, поэтому они разрастаются под содержимое и
   вылезают за высоту .chat-preview, вместо того чтобы включить свою прокрутку.
   Обнулённый min-height разрешает им сжаться до отведённой строки. */
.chat-preview{grid-template-rows:minmax(0,1fr)}
.sidebar,.chat-main,.profile-rail{min-height:0}
.message-history,.sidebar-scroll{min-height:0}


/* ── изображение в ленте ──────────────────────────────────────────────────── */
/* Место под картинку занимается до её появления: иначе лента прыгает, когда
   изображение догружается, и человек теряет строку, которую читал. */
.photo{position:relative;width:min(280px,66%);aspect-ratio:1;overflow:hidden;
  border:1px solid rgba(255,255,255,.1);border-radius:16px;background:rgba(255,255,255,.04)}
.photo img{width:100%;height:100%;display:block;object-fit:cover;
  animation:chunk-in .6s ease-out both}
/* Кадр как у телефона: вертикальный или горизонтальный, выбирается случайно.
   Вертикальный делаем уже — при той же ширине он был бы вдвое выше
   горизонтального и занимал бы пол-ленты. */
/* Снимок в ленте кликабелен — открывается крупно. */
.photo img{cursor:zoom-in}
.photo-portrait{width:min(232px,56%);aspect-ratio:832/1216}

/* ── просмотр снимков ──────────────────────────────────────────────────────
   Фон плотнее, чем у обычных окон: снимок разглядывают, и подложка не должна
   спорить с ним по яркости. Кадр вписывается целиком (contain), а не обрезается:
   в ленте он и так подрезан рамкой, крупный показ для того и нужен. */
.viewer{position:fixed;inset:0;z-index:60;display:none;align-items:center;
  justify-content:center;padding:24px;background:rgba(8,9,11,.94);
  backdrop-filter:blur(6px);touch-action:pan-y}
.viewer.open{display:flex}
/* Лента кадров: показываем один, сдвигаем всю ленту. Плавность здесь, а не на
   картинке, — так кадр уезжает, а не подменяется на месте. Во время свайпа
   класс dragging снимает плавность, чтобы лента шла ровно за пальцем. */
.viewer-track{display:flex;width:100%;height:100%;align-items:center;
  will-change:transform;transition:transform .3s cubic-bezier(.22,.61,.36,1)}
.viewer-track.dragging,.viewer-track.no-anim{transition:none}
.viewer-slide{flex:0 0 100%;height:100%;display:flex;align-items:center;
  justify-content:center;padding:0 6px}
.viewer img{max-width:min(100%,1100px);max-height:100%;display:block;
  object-fit:contain;border-radius:10px;box-shadow:0 24px 80px rgba(0,0,0,.55);
  user-select:none;-webkit-user-drag:none}
.viewer-nav:disabled{opacity:.25;cursor:default}
/* Кнопки держим НАД лентой явным слоем. Лента с will-change:transform заводит
   собственный контекст наложения и без этого перекрывала крестик и стрелки —
   они переставали нажиматься, хотя и были видны. */
.viewer-close,.viewer-nav,.viewer-count{z-index:2}
.viewer-close{position:absolute;top:16px;right:18px;width:40px;height:40px;
  border:1px solid var(--border);border-radius:10px;background:rgba(255,255,255,.06);
  color:#fff;font-size:17px;line-height:1;cursor:pointer;transition:background .15s}
.viewer-nav{position:absolute;top:50%;transform:translateY(-50%);width:46px;height:76px;
  border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.06);
  color:#fff;font-size:30px;line-height:1;cursor:pointer;transition:background .15s}
.viewer-prev{left:14px}
.viewer-next{right:14px}
@media (hover:hover){.viewer-close:hover,.viewer-nav:hover{background:rgba(255,255,255,.15)}}
.viewer-count{position:absolute;bottom:18px;left:50%;transform:translateX(-50%);
  padding:6px 12px;border-radius:999px;background:rgba(255,255,255,.08);
  color:rgba(255,255,255,.72);font-size:11px;font-weight:700;letter-spacing:.08em}
/* Страница под открытым снимком не прокручивается: иначе колесо и палец
   листают ленту за спиной у просмотра. */
body.viewer-open{overflow:hidden}
/* На телефоне стрелки мельче и ближе к краю — основной способ там свайп,
   а кнопки не должны закрывать сам кадр. */
@media (max-width:640px){
  .viewer{padding:12px}
  .viewer-nav{width:36px;height:60px;font-size:24px;background:rgba(255,255,255,.08)}
  .viewer-prev{left:4px}
  .viewer-next{right:4px}
}
.photo-landscape{width:min(320px,74%);aspect-ratio:1216/832}

.photo-loading{display:grid;place-items:center}
.photo-loading::before{content:'';position:absolute;inset:0;
  background:linear-gradient(100deg,transparent 20%,rgba(255,255,255,.06) 50%,transparent 80%);
  background-size:220% 100%;animation:photo-wait 1.4s linear infinite}
@keyframes photo-wait{from{background-position:120% 0}to{background-position:-120% 0}}
.photo-note{position:relative;color:rgba(255,255,255,.4);font-size:11px;
  letter-spacing:.16em;text-transform:uppercase}
.photo-failed{display:grid;place-items:center;padding:16px;text-align:center;
  color:rgba(255,255,255,.35);font-size:12px}

/* ── время отправки ───────────────────────────────────────────────────────── */
/* Как в мессенджерах: мелко, в правом нижнем углу пузыря. float даёт обтекание —
   на короткой реплике отметка встаёт в ту же строку, на длинной уходит под
   последнюю. Отрицательные отступы подтягивают её к самому углу. */
.message-row .stamp{float:right;margin:6px -4px -3px 12px;font-size:10px;line-height:1;
  color:rgba(255,255,255,.26);white-space:nowrap;user-select:none}
.message-row.sent .stamp{color:rgba(255,255,255,.42)}
.message-row.system .stamp{color:rgba(255,217,168,.45)}
/* Действие занимает всю строку, и время не должно приклеиваться к нему сбоку. */
.message-row .act + .stamp{clear:both}

/* ── описания действий персонажа ──────────────────────────────────────────── */
/* Персонаж иногда обрамляет жест или взгляд звёздочками: *отставляет чашку*.
   Сами звёздочки не показываем — это разметка. Оформляем приглушённым курсивом,
   чтобы действие отличалось от речи и не спорило с ней за внимание. */
/* Как в макете: отдельный абзац, курсив, приглушённый, со звёздочками по краям.
   Блочный режим работает только потому, что на всё действие заводится один
   элемент, а куски потока падают внутрь него — иначе действие вставало бы
   столбиком по слогу в строке.
   Начертание задано явно: жирным описание быть не должно ни при каком шрифте. */
.message-row .act{display:block;margin:12px 0;font-style:italic;font-weight:400;
  color:rgba(255,255,255,.38);line-height:1.55}
/* Отступы безусловные. Условие «не последний элемент» тут не работает: после
   действия идёт голый текст, а он не элемент — правило молча не применялось,
   и речь прилипала к описанию. У краёв пузыря отступ убираем, там своё поле. */
/* Позиционные псевдоклассы тут бесполезны в ОБЕ стороны: текстовые узлы
   элементами не считаются, поэтому действие почти всегда и :first-child,
   и :last-child, и :only-child одновременно. Признак «действие открывает
   реплику» проставляет JS классом lead. */
.message-row .act.lead{margin-top:0}
/* Действие человека живёт в коралловом пузыре: серый курсив персонажа на нём
   не читается, поэтому свой оттенок — светлее фона, но тише речи. */
.message-row.sent .act{color:rgba(255,255,255,.62)}
.message-row p{font-weight:400}

/* ── проявление текста персонажа ──────────────────────────────────────────── */
/* Каждый пришедший от модели кусок проявляется из размытия.
   При 1.1s одновременно анимируются сразу десятки кусков — получается плавная
   волна вместо резкого возникновения слов. Кривая ease-out: рывок в начале,
   долгое мягкое доведение до конца.
   transform не используем: на строчных элементах он не работает, а inline-block
   ломал бы перенос слов внутри реплики. */
@keyframes chunk-in{from{opacity:0;filter:blur(7px)}to{opacity:1;filter:blur(0)}}
.message-row .rv{animation:chunk-in 1.1s ease-out both;will-change:opacity,filter}

/* ── полосы прокрутки ─────────────────────────────────────────────────────── */
/* Едет только содержимое: лента сообщений, список диалогов и список фактов.
   Сами колонки зафиксированы, поэтому у них полос нет вовсе.
   overscroll-behavior не даёт странице поехать, когда лента домотана до края —
   иначе прокрутка «проваливается» на весь документ и чат уезжает из виду. */
:root{--scrollbar:#f55555;--scrollbar-hover:#ff6b6b}

.message-history,.sidebar-scroll,.profile-rail,.modal-card,.sheet{
  overscroll-behavior:contain;
  scrollbar-width:thin;
  scrollbar-color:var(--scrollbar) transparent}

.message-history::-webkit-scrollbar,
.sidebar-scroll::-webkit-scrollbar,
.profile-rail::-webkit-scrollbar,
.modal-card::-webkit-scrollbar,
.sheet::-webkit-scrollbar{width:10px;height:10px}

.message-history::-webkit-scrollbar-track,
.sidebar-scroll::-webkit-scrollbar-track,
.profile-rail::-webkit-scrollbar-track,
.modal-card::-webkit-scrollbar-track,
.sheet::-webkit-scrollbar-track{background:transparent}

/* Прозрачная рамка + background-clip даёт зазор от края без второго элемента. */
.message-history::-webkit-scrollbar-thumb,
.sidebar-scroll::-webkit-scrollbar-thumb,
.profile-rail::-webkit-scrollbar-thumb,
.modal-card::-webkit-scrollbar-thumb,
.sheet::-webkit-scrollbar-thumb{
  border:3px solid transparent;border-radius:999px;
  background:var(--scrollbar);background-clip:content-box}

.message-history::-webkit-scrollbar-thumb:hover,
.sidebar-scroll::-webkit-scrollbar-thumb:hover,
.profile-rail::-webkit-scrollbar-thumb:hover,
.modal-card::-webkit-scrollbar-thumb:hover,
.sheet::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-hover)}

/* Список диалогов и факты — второстепенные, полоса у них тоньше и приглушена,
   чтобы не спорить с лентой за внимание. */
.sidebar-scroll,.profile-rail{scrollbar-color:rgba(245,85,85,.45) transparent}
.sidebar-scroll::-webkit-scrollbar,.profile-rail::-webkit-scrollbar{width:8px}
.sidebar-scroll::-webkit-scrollbar-thumb,
.profile-rail::-webkit-scrollbar-thumb{background:rgba(245,85,85,.45);border-width:2px}


/* ══════════════════════════════════════════════════════════════════════════
   3. МОБИЛЬНЫЙ МАКЕТ
   Та же разметка, другой характер: тяжёлый курсивный капс, крупные скругления,
   кнопки во всю ширину, вертикальные карточки, шапка на фиксации.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:899px){
  :root{--bg:#0f0f13;--panel:#1c1c21;--panel-deep:#16161b;--coral:#ff4b4b;--coral-hover:#ff6b6b;
        --blue:#168cff;--border:rgba(255,255,255,.08)}
  section[id],main[id]{scroll-margin-top:72px}

  h1,h2,h3,h4,.brand,.section-title{font-family:Inter,system-ui,sans-serif}
  .container{width:100%;padding-inline:24px}

  /* шапка */
  .site-nav{position:fixed;top:0;left:0;right:0;background:rgba(15,15,19,.86)}
  .nav-inner{height:60px}
  .nav-links,.signin-link{display:none}
  .brand{font-size:19px;letter-spacing:-.07em}
  /* Знак — картинка со своим скруглением, кегль и начертание тут ни при чём. */
  .brand-mark{border-radius:7px}
  .auth-actions{gap:16px}
  .menu-button{display:grid;place-items:center}

  /* верхняя плашка: две строки — «режим + кнопка», под ними текст */
  .promo-banner{position:relative;z-index:10;margin-top:60px;padding:12px 16px 14px}
  .promo-inner{display:block;min-height:0;padding:0;width:100%}
  .promo-top{display:flex;align-items:center;justify-content:space-between;gap:12px}
  /* min-width:0 плюс разрешённый перенос подписи: иначе на 320 px строка
     «иконка + подпись + кнопка» не влезала и растягивала документ на 6 px.
     На 390 px запаса хватает, подпись всё так же в одну строку. */
  .promo-mode{display:flex;align-items:center;gap:8px;min-width:0}
  .promo-icon{display:grid;place-items:center;width:36px;height:36px;border:1px solid rgba(255,75,75,.22);
    border-radius:12px;background:rgba(255,75,75,.1);color:var(--coral);font-size:16px}
  .promo-inner .eyebrow{color:var(--coral);font-size:9px;font-weight:900;letter-spacing:.15em;
    text-transform:uppercase;white-space:normal}
  .promo-mode small{color:rgba(255,255,255,.3);font-size:8px;letter-spacing:.12em}
  .promo-mode small i{display:inline-block;width:4px;height:4px;margin-right:3px;border-radius:50%;
    background:#34d399}
  .promo-inner p{margin:12px 0 0;padding-left:44px;font-size:12px;font-weight:700;
    line-height:1.35;text-align:left;color:#fff}
  .pill-button{display:flex;align-items:center;gap:6px;min-height:44px;padding:0 12px;
    border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.04);
    font-size:10px;font-weight:900;letter-spacing:.08em;white-space:nowrap}

  /* первый экран */
  .hero{padding:78px 0 64px;text-align:center}
  .hero-glow-violet{display:none}
  .hero-glow-blue{left:50%;top:0;width:100%;height:580px;transform:translateX(-50%);animation:none;
    background:radial-gradient(circle at center,rgba(255,75,75,.12),transparent 70%)}
  .live-badge{margin-bottom:40px;padding:7px 13px;font-size:9px;letter-spacing:.12em}
  .hero-heading{margin-bottom:30px}
  /* в макете 50 px; clamp оставлен ради узких экранов (на 320 px даёт 41 px) */
  .hero-heading .hero-poster{font-size:clamp(34px,12.8vw,50px);line-height:.9;letter-spacing:-.09em;
    font-weight:900;font-style:italic;text-transform:uppercase;
    text-shadow:0 0 40px rgba(255,75,75,.2)}
  .hero-heading em,.hero-kto{font-style:italic}
  .hero-kto{color:var(--coral)}
  .hero-description{max-width:295px;margin-bottom:42px;font-size:16px;font-weight:400;
    line-height:1.6;color:rgba(255,255,255,.68)}
  .hero-actions{flex-direction:column;gap:12px;width:100%}
  .quote-bottom{display:block;margin:32px auto 0;color:rgba(255,255,255,.08);font-size:64px;
    position:static}

  /* кнопки */
  .button{width:100%;min-height:60px;border-radius:15px;font-size:13px;font-weight:900;
    letter-spacing:.13em}
  .button:hover{transform:none}
  .button:active{transform:scale(.97)}
  .button-primary{box-shadow:0 8px 28px rgba(255,75,75,.28)}
  .button-ghost{border-color:rgba(255,255,255,.14)}
  .button-small{width:auto;min-height:auto;padding:8px 16px;border-radius:999px;font-size:11px;
    font-weight:900;letter-spacing:.1em}

  /* чат */
  .preview-section{margin-bottom:78px;padding-inline:16px}
  .chat-preview{display:block;height:auto;overflow:visible;border:0;border-radius:0;
    background:transparent;box-shadow:none}

  /* ── вкладки: три колонки по очереди ─────────────────────────────────── */
  .chat-tabs{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;margin-bottom:14px;
    padding:4px;border:1px solid var(--border);border-radius:14px;background:var(--panel-deep)}
  .chat-tabs button{display:flex;align-items:center;justify-content:center;gap:6px;
    min-height:42px;padding:0 4px;border:0;border-radius:10px;background:transparent;
    color:rgba(255,255,255,.44);font-size:10px;font-weight:900;letter-spacing:.06em;
    text-transform:uppercase;cursor:pointer;transition:background .2s,color .2s}
  .chat-tabs button i{font-size:15px}
  .chat-tabs button.active{background:rgba(255,75,75,.12);color:var(--coral)}

  /* Показываем ровно одну колонку. Правила «спрятать» живут только здесь, в
     мобильном слое: на широком экране колонки обязаны стоять рядом. */
  .chat-preview>.sidebar,
  .chat-preview>.chat-main,
  .chat-preview>.profile-rail{display:none}
  .chat-preview[data-tab="dialogs"]>.sidebar{display:flex}
  .chat-preview[data-tab="chat"]>.chat-main{display:flex}
  .chat-preview[data-tab="profile"]>.profile-rail{display:block}

  /* левая колонка на мобилке — такая же карточка, как правая */
  .sidebar{border:1px solid var(--border);border-right:0;border-radius:24px;
    background:var(--panel);overflow:hidden}
  /* заголовок колонки не нужен — так же называется сама вкладка */
  .sidebar-title{display:none}
  .sidebar-scroll{overflow:visible;padding:16px 12px 12px}
  /* width:auto обязателен: на десктопе кнопка растянута на всю колонку
     (width:100%), а здесь у неё ещё и боковые отступы — вместе они выносили
     её вправо на 12 px, и блок переставал стоять по центру. */
  .sidebar-settings{margin:0 12px 12px;width:auto}
  /* Между двумя кнопками отступ лишний: они читаются как один блок действий. */
  .sidebar-actions .sidebar-settings:first-child{margin-bottom:0}
  .radio{margin:0 12px 12px;padding:12px}
  .radio-play{width:46px;height:46px}
  .radio-track{font-size:13px}

  /* На касании удаляют свайпом влево, как в мессенджерах, — крестик тут не
     нужен: наведения нет, а постоянный ряд крестиков в узкой колонке шумит и
     ловит случайные нажатия. Строка обрезает всё лишнее, чтобы уехавшая
     карточка не вылезала за колонку. */
  .recent-del{display:none}
  /* Пальцем — крупнее: строка примерно с высоту строки в мессенджере, лицо
     заметное, имя и последняя реплика читаются не приглядываясь. */
  .recent-item{gap:13px;padding:11px 12px}
  .recent-item .pic{flex-basis:48px;width:48px;height:48px;font-size:17px}
  .recent-item .pic-letter{font-size:17px}
  .recent-item b{font-size:15px}
  .recent-item small{font-size:13px}
  .recent-item time{font-size:12px}
  .recent-row{overflow:hidden;border-radius:10px}
  .recent-swipe{display:flex}
  /* Пока тянут — карточке нужен непрозрачный фон, иначе надпись «Удаление
     чата» просвечивает сквозь неё. И коралловая рамка выбранного чата на
     время жеста снимается: она спорит с коралловой подложкой и разрезает
     строку пополам, пока та едет. */
  .recent-row.swiping .recent-item{background:var(--panel);border-color:transparent}
  .recent-row.swiping .recent-swipe{opacity:1}

  .chat-main{border:1px solid var(--border);border-radius:24px;overflow:hidden}
  .chat-header{padding:16px}
  .avatar-initial{border:1px solid rgba(255,255,255,.1);background:rgba(255,255,255,.07);color:#fff}
  .chat-contact strong{font-size:14px}
  .chat-contact small{color:#22c55e;font-size:9px;font-weight:700;letter-spacing:.08em;
    text-transform:uppercase}
  .chat-badges{display:flex;gap:4px}
  /* Крупнее, чем было (5px/7px): по кнопкам надо попадать пальцем. */
  .chat-badges a{padding:9px 11px;font-size:9px}
  /* flex:none обязателен. В базе у ленты flex:1, то есть flex-basis:0, а в
     колоночном флекс-контейнере основной размер берётся из flex-basis — height
     при этом не действует вовсе. Лента съёживалась до высоты содержимого, и
     прокручивать было нечего. */
  .message-history{flex:none;height:400px;padding:16px;gap:22px;background:rgba(15,15,19,.52)}
  /* Демо-чат на ЛЕНДИНГЕ прокрутку не крадёт. Лента выше — коробка в 400 px с
     overflow:auto из базового слоя, и палец на телефоне крутил её, а не
     страницу: пока не упрётся в дно, лендинг стоит на месте (жалоба владельца
     26.08.2026). Прокручивать её человеку и незачем — демо показывает, как
     выглядит переписка, а не хранит историю.
     Свежие реплики при этом доезжают: scrollLog() двигает scrollTop сам, а он
     работает и при overflow:hidden. В приложении (body.chat-full) лента
     скроллится как прежде — там это её работа. */
  /* ⚠️ Жёсткая высота ВМЕСТЕ с обрезкой = ловушка для пальца. Замер на профиле
     андроида 26.08.2026, жест в одной точке экрана: height:400px+overflow:hidden
     — страница не двигается вовсе; overflow:visible при той же высоте, или
     height:auto при той же обрезке, или max-height вместо height — листается.
     То есть браузер считает коробку прокручиваемой по одной лишь фиксированной
     высоте, даже когда переполнять её нечем (scrollHeight равен clientHeight).
     Первая моя правка поставила overflow:hidden к height:400px и тем самым
     ловушку и создала. Потолок держим max-height'ом: вид тот же, коробки нет. */
  body:not(.chat-full) .message-history{height:auto;max-height:400px;overflow:hidden}
  .message-row{max-width:90%;gap:8px;align-items:flex-start}
  .message-row p{padding:15px;border-radius:17px;
    background:linear-gradient(rgba(255,255,255,.03),rgba(255,255,255,.03)),rgba(46,48,56,var(--bub-a,.1))}
  .message-row.sent p{background:linear-gradient(rgba(255,75,75,.1),rgba(255,75,75,.1)),rgba(46,48,56,var(--bub-a,.1));
    border-color:rgba(255,75,75,.2)}
  .bot-icon{flex:0 0 36px;width:36px;height:36px;border:1px solid rgba(255,75,75,.3);
    box-shadow:0 0 14px rgba(255,75,75,.18)}
  .composer{gap:5px;padding:12px}
  .composer input,.composer textarea{padding:12px;border:0;border-radius:0;background:rgba(255,255,255,.04)}
  .icon-button{width:38px;height:38px}
  .send-button{width:38px;height:38px;border-radius:11px}

  /* карточка персонажа — вкладка, не блок под чатом, поэтому без верхнего отступа */
  .profile-rail{margin-top:0;border:1px solid var(--border);border-left:0;
    border-radius:24px;background:var(--panel);align-items:stretch;text-align:left;
    overflow:visible;padding:24px}
  /* тут колонка не ограничена высотой — факты показываем целиком, без своей полосы */
  .portrait{max-height:none}
  .memory-box{display:block;min-height:0}
  .profile-head{position:static;padding:0;background:none}
  .portrait{aspect-ratio:4/5;margin-bottom:24px;border-radius:16px}
  .profile-copy{margin:0;text-align:left}
  .profile-copy h2{font-size:29px;font-weight:900;font-style:italic;letter-spacing:-.08em;
    text-transform:uppercase}
  .profile-copy strong{font-size:11px;font-weight:900;letter-spacing:.14em}
  .profile-rail .tag-list{justify-content:flex-start;margin-top:18px}
  .tag-list span{padding:5px 8px;border-radius:4px;font-size:9px;font-style:normal;font-weight:700;
    letter-spacing:.06em;text-transform:uppercase}
  .profile-bio{margin:24px 0;text-align:left;font-size:13px;color:rgba(255,255,255,.48)}
  .profile-button{margin-top:0}
  .profile-actions button{min-height:46px;border-radius:13px;font-size:10px;font-weight:900}

  /* заголовки секций */
  .section-header{align-items:flex-end;gap:12px;margin-bottom:28px}
  .section-title{padding-left:12px;border-left-width:3px;font-size:25px;line-height:.95;
    font-weight:900;font-style:italic;letter-spacing:-.08em;text-transform:uppercase}
  .section-subtitle{padding-left:15px;font-size:9px;font-weight:700;letter-spacing:.1em}
  .section-link{font-size:9px;font-weight:900;white-space:nowrap}

  /* витрина */
  .characters-section{margin-bottom:88px}
  /* Витрина в два столбца, все карточки одинаковые */
  .characters-grid{grid-template-columns:repeat(2,1fr);gap:16px}
  .character-card{display:block;position:relative;height:auto;border-radius:18px;min-width:0}
  .card-image{width:auto;flex:none;aspect-ratio:4/5}
  .card-copy{padding:14px 14px 16px}
  .card-copy h3{font-size:17px;line-height:1.05;font-weight:900;letter-spacing:-.06em;
    text-transform:uppercase;overflow-wrap:anywhere}
  .card-copy>strong{display:block;font-size:9px;font-weight:900;letter-spacing:.12em;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .card-copy .status{top:12px;right:12px}
  .card-copy .tag-list span{padding:4px 6px;font-size:8px;letter-spacing:.04em}
  /* в узкой колонке второй тег почти всегда обрезается — оставляем один */
  .card-copy .tag-list span:nth-child(n+2){display:none}

  /* Выделения первой карточки нет: в сетке все ячейки равны, иначе Сатору
     выпадает из двух колонок. Правила ниже гасят «избранный» вид, который
     остался в базовом слое. */
  .characters-grid>.character-card:first-child .card-image{aspect-ratio:4/5}
  .characters-grid>.character-card:first-child .card-copy{position:static;padding:14px 14px 16px}
  .characters-grid>.character-card:first-child h3{font-size:17px;font-style:normal;
    letter-spacing:-.06em}

  /* возможности */
  .features-section{margin-bottom:92px}
  .feature-grid{grid-template-columns:1fr;gap:42px}
  .feature-card{display:flex;align-items:flex-start;gap:22px;min-height:0;padding:0;border:0;
    background:transparent;overflow:visible}
  .feature-icon{flex:0 0 56px;margin-bottom:0;border-radius:16px}
  .feature-icon.coral{border:1px solid rgba(255,75,75,.2);background:rgba(255,75,75,.1)}
  .feature-icon.blue{border:1px solid rgba(22,140,255,.2);background:rgba(22,140,255,.1)}
  .feature-card h3{margin:4px 0 10px;font-size:20px;font-weight:900;font-style:italic;
    letter-spacing:-.07em;text-transform:uppercase}
  .feature-card p{font-size:13px;color:rgba(255,255,255,.48)}
  /* overflow возвращаем: строкой выше .feature-card снимает обрезку ради
     раскладки «иконка + текст», а здесь под фоном лежит огромный значок,
     вынесенный за правый край (right:-34px). Без обрезки он расширял документ
     на 27 px — появлялась горизонтальная прокрутка, и всё центрированное
     съезжало влево, потому что центровка шла по 417 px вместо 390. */
  .feature-highlight{display:block;padding:32px;border:1px solid var(--border);border-radius:22px;
    overflow:hidden;
    background:linear-gradient(145deg,var(--panel),var(--bg));box-shadow:0 20px 50px rgba(0,0,0,.35)}
  .feature-highlight .feature-body{position:relative;z-index:1}
  .feature-highlight h3{font-size:31px;line-height:.92}
  .feature-highlight p{margin-bottom:30px}
  .background-icon{right:-34px;top:auto;bottom:-24px;font-size:190px;opacity:.04}

  /* шаги */
  .steps-section{margin-bottom:92px}
  .steps-grid{grid-template-columns:1fr;gap:18px}
  .step{padding:28px;border-radius:22px}
  .step h3{font-size:20px;font-weight:900;font-style:italic;letter-spacing:-.07em;
    text-transform:uppercase}

  /* призыв */
  .cta-section{margin-bottom:0}
  /* Обрезку снимаем: она резала тень-свечение под кнопкой «Создать первый чат»
     (ширина .cta-inner ровно как у кнопки, а тень расходится на 28 px). Чтобы
     снятая обрезка не выпустила подсветку за край документа, ниже свечение
     переведено на габариты самой секции — по горизонтали оно теперь никуда
     не выходит, как и в макете. */
  .cta-inner{position:relative;min-height:0;padding:0 0 96px;border:0;border-radius:0;
    background:transparent;overflow:visible}
  .cta-content{position:relative;z-index:1;padding:0}
  .cta-content h2{font-size:clamp(32px,10.5vw,44px);line-height:.9;font-weight:900;font-style:italic;
    letter-spacing:-.09em;text-transform:uppercase}
  .cta-content p{margin-bottom:34px;font-size:15px}
  /* Подсветка по габаритам секции, а не круг шире неё: круг на 420 px в
     контейнере 342 px и был причиной, по которой обрезку вообще поставили. */
  .cta-glow.blue{inset:-80px 0 0;width:auto;height:auto;transform:none;filter:none;animation:none;
    border-radius:0;opacity:.5;pointer-events:none;
    background:radial-gradient(circle at center,rgba(255,75,75,.15),transparent 70%)}
  .cta-glow.violet{display:none}

  /* подвал */
  .site-footer{padding:64px 0 40px}
  /* 52 px между блоком бренда и колонками — как в макете; 36 px между колонками */
  .footer-grid{grid-template-columns:1fr 1fr;gap:52px 36px;margin-bottom:0}
  .footer-brand{grid-column:1/-1;max-width:none}
  .footer-brand p{max-width:250px}
  .socials{gap:14px}
  .socials a{border:1px solid var(--border);background:rgba(255,255,255,.04)}
  .site-footer h4{margin-bottom:18px;font-size:9px;letter-spacing:.2em}
  .footer-col a{margin-bottom:14px;font-size:13px;font-weight:700;line-height:1.3}
  .footer-bottom{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:52px;padding-top:34px;
    color:rgba(255,255,255,.27);font-size:9px;letter-spacing:.1em}
  .footer-bottom .fb-note{margin-right:0}
  .footer-bottom b{margin-left:0;text-align:right}

  /* Окна прижаты к ВЕРХУ экрана (решение владельца 30.08.2026), не к центру и
     не шторкой снизу. По центру длинное окно (вход с двумя галочками, форма)
     упиралось низом в панель браузера, и кнопка под полями уезжала за экран.
     Высота — от dvh, а не vh: vh на телефоне считает и адресную строку, и
     88vh при открытой клавиатуре всё равно вылезал за край. */
  .modal{padding:12px 12px 16px;place-items:start stretch}
  .modal-card{width:100%;max-width:none;max-height:calc(100vh - 28px);max-height:calc(100dvh - 28px);
    padding:28px 24px 30px;
    border-radius:20px;animation:sheet-up .28s ease}
  .modal-card h3{font-size:27px;line-height:1;font-weight:900;font-style:italic;letter-spacing:-.07em;
    text-transform:uppercase}
  .modal-close{top:22px;right:20px;width:36px;height:36px}
  /* Место под крестик: заголовок здесь крупный, и длинный
     («Вернуть всех персонажей к оригиналу?») заезжал под кнопку закрытия.
     Отступ у всего заголовка, а не только у первой строки: так проще, а
     переносы в две-три строки выглядят ровным блоком. */
  .modal-card h3{padding-right:44px}
  .field input[type=text]{padding:16px;border-radius:13px;background:rgba(255,255,255,.04)}
  .check input{width:19px;height:19px}
  .form-note,.form-err{border-radius:12px}
  @keyframes sheet-up{from{transform:translateY(30px)}to{transform:none}}

  .toast{left:16px;right:16px;bottom:24px;text-align:center;transform:translateY(16px)}
  .toast.show{transform:none}

  /* полный экран */
  body.chat-full{overflow:auto}
  /* margin-top:60px держал место под ЗАКРЕПЛЁННУЮ шапку сайта. В этом режиме
     шапки нет — иначе сверху осталась бы пустая полоса. */
  body.chat-full .preview-section{margin-top:0;padding-inline:0}
  /* Высоту ленты раньше считал жёсткий calc по 100vh — он развалился дважды:
     шапка стала выше (кнопка «Свернуть»), а мобильный vh не учитывает адресную
     строку браузера, и строка ввода уезжала за край экрана. Теперь колонка
     гибкая: лента забирает всё между шапкой и вводом, сколько бы их ни было.
     dvh — «динамический» вьюпорт, меняется вместе с адресной строкой;
     строка с vh выше — запас для старых браузеров. */
  body.chat-full .chat-preview{height:100vh}
  body.chat-full .chat-preview{height:100dvh}
  body.chat-full .chat-main{border-radius:0;border-left:0;border-right:0;border-top:0;
    flex-direction:column;height:100%}
  body.chat-full .message-history{flex:1;min-height:0;height:auto}
  /* Приложение на телефоне — как мессенджер: вкладок нет, экраны сменяют
     друг друга. Какой показан, по-прежнему говорит data-tab (правила выше):
     dialogs — список чатов, chat — разговор со стрелкой «к списку» в шапке,
     profile — карточка персонажа (по имени в шапке) со стрелкой «к чату». */
  body.chat-full .chat-tabs{display:none}
  body.chat-full .chat-preview>.sidebar{height:100%;border:0;border-radius:0;
    background:var(--panel-deep)}
  body.chat-full .side-user{padding-top:calc(14px + env(safe-area-inset-top))}
  body.chat-full .sidebar-scroll{overflow-y:auto;flex:1;min-height:0}
  body.chat-full .sidebar-actions{padding-bottom:env(safe-area-inset-bottom)}
  body.chat-full .chat-back{display:grid;place-items:center;flex:none;width:36px;height:36px;
    margin-left:-6px;border:0;border-radius:10px;background:transparent;color:#fff;cursor:pointer}
  body.chat-full .chat-back svg{width:22px;height:22px}
  body.chat-full .chat-back:active{background:rgba(255,255,255,.08)}
  body.chat-full .chat-who{cursor:pointer}
  /* Лицо — такой же вход в карточку, что и имя: и в шапке, и у пузыря.
     Своё лицо не в счёт — карточки у человека нет. */
  body.chat-full #chat-avatar,
  body.chat-full #chat-log .bubble-avatar:not(.mine){cursor:pointer}
  body.chat-full #chat-avatar:active,
  body.chat-full #chat-log .bubble-avatar:not(.mine):active{opacity:.6}
  body.chat-full .chat-preview>.profile-rail{height:100%;overflow-y:auto;border:0;
    border-radius:0;padding-top:calc(12px + env(safe-area-inset-top))}
  body.chat-full .rail-back{display:inline-flex;align-items:center;gap:6px;margin:0 0 14px -8px;
    padding:8px 12px 8px 6px;border:0;border-radius:10px;background:transparent;
    color:rgba(255,255,255,.72);font-size:13px;font-weight:700;cursor:pointer}
  body.chat-full .rail-back svg{width:20px;height:20px}
  body.chat-full .rail-back:active{background:rgba(255,255,255,.08)}
}

@media (min-width:600px) and (max-width:899px){
  .characters-grid{grid-template-columns:1fr 1fr}
  .characters-grid>.character-card:first-child{grid-column:1/-1}
  .feature-highlight{grid-column:1/-1}
  .preview-section,.characters-section,.features-section,.steps-section,.cta-section{
    max-width:620px;margin-inline:auto}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
}
/* ── вход и регистрация ──────────────────────────────────────────────────── */
/* Поля пароля и почты выглядят как текстовые: селектор был написан только под
   [type=text], и любое новое поле оставалось голым инпутом браузера. */
.field input[type=password],
.field input[type=email]{width:100%;padding:15px;border:1px solid var(--border);border-radius:10px;
  background:var(--panel-deep);color:#fff;outline:0}
.field input[type=password]:focus,
.field input[type=email]:focus{border-color:rgba(245,85,85,.5)}
.field input::placeholder{color:rgba(255,255,255,.2)}

.tabs{display:flex;gap:6px;margin:0 0 26px;padding:5px;border:1px solid var(--border);
  border-radius:12px;background:var(--panel-deep)}
.tabs .tab{flex:1;min-height:42px;border:0;border-radius:9px;background:transparent;
  color:rgba(255,255,255,.45);font-size:12px;font-weight:600;cursor:pointer;
  transition:background .2s,color .2s}
.tabs .tab:hover{color:#fff}
.tabs .tab.on{background:var(--coral);color:#fff}

/* Разделитель перед провайдерами: тонкая линия по бокам подписи. Без неё
   кнопки читаются как продолжение формы, а это другой способ входа. */
.providers{margin:0 0 22px}
.providers-title{display:flex;align-items:center;gap:12px;margin:0 0 14px;
  color:rgba(255,255,255,.32);font-size:12px}
.providers-title::before,.providers-title::after{content:"";flex:1;height:1px;
  background:rgba(255,255,255,.09)}
/* Сетка, а не строка: провайдеров бывает и четыре — ВК, Яндекс и две учётки
   через VK ID, — и в одну строку они превращаются в нечитаемые огрызки. */
.providers-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
/* Значки прижаты к левому краю, а не отцентрованы вместе с подписью: подписи
   разной длины («ВКонтакте» и «Одноклассники»), и при центрировании значки
   разъезжаются по горизонтали — четыре кнопки перестают читаться как ряд. */
.provider-button{flex:1;display:inline-flex;align-items:center;justify-content:flex-start;gap:9px;
  min-height:48px;padding:0 13px;border:1px solid var(--border);border-radius:10px;
  background:rgba(255,255,255,.04);color:#fff;font-size:13px;font-weight:600;
  cursor:pointer;transition:background .2s,border-color .2s,transform .2s}
/* Самая длинная подпись не должна ломать строку и растягивать кнопку по высоте. */
.provider-button>span:last-child{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.provider-button:hover{transform:translateY(-2px);background:rgba(255,255,255,.08)}
/* Кружок с буквой вместо логотипа: чужие марки мы не рисуем, а цвет и первая
   буква узнаются мгновенно и не врут о принадлежности. */
.provider-mark{display:grid;place-items:center;width:26px;height:26px;flex:0 0 26px;
  border-radius:7px;font:700 14px/1 'Space Grotesk',sans-serif;color:#fff}
.provider-vk .provider-mark{background:#07f}
.provider-vk:hover{border-color:rgba(0,119,255,.55)}
.provider-yandex .provider-mark{background:#fc3f1d}
.provider-yandex:hover{border-color:rgba(252,63,29,.55)}
.provider-mail .provider-mark{background:#005ff9}
.provider-mail:hover{border-color:rgba(0,95,249,.55)}

/* Кнопка входа в шапке: это <button>, а не ссылка, и ей нужны курсор и та же
   высота строки, что у прежней ссылки. */
button.button-small{cursor:pointer;line-height:1}

/* На узком экране половина ширины не вмещает «Одноклассников» — подпись
   обрезалась многоточием. Один столбец: подписи целиком, значки по-прежнему
   на одной вертикали. Порог 640, а не 899: на планшете окно входа всё ещё
   540 пикселей шириной, и две колонки там помещаются свободно. */
@media (max-width:640px){
  .providers-row{grid-template-columns:1fr}
}

/* ── витрина персонажей на широком экране ────────────────────────────────── */
/* Четыре в ряд. Горизонтальная карточка (портрет слева, текст справа) для
   такой ширины не годится: на колонку приходится около 270 пикселей, из них
   192 забирал портрет — тексту оставалась щель. Поэтому здесь та же
   вертикальная форма, что давно живёт в мобильном слое: портрет сверху,
   подпись под ним. Порог 900, чтобы не спорить с мобильными правилами. */
@media (min-width:900px){
  .characters-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:22px}
  .character-card{display:block;position:relative;height:auto;min-width:0}
  .card-image{width:auto;flex:none;aspect-ratio:4/5}
  .card-copy{padding:16px 16px 18px}
  .card-copy h3{margin:0 0 5px;font-size:19px;line-height:1.1;overflow-wrap:anywhere}
  .card-copy>strong{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .card-copy .tag-list{margin-top:12px}
  /* Третий тег в узкой колонке переносится на свою строку и рвёт ряд по
     высоте — двух хватает, чтобы понять характер. */
  .card-copy .tag-list span:nth-child(n+3){display:none}
}

/* ── вид произведения в подписи персонажа ────────────────────────────────── */
/* «#сериал #игра Ведьмак». Метка приглушена относительно названия мира: она
   уточняет, а не спорит с ним за внимание. Строка подписи набрана прописными
   и коралловым, поэтому метке достаточно снять цвет и убрать разрядку. */
/* Вид произведения приглушён: он уточняет, откуда персонаж, и не должен спорить
   с названием мира за внимание. Тёплый акцент отдан чертам характера — см. ниже. */
.media-tag{margin-right:6px;color:rgba(255,255,255,.34);letter-spacing:.04em;font-weight:700}
.media-tag + .media-tag{margin-left:-2px}

/* ── черты характера ─────────────────────────────────────────────────────── */
/* Медно-золотой, тот же, что у предупреждения в кастомизации: тёплый оттенок
   в теме один. Черта — это то, чем персонаж отличается от соседа по витрине,
   поэтому акцент отдан ей, а не виду произведения. Правило одно на все три
   места, где черты показываются: карточка, правая колонка, кастомизация. */
.tag-list span{border-color:rgba(201,150,79,.3);background:rgba(201,150,79,.08);color:#d9a95f}

/* ── Разделы каталога ────────────────────────────────────────────────────────
   Вкладки появились на 21 персонаже: «показать ещё пять» перестало быть
   навигацией. Счётчики берутся с сервера — там один словарь видов, и новый
   раздел не надо заводить ещё и здесь. */
.cat-tabs{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:26px}
.cat-tab{padding:9px 16px;border:1px solid var(--border);border-radius:999px;
  background:rgba(255,255,255,.04);color:rgba(255,255,255,.62);
  font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  cursor:pointer;transition:background .2s,border-color .2s,color .2s}
.cat-tab:hover{background:rgba(255,255,255,.09);color:#fff}
.cat-tab.is-on{background:var(--coral);border-color:var(--coral);color:#fff}
.cat-tab b{margin-left:7px;font-weight:700;opacity:.65}
@media (max-width:640px){.cat-tabs{gap:8px}.cat-tab{padding:8px 13px;font-size:10px}}
/* Подпись «вы в очереди» под тремя точками ожидания: слотов у модели четыре,
   пятый ждёт, и молчание он читает как поломку. */
.queue-note{display:block;margin-top:8px;color:var(--muted);font-size:11px;line-height:1.4}
/* Ссылка на кабинет в шапке. Неприметная надпись рядом с кнопкой входа:
   это не действие, а переход, и спорить с «Войти» за внимание ей незачем. */
.cab-link{font-size:13px;font-weight:600;color:rgba(255,255,255,.62);transition:color .2s}
.cab-link:hover{color:var(--coral)}
/* Аватарка вместо слова: 40px — заметно крупнее строки меню, чтобы по ней
   легко попадать и с мыши, и пальцем; на телефоне тоже видна. */
.cab-avatar{display:inline-grid;place-items:center;width:40px;height:40px;border-radius:50%;
  overflow:hidden;border:2px solid rgba(255,255,255,.14);background:rgba(255,255,255,.06);
  transition:border-color .2s,transform .2s;flex:none}
.cab-avatar:hover{border-color:var(--coral);transform:translateY(-1px)}
.cab-avatar img{width:100%;height:100%;object-fit:cover;display:block}
.cab-avatar .letter{font:700 16px/1 'Space Grotesk',sans-serif;color:rgba(255,255,255,.75)}
.cab-avatar.is-hidden{display:none}
/* На телефоне первую ссылку шапки прячет старое правило .auth-actions>a:first-child
   (там был текст «Кабинет»); аватарке место есть — возвращаем и уменьшаем. */
@media (max-width:640px){.auth-actions>a.cab-avatar:first-child{display:inline-grid;width:36px;height:36px}
  .auth-actions>a.cab-avatar.is-hidden{display:none}}

/* Кнопка диктовки. Свечение золото-медное, а не коралловое: коралл у нас —
   цвет действия («отправить», «удалить»), и микрофон не должен с ним спорить
   до того, как его нажали. */
.mic-button{position:relative;border-radius:50%;transition:color .2s,background .2s,box-shadow .3s}
.mic-button:hover:not(:disabled){color:#f0c674;background:rgba(198,132,58,.12);
  box-shadow:0 0 18px -2px rgba(205,127,50,.55),inset 0 0 10px -4px rgba(240,198,116,.6)}
.mic-button:active:not(:disabled){transform:scale(.94)}
/* Идёт запись: пульс тем же тёплым цветом, чтобы состояние читалось без слов. */
.mic-button.recording{color:#f3d08a;background:rgba(198,132,58,.18);
  box-shadow:0 0 22px -2px rgba(205,127,50,.7);animation:mic-pulse 1.4s ease-in-out infinite}
/* Расшифровка: гаснем и ждём, нажимать нечего. */
.mic-button.busy{color:rgba(240,198,116,.5);animation:none}
@keyframes mic-pulse{50%{box-shadow:0 0 34px 2px rgba(205,127,50,.85)}}

/* Остаток бесплатных сообщений. Коралловым выделено только число со словом
   «бесплатных» — оно и есть новость, остальная фраза служебная. */
#free-note b{color:var(--coral);font-weight:700}

/* Сообщение о том, что бесплатные кончились. Золото-оранжевое, а не
   коралловое: коралл у нас — цвет действия и цвет опасности («удалить»), а
   здесь не тревога, а предложение. Тон тот же тёплый, что у микрофона. */
.free-gate{display:inline-flex;align-items:center;gap:9px;margin:2px 0 0;
  padding:8px 14px;border:1px solid rgba(230,162,60,.32);border-radius:999px;
  background:rgba(230,162,60,.09);color:#f0b429;
  font-size:12px;font-weight:600;line-height:1.4}
.free-gate i{font-size:15px;flex:0 0 auto}
.guest-back{border-color:rgba(245,85,85,.35);background:rgba(245,85,85,.08);color:#fff;font-weight:500;flex-wrap:wrap}
.guest-back a{color:#ff6b6b;font-weight:700;white-space:nowrap}
.capwall-providers{margin:6px 0 4px}
.capwall-or{margin:0 0 8px;text-align:center}
@media (max-width:640px){.free-gate{border-radius:12px;align-items:flex-start}
  .free-gate i{margin-top:1px}}
/* Ссылка внутри системного сообщения в ленте: «оформить подписку» после
   исчерпанного лимита. Красим как действие, а не как текст. */
.system-link{color:var(--coral);font-weight:600;text-decoration:underline}

/* Как в мессенджерах: пустое поле — микрофон, есть текст — отправка. Показан
   ровно один, поэтому кнопки не прыгают и ширина строки не меняется.
   Микрофон сразу в круге: так он читается кнопкой, а не значком-украшением. */
/* Обе кнопки лежат в одном гнезде друг на друге: через display подмену не
   анимировать, а скачок в поле ввода бросается в глаза сильнее всего.
   Уходящая опускается и уменьшается, приходящая поднимается на её место —
   движение маленькое, шесть пикселей, иначе оно начинает отвлекать. */
.composer-actions{position:relative;flex:0 0 40px;width:40px;height:40px}
.composer-actions>button{position:absolute;inset:0;
  transition:opacity .16s ease,transform .24s cubic-bezier(.2,.8,.3,1),
             color .2s,background .2s,box-shadow .3s}
.composer .send-button{opacity:0;transform:translateY(7px) scale(.82);pointer-events:none}
.composer.has-text .send-button{opacity:1;transform:none;pointer-events:auto}
.composer.has-text .mic-button{opacity:0;transform:translateY(-7px) scale(.82);pointer-events:none}
.mic-button{width:40px;height:40px;color:#f0c674;background:rgba(198,132,58,.14);
  border:1px solid rgba(205,127,50,.28)}
/* Кому движение мешает — тому его нет: остаётся то же появление, но мгновенное. */
@media (prefers-reduced-motion:reduce){.composer-actions>button{transition-duration:.01ms}}

/* ══════════════════════════════════════════════════════════════════════════
   КОЛЛЕКТИВНЫЙ РАЗГОВОР
   Втроём в одной ленте главный вопрос — «кто это сказал». На него отвечают
   три вещи разом: лицо у пузыря, имя над репликой и постоянный цвет
   участника. Одного лица в 32 пикселя мало: на телефоне их не различить,
   не приглядываясь, а приглядываться в переписке никто не станет.
   Цвет закреплён за МЕСТОМ в составе (data-seat), а не за персонажем:
   персонажей две сотни, палитра из трёх цветов, и привязка к месту делает
   её предсказуемой — первый всегда коралловый, как и весь остальной сайт.
   ══════════════════════════════════════════════════════════════════════════ */
.message-row[data-seat="0"]{--seat:var(--coral)}
.message-row[data-seat="1"]{--seat:#a855f7}
.message-row[data-seat="2"]{--seat:#56a2ff}
.cast-face[data-seat="0"]{--seat:var(--coral)}
.cast-face[data-seat="1"]{--seat:#a855f7}
.cast-face[data-seat="2"]{--seat:#56a2ff}

/* ── шапка чата: лица участников ──────────────────────────────────────────── */
/* Портреты внахлёст — так их показывают все мессенджеры: три лица занимают
   место полутора и читаются как один объект «участники». */
.chat-contact{flex:1;min-width:0}
/* Имя ужимается первым: втроём оно длинное («Макима, Пауэр и Аки»), а места в
   шапке столько же. Без min-width:0 флекс не даёт колонке сжаться меньше
   содержимого — на телефоне подпись переносилась в три строки, а имя
   выдавливалось из шапки совсем. */
.chat-who{flex:1;min-width:0}
.chat-who strong,.chat-who small{display:block;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.cast-faces{display:flex;align-items:center;flex:none}
.cast-face{position:relative;display:grid;place-items:center;width:38px;height:38px;
  padding:0;border:2px solid var(--panel);border-radius:50%;background:var(--panel-deep);
  overflow:hidden;cursor:pointer;transition:transform .18s,box-shadow .18s}
.cast-face+.cast-face{margin-left:-12px}
/* Порядок наложения обратный: первое лицо сверху, как в списке участников. */
.cast-face:nth-child(1){z-index:3}
.cast-face:nth-child(2){z-index:2}
.cast-face:nth-child(3){z-index:1}
.cast-face img{width:100%;height:100%;object-fit:cover;border-radius:50%}
.cast-face .letter{display:grid;place-items:center;width:100%;height:100%;
  font-size:15px;font-weight:700;color:rgba(255,255,255,.75)}
/* Кольцо цвета участника: тот же цвет стоит у его имени в ленте, и связь
   «лицо наверху — реплика внизу» держится на нём. */
.cast-face{box-shadow:0 0 0 2px var(--seat,transparent)}
@media (hover:hover){.cast-face:hover{transform:translateY(-2px);z-index:4}}

/* ── кнопки режима: только значок ─────────────────────────────────────────── */
/* Подпись «Во весь экран» занимала половину шапки, а рядом теперь стоят лица
   участников, имена и кнопка «позвать». Стрелки понятны без слов — так эту
   кнопку и показывают в чатах. Название осталось в title и aria-label. */
.chat-badges a{width:36px;height:36px;padding:0;justify-content:center}
.chat-badges a i{font-size:15px}

/* ── кнопка «позвать ещё» ─────────────────────────────────────────────────── */
/* Пунктир — обещание пустого места: так обозначают «сюда можно добавить».
   Уводим вправо, к краю шапки: это действие над разговором целиком, а не
   часть имени собеседника. */
/* Отступ справа — тот же, что между корзиной и «во весь экран» (.chat-badges
   gap). Кнопка живёт в соседнем блоке, и общий gap на неё не действует: без
   этого поля она прилипала к корзине, и три значка читались как два. */
.cast-add{display:grid;place-items:center;flex:none;margin-left:auto;margin-right:8px;
  width:36px;height:36px;
  padding:0;border:1px dashed rgba(255,255,255,.22);border-radius:10px;
  background:transparent;color:rgba(255,255,255,.5);cursor:pointer;
  transition:background .15s,border-color .15s,color .15s}
.cast-add svg{width:19px;height:19px;display:block}
@media (hover:hover){.cast-add:hover{border-color:rgba(245,85,85,.5);
  background:rgba(245,85,85,.12);color:#fff}}
/* Состав полон — кнопка не пропадает: через неё же и убирают. Но зазывать
   ей больше нечем, поэтому пунктир становится сплошным. */
.cast-add.is-full{border-style:solid}

/* ── имя над репликой ─────────────────────────────────────────────────────── */
.message-row .who{display:block;margin-bottom:5px;font-size:11px;font-weight:800;
  letter-spacing:.06em;text-transform:uppercase;color:var(--seat,var(--coral))}
/* Действие сразу за именем: у имени свой отступ снизу, а у действия — сверху,
   вместе они разрывали пузырь пополам. */
.message-row .who+.act{margin-top:0}
.message-row.in-group .bubble-avatar{border:1px solid var(--seat,var(--coral));
  box-shadow:0 0 12px -4px var(--seat,var(--coral))}
/* Точки «печатает» в комнате приходят с лицом — видно, чьего ответа ждём. */
.typing-row{display:flex;gap:14px;max-width:86%;align-items:flex-start}
.typing-row .typing{align-self:flex-start}

/* ── подсказка обращения через «@» ────────────────────────────────────────── */
.composer{position:relative}
.mention-pop{position:absolute;left:20px;right:20px;bottom:100%;z-index:20;
  margin-bottom:8px;padding:6px;max-height:230px;overflow-y:auto;
  border:1px solid var(--border);border-radius:14px;background:var(--panel);
  box-shadow:0 20px 50px rgba(0,0,0,.45)}
.mention-item{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;
  border:0;border-radius:10px;background:transparent;color:rgba(255,255,255,.72);
  text-align:left;cursor:pointer}
.mention-item.on,.mention-item:hover{background:rgba(245,85,85,.14);color:#fff}
.mention-face{display:grid;place-items:center;flex:0 0 30px;width:30px;height:30px;
  overflow:hidden;border-radius:50%;background:rgba(255,255,255,.07);font-size:13px;font-weight:700}
.mention-face img{width:100%;height:100%;object-fit:cover}
.mention-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:14px;font-weight:600}
.mention-item small{color:rgba(255,255,255,.35);font-size:12px}

/* ── окно состава ─────────────────────────────────────────────────────────── */
.mem-cast{margin:18px 0 6px}
.mem-list{max-height:300px;overflow-y:auto;margin-top:6px}
.mem-row{display:flex;align-items:center;gap:12px;margin-bottom:8px;padding:10px 12px;
  border:1px solid var(--border);border-radius:14px;background:var(--panel-deep)}
.mem-face{display:grid;place-items:center;flex:0 0 42px;width:42px;height:42px;
  overflow:hidden;border-radius:50%;background:rgba(255,255,255,.07);font-size:16px;font-weight:700}
.mem-face img{width:100%;height:100%;object-fit:cover}
.mem-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}
.mem-text b{font-size:15px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mem-text small{color:rgba(255,255,255,.38);font-size:12px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mem-add,.mem-drop{display:grid;place-items:center;flex:none;width:34px;height:34px;
  padding:0;border:1px solid var(--border);border-radius:10px;background:transparent;
  font-size:15px;line-height:1;cursor:pointer;transition:.15s}
.mem-add{color:var(--coral);border-color:rgba(245,85,85,.38);background:rgba(245,85,85,.1)}
.mem-drop{color:rgba(255,255,255,.4)}
@media (hover:hover){
  .mem-add:hover{background:rgba(245,85,85,.24)}
  .mem-drop:hover{color:#fff;border-color:rgba(245,85,85,.45);background:rgba(245,85,85,.14)}
}
.mem-note{margin:10px 2px 0;color:rgba(255,255,255,.4);font-size:13px;line-height:1.6}
/* Звать некуда — поле поиска гаснет вместе со списком. */
#mem-search:disabled{opacity:.4;cursor:not-allowed}

/* ── узкий экран ──────────────────────────────────────────────────────────── */
@media (max-width:899px){
  /* Лица сильнее внахлёст: три портрета в ряд рядом с именами на 390-пиксельном
     экране не помещаются, а нахлёст — то же, что и в списках мессенджеров. */
  .cast-face{width:36px;height:36px;border-color:var(--panel)}
  .cast-face+.cast-face{margin-left:-14px}
  /* Отступ справа равняем на здешний gap кнопок режима — он тут теснее. */
  .cast-add{width:40px;height:40px;border-radius:12px;margin-right:4px}
  /* Кнопки шапки под палец: все три одного размера и в ряд. */
  .chat-badges a,.chat-badges .badge-icon{width:40px;height:40px;padding:0}
  /* Втроём в шапке тесно, и первым страдает имя — оно единственное, что
     умеет ужиматься. Отступы отдаём ему: каждые сэкономленные пять пикселей
     это ещё половина имени участника. */
  .chat-preview.is-group .chat-contact{gap:9px}
  .mention-pop{left:12px;right:12px;max-height:200px}
  .mention-item{padding:10px}
  .mem-list{max-height:240px}
  .mem-row{padding:10px}
  .mem-add,.mem-drop{width:40px;height:40px}
}

/* ── правая колонка: кто в чате ───────────────────────────────────────────── */
/* Полоска участников. В разговоре вдвоём её нет вовсе — выбирать не из кого,
   и пустой заголовок над одним лицом только занимал бы место. */
/* Во всю ширину колонки. Колонка центрирует детей (align-items:center), и блок
   по содержимому вставал уже соседей — заголовок съезжал вправо относительно
   портрета и всего остального. */
/* Верхний отступ колонки давала шапка карточки (padding 26px сверху) — у самой
   колонки его нет вовсе. Полоска встала первой и прилипла к потолку, поэтому
   отступ теперь несёт она. */
.rail-cast-box{align-self:stretch;width:100%;margin:0 0 2px;padding-top:26px}
/* Заголовок здесь крупнее и заметнее, чем «НЕДАВНИЕ» в левой колонке: тот
   подписывает длинный список и должен молчать, а этот стоит над тремя лицами
   и объясняет, что это вообще такое. И по центру — как всё остальное в
   колонке: имя, мир, черты. */
.rail-cast-box .rail-label{margin:0 0 8px;text-align:center;font-size:11px;
  letter-spacing:.16em;color:rgba(255,255,255,.5)}
/* Лица тоже по центру. safe — чтобы при нехватке места полоса резалась справа,
   а не с обоих краёв: иначе первое лицо уезжает за край и его не достать. */
.rail-cast{justify-content:safe center}
/* Голова карточки держит верхний отступ на случай, когда полоски нет. Есть
   полоска — своё расстояние она уже отдала, и второй отступ подряд читается
   провалом между лицами и портретом. */
.rail-cast-box+.profile-head{padding-top:6px}
/* Имя под портретом: 22 пикселя выглядели дырой, портрет и имя — одно целое. */
.profile-head .profile-copy{margin-top:12px}
/* Листается вбок: троим место есть всегда, но карточки бывают с длинными
   именами, а полоса прокрутки внутри колонки съедала бы её ширину. Поэтому
   прокрутка без видимой полосы — пальцем на телефоне, колесом на компьютере. */
/* padding сверху — место значку настройки: полоса листается вбок, а всё, что
   вылезает за её край, обрезается вместе с ним. Без этих четырёх пикселей у
   значка срезало макушку. */
.rail-cast{display:flex;gap:10px;overflow-x:auto;padding:4px 0 2px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.rail-cast::-webkit-scrollbar{display:none}
.rail-face{flex:0 0 auto;display:grid;justify-items:center;gap:6px;width:64px;
  padding:0;border:0;background:none;cursor:pointer;color:rgba(255,255,255,.45)}
/* Выбранный участник — в цвете, остальные обесцвечены. Кольцо вокруг лица
   пробовали раньше: в полоске из трёх кружков оно спорило с цветными
   портретами и читалось рамкой, а не выбором. Обесцвечивание работает само
   собой — глаз находит единственное цветное пятно, ничего не разглядывая. */
.rail-face>span,.rail-face>img{width:52px;height:52px;overflow:hidden;
  border-radius:50%;display:grid;place-items:center;background:rgba(255,255,255,.06);
  filter:grayscale(1);opacity:.65;
  transition:filter .18s,opacity .18s,transform .16s}
.rail-face img{width:100%;height:100%;object-fit:cover}
.rail-face small{font-size:11px;line-height:1.2;text-align:center;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
/* Имя выбранного тоже ярче: цвет портрета работает издалека, подпись — вблизи. */
.rail-face.on{color:#fff}
.rail-face.on>span,.rail-face.on>img{filter:none;opacity:1}
@media (hover:hover){.rail-face:hover>span,.rail-face:hover>img{opacity:.9}}
@media (hover:hover){.rail-face:hover>span,.rail-face:hover>img{transform:translateY(-2px)}}
/* Настройка гостя открывается в его собственном разговоре — здесь кнопка
   гаснет, но остаётся нажимаемой: молча ничего не делать хуже, чем объяснить. */
.profile-button.is-off{opacity:.4}
@media (max-width:899px){
  /* На узком экране отступ сверху даёт сама колонка (padding 24px), и второй
     подряд превращался бы в пустую полосу над лицами. */
  .rail-cast-box{padding-top:0}
  .rail-face{width:72px}
  .rail-face>span,.rail-face>img{width:58px;height:58px}
  .rail-face small{font-size:12px}
}

/* ── поиск персонажа: отметки и разные действия ───────────────────────────── */
/* Два действия рядом — два разных цвета. Коралловый «＋» заводит новый
   разговор, золото-медная «→» возвращает в начатый: без цвета их приходилось
   бы различать по подписи под именем, то есть вчитываться. */
.mem-add.mem-back{color:#f0c674;border-color:rgba(205,127,50,.3);
  background:rgba(198,132,58,.14)}
@media (hover:hover){.mem-add.mem-back:hover{background:rgba(198,132,58,.26)}}
/* Якорь настроенного персонажа — поверх портрета, тем же золото-медным.
   Смысл у цвета один на весь интерфейс: «это уже ваше, не каноническое».
   Значок один на все места, где персонаж показан лицом: поиск, полоска
   участников, список диалогов, витрина. Отличается только размер. */
.tuned{position:absolute;z-index:2;display:grid;place-items:center;
  width:18px;height:18px;top:-3px;right:-3px;
  border:1.5px solid var(--panel-deep);border-radius:50%;
  background:linear-gradient(150deg,#f0c674,#b87333);color:#231708;
  font-style:normal;cursor:help}
/* Карандаш нарисован своей разметкой: в шрифте его нет. Размер задаётся здесь,
   чтобы в каждом месте (полоска, список, витрина) он тянулся вместе с кружком. */
.tuned svg{width:62%;height:62%;display:block}
.mem-face{position:relative;overflow:visible}
.mem-face>img,.mem-face>.letter{border-radius:50%;width:100%;height:100%;
  object-fit:cover;display:grid;place-items:center}
/* Полоска участников: лицо обёрнуто своим узлом, иначе значку не за что
   зацепиться — кнопка выше по дереву и содержит ещё подпись. */
.rail-pic{position:relative;display:block}
.rail-face .tuned{top:-2px;right:-2px;border-color:var(--panel-deep)}
/* Список диалогов: кружок мелкий, значок тоже. */
.recent-item .pic{position:relative;overflow:visible}
.recent-item .pic>img,.recent-item .pic>.pic-letter{border-radius:50%;
  width:100%;height:100%;object-fit:cover}
.recent-item .tuned{width:15px;height:15px;top:-2px;right:-2px;
  border-color:var(--panel)}
/* Витрина: карточка большая, значок крупнее и стоит в углу портрета. */
.card-image{position:relative}
.card-image .tuned{width:26px;height:26px;top:10px;right:10px;
  border-color:rgba(0,0,0,.35)}

/* ── меню чата, поиск и оформление ─────────────────────────────────────────
   Всё, что делают с самим разговором, собрано под тремя точками: раньше в
   шапке стояла отдельная корзина, а поиск и оформление жить там были негде —
   шапка и так занята лицами участников. */
.chat-menu-box{position:relative}
.chat-menu{position:absolute;right:0;top:calc(100% + 8px);z-index:30;min-width:224px;
  padding:6px;border:1px solid var(--border);border-radius:12px;
  background:var(--panel-deep);box-shadow:0 18px 44px rgba(0,0,0,.5)}
.chat-menu button{display:flex;align-items:center;gap:11px;width:100%;
  padding:10px 12px;border:0;border-radius:8px;background:transparent;
  color:rgba(255,255,255,.82);font-size:13px;text-align:left;cursor:pointer;
  transition:background .15s,color .15s}
.chat-menu button:hover{background:rgba(255,255,255,.07);color:#fff}
.chat-menu button svg{width:17px;height:17px;flex:0 0 17px;color:var(--coral)}
/* Удаление всего разговора отделено чертой: рядом стоит очистка истории, и
   промах между ними стоит слишком дорого, чтобы полагаться на внимание. */
.chat-menu .is-danger{margin-top:4px;padding-top:12px;
  border-top:1px solid var(--border);border-radius:0 0 8px 8px;color:#ff8080}
.chat-menu .is-danger svg{color:#ff8080}
.chat-menu .is-danger:hover{background:rgba(255,80,80,.12);color:#ff9b9b}

.chat-find{display:flex;align-items:center;gap:8px;padding:10px 16px;
  border-bottom:1px solid var(--border);background:var(--panel-deep)}
.chat-find>svg{width:17px;height:17px;flex:0 0 17px;color:rgba(255,255,255,.4)}
.chat-find input{flex:1;min-width:0;border:0;outline:0;background:transparent;
  color:#fff;font-size:13px}
.chat-find input::placeholder{color:rgba(255,255,255,.25)}
.find-count{color:rgba(255,255,255,.4);font-size:11px;white-space:nowrap}
.find-step{display:grid;place-items:center;width:28px;height:28px;flex:0 0 28px;
  border:0;border-radius:6px;background:transparent;color:rgba(255,255,255,.5);
  cursor:pointer;transition:background .15s,color .15s}
.find-step:hover{background:rgba(255,255,255,.07);color:#fff}
.find-step svg{width:16px;height:16px}
/* Найденное подсвечиваем прямо в реплике, а не списком отрывков: человек ищет,
   чтобы ВЕРНУТЬСЯ к месту разговора, и место важно видеть в его окружении. */
mark.find-hit{padding:0 2px;border-radius:3px;background:rgba(245,85,85,.28);
  color:inherit}
mark.find-hit.is-current{background:var(--coral);color:#fff}

.cs-group{margin-bottom:18px}
.cs-group>label{display:block;margin-bottom:8px;color:rgba(255,255,255,.44);
  font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase}
.cs-row{display:flex;flex-wrap:wrap;gap:8px}
.cs-row button{padding:9px 14px;border:1px solid var(--border);border-radius:8px;
  background:rgba(255,255,255,.04);color:rgba(255,255,255,.7);font-size:12px;
  cursor:pointer;transition:border-color .15s,background .15s,color .15s}
.cs-row button:hover{background:rgba(255,255,255,.08);color:#fff}
.cs-row button.is-on{border-color:var(--coral);background:rgba(245,85,85,.14);color:#fff}
.cs-chip{position:relative;padding-left:32px !important}
/* Кружок-образец у названия: цвет выбирают глазами, а не по слову. */
.cs-chip:before{content:"";position:absolute;left:11px;top:50%;width:14px;height:14px;
  margin-top:-7px;border:1px solid rgba(255,255,255,.18);border-radius:50%}
.cs-bg-default:before{background:#1b1c1f}
.cs-bg-graphite:before{background:linear-gradient(160deg,#24262b,#15161a)}
.cs-bg-warm:before{background:linear-gradient(160deg,#2a211d,#191413)}
.cs-bg-night:before{background:linear-gradient(160deg,#161c33,#0e1120)}
.cs-ink-coral:before{background:var(--coral)}
.cs-ink-violet:before{background:#a855f7}
.cs-ink-blue:before{background:#56a2ff}
.cs-ink-slate:before{background:rgba(255,255,255,.28)}
.cs-reset{width:100%;min-height:44px;margin-top:4px}

/* Пузыри: цветной оттенок поверх подложки rgba(46,48,56,--bub-a) — она заметно светлее панели, иначе на обычном фоне плотность не видна.
   Плотность подложки задаёт ползунок «Прозрачность пузырей» в оформлении
   чата (решение владельца 17.08.2026): по умолчанию как было всегда — почти
   прозрачные (.1), на узорных фонах человек сам добавляет плотности; в самый
   ноль (совсем без подложки) не даём — текст должен читаться. */
.cs-range{display:flex;align-items:center;gap:12px}
.cs-range input{flex:1;height:4px;margin:0;appearance:none;-webkit-appearance:none;border-radius:2px;
  background:linear-gradient(90deg,var(--coral) var(--v,15%),rgba(255,255,255,.14) 0);cursor:pointer}
.cs-range input::-webkit-slider-thumb{appearance:none;-webkit-appearance:none;width:16px;height:16px;
  border-radius:50%;background:#fff;border:0;box-shadow:0 1px 5px rgba(0,0,0,.5)}
.cs-range input::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:#fff;border:0}
.cs-range input::-moz-range-track{height:4px;background:transparent}
.cs-range output{flex:none;min-width:38px;text-align:right;font-size:12px;font-variant-numeric:tabular-nums;
  color:rgba(255,255,255,.75)}
.cs-range-ends{display:flex;justify-content:space-between;margin-top:5px;font-size:10px;
  color:rgba(255,255,255,.32)}
/* ── сами наряды ───────────────────────────────────────────────────────────
   Ставятся атрибутами на .chat-main, чтобы одним выбором красились и лента, и
   пузыри, и шапка — иначе фон и реплики разъезжались бы по разным правилам. */
.chat-main[data-bg="graphite"] .message-history{background:linear-gradient(170deg,#24262b,#141519)}
.chat-main[data-bg="warm"] .message-history{background:linear-gradient(170deg,#2a211d,#17120f)}
.chat-main[data-bg="night"] .message-history{background:linear-gradient(170deg,#161c33,#0d101c)}

.chat-main[data-ink="violet"] .message-row.sent p{
  border-color:rgba(168,85,247,.34);background:linear-gradient(rgba(168,85,247,.16),rgba(168,85,247,.16)),rgba(46,48,56,var(--bub-a,.1))}
.chat-main[data-ink="blue"] .message-row.sent p{
  border-color:rgba(86,162,255,.34);background:linear-gradient(rgba(86,162,255,.16),rgba(86,162,255,.16)),rgba(46,48,56,var(--bub-a,.1))}
.chat-main[data-ink="slate"] .message-row.sent p{
  border-color:rgba(255,255,255,.16);background:linear-gradient(rgba(255,255,255,.09),rgba(255,255,255,.09)),rgba(46,48,56,var(--bub-a,.1))}

/* Реплики персонажей — та же палитра, отдельный атрибут. «Графит» — их
   обычный вид (без правила), поэтому по умолчанию ничего не меняется.
   Служебные и записки рассказчика (.system) не трогаем — у них свой янтарь. */
.chat-main[data-cast="coral"] .message-row.received p{
  border-color:rgba(245,85,85,.3);background:linear-gradient(rgba(245,85,85,.12),rgba(245,85,85,.12)),rgba(46,48,56,var(--bub-a,.1))}
.chat-main[data-cast="violet"] .message-row.received p{
  border-color:rgba(168,85,247,.34);background:linear-gradient(rgba(168,85,247,.16),rgba(168,85,247,.16)),rgba(46,48,56,var(--bub-a,.1))}
.chat-main[data-cast="blue"] .message-row.received p{
  border-color:rgba(86,162,255,.34);background:linear-gradient(rgba(86,162,255,.16),rgba(86,162,255,.16)),rgba(46,48,56,var(--bub-a,.1))}
.chat-main[data-cast="teal"] .message-row.received p{
  border-color:rgba(45,212,191,.34);background:linear-gradient(rgba(45,212,191,.16),rgba(45,212,191,.16)),rgba(46,48,56,var(--bub-a,.1))}
/* Погашенный цвет: занят другой стороной. Зачёркивать кружок нельзя — он и
   есть смысл кнопки, поэтому просто тускнеет и не нажимается. */
.cs-row .cs-chip.is-blocked{opacity:.32;cursor:not-allowed}
.cs-row .cs-chip.is-blocked:hover{background:transparent;color:rgba(255,255,255,.62)}

.chat-main[data-size="s"] .message-row p{font-size:12px}
.chat-main[data-size="l"] .message-row p{font-size:15px;line-height:1.65}

.chat-main[data-gap="tight"] .message-history{gap:16px}
.chat-main[data-gap="tight"] .message-row p{padding:12px 14px}
.chat-main[data-gap="airy"] .message-history{gap:38px}
.chat-main[data-gap="airy"] .message-row p{padding:20px 22px}

/* ── оживление снимка ──────────────────────────────────────────────────────
   Дописано В КОНЕЦ файла намеренно: середина styles.css — это тело
   @media (max-width:899px), и правило, положенное туда, тихо действовало бы
   только на узких экранах. Проверять на ДВУХ ширинах. */

/* Кнопка поверх снимка, в углу: отдельной строкой под картинкой она
   растягивала бы пузырь, а места в ленте и так немного. */
.photo-anim{position:absolute;right:8px;bottom:8px;z-index:2;
  width:34px;height:34px;display:flex;align-items:center;justify-content:center;
  padding:0;border:1px solid rgba(255,255,255,.22);border-radius:50%;
  color:#fff;background:rgba(12,14,18,.62);backdrop-filter:blur(6px);
  cursor:pointer;opacity:.72;transition:opacity .15s,transform .15s,background .15s}
.photo-anim:hover{opacity:1;transform:scale(1.06);background:rgba(12,14,18,.82)}
.photo-anim:disabled{cursor:default;transform:none}
/* Подпись ожидания ролика: у нижнего края кадра, слева от кнопок. Не поверх
   лица — снимок человек в это время разглядывает. */
.photo-wait{position:absolute;left:8px;bottom:8px;right:50px;z-index:2;
  padding:5px 9px;border-radius:9px;font-size:11px;line-height:1.25;color:rgba(255,255,255,.92);
  background:rgba(12,14,18,.66);backdrop-filter:blur(6px);pointer-events:none}
/* На узком экране кнопка крупнее: 34 точки пальцем не берутся. */
@media (max-width:640px){
  .photo-anim{width:40px;height:40px;opacity:.85}
}

/* Пока считается — кольцо вместо значка. Крутится медленно и намеренно:
   счёт занимает минуту, и бодрый спиннер обещал бы скорое завершение. */
.photo-anim-busy{opacity:1;background:rgba(12,14,18,.82)}
.photo-anim-spin{width:16px;height:16px;border-radius:50%;
  border:2px solid rgba(255,255,255,.28);border-top-color:#fff;
  animation:photo-anim-turn 1.4s linear infinite}
@keyframes photo-anim-turn{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  .photo-anim-spin{animation-duration:3s}
}

/* Ролик занимает место снимка ровно: рамка и пропорции заданы на .photo,
   поэтому video наследует их так же, как это делал img. */
.photo-animated video{width:100%;height:100%;display:block;object-fit:cover}

/* ── ролик: пауза и возврат к снимку ────────────────────────────────────────
   Снимок и ролик лежат в разметке ОБА, показ переключается классом. Так
   возврат к исходнику мгновенный и не тянет файл заново, а ролик не теряет
   место в ленте: рамка и пропорции заданы на .photo и наследуются обоими. */
.photo-animated img,
.photo-animated video{width:100%;height:100%;display:block;object-fit:cover}
.photo-animated.photo-video-on img{display:none}
.photo-animated:not(.photo-video-on) video{display:none}
/* Нажатие по ролику останавливает и продолжает — курсор об этом сообщает. */
.photo-animated.photo-video-on video{cursor:pointer}

/* Крупный треугольник поверх кадра — знак остановки. Показываем ТОЛЬКО на
   паузе: иначе он закрывал бы собой то, ради чего ролик и смотрят. Кружок
   под ним нужен на светлых кадрах, где белый значок иначе теряется. */
.photo-play{position:absolute;inset:0;z-index:1;display:grid;place-items:center;
  pointer-events:none;opacity:0;transition:opacity .18s ease;color:#fff}
.photo-play svg{border-radius:50%;background:rgba(12,14,18,.55);
  padding:12px;box-sizing:content-box;
  box-shadow:0 2px 10px rgba(0,0,0,.35)}
.photo-animated.photo-video-on.photo-paused .photo-play{opacity:1}
@media (prefers-reduced-motion:reduce){
  .photo-play{transition:none}
}

/* Переключатель наследует вид кнопки оживления — место то же, привычка та же.
   Оставляем его заметнее, чем ту: она исчезала после нажатия, а этот нужен
   постоянно, и на паузе его надо видеть поверх треугольника. */
.photo-swap{opacity:.82;z-index:3}
.photo-swap:hover{opacity:1}

/* Точка «в сети» пропадала, и причина тоньше, чем кажется.
   Размеры ей задаёт `.online-dot{width:6px;height:6px}`, но сама она <span>,
   то есть СТРОЧНАЯ — ширина и высота на такой не действуют. Работало это лишь
   потому, что родитель был гибким контейнером: `.chat-contact small{display:flex}`
   превращал точку в его элемент, и размеры оживали.
   Потом появилось `.chat-who strong,.chat-who small{display:block}` — для
   обрезки длинных имён многоточием. Вес у обоих селекторов ОДИНАКОВ (класс +
   тег), при равенстве побеждает тот, что ниже в файле, а `.chat-who` описан
   позже. Статус перестал быть гибким контейнером, и точка схлопнулась в ничто.
   Лечим саму точку, а не родителя: inline-block включает размеры независимо от
   того, каким окажется родитель, и не мешает обрезке имён многоточием.
   vertical-align — чтобы кружок стоял по центру строки, а не на базовой линии.
   Отступ полем, а не gap: gap задавался на родителе и умер вместе с его
   гибкостью. 4 пикселя, а не 6 из прежнего gap, — между точкой и словом стоит
   ещё и пробел из текста, вместе выходит примерно та же щель, что была. */
.online-dot{display:inline-block;vertical-align:middle;margin-right:4px}

/* Кнопка «сохранить» встаёт слева от кнопки оживления: та занимает угол,
   и сдвиг ровно на её ширину плюс тот же зазор, что у неё от края.
   На узком экране кнопки крупнее (40 точек вместо 34) — сдвиг тоже больше. */
.photo-save{right:50px}
@media (max-width:640px){
  .photo-save{right:56px}
}

/* ── фоны-узоры и пятые варианты оформления ──────────────────────────────────
   Узор не повторяем плиткой, а растягиваем по ленте: картинки нарезаны без
   строгой бесшовности, и стык был бы виден полосой. Фон закреплён за окном,
   а не за содержимым, — при прокрутке переписки он стоит на месте, как в
   привычных мессенджерах. Под картинкой оставлен сплошной цвет: пока она
   грузится, лента не мигает белым. */
.chat-main[data-bg="grey"] .message-history{
  background:#15161a url(/static/img/chat-bg/grey.webp) center/cover no-repeat}
.chat-main[data-bg="wine"] .message-history{
  background:#150d10 url(/static/img/chat-bg/wine.webp) center/cover no-repeat}
.chat-main[data-bg="navy"] .message-history{
  background:#0d101c url(/static/img/chat-bg/navy.webp) center/cover no-repeat}
.chat-main[data-bg="forest"] .message-history{
  background:#0e1512 url(/static/img/chat-bg/forest.webp) center/cover no-repeat}
.chat-main[data-bg="cosmos"] .message-history{
  background:#130f1c url(/static/img/chat-bg/cosmos.webp) center/cover no-repeat}

/* Пятый простой фон — зелёный: серый, тёплый и ночь уже заняли нейтральный,
   коричневый и синий, а зелёного среди них не было. */
.chat-main[data-bg="moss"] .message-history{
  background:linear-gradient(170deg,#1e2723,#0f1512)}

/* Пятый цвет реплик — бирюза. Янтарь отсюда убран: янтарным в ленте уже
   помечены служебные сообщения, и одинаковый цвет у своей реплики и у
   системной записки стирал бы между ними границу — а её надо держать
   заметной. Бирюзы среди коралла, пурпура, синего и нейтрального не было,
   она и заняла свободное место. */
.chat-main[data-ink="teal"] .message-row.sent p{
  border-color:rgba(45,212,191,.34);background:linear-gradient(rgba(45,212,191,.16),rgba(45,212,191,.16)),rgba(46,48,56,var(--bub-a,.1))}

/* Образцы на кнопках выбора. */
.cs-bg-grey:before{background:url(/static/img/chat-bg/grey.webp) center/cover}
.cs-bg-wine:before{background:url(/static/img/chat-bg/wine.webp) center/cover}
.cs-bg-navy:before{background:url(/static/img/chat-bg/navy.webp) center/cover}
.cs-bg-forest:before{background:url(/static/img/chat-bg/forest.webp) center/cover}
.cs-bg-cosmos:before{background:url(/static/img/chat-bg/cosmos.webp) center/cover}
.cs-bg-moss:before{background:linear-gradient(160deg,#1e2723,#0f1512)}
.cs-ink-teal:before{background:#2dd4bf}

/* ── фон и цвет выбираем плитками ────────────────────────────────────────────
   У обоев главное — как они выглядят, а кружок в 14 точек об этом не сообщает
   ничего: «Лес» и «Полночь» в нём одинаково тёмные пятна. Поэтому ряд фонов
   показывает вертикальные превью в пропорции ленты, с подписью снизу.

   Цвета реплик — кружками слева от названия (решение владельца 17.08.2026),
   ряд переносится по ширине панели; правила плиток на них не действуют.

   Перебиваем padding у .cs-chip: там он задан с !important ради кружка.

   Сетка в пять колонок, а не перенос по ширине: фонов десять, и так они
   ложатся ровно двумя рядами по пять на любом экране. При переносе разбивка
   плясала бы от ширины панели — то четыре, то шесть в ряду. */
.cs-row[data-style="bg"]{
  display:grid;grid-template-columns:repeat(5,1fr);gap:10px}
.cs-row[data-style="bg"] .cs-chip{
  padding:0 0 6px !important;width:auto;min-width:0;overflow:hidden;
  border-radius:10px;display:flex;flex-direction:column;gap:6px;
  font-size:10px;line-height:1.15;text-align:center}
/* Соотношение сторон вместо жёсткой высоты: плитка тянется под панель, а
   пропорция сохраняется на любой ширине. */
.cs-row[data-style="bg"] .cs-chip:before{
  position:static;margin:0;border:0;border-radius:0;
  width:100%;height:auto;display:block;aspect-ratio:3/4}
/* Выбранный отмечаем кольцом внутрь, а не только рамкой: рамка в один пиксель
   рядом с картинкой почти не читается. */
.cs-row[data-style="bg"] .cs-chip.is-on{
  box-shadow:inset 0 0 0 2px var(--coral)}
/* На узком экране пять колонок остаются, но зазор и подпись ужимаются:
   ширину плитки задаёт сетка, а не мы, — поэтому здесь ни width, ни height,
   иначе они переспорили бы колонки и соотношение сторон. */
@media (max-width:640px){
  .cs-row[data-style="bg"]{gap:6px}
  .cs-row[data-style="bg"] .cs-chip{font-size:9px;padding-bottom:4px !important}
}
/* Кружки цвета — чуть крупнее базовых 14 px: точку видно и так, а на
   выбранной кнопке рамка уже коралловая. */
.cs-dots .cs-chip:before{width:15px;height:15px;margin-top:-7.5px;left:9px}
/* Поля ужаты, чтобы пятёрка на ПК вставала в одну строку; на узком экране
   ряд переносится сам. */
.cs-dots .cs-chip{padding:8px 11px 8px 30px !important;font-size:12px}

/* ── широкие дубли узорных фонов для ПК ──────────────────────────────────────
   Узоры нарисованы вертикальными, 768×1376: под телефон, где лента и правда
   вытянута вниз. На ПК лента наоборот широкая — грубо 800×560. При `cover`
   вертикальная картинка увеличивается всего в 1,04 раза, зато обрезается по
   высоте, и видно лишь СРЕДНЮЮ ПОЛОСУ, около 40% рисунка, растянутую во всю
   ширину. Узор от этого читается разреженным и обрубленным.

   Поэтому у каждого узора есть горизонтальный дубль — тот же рисунок,
   нарисованный сразу под широкий кадр. Подменяем ТОЛЬКО картинку: цвет
   подложки, `center/cover` и `no-repeat` достаются от правил выше, потому что
   там сокращённая запись `background`, а здесь длинная `background-image`.

   ⚠ РАЗМЕР ДУБЛЕЙ — 2752×1536, И МЕНЬШЕ НЕЛЬЗЯ. Первая попытка была 1376×768,
   и в развёрнутом чате её мылило. Замер: лента там доходит до 1984×1264
   CSS-точек, а на экране с удвоенной плотностью (или при масштабе Windows
   125–150%) это до 3968×2528 настоящих точек — растяжение выходило 2,3–3,3
   раза. При 2752 оно падает до 1,4 раза в худшем случае и до единицы на самом
   ходовом экране 1920 при плотности 2.

   Генератор больше 1376×768 не отдаёт, поэтому дубли увеличены моделью
   4x-AnimeSharp (она под контурную графику) и уменьшены до цели: так линии
   остаются резкими, тогда как простое растягивание их размывает и добавляет
   ряби по фону.

   Плиткой не размножаем по-прежнему: узоры без строгой бесшовности, стык был
   бы виден полосой.

   Порог 900 — тот же, по которому весь сайт делит ПК и телефон
   (`.only-mobile` / `.only-desktop` в начале файла). Между 900 и 980 лента уже
   одноколоночная, но окно всё равно широкое, так что дубль там тоже к месту. */
/* ── сворачивание правой колонки ─────────────────────────────────────────────
   Кнопка нужна только там, где карточка персонажа существует ОТДЕЛЬНЫМ
   столбцом. Ниже 981 раскладка одноколоночная (см. медиазапрос в начале файла),
   карточка открывается вкладкой, и сворачивать там нечего.

   Селектор с .chat-badges намеренно: у кнопок шапки правило заведено как
   `.chat-badges .badge-icon`, и одиночный класс ему проиграл бы по весу. */
.chat-badges .rail-toggle{display:none}
/* Между 900 и 980 лендинг складывает чат в одну колонку (сайдбар спрятан,
   карточка снизу). Приложению на этой ширине нужны хотя бы две: список
   слева, чат справа; карточку персонажа отдаём в пользу чата. */
@media (min-width:900px) and (max-width:980px){
  body.chat-full .chat-preview{grid-template-columns:232px minmax(0,1fr);height:100dvh}
  body.chat-full .sidebar{display:flex}
  body.chat-full .profile-rail{display:none}
}
@media (min-width:981px){
  .chat-badges .rail-toggle{display:inline-flex}
  /* Убираем колонку И из сетки, и с экрана. Только display:none мало: её 320
     точек остались бы пустой полосой справа. */
  .chat-preview.rail-off{grid-template-columns:256px minmax(0,1fr)}
  /* Приложение: левая колонка шире (350 по умолчанию, решение владельца
     17.08.2026) и тянется за правый край в пределах 256–500. Ширина живёт в
     переменной, которую ставит app.js; на лендинге-виджете остаётся 256. */
  body.chat-full .chat-preview{--side-w:350px;grid-template-columns:var(--side-w) minmax(0,1fr) 320px}
  body.chat-full .chat-preview.rail-off{grid-template-columns:var(--side-w) minmax(0,1fr)}
  body.chat-full .sidebar{position:relative}
  body.chat-full .side-resize{display:block;position:absolute;top:0;bottom:0;right:-4px;width:8px;
    z-index:3;cursor:col-resize;touch-action:none}
  /* Полоска подсвечивается под курсором и пока тянут — иначе ручку не найти. */
  body.chat-full .side-resize:after{content:"";position:absolute;top:0;bottom:0;left:3px;width:2px;
    background:transparent;transition:background .15s}
  body.chat-full .side-resize:hover:after,body.chat-full .side-resize.dragging:after{
    background:rgba(245,85,85,.55)}
  /* Пока тянут — без выделения текста и с общим курсором на всей странице. */
  body.side-resizing{cursor:col-resize;user-select:none}
  body.side-resizing .chat-preview{transition:none}
  .chat-preview.rail-off .profile-rail{display:none}
}
/* Стрелка показывает, КУДА уедет панель, поэтому при скрытой колонке смотрит
   обратно. Переворачиваем только её: отразив весь значок, мы перенесли бы
   полосу панели влево, и картинка стала бы описывать другую раскладку.
   Точка отсчёта — в пользовательских единицах SVG, середина самой стрелки. */
.rail-arrow{transition:transform .18s}
.chat-preview.rail-off .rail-arrow{transform:scaleX(-1);transform-origin:18.25px 12px}
@media (prefers-reduced-motion:reduce){
  .rail-arrow{transition:none}
}

/* ── кнопки снимка: столбцом СПРАВА ЗА КАДРОМ ────────────────────────────────
   Раньше они лежали поверх картинки в углу. Логика была «места в ленте мало»,
   но закрывали они собой ровно то, ради чего снимок и прислан: на вертикальном
   кадре кнопка приходилась на лицо.

   Место справа есть: снимок занимает 56% ширины строки, остальное пустует.

   ⚠ Пришлось снять overflow:hidden с .photo — он обрезал всё, что выходит за
   кадр, вместе с кнопками. Скругление углов при этом никуда не делось: оно
   переехало на саму картинку и на ролик через border-radius:inherit. */
.photo{overflow:visible}
.photo img,.photo video{border-radius:inherit}

/* Порядок задаёт CSS, а не очередь добавления: сохранение появляется, когда
   готова картинка, оживление — когда доступно видео, переключатель — когда
   ролик уже посчитан. Появляются они в разное время и в разном сочетании,
   поэтому «сверху сохранение» держится на order, а не на порядке в разметке. */
.photo-tools{position:absolute;left:100%;top:0;margin-left:8px;z-index:2;
  display:flex;flex-direction:column;gap:8px}
.photo-anim{position:static;order:1}
.photo-save{order:0}
/* Порядок столбца сверху вниз: сохранить → окошко → вернуться к снимку
   (просьба Ромы 19.08.2026). Переключателю номер задан явно: он носит и класс
   .photo-anim, а тот стоит первым — без своего order окошко и переключатель
   встали бы в одну ступень и порядок решала бы очередь добавления. */
.photo-pip{order:1}
.photo-swap{order:2}
/* На исходном снимке окошка нет: уводить в него нечего, а браузер на скрытом
   ролике режим и не откроет. */
.photo-animated:not(.photo-video-on) .photo-pip{display:none}
/* Вне картинки кнопки стоят на тёмном фоне ленты, а не на светлом кадре, и
   прежняя полупрозрачность делала их еле заметными. */
.photo-anim{opacity:.85}

@media (min-width:900px){
  .chat-main[data-bg="grey"] .message-history{
    background-image:url(/static/img/chat-bg/grey-wide.webp)}
  .chat-main[data-bg="wine"] .message-history{
    background-image:url(/static/img/chat-bg/wine-wide.webp)}
  .chat-main[data-bg="navy"] .message-history{
    background-image:url(/static/img/chat-bg/navy-wide.webp)}
  .chat-main[data-bg="forest"] .message-history{
    background-image:url(/static/img/chat-bg/forest-wide.webp)}
  .chat-main[data-bg="cosmos"] .message-history{
    background-image:url(/static/img/chat-bg/cosmos-wide.webp)}
}

/* ── заглушка фото: пояснение про очередь за роликом ─────────────────────── */
.photo-loading{grid-auto-rows:min-content;align-content:center;row-gap:6px}
.photo-note-sub{position:relative;color:rgba(255,255,255,.32);font-size:11px;
  line-height:1.3;text-align:center;padding:0 12px;text-transform:none;letter-spacing:0}


/* ── сценарии: окно, сетка состава, карточки, плашка сцены, рассказчик ──── */
/* Окно шире обычного: два столбца на втором шаге. На узком экране столбцы
   складываются (см. медиа-блок ниже). */
#scen .modal-card{width:min(680px,100%)}
.scen-steps{display:flex;gap:18px;margin:14px 0 18px;font-size:11px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.32)}
.scen-steps span{padding-bottom:6px;border-bottom:2px solid transparent}
.scen-steps span.on{color:#fff;border-color:var(--coral)}
.scen-count{float:right;font-weight:600;color:rgba(255,255,255,.4);letter-spacing:0;text-transform:none}
.scen-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;
  max-height:264px;overflow-y:auto;padding:2px;margin-top:6px}
.scen-chip{display:flex;flex-direction:column;align-items:center;gap:6px;padding:10px 6px 8px;
  border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.03);
  color:rgba(255,255,255,.7);text-align:center;cursor:pointer;transition:border-color .2s,background .2s}
.scen-chip:hover{background:rgba(255,255,255,.06);color:#fff}
.scen-chip.on{border-color:rgba(245,85,85,.6);background:rgba(245,85,85,.12);color:#fff}
.scen-chip b{font-size:12px;line-height:1.2;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.scen-chip small{font-size:9px;color:rgba(255,255,255,.35);max-width:100%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
/* overflow:hidden здесь нельзя: он резал номер очереди, который висит на
   краю портрета. Круг делает не контейнер, а сама картинка/буква. */
.scen-face{position:relative;display:block;width:48px;height:48px;border-radius:50%;
  background:rgba(255,255,255,.06)}
.scen-face img,.scen-face .letter{width:100%;height:100%;object-fit:cover;display:grid;
  place-items:center;border-radius:50%;overflow:hidden}
.scen-face.small{width:28px;height:28px}
.scen-num{position:absolute;right:-2px;bottom:-2px;display:grid;place-items:center;width:18px;height:18px;
  border-radius:50%;background:var(--coral);color:#fff;font:700 10px/1 Inter,sans-serif;font-style:normal;
  box-shadow:0 0 0 2px var(--panel)}
.scen-next{width:100%;margin-top:14px}
.scen-mine{margin-top:22px}
/* Вкладки шага «кто играет». Вид берут у общего переключателя (.choice),
   своего здесь только отступ: под ними сразу начинается содержимое панели. */
/* Галерея сцен в левой колонке отделена от пунктов выше пунктиром: над ним —
   «сделать своё», под ним — «посмотреть, что сделали другие». Коралловый, но
   вполсилы: это разделитель, а не акцент, и в полную силу он спорил бы с
   подсветкой активного пункта. */
.side-gallery{margin-top:10px;padding-top:14px;
  border-top:1px dashed rgba(245,85,85,.45);border-radius:0 0 8px 8px}
/* Число сцен прижато к правому краю пункта — как счётчики в мессенджерах. */
.side-gallery-n{margin-left:auto;padding:2px 7px;border-radius:999px;font-style:normal;
  background:rgba(245,85,85,.14);color:var(--coral);font-size:10px;font-weight:800}
/* Поле почты в окнах оплаты. Стоит перед выбором пакета и перед кнопкой
   оформления: адрес нужен раньше денег, и спрашивать его после нажатия
   «Оплатить» поздно — человек уже ушёл на страницу банка. */
.pay-mail{margin:16px 0 4px}
.pay-mail .field-hint{margin-top:6px}
.scen-tabs{margin-bottom:18px}
/* Первая вкладка шире прочих: «Новая сцена» — главное действие, и в ряду
   одинаковых кнопок она терялась. */
.scen-tabs button[data-scen-tab="new"]{flex-grow:1.6}
.scen-mine .rail-label{margin-bottom:8px}
.scen-mine-row{display:flex;align-items:center;gap:10px;width:100%;padding:9px 12px;margin-bottom:6px;
  border:1px solid var(--border);border-radius:10px;background:rgba(255,255,255,.03);color:inherit;
  text-align:left;cursor:pointer;transition:background .2s}
.scen-mine-row:hover{background:rgba(255,255,255,.07)}
.scen-mine-text{display:flex;flex-direction:column;min-width:0;flex:1}
.scen-mine-text b{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.scen-mine-text small{font-size:11px;color:rgba(255,255,255,.4);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.scen-mine-go{color:var(--coral);font-weight:700}
/* Сценарий дня — плашка над выбором состава: золотая рамка, как у рассказчика. */
.scen-daily{position:relative;margin:0 0 18px;padding:14px 16px;border:1px solid rgba(201,150,79,.5);
  border-radius:14px;background:#16171a} /* фон как у пузыря рассказчика (решение владельца 22.08.2026) */
.scen-daily .scen-genre{margin-bottom:6px}
.scen-daily b{display:block;font-size:15px;margin-bottom:6px}
.scen-daily p{margin:0 0 10px;font-size:12.5px;line-height:1.5;color:rgba(255,255,255,.7)}
.scen-daily small{display:block;margin-bottom:10px;font-size:11px;color:rgba(255,255,255,.4)}
.scen-daily .button-small{min-height:32px}
/* Галерея опубликованных сцен. */
.scen-gallery{margin-top:22px}
.scen-gallery .rail-label{margin-bottom:8px}
/* Ссылка на открытую витрину из вкладки «Галерея». Приглушённая: это выход
   вбок, а не главное действие вкладки — играть зовут карточки ниже. */
.scen-gal-link{display:inline-block;margin:0 0 14px;color:var(--coral);
  font-size:12px;font-weight:700}
.scen-gal-link:hover{color:var(--coral-hover)}
/* Ссылка переехала под список — отступ теперь сверху, а не снизу. */
.scen-gal-more{margin:12px 0 0}
.scen-gal-item{display:flex;gap:12px;align-items:stretch;margin-bottom:8px;padding:10px 12px;
  border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.03)}
.scen-gal-cover{flex:none;width:96px;height:64px;border-radius:8px;overflow:hidden;background:rgba(255,255,255,.05)}
.scen-gal-cover img{width:100%;height:100%;object-fit:cover;display:block}
.scen-gal-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
/* Заголовок и жанр в строку: название забирает остаток, жанр не сжимается. */
.scen-gal-head{display:flex;align-items:center;gap:8px;min-width:0}
.scen-gal-text b{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  flex:1 1 auto;min-width:0}
.scen-gal-genre{flex:none;padding:2px 8px;border-radius:999px;font-style:normal;
  font-size:10px;font-weight:800;letter-spacing:.04em;
  background:rgba(245,85,85,.14);color:var(--coral)}
.scen-gal-text small{font-size:11px;color:rgba(255,255,255,.42);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.scen-gal-text p{margin:2px 0 0;font-size:12px;line-height:1.4;color:rgba(255,255,255,.62);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* ⚠️ В базовом слое стоит .modal .button{width:100%} — оно задумано для
   главных кнопок окон (оплатить, оформить) и действует на ЛЮБОЙ ширине.
   Правило карточки ниже ширину не задавало вовсе, поэтому «Играть»
   растягивалась на всю строку, выдавливая обложку и текст: владелец видел
   пустую карточку с одной кнопкой (26.08.2026).
   Три класса — чтобы не зависеть от порядка правил в файле. */
.modal .scen-gal-item .button{width:auto;flex:none}
.scen-gal-item .button-small{align-self:center;min-height:32px;padding:0 14px}
/* На узком экране кнопка уходит под текст: обложка, текст и кнопка в одну
   строку на телефоне оставляют названию сцены полтора десятка точек. */
@media (max-width:520px){
  .scen-gal-item{flex-wrap:wrap}
  .scen-gal-item .scen-gal-text{flex:1 1 100%;order:2}
  .modal .scen-gal-item .button{order:3;margin-left:auto}
}
/* Кнопка публикации в «Моих сценариях». */
.scen-pub{flex:none;padding:5px 10px;border:1px solid rgba(255,255,255,.16);border-radius:999px;
  background:transparent;color:rgba(255,255,255,.6);font-size:10px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;cursor:pointer}
.scen-pub:hover{background:rgba(255,255,255,.08);color:#fff}
.scen-pub.on{border-color:rgba(201,150,79,.6);color:#f3dfb6;background:rgba(201,150,79,.12)}
.scen-mine-row{display:flex;align-items:center;gap:8px;padding:0;background:transparent;border:0;margin-bottom:6px}
.scen-mine-row:hover{background:transparent}
.scen-mine-open{display:flex;align-items:center;gap:10px;flex:1;min-width:0;padding:9px 12px;
  border:1px solid var(--border);border-radius:10px;background:rgba(255,255,255,.03);color:inherit;
  text-align:left;cursor:pointer;transition:background .2s}
.scen-mine-open:hover{background:rgba(255,255,255,.07)}
.scen-cast{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px}
.scen-cast-chip{display:inline-flex;align-items:center;gap:8px;padding:5px 12px 5px 5px;
  border:1px solid var(--border);border-radius:999px;background:rgba(255,255,255,.04);font-size:12px}
.scen-two{display:grid;grid-template-columns:1fr auto 1fr;gap:18px;align-items:start}
.scen-col label{display:block;margin-bottom:8px}
/* Тот же вид, что у полей формы (.field textarea): столбец не завёрнут в .field,
   и без этого textarea оставалась браузерной, моноширинной. */
.scen-col textarea{width:100%;resize:vertical;margin-bottom:10px;padding:14px 16px;
  border:1px solid var(--border);border-radius:13px;background:var(--panel-deep);color:#fff;
  font:inherit;font-size:13px;line-height:1.5}
.scen-col textarea:focus{outline:0;border-color:rgba(245,85,85,.5)}
.scen-col textarea::placeholder{color:rgba(255,255,255,.2)}
.scen-col .button{width:100%;min-height:48px}
/* Кнопка «Придумать три сцены» шла вплотную к подсказке над ней (скрин владельца
   22.08.2026) — у подсказки нет нижнего отступа, у текстареа слева он есть. */
.scen-col .field-hint+.button{margin-top:12px}
.scen-or{display:flex;align-items:center;justify-content:center;align-self:stretch;
  color:rgba(255,255,255,.3);font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase}
.scen-or span{padding:0 4px}
.scen-cards{display:flex;flex-direction:column;gap:10px;margin-top:12px}
.scen-card-item{position:relative;padding:12px 14px 12px;border:1px solid var(--border);border-radius:12px;
  background:rgba(255,255,255,.03)}
.scen-card-item:hover{border-color:rgba(245,85,85,.4)}
.scen-genre{display:block;margin-bottom:4px;font-size:9px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--coral)}
.scen-card-item b{display:block;font-size:14px;margin-bottom:6px}
.scen-card-item p{margin:0 0 10px;font-size:12.5px;line-height:1.5;color:rgba(255,255,255,.66)}
.scen-card-item .button-small{min-height:32px}
/* Вуаль ожидания: поверх всего, по центру экрана. z-index выше модалок (60)
   и на уровне тоста (70): пока сценарист пишет, окно и так заблокировано. */
.wait-veil{position:fixed;inset:0;z-index:70;display:flex;align-items:center;justify-content:center;
  padding:24px;background:rgba(10,10,12,.62);backdrop-filter:blur(4px)}
.wait-box{display:flex;flex-direction:column;align-items:center;gap:12px;max-width:380px;
  padding:26px 30px;border:1px solid rgba(201,150,79,.45);border-radius:16px;
  background:rgba(24,22,20,.96);box-shadow:0 24px 80px rgba(0,0,0,.5);text-align:center}
.wait-box b{font-size:15px;color:#fff}
.wait-box span:not(.scen-dots){font-size:13px;line-height:1.5;color:rgba(255,255,255,.62)}
.wait-box .scen-dots i{width:8px;height:8px}
.scen-dots{display:inline-flex;gap:5px}
.scen-dots i{width:6px;height:6px;border-radius:50%;background:#e8c890;animation:scenBlink 1.2s infinite}
.scen-dots i:nth-child(2){animation-delay:.2s}.scen-dots i:nth-child(3){animation-delay:.4s}
@keyframes scenBlink{0%,80%,100%{opacity:.25}40%{opacity:1}}
.scen-back{margin-top:16px;padding:0;border:0;background:none;color:rgba(255,255,255,.5);
  font-size:12px;cursor:pointer}
.scen-back:hover{color:#fff}
/* Плашка идущей сцены — над лентой, между шапкой и переписью.
   Фон плотный (#16171a), а не золотая полупрозрачная плёнка, и текст на тон
   тише — решение Ромы 19.08.2026: полоса стояла ярче самой переписки и
   перетягивала на себя взгляд, хотя это подпись к сцене, а не сцена. */
.scene-bar{display:flex;flex-direction:column;gap:7px;padding:8px 16px 9px;
  border-bottom:1px solid rgba(201,150,79,.3);background:#16171a;
  color:rgba(232,200,144,.75);font-size:12px}
.scene-bar-row{display:flex;align-items:center;gap:10px;min-width:0}
.scene-bar-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.scene-bar-text b{color:#fff;font-weight:600}
/* Цель сцены и находки — из плана режиссёра (сцены с 17.08.2026): «· Цель:
   открыть дверь · найдено 2/4». Тонко, тем же золотом, чтобы не спорить с
   названием; на узком экране скрыто — там и так тесно. */
.scene-goal{font-style:normal;color:rgba(232,200,144,.75);margin-left:8px}
.scene-goal:empty{display:none}
.scene-goal em{font-style:normal;color:rgba(255,255,255,.5)}
@media (max-width:899px){.scene-goal{display:none}}
/* ── ход сцены: акты как дорожка ──────────────────────────────────────────
   Подпись слева, дорожка справа. Сегмент — пройденный акт залит золотом,
   текущий наполняется по мере реплик (act_turn) и мягко дышит, следующие
   тусклые. Названия актов — под сегментами: видно, куда идёт история. */
.scene-progress{display:flex;align-items:center;gap:12px;min-width:0}
.scene-act{flex:none;font-style:normal;color:#f3dfb6;font-size:10.5px;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;white-space:nowrap}
.scene-act b{color:#fff;font-weight:800}
.scene-act span{color:rgba(243,223,182,.6);font-weight:600;letter-spacing:.04em;text-transform:none;
  font-size:11px}
.scene-steps{display:flex;flex:1;gap:5px;min-width:0}
.scene-step{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.scene-step i{display:block;height:6px;border-radius:4px;background:rgba(255,255,255,.1);
  overflow:hidden;position:relative}
.scene-step i:before{content:"";position:absolute;inset:0;width:var(--fill,0%);border-radius:4px;
  background:linear-gradient(90deg,#c9964f,#f0c675);transition:width .5s ease}
.scene-step.is-done i:before{width:100%;background:linear-gradient(90deg,#b8843f,#d9a85a)}
/* Текущий акт: заливка по числу реплик и живой отблеск, чтобы взгляд ловил,
   где мы сейчас. */
.scene-step.is-now i{box-shadow:0 0 0 1px rgba(240,198,117,.35),0 0 10px rgba(240,198,117,.25)}
.scene-step.is-now i:after{content:"";position:absolute;inset:0;width:var(--fill,0%);border-radius:4px;
  background:linear-gradient(90deg,transparent 0,rgba(255,255,255,.35) 50%,transparent 100%);
  background-size:200% 100%;animation:sceneShine 2.6s linear infinite}
@keyframes sceneShine{0%{background-position:200% 0}100%{background-position:-200% 0}}
/* opacity, а не приглушение цвета: у названий актов три состояния (пройден,
   идёт, впереди) со своими цветами, и подкрутить надо все три сразу. */
.scene-step em{font-style:normal;font-size:9.5px;line-height:1;letter-spacing:.06em;
  text-transform:uppercase;color:rgba(255,255,255,.32);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;text-align:center;opacity:.75}
.scene-step.is-done em{color:rgba(232,200,144,.7)}
.scene-step.is-now em{color:#f3dfb6;font-weight:700}
@media (prefers-reduced-motion:reduce){.scene-step.is-now i:after{animation:none}}
.scene-next{padding:6px 12px;border:1px solid rgba(255,255,255,.18);border-radius:999px;
  background:rgba(255,255,255,.05);color:#fff;font-size:10px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;cursor:pointer;transition:background .2s,box-shadow .3s}
.scene-next:hover{background:rgba(255,255,255,.12)}
/* Подсказка «пора дальше»: после нескольких реплик в акте кнопка мягко светится. */
.scene-next.nudge{border-color:rgba(201,150,79,.7);box-shadow:0 0 0 0 rgba(201,150,79,.5);
  animation:sceneNudge 2.2s ease-out infinite}
@keyframes sceneNudge{0%{box-shadow:0 0 0 0 rgba(201,150,79,.5)}70%{box-shadow:0 0 0 8px rgba(201,150,79,0)}100%{box-shadow:0 0 0 0 rgba(201,150,79,0)}}
/* Развилки рассказчика: кнопки под плашкой. Клик отправляет вариант как
   реплику; любая своя реплика убирает кнопки — выбор сделан. */
.scene-choices{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 2px}
.scene-go{display:flex;margin:10px 0 2px}
.scene-choices button,.scene-go button{padding:8px 12px;border:1px solid rgba(201,150,79,.5);border-radius:10px;
  background:rgba(201,150,79,.12);color:#f3dfb6;font:inherit;font-size:12.5px;font-style:normal;
  text-align:left;cursor:pointer;transition:background .2s}
.scene-choices button:hover:not(:disabled),.scene-go button:hover{background:rgba(201,150,79,.26)}
/* Выбор сделан: остаётся только выбранная кнопка — подсвеченная, неактивная,
   с галочкой; остальные прячутся. Один вариант за ход (21.08.2026). */
.scene-choices.is-done button:not(.picked){display:none}
.scene-choices.is-done button.picked{cursor:default;background:rgba(201,150,79,.3);
  border-color:rgba(201,150,79,.9);color:#fff}
.scene-choices.is-done button.picked::before{content:"✓ ";font-weight:700}
/* Смена акта — разделитель глав над словами рассказчика: «АКТ 2 · ПОВОРОТ»
   с чертой во всю ширину плашки (22.08.2026). Поворот сюжета должен читаться
   в самой переписке. */
.message-row.system.act-row p{border-color:rgba(201,150,79,.75)}
.act-chip{display:flex;align-items:center;gap:10px;margin:-2px 0 10px;font-style:normal;
  font-size:10px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;color:#f3dfb6}
.act-chip:after{content:"";flex:1;height:1px;background:linear-gradient(90deg,
  rgba(201,150,79,.6),rgba(201,150,79,0))}
/* Зов следующего акта: тот же пузырь рассказчика, но пунктиром — это не его
   слова, а предложение интерфейса (22.08.2026). */
.message-row.system.scene-nudge p{border-style:dashed;color:rgba(255,255,255,.66)}
.message-row.system.scene-nudge .scene-go{margin-bottom:0}
.message-row.system.scene-nudge .stamp{display:none}
.scene-finish{padding:6px 12px;border:1px solid rgba(201,150,79,.5);border-radius:999px;
  background:rgba(201,150,79,.14);color:#f3dfb6;font-size:10px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;cursor:pointer;transition:background .2s}
.scene-finish:hover{background:rgba(201,150,79,.3)}
.scene-drop{width:28px;height:28px;border:0;border-radius:50%;background:transparent;
  color:rgba(255,255,255,.4);cursor:pointer}
.scene-drop:hover{background:rgba(255,255,255,.08);color:#fff}
/* Метка PRO у пункта «Сценарии» в колонке: у подписчика скрыта. */
.pro-tag{margin-left:auto;padding:2px 6px;border:1px solid rgba(201,150,79,.55);border-radius:6px;
  font:700 9px/1 Inter,sans-serif;font-style:normal;letter-spacing:.12em;color:#e8c890;
  background:rgba(201,150,79,.12)}
.pro-tag.is-hidden{display:none}
/* Окно PRO. Коралл — только у слова PRO в заголовке; акценты сроков и акции —
   золото, как у рассказчика: подписка здесь про сцены. */
#pro .modal-card{width:min(600px,100%)}
.pro-card h3{margin-top:8px}
.pro-word{color:var(--coral)}
.pro-perks{margin:14px 0 18px;padding:0;list-style:none;display:flex;flex-direction:column;gap:11px}
.pro-perks li{position:relative;padding-left:24px;font-size:13px;line-height:1.5;color:rgba(255,255,255,.66)}
.pro-perks li:before{content:"✓";position:absolute;left:0;top:1px;color:#c9964f;font-weight:700}
.pro-perks li b{display:block;color:#fff;font-weight:600;margin-bottom:1px}
.pro-promo{display:flex;align-items:flex-start;gap:12px;margin:0 0 14px;padding:12px 14px;
  border:1px solid rgba(201,150,79,.5);border-radius:12px;
  background:linear-gradient(135deg,rgba(201,150,79,.16),rgba(201,150,79,.05));font-size:12.5px;line-height:1.5;
  color:rgba(255,255,255,.72)}
.pro-promo-ico{font-size:18px;line-height:1}
.pro-promo b{color:#f3dfb6}
.pro-promo em{font-style:normal;color:#fff;font-weight:700}
.pro-promo s{color:rgba(255,255,255,.4)}
/* Сроки — четыре карточки в ряд, на телефоне два на два. */
.pro-terms{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin:0 0 18px}
.pro-term{position:relative;display:flex;flex-direction:column;gap:3px;padding:12px 10px 10px;
  border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.03);color:inherit;
  text-align:left;cursor:pointer;transition:border-color .2s,background .2s}
.pro-term:hover{background:rgba(255,255,255,.06)}
.pro-term.on{border-color:rgba(201,150,79,.75);background:rgba(201,150,79,.1);box-shadow:inset 0 0 0 1px rgba(201,150,79,.35)}
.pro-term-months{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.55)}
.pro-term.on .pro-term-months{color:#f3dfb6}
.pro-term-price{font:700 18px/1.1 'Space Grotesk',sans-serif;color:#fff}
.pro-term-was{font-size:11px;color:rgba(255,255,255,.35)}
.pro-term-per{font-size:11px;color:rgba(255,255,255,.45)}
.pro-term-badge{position:absolute;top:-9px;right:8px;padding:2px 7px;border-radius:999px;
  background:#c9964f;color:#1a1612;font:700 9px/1.4 Inter,sans-serif;letter-spacing:.08em;text-transform:uppercase}
.pro-term-badge.promo{background:var(--coral);color:#fff}
.pro-actions{display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.pro-actions .button{min-height:50px;padding:0 26px}
.pro-more{font-size:12px;color:rgba(255,255,255,.55);text-decoration:underline;text-underline-offset:3px}
.pro-more:hover{color:#fff}
.pro-fine{margin:14px 0 0;font-size:11px;line-height:1.5;color:rgba(255,255,255,.38)}
/* Та же карточка в кабинете: без модалки, внутри блока тарифа. */
/* Блок кабинета сам без внутренних отступов — их несут дети (h2, p, .cab-row
   по 24px). Карточка тарифа стояла впритык к краям: даём ей те же 24px и
   отделяем от строк лимитов линией. */
.pro-inline{margin:0;padding:4px 24px 26px}
.pro-inline-title{margin:0;padding:22px 24px 12px;border-top:1px solid var(--border);
  font:700 18px/1.1 'Space Grotesk',sans-serif}
.pro-inline .pro-perks{margin-top:0}
@media (max-width:640px){.pro-inline{padding:4px 16px 20px}.pro-inline-title{padding:18px 16px 10px}}
.pro-inline .pro-terms{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:640px){.pro-inline .pro-terms{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:640px){
  .pro-terms{grid-template-columns:repeat(2,minmax(0,1fr))}
  .pro-actions .button{width:100%}
}
/* Диалог с идущей сценой в «Недавних»: хлопушка перед именами и золотая
   полоска слева — читается как «здесь игра», не сливается с обычными чатами. */
.recent-scene{font-style:normal;font-size:11px;margin-right:5px}
.recent-row.has-scene .recent-item{box-shadow:inset 3px 0 0 rgba(201,150,79,.75)}
/* Рассказчик: плашка шире служебной строки, курсив, своя подпись. Финал — с
   золотой рамкой: это итог, его хочется перечитать.
   Фон — глухой #16171a (решение владельца 21.08.2026), а не золотистая
   подложка: золото остаётся на рамке, подписи и штампе, сам пузырь спокойнее
   и не спорит с репликами персонажей. У финала рамка ярче, фон тот же. */
.message-row.system.scene{max-width:88%}
.message-row.system.scene p{border-color:rgba(201,150,79,.35);background:#16171a;
  color:#eadcc3;font-style:italic;line-height:1.6;white-space:pre-line}
.message-row.system.scene p .who{display:block;margin-bottom:6px;font-style:normal;font-size:10px;
  font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:#c9964f}
.message-row.system.scene-end p{border-color:rgba(201,150,79,.65);background:#16171a;color:#fff}
/* Кнопка «в галерею» под итогом сцены. Вид берёт у кнопки из «Моих сцен»
   (.scen-pub), своё здесь только место: отдельной строкой под текстом и с
   отбивкой сверху — иначе она липнет к последнему слову итога. */
.scene-pub{display:block;margin:14px 0 0}
.message-row.system.scene .stamp{color:rgba(201,150,79,.6)}
@media (max-width:640px){
  .scen-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .scen-two{grid-template-columns:1fr}
  .scen-or{padding:2px 0}
  .scene-bar{padding:8px 12px 9px;gap:6px}
  .scene-bar-row{flex-wrap:wrap}
  /* Хлопушка на телефоне оставалась одна на строке (название занимает всю
     ширину) — прячем, золотая плашка и так говорит, что это сцена. */
  .scene-bar-ico{display:none}
  .scene-bar-text{font-size:11px;flex-basis:100%}
  .scene-next,.scene-finish{padding:5px 10px}
  .scene-progress{gap:9px}
  .scene-act span{display:none}    /* название текущего акта и так подсвечено под дорожкой */
  .scene-step em{font-size:8.5px}
}

/* ── тарифы, реквизиты, юридические страницы ──────────────────────────────── */
/* Публичный блок тарифов на лендинге. Карточек пять (бесплатно + четыре срока),
   поэтому не сетка в три колонки, а авторазмещение: на широком экране пять
   в ряд не влезают по-человечески, а фиксированная колонка оставляла бы
   пустое место при смене числа сроков в настройках. */
.pricing-section{margin-bottom:128px}
.pricing-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:20px}
.pricing-load{grid-column:1/-1;margin:0;color:rgba(255,255,255,.35);font-size:13px}
.price-card{display:flex;flex-direction:column;padding:26px 22px;border:1px solid rgba(255,255,255,.07);border-radius:14px;background:var(--panel)}
/* Годовой — единственный выделенный: подсвечивать «выгодный» нужно один,
   иначе выделение перестаёт что-либо значить. */
.price-card.is-best{border-color:rgba(245,85,85,.38);box-shadow:0 18px 50px -22px rgba(245,85,85,.4)}
.price-card h3{margin:0 0 14px;font:700 15px/1.2 'Space Grotesk',sans-serif}
.price-big{margin:0;font:700 30px/1 'Space Grotesk',sans-serif;letter-spacing:-.03em}
.price-note{margin:8px 0 18px;color:rgba(255,255,255,.42);font-size:12px;line-height:1.5}
.price-card ul{margin:0;padding-left:18px;color:rgba(255,255,255,.5);font-size:12px;line-height:1.85}
.pricing-promo{grid-column:1/-1;margin:4px 0 0;padding:14px 16px;border:1px solid rgba(245,85,85,.2);border-radius:10px;background:rgba(245,85,85,.06);color:rgba(255,255,255,.7);font-size:13px}
.pricing-fine{margin:20px 0 0;color:rgba(255,255,255,.3);font-size:12px;line-height:1.6}
.pricing-fine a,.price-card a{color:var(--coral)}

/* Реквизиты продавца. Отдельной полосой над «© 2026»: это не подпись, а
   обязательные сведения, и мельче основного текста футера они быть не должны. */
.footer-legal{padding-top:24px;border-top:1px solid rgba(255,255,255,.05);color:rgba(255,255,255,.34);font-size:12px;line-height:1.65}
.footer-legal p{margin:0 0 6px}
.fl-seller{color:rgba(255,255,255,.52);font-weight:600}
.footer-legal a{color:var(--coral)}

/* Галочка согласия. Крупная область нажатия и выравнивание по первой строке:
   текст в три строки, и галочка, центрированная по блоку, съезжала бы вниз. */
.consent{display:flex;align-items:flex-start;gap:10px;margin:4px 0 18px;color:rgba(255,255,255,.5);font-size:12px;line-height:1.55;cursor:pointer}
.consent input{flex:0 0 18px;width:18px;height:18px;margin:1px 0 0;accent-color:var(--coral);cursor:pointer}
.consent a{color:var(--coral)}
/* Согласия у кнопок провайдеров. Отбивка снизу — 14px: галочки и кнопки
   слипались, и человек нажимал кнопку, не заметив, что над ней ещё что-то
   есть. Шрифт мельче, чем в регистрации: тут форма и без того длинная. */
.providers .consent{margin:0 0 10px;font-size:11.5px}
/* Отбивка от кнопок провайдеров: между собой они стоят на 10px, и
   без большего просвета галочки читались как третья кнопка в ряду.
   Отступ на первой галочке, а не на ряду кнопок: строка ошибки
   между ними должна оставаться вплотную к кнопке, по которой
   человек нажал. */
.providers .consent:first-of-type{margin-top:18px}
.providers .consent:last-of-type{margin-bottom:14px}
/* Пока не отмечены обе — кнопки приглушены. Нажатие при этом НЕ блокируем:
   человек должен получить объяснение, а не немую кнопку. */
.providers-row.off{opacity:.9}
/* Разделитель перед формой логина: провайдеры выше него уже
   отбиты своим отступом, а форме нужен воздух сверху. */
.auth-or{margin-top:22px}

/* Страницы документов (/legal/…). Одна колонка ограниченной ширины: юридический
   текст читают подряд, и строка во всю ширину экрана для этого негодна. */
.legal-page{background:var(--bg)}
.legal-wrap{max-width:760px;padding-block:56px 96px} /* только по вертикали: шорткат обнулял боковые поля .container на телефоне (22.08.2026) */
.legal-back{display:inline-block;margin-bottom:32px;color:var(--coral);font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase}
.legal-wrap h1{margin:0 0 28px;font:700 clamp(28px,4vw,40px)/1.1 'Space Grotesk',sans-serif;letter-spacing:-.04em}
.legal-wrap h4{margin:34px 0 12px;font:700 15px/1.3 'Space Grotesk',sans-serif;color:#fff}
/* ── витрина сцен (/scenes) ────────────────────────────────────────────────
   Страница собирается на сервере и живёт в оболочке правовых страниц, поэтому
   классы свои, а палитра общая. Обложка кадра — главное на карточке: по ней
   решают, открывать сцену или пролистать. */
/* Жанры над списком. Появляются, когда жанров больше одного: выбор из одного
   это не выбор, а лишняя строка. Число рядом с тегом — сколько там сцен. */
.scene-tags{display:flex;flex-wrap:wrap;gap:8px;margin:22px 0 4px}
.scene-tag{padding:7px 13px;border:1px solid var(--border);border-radius:999px;
  background:var(--panel);color:rgba(255,255,255,.6);font-size:12px;font-weight:600;
  transition:border-color .2s,color .2s}
.scene-tag:hover{border-color:rgba(245,85,85,.45);color:#fff}
.scene-tag.on{border-color:rgba(245,85,85,.55);background:rgba(245,85,85,.12);color:#fff}
.scene-tag i{font-style:normal;opacity:.5;margin-left:4px}
/* Четыре в ряд (решение владельца 26.08.2026). При колонке в 1240 px это
   даёт карточку ~296 px, и прежняя горизонтальная раскладка — обложка
   слева, текст справа — в такую ширину не влезает: тексту оставалось бы
   меньше 180 px. Поэтому карточка стала вертикальной. */
.scene-list{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:18px;margin:26px 0}
.scene-card{display:flex;gap:14px;padding:14px;border:1px solid var(--border);
  border-radius:14px;background:var(--panel);transition:border-color .2s,transform .2s}
.scene-card:hover{border-color:rgba(245,85,85,.45);transform:translateY(-2px)}
.scene-card-cover{flex:0 0 92px;height:92px;overflow:hidden;border-radius:10px;
  background:var(--panel-deep)}
.scene-card-cover img{width:100%;height:100%;display:block;object-fit:cover}
.scene-card-text{display:flex;flex-direction:column;gap:5px;min-width:0}
.scene-card-text b{font:700 15px/1.25 'Space Grotesk',sans-serif;color:#fff}
.scene-card-text small{color:rgba(255,255,255,.38);font-size:11px}
/* Завязку обрезаем тремя строками: карточки в ряду должны быть одной высоты,
   а сцены пишет модель, и длина у них гуляет вдвое. */
.scene-card-text span{color:rgba(255,255,255,.5);font-size:12px;line-height:1.55;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.scene-cover img{width:100%;border-radius:14px;display:block}
.scene-premise{margin:22px 0;font-size:15px;line-height:1.7;color:rgba(255,255,255,.78)}
.scene-facts{width:100%;margin:22px 0;border-collapse:collapse}
.scene-facts td{padding:10px 0;border-bottom:1px solid var(--border);font-size:14px;
  color:rgba(255,255,255,.72)}
.scene-facts td:first-child{width:34%;color:rgba(255,255,255,.4)}
.scene-play{margin:28px 0 14px}
/* ⚠️ В мобильном слое стоит общее .button{width:100%} — оно задумано для
   главных кнопок лендинга, но накрывает и эту. «Сыграть» растягивалась
   коралловой плитой во всю ширину и давила на всё вокруг (замечено владельцем
   26.08.2026). Два класса перебивают общее правило независимо от порядка. */
.scene-play .button{width:auto;min-height:48px;padding:0 36px;border-radius:12px;
  font-size:12px;letter-spacing:.14em}
.scene-cover{margin:18px 0 0}
@media (max-width:640px){
  .scene-list{grid-template-columns:1fr}
}
.legal-wrap p,.legal-wrap li{color:rgba(255,255,255,.62);font-size:14px;line-height:1.75}
.legal-wrap ul{padding-left:20px}
.legal-wrap li{margin-bottom:8px}
.legal-wrap a{color:var(--coral)}
/* Кнопка на серверной странице — не ссылка в тексте. Правило выше красит
   коралловым ВСЕ ссылки в теле, включая те, что оформлены кнопкой: у
   .button-primary задан только фон, а цвет текста наследуется. Выходил
   коралловый по коралловому — надпись «Сыграть» сливалась с кнопкой
   (замечено владельцем 26.08.2026).
   Селектор с классом кнопки: одного .legal-wrap a ему не перебить — там
   класс с тегом, и по специфичности он сильнее голого .button-primary. */
.legal-wrap a.button{color:#fff}
.legal-wrap a.button:hover{color:#fff}
.legal-meta{margin:0 0 24px;padding-bottom:20px;border-bottom:1px solid rgba(255,255,255,.07);color:rgba(255,255,255,.34)!important;font-size:12px!important}
/* Таблица цен в оферте: на телефоне она шире экрана, поэтому прокручивается
   сама, а не растягивает страницу по горизонтали. */
.legal-table{display:block;overflow-x:auto;width:100%;margin:16px 0;border-collapse:collapse;white-space:nowrap}
.legal-table th,.legal-table td{padding:10px 14px;border:1px solid rgba(255,255,255,.09);color:rgba(255,255,255,.62);font-size:13px;text-align:left}
.legal-table th{color:rgba(255,255,255,.4);font-weight:700;font-size:11px;letter-spacing:.1em;text-transform:uppercase}
.legal-nav{display:flex;flex-wrap:wrap;gap:8px 20px;margin:48px 0 0;padding-top:26px;border-top:1px solid rgba(255,255,255,.07)}
.legal-nav a{color:rgba(255,255,255,.44);font-size:12px}
.legal-nav a:hover{color:var(--coral)}
.legal-seller{margin:22px 0 0;color:rgba(255,255,255,.3);font-size:12px;line-height:1.7}
/* ── смайлики и реакции (20.08.2026) ────────────────────────────────────────
   Панель одна на страницу и всплывает там, где нажали: и от кнопки в поле
   ввода, и от реплики в ленте. Позицию считает openEmoji — здесь только вид. */
.emoji-button{font-size:19px;line-height:1;flex:none;
  filter:grayscale(.35);transition:filter .15s,transform .15s}
.emoji-button:hover{filter:none;transform:scale(1.1)}
/* fixed, а не absolute: панель зовут и от кнопки под лентой, и от реплики
   внутри прокручиваемой ленты — родители разные, и от них позиция считается
   по-разному. Координаты окна одинаковы для обоих случаев. */
.emoji-pop{position:fixed;z-index:60;width:min(320px,calc(100vw - 24px));
  max-height:min(300px,60vh);overflow-y:auto;padding:10px 12px;
  border:1px solid var(--border);border-radius:14px;background:var(--panel-deep);
  box-shadow:0 18px 48px rgba(0,0,0,.5)}
.emoji-cat{margin:8px 0 6px;color:rgba(255,255,255,.34);font-size:9px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase}
.emoji-cat:first-child{margin-top:0}
.emoji-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(34px,1fr));gap:2px}
.emoji-one{width:34px;height:34px;padding:0;border:0;border-radius:8px;
  background:transparent;font-size:20px;line-height:1;cursor:pointer;
  transition:background .12s,transform .12s}
.emoji-one:hover{background:rgba(255,255,255,.08);transform:scale(1.15)}

/* Кнопка реакции проступает на наведение — постоянная у каждой реплики
   зашумила бы ленту. На касании наведения нет: там она видна всегда, но
   тише, иначе о ней никто не узнает. */
.react-btn{width:26px;height:26px;
  display:grid;place-items:center;padding:0;border:1px solid var(--border);
  border-radius:50%;background:var(--panel-deep);font-size:13px;line-height:1;
  cursor:pointer;opacity:0;transition:opacity .15s,transform .15s}
.message-row.received{position:relative}
.message-row.received:hover .react-btn,
.message-row.received:focus-within .react-btn{opacity:.75}
.react-btn:hover{opacity:1;transform:scale(1.12)}
/* Кнопки реплики столбиком справа от пузыря: сверху динамик, снизу смайлик. В ряд они занимали ширину, которой у длинной реплики и так нет, и на узком экране отжимали сам пузырь. Держим их у ВЕРХА строки: у длинной реплики кнопки, съехавшие к середине, теряются рядом с текстом. */
.msg-actions{display:flex;flex-direction:column;align-self:flex-start;gap:4px;padding-top:4px}
/* Уже отмеченной реплике кнопка не нужна: её место занимает сама отметка,
   и по ней же реакцию меняют. */
.message-row.has-react .react-btn{display:none}
.react-mark{position:absolute;right:-6px;bottom:-10px;min-width:28px;height:24px;
  padding:0 6px;border:1px solid rgba(245,85,85,.35);border-radius:999px;
  background:var(--panel-deep);font-size:14px;line-height:1;cursor:pointer;
  transition:transform .15s}
.react-mark:hover{transform:scale(1.1)}
@media (hover:none){
  .message-row.received .react-btn{opacity:.4}
}

/* Динамик — над реакцией и по тем же правилам видимости: проступает на
   наведение, а на касании виден всегда и тише. Обе кнопки лежат в потоке,
   внутри `.msg-actions`: раньше каждая была прибита к углу строки своим
   `position:absolute`, и разложить их столбиком не получалось — абсолютный
   элемент из потока выпадает, и контейнер его не раскладывает. */
.voice-btn{width:26px;height:26px;
  display:grid;place-items:center;padding:0;border:1px solid var(--border);
  border-radius:50%;background:var(--panel-deep);color:rgba(255,255,255,.65);
  line-height:1;cursor:pointer;opacity:0;transition:opacity .15s,transform .15s}
.message-row.received:hover .voice-btn,
.message-row.received:focus-within .voice-btn{opacity:.75}
.voice-btn:hover{opacity:1;transform:scale(1.12);color:#fff}
/* Пока запись считается (это около десяти секунд), кнопка мигает: без этого
   нажатие выглядит как «ничего не произошло», и на неё жмут второй раз. */
.voice-btn.is-busy{opacity:.8;animation:voice-wait 1s ease-in-out infinite}
@keyframes voice-wait{0%,100%{opacity:.35}50%{opacity:.9}}
@media (hover:none){
  .message-row.received .voice-btn{opacity:.4}
}

/* ── справка (/faq) ─────────────────────────────────────────────────────────
   Тело страницы то же, что у документов, — отличается только оглавлением.
   Оно плиткой, а не столбцом: разделов полтора десятка, столбцом они заняли
   бы весь первый экран, и до самой справки человек не долистал бы. */
.faq-toc{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 12px}
.faq-toc a{padding:7px 12px;border:1px solid rgba(255,255,255,.1);border-radius:999px;
  background:rgba(255,255,255,.03);color:rgba(255,255,255,.6)!important;font-size:12px;
  transition:border-color .15s,color .15s,background .15s}
.faq-toc a:hover{border-color:rgba(245,85,85,.5);background:rgba(245,85,85,.08);
  color:#fff!important}
/* Заголовок раздела не должен вставать вплотную под шапку при переходе по
   ссылке из оглавления. */
.legal-wrap section{scroll-margin-top:24px}
@media (max-width:640px){
  .pricing-section{margin-bottom:88px}
  .pricing-grid{grid-template-columns:1fr}
  .legal-wrap{padding-block:36px 64px}
}

/* ── колонка: меню у имени, «Создать», поиск по чатам (17.08.2026) ──────────
   Три точки у имени — редкие действия («удалить все чаты», «вернуть
   персонажей») ушли из низа колонки в подменю; вид тот же, что у меню чата.
   «Создать» — только телефон, приложение: заменяет три пункта навигации.
   Поиск по чатам — вместо подписи «Недавние», везде. */
.side-menu-box{flex:none}
.side-more{display:grid;place-items:center;width:38px;height:38px;border:1px solid var(--border);
  border-radius:10px;background:transparent;color:rgba(255,255,255,.55);cursor:pointer;
  transition:background .2s,color .2s}
.side-more svg{width:18px;height:18px}
.side-more:hover,.side-more[aria-expanded="true"]{background:rgba(255,255,255,.08);color:#fff}
.side-menu{min-width:250px}
.side-menu button:disabled{opacity:.4;cursor:default}
.side-menu button:disabled:hover{background:transparent}
.side-menu button:not(.is-danger) svg{color:var(--coral)}
.side-create{display:none;padding:4px 16px 10px}
/* Приложение (/chat), любой экран: «Создать» вместо трёх пунктов навигации
   (единообразие ПК и телефона — решение владельца 17.08.2026). На лендинге
   демо-колонка остаётся с пунктами. */
body.chat-full .sidebar-links{display:none}
body.chat-full .side-create{display:block}
.group-cast{display:flex;flex-direction:column;gap:6px;margin:6px 0 14px}
.group-go{width:100%;margin-top:14px;min-height:48px;font-size:12px}
.group-go:disabled{opacity:.4;cursor:default;transform:none;box-shadow:none}
/* Комната и сцена — белым: у обеих подпись с приставкой, и приглушённый
   цвет читался как «неактивно» (владелец, 30.08.2026). */
.recent-row.is-group .recent-item b,.recent-row.is-scene .recent-item b{color:#fff}
.recent-group{font-style:normal;font-size:11px;margin-right:5px}
/* Окна комнаты: аватарка-кружок слева, название справа (как в мессенджерах). */
.room-head{display:flex;align-items:center;gap:14px;margin:6px 0 4px}
.room-head .field{flex:1;min-width:0;margin:0}
.room-face{position:relative;flex:none;width:64px;height:64px;border-radius:50%;border:1px dashed rgba(255,255,255,.28);
  background:rgba(255,255,255,.05);color:rgba(255,255,255,.55);cursor:pointer;overflow:hidden;
  display:grid;place-items:center;transition:border-color .2s,background .2s}
.room-face:hover{border-color:var(--coral);background:rgba(245,85,85,.08)}
.room-face.has-face{border-style:solid;border-color:rgba(255,255,255,.18)}
.room-face img{width:100%;height:100%;object-fit:cover;display:block}
.room-face-plus{font-size:26px;line-height:1;font-weight:300}
.room-acts{display:flex;align-items:center;gap:14px;margin-top:18px}
.room-save{min-height:46px;font-size:11px;padding:0 24px}
.room-drop{background:transparent;border:0;color:rgba(255,255,255,.55);cursor:pointer;font-size:12px}
.room-drop:hover{color:#ff8080}
#chat-avatar img{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block}
.recent-row.is-group .recent-item{box-shadow:inset 3px 0 0 rgba(96,165,250,.7)}
.recent-row.is-group .recent-item.active{box-shadow:inset 3px 0 0 rgba(96,165,250,.9)}
.side-create-btn{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;
  min-height:46px;border:0;border-radius:12px;background:var(--coral);color:#fff;
  font-size:14px;font-weight:700;letter-spacing:.02em;cursor:pointer;
  box-shadow:0 10px 26px -10px rgba(245,85,85,.75);transition:background .2s,transform .15s}
.side-create-btn:hover{background:var(--coral-hover)}
.side-create-btn:active{transform:translateY(1px)}
.side-create-plus{font-size:20px;line-height:1;font-weight:400;margin-top:-2px}
.side-search{position:relative;display:flex;align-items:center;margin:14px 12px 8px}
.side-search svg{position:absolute;left:12px;width:16px;height:16px;color:rgba(255,255,255,.35);pointer-events:none}
.side-search input{width:100%;min-width:0;padding:10px 34px 10px 36px;border:1px solid var(--border);
  border-radius:11px;background:rgba(255,255,255,.04);color:#fff;font-size:13px;outline:0;
  transition:border-color .2s,background .2s}
.side-search input::placeholder{color:rgba(255,255,255,.32)}
.side-search input:focus{border-color:rgba(245,85,85,.5);background:rgba(255,255,255,.06)}
.side-search input::-webkit-search-cancel-button{display:none}
.side-search-clear{position:absolute;right:8px;width:24px;height:24px;border:0;border-radius:50%;
  background:rgba(255,255,255,.1);color:rgba(255,255,255,.7);font-size:11px;cursor:pointer}
.side-search-clear:hover{background:rgba(255,255,255,.2);color:#fff}
.create-card{padding-bottom:22px}
.create-list{display:flex;flex-direction:column;gap:6px;margin-top:6px}
.create-item{display:flex;align-items:center;gap:14px;width:100%;padding:13px 14px;border:1px solid var(--border);
  border-radius:12px;background:rgba(255,255,255,.03);color:#fff;text-align:left;cursor:pointer;
  transition:background .2s,border-color .2s}
.create-item:hover{background:rgba(255,255,255,.07);border-color:rgba(245,85,85,.4)}
.create-item i{font-size:22px;color:var(--coral);flex:none}
/* Свой значок вместо глифа: размер тот же, что у шрифтовых соседей, чтобы
   строка не подпрыгивала. Цвет наследуется — currentColor в самом svg. */
.create-item svg{width:22px;height:22px;color:var(--coral);flex:none}
.create-item span{display:flex;flex-direction:column;gap:3px;min-width:0}
.create-item b{font-size:15px;font-weight:600}
.create-item small{font-size:12px;color:rgba(255,255,255,.45)}
.create-item.is-soon{opacity:.6}
.create-item.is-soon i{color:rgba(255,255,255,.4)}
/* ── выбор помощника ────────────────────────────────────────────────────────
   Те же карточки, что в «Создать», но с лицом слева вместо значка: помощников
   пятеро и они различаются не действием, а тем, кто это. */
.assist-lead{margin:0 0 16px;color:rgba(255,255,255,.5);font-size:13px;line-height:1.6}
.assist-item{align-items:center}
.assist-face{width:40px;height:40px;flex:none;border-radius:50%;overflow:hidden;
  display:grid;place-items:center;background:rgba(255,255,255,.05)}
.assist-face img{width:100%;height:100%;object-fit:cover}
.assist-item small{white-space:normal}
@media (max-width:899px){
  body.chat-full .side-create{padding:8px 12px 4px}
  .side-search{margin:10px 12px 6px}
  .side-search input{padding-block:12px;font-size:15px}
  .create-item{padding:15px 14px}
}

/* ── NamiCoin (17.08.2026): бейдж в колонке, окно монет, карточка в кабинете ── */
.side-coins{display:inline-flex;align-items:center;gap:4px;margin-top:4px;padding:2px 8px 2px 6px;border:1px solid rgba(240,198,117,.35);
  border-radius:999px;background:rgba(240,198,117,.08);color:#f0c675;font-size:11px;font-weight:700;cursor:pointer;
  transition:background .2s,border-color .2s}
.side-coins:hover{background:rgba(240,198,117,.16);border-color:rgba(240,198,117,.6)}
.side-coins svg{width:13px;height:13px}
.side-coins span{font-weight:600;opacity:.8}
/* Подпись строки — обычным весом и потише числа: главное здесь сколько монет,
   а не слово «Баланс». */
.side-coins-cap{font-weight:600;opacity:.62;letter-spacing:.01em}
/* Плюс отделён чертой и стоит вплотную к краю: так видно, что это отдельное
   дело — пополнить, — а не часть числа. */
/* content-box обязателен: в файле стоит общий *{box-sizing:border-box}, и
   поле слева съело бы 5 из 13 точек ширины — плюс сжимался в точку. */
.side-coins-plus{box-sizing:content-box;margin-left:3px;padding-left:5px;opacity:.75;
  border-left:1px solid rgba(240,198,117,.3)}
.side-coins:hover .side-coins-plus{opacity:1}
.side-user-text{overflow:visible}
.coins-body{padding:0 24px 22px}
.coins-body .cab-msg{padding:12px 0 0;min-height:0}
.coins-body h4{margin:18px 0 0;font:700 13px/1 'Space Grotesk',sans-serif;color:rgba(255,255,255,.75)}
.coins-lead{margin:0 0 14px;color:rgba(255,255,255,.62);font-size:13px;line-height:1.55}
.coins-balance{display:flex;align-items:baseline;gap:8px;margin:0 0 14px;padding:12px 16px;border-radius:12px;
  background:rgba(240,198,117,.08);border:1px solid rgba(240,198,117,.25)}
.coins-balance span{color:rgba(255,255,255,.55);font-size:12px}
.coins-balance b{font:800 24px/1 'Space Grotesk',sans-serif;color:#f0c675}
.coins-balance em{font-style:normal;color:rgba(240,198,117,.7);font-size:12px;font-weight:700}
.coins-prices{list-style:none;margin:0 0 16px;padding:0;display:flex;flex-direction:column;gap:6px}
.coins-prices li{display:flex;justify-content:space-between;align-items:center;font-size:13px;color:rgba(255,255,255,.72)}
.coins-prices li b{color:#fff}
.coins-prices li.coins-norm{font-size:12px;color:rgba(255,255,255,.45);border-top:1px solid var(--border);padding-top:8px;margin-top:2px}
.coins-packs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;align-items:stretch;padding-top:8px}
.coins-pack{position:relative;display:flex;flex-direction:column;gap:5px;padding:16px 12px 12px;border:1px solid var(--border);border-radius:14px;
  background:rgba(255,255,255,.03);text-align:center}
.coins-pack>small{margin-top:auto}
.coins-pack>b{font:800 20px/1 'Space Grotesk',sans-serif}
/* Бонус — плашка на верхней кромке карточки, вне потока (высоту не двигает). */
.coins-bonus{position:absolute;top:-9px;right:10px;font-style:normal;font-size:10px;font-weight:800;line-height:1;white-space:nowrap;
  color:#0f1512;background:#f0c675;border-radius:999px;padding:4px 8px;box-shadow:0 0 0 3px var(--panel,#14171d)}
.coins-price{display:flex;flex-direction:column;align-items:center;gap:1px;margin-top:4px}
.coins-price s{color:rgba(255,255,255,.35);font-size:12px}
.coins-price strong{font-size:18px}
.coins-pack small{color:rgba(255,255,255,.4);font-size:11px}
.coins-buy{min-height:38px;padding:0 10px;font-size:10px;margin-top:6px}
.coins-note{min-height:18px;margin:12px 0 0;font-size:12px;color:rgba(255,255,255,.7)}
.coins-fine{margin:10px 0 0;font-size:11px;color:rgba(255,255,255,.38);line-height:1.5}
.coins-ledger{list-style:none;margin:8px 0 0;padding:0;display:flex;flex-direction:column;gap:4px}
.coins-ledger li{display:flex;justify-content:space-between;font-size:12px;color:rgba(255,255,255,.6)}
.coins-ledger b.plus{color:#22c55e}.coins-ledger b.minus{color:#ff8080}
@media (max-width:899px){.coins-packs{grid-template-columns:1fr;gap:16px}.coins-pack{flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:space-between;text-align:left}
  .coins-pack>b{flex-basis:100%}.coins-pack>small{margin-top:0}.coins-buy{margin-top:0}.coins-body{padding:0 16px 18px}}

/* ══════════════════════════════════════════════════════════════════════════
   ЗНАЧОК В КНОПКЕ — РОВНО ПО ЦЕНТРУ
   Снимки с iPhone (18.08.2026): в круглых и квадратных кнопках значок стоит
   не по центру, а прижат вправо. Замер по снимкам: кнопка 38 CSS-px, краска
   значка смещена на +4,5 px («три точки», рисунок) и +5,9 px (отправка,
   шрифтовой значок) — то есть почти ровно на 6.
   Столько и составляет СОБСТВЕННЫЙ отступ, который браузер даёт всякой
   <button>: в WebKit это `2px 6px 3px`, в Chromium `1px 6px`. Мы его нигде не
   сняли, а ширину кнопке задали жёсткую. На настольных движках центровка
   сетки перекос гасит, на iOS — нет, и значок уезжает ровно на padding-left.
   Оттуда же еле заметный подъём: сверху 2px, снизу 3px.
   Лечение общее для всех кнопок-значков: своего отступа у них быть не должно,
   а высота строки не должна тянуть значок за базовую линию. Кнопки с текстом
   сюда не входят — там отступ задан осознанно.
   ══════════════════════════════════════════════════════════════════════════ */
.icon-button,.send-button,.mic-button,.side-more,.side-logout,.radio-play,
.modal-close,.chat-back,.menu-button,.cast-add,.find-step,
.chat-badges .badge-icon{padding:0;line-height:1}
/* Делать рисунок внутри блоком отдельным правилом НЕ НАДО: все эти кнопки —
   сетка или флекс, а их дети и так становятся блоками. Такое правило тут
   стояло полдня и успело навредить: `.radio-play>svg` весом (0,1,1) перебило
   `.radio-ico-pause{display:none}` весом (0,1,0), и на кнопке радио «пауза»
   легла поверх «играть». Правило убрано, замечание оставлено, чтобы его не
   вернули. */


/* ═══ 4. ЛЕНДИНГ: ПОЯВЛЕНИЕ И МИНИАТЮРЫ (22.08.2026) ═══
   Раскадровки — артборд «Namiko · моушн лендинга». Правило одно на всё:
   двигаем ТОЛЬКО прозрачность и трансформацию, каждый блок оживает один раз
   при входе в экран. Ни высот, ни отступов, ни размеров шрифта — иначе
   страница дёргается под курсором и портит показатели загрузки.

   Прячем блоки только когда есть чему их показать: класс js-reveal ставит
   скрипт (revealInit). Без JS страница остаётся читаемой целиком. */
body.js-reveal [data-reveal]{opacity:0;transform:translateY(22px)}
body.js-reveal [data-reveal].is-in{opacity:1;transform:none;
  transition:opacity .62s cubic-bezier(.22,.8,.28,1),transform .62s cubic-bezier(.22,.8,.28,1);
  transition-delay:calc(var(--i,0)*70ms)}

/* ── миниатюры возможностей ────────────────────────────────────────────────
   Каждая показывает свою механику, а не украшает. Повтор ограничен тремя
   проходами: бесконечное движение в шести карточках сразу — это шум и
   лишняя работа для батареи. */
.feat-art{position:relative;display:block;height:104px;margin-bottom:24px;overflow:hidden;
  border:1px solid var(--border);border-radius:12px;background:var(--panel-deep)}

/* память: факты выплывают снизу и остаются */
.feat-memory i{position:absolute;left:12px;right:12px;padding:6px 9px;border:1px solid var(--border);
  border-radius:9px;background:rgba(255,255,255,.04);font-style:normal;font-size:10.5px;
  line-height:1.3;color:rgba(255,255,255,.7);opacity:0;transform:translateY(14px)}
.feat-memory i:nth-child(1){top:12px}
.feat-memory i:nth-child(2){top:41px}
.feat-memory i:nth-child(3){top:70px}
.is-in .feat-memory i{animation:featUp 4s cubic-bezier(.22,.8,.28,1) 3 both}
.is-in .feat-memory i:nth-child(2){animation-delay:.45s}
.is-in .feat-memory i:nth-child(3){animation-delay:.9s}
@keyframes featUp{0%{opacity:0;transform:translateY(14px)}22%,100%{opacity:1;transform:none}}

/* фото: вспышка затвора и снимок из размытия */
.feat-photo b{position:absolute;inset:12px;border-radius:9px;
  background:linear-gradient(150deg,#2b2029,#17181c 62%)}
.feat-photo u{position:absolute;inset:0;background:#fff;opacity:0}
.is-in .feat-photo b{animation:featDev 4s ease-in-out 3 both}
.is-in .feat-photo u{animation:featFlash 4s ease-out 3 both}
@keyframes featDev{0%,12%{filter:blur(8px);opacity:.35}42%,100%{filter:blur(0);opacity:1}}
@keyframes featFlash{0%{opacity:.5}8%,100%{opacity:0}}

/* оживление: кадр дышит */
.feat-live b{position:absolute;inset:12px;border-radius:9px;
  background:linear-gradient(150deg,#202a2b,#17181c 62%)}
.is-in .feat-live b{animation:featBreathe 4.4s ease-in-out 3 both}
@keyframes featBreathe{0%,100%{transform:scale(1)}50%{transform:scale(1.05)}}
.feat-live svg{position:absolute;left:50%;top:50%;width:30px;height:30px;margin:-15px 0 0 -15px;
  padding:8px;border-radius:50%;background:rgba(17,18,20,.72);border:1px solid rgba(255,255,255,.24);
  color:#fff}

/* комната: три фигуры сходятся */
.feat-room b{position:absolute;top:36px;width:32px;height:32px;border-radius:50%;
  border:1px solid rgba(255,255,255,.14);background:linear-gradient(160deg,#2a1b22,#17181c);opacity:0}
.feat-room b:nth-child(1){left:calc(50% - 52px);--from:-26px}
.feat-room b:nth-child(2){left:calc(50% - 16px);--from:0px}
.feat-room b:nth-child(3){left:calc(50% + 20px);--from:26px}
.is-in .feat-room b{animation:featJoin 4s cubic-bezier(.22,.8,.28,1) 3 both}
.is-in .feat-room b:nth-child(2){animation-delay:.16s}
.is-in .feat-room b:nth-child(3){animation-delay:.32s}
@keyframes featJoin{0%{opacity:0;transform:translateX(var(--from,-24px))}30%,100%{opacity:1;transform:none}}

/* настройка: три ползунка ищут своё место */
.feat-tune i{position:absolute;left:18px;right:18px;height:3px;border-radius:2px;
  background:rgba(255,255,255,.1)}
.feat-tune i:nth-child(1){top:28px}
.feat-tune i:nth-child(2){top:50px}
.feat-tune i:nth-child(3){top:72px}
.feat-tune i:after{content:"";position:absolute;top:-4px;left:16%;width:11px;height:11px;
  border-radius:50%;background:var(--coral);box-shadow:0 0 12px -2px rgba(245,85,85,.8)}
.is-in .feat-tune i:after{animation:featSlide 4s cubic-bezier(.4,0,.2,1) 3 both}
.is-in .feat-tune i:nth-child(2):after{animation-delay:.2s}
.is-in .feat-tune i:nth-child(3):after{animation-delay:.4s}
@keyframes featSlide{0%{left:16%}45%{left:68%}100%{left:52%}}

/* озвучка: динамик и полоски звука, которые дышат по очереди — так рисуют
   идущее воспроизведение везде, и объяснять это не нужно */
.feat-voice b{position:absolute;left:50%;top:50%;width:0;height:0;margin:-13px 0 0 -34px;
  border-style:solid;border-width:13px 18px 13px 0;
  border-color:transparent var(--coral) transparent transparent;
  filter:drop-shadow(0 0 14px rgba(245,85,85,.45))}
.feat-voice i{position:absolute;top:50%;width:4px;border-radius:2px;background:rgba(255,255,255,.22)}
.feat-voice i:nth-child(2){left:calc(50% - 8px);height:16px;margin-top:-8px}
.feat-voice i:nth-child(3){left:calc(50% + 2px);height:30px;margin-top:-15px}
.feat-voice i:nth-child(4){left:calc(50% + 12px);height:44px;margin-top:-22px}
.feat-voice i:nth-child(5){left:calc(50% + 22px);height:24px;margin-top:-12px}
.feat-voice i:nth-child(6){left:calc(50% + 32px);height:12px;margin-top:-6px}
.is-in .feat-voice i{animation:featSound 1.5s ease-in-out infinite}
.is-in .feat-voice i:nth-child(3){animation-delay:.15s}
.is-in .feat-voice i:nth-child(4){animation-delay:.3s}
.is-in .feat-voice i:nth-child(5){animation-delay:.45s}
.is-in .feat-voice i:nth-child(6){animation-delay:.6s}
@keyframes featSound{0%,100%{transform:scaleY(.5);background:rgba(255,255,255,.18)}
  50%{transform:scaleY(1);background:rgba(245,85,85,.75)}}

/* монета переворачивается */
.feat-coin b{position:absolute;left:50%;top:50%;width:48px;height:48px;margin:-24px 0 0 -24px;
  display:grid;place-items:center;border-radius:50%;border:1px solid rgba(201,150,79,.6);
  background:radial-gradient(circle at 34% 30%,rgba(232,200,144,.4),rgba(201,150,79,.16));
  color:#f3dfb6;font:700 14px/1 'Space Grotesk',sans-serif;letter-spacing:.04em}
.is-in .feat-coin b{animation:featFlip 4.2s cubic-bezier(.4,0,.2,1) 3 both}
@keyframes featFlip{0%,55%{transform:rotateY(0)}78%,100%{transform:rotateY(360deg)}}

/* ── NamiCoin: цены услуг и пакеты монет ───────────────────────────────────
   Карточка на две колонки в ряду возможностей. Появилась 26.08.2026: после
   карточки про озвучку NamiCoin остался в ряду один, и справа от него зияли
   две пустые клетки.

   Движение заведено ровно как у монеты выше — через .is-in и конечным числом
   проходов: блок оживает, когда до него долистали, и замирает. Бесконечная
   анимация в секции из восьми карточек — это шум и работа для батареи. */
.nc-card{grid-column:span 2}
.nc-card .feature-body{display:flex;flex-direction:column;height:100%}
.nc-card h3{margin-bottom:4px}
.nc-card .feature-body>p{margin-bottom:22px}
.nc-lay{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:30px;flex-grow:1}
.nc-side{display:flex;flex-direction:column;min-width:0}
.nc-side-buy{padding-left:30px;border-left:1px solid rgba(255,255,255,.06)}
.nc-cap{display:block;margin-bottom:14px;color:rgba(255,255,255,.35);font-size:9px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase}
.nc-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:13px}
.nc-list li{display:flex;align-items:baseline}
.nc-list span{color:rgba(255,255,255,.72);font-size:13px}
/* Поводок из точек: строк четыре, и без него название с числом читаются
   двумя несвязанными столбцами, а не строкой прайса. */
.nc-list i{flex-grow:1;margin:0 10px 4px;border-bottom:1px dashed rgba(255,255,255,.12);
  transform-origin:left center}
.nc-list b{font:700 15px/1 'Space Grotesk',sans-serif;color:#f0c675;white-space:nowrap}
/* Отступ заметный, а не «на волосок»: строка объясняет уже другое —
   что монет НЕ стоит, — и вплотную к прайсу читалась его пятым пунктом.
   Правой колонки это не касается: там .nc-fine-top прижат к низу. */
.nc-card .nc-fine{margin:28px 0 0;color:rgba(255,255,255,.3);font-size:11px;line-height:1.55}
.nc-card .nc-fine-top{margin-top:auto;padding-top:12px;border-top:1px solid rgba(255,255,255,.06);
  color:rgba(255,255,255,.38)}
.nc-card .nc-fine-top b{color:#f0c675;font-weight:700}
.nc-packs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;align-items:stretch}
.nc-pack{position:relative;display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:15px 10px 13px;border:1px solid var(--border);border-radius:14px;background:rgba(255,255,255,.03)}
.nc-pack b{font:700 20px/1 'Space Grotesk',sans-serif;color:#fff}
.nc-pack small{color:rgba(255,255,255,.4);font-size:11px}
.nc-pack strong{margin-top:5px;font-size:17px}
.nc-pack s{color:rgba(255,255,255,.35);font-size:12px}
/* Бонус — плашка на верхней кромке плитки. Обрезки на самой плитке быть НЕ
   должно: overflow:hidden срезал ей верх (замечено владельцем на макете).
   Поэтому блик у выгодного пакета — не отдельный узел, а фон псевдоэлемента:
   фон и так обрезается по его рамке, а плашка к нему не относится. */
.nc-pack em{position:absolute;top:-9px;right:10px;padding:4px 8px;border-radius:999px;font-style:normal;
  font-size:10px;font-weight:800;line-height:1;white-space:nowrap;color:#0f1512;background:#f0c675;
  box-shadow:0 0 0 3px var(--panel)}
.nc-pack.is-best{border-color:rgba(240,198,117,.3);background:rgba(240,198,117,.06)}
.nc-pack.is-best:after{content:"";position:absolute;inset:0;border-radius:14px;pointer-events:none;
  background:linear-gradient(105deg,rgba(240,198,117,0),rgba(240,198,117,.16),rgba(240,198,117,0));
  background-size:220% 100%;background-repeat:no-repeat;background-position:-120% 0}

/* Один сквозной проход: строки прайса подъезжают по очереди, поводок
   дочерчивается следом, число загорается золотом — и уже после этого
   поднимаются пакеты. Порядок = порядок чтения, а не «всё сразу». */
.is-in .nc-list li{animation:ncRow .5s ease-out both}
.is-in .nc-list li:nth-child(1){animation-delay:.15s}
.is-in .nc-list li:nth-child(2){animation-delay:.24s}
.is-in .nc-list li:nth-child(3){animation-delay:.33s}
.is-in .nc-list li:nth-child(4){animation-delay:.42s}
.is-in .nc-list i{animation:ncLead .55s ease-out both}
.is-in .nc-list li:nth-child(1) i{animation-delay:.3s}
.is-in .nc-list li:nth-child(2) i{animation-delay:.39s}
.is-in .nc-list li:nth-child(3) i{animation-delay:.48s}
.is-in .nc-list li:nth-child(4) i{animation-delay:.57s}
.is-in .nc-list b{animation:ncVal .6s ease-out both}
.is-in .nc-list li:nth-child(1) b{animation-delay:.5s}
.is-in .nc-list li:nth-child(2) b{animation-delay:.59s}
.is-in .nc-list li:nth-child(3) b{animation-delay:.68s}
.is-in .nc-list li:nth-child(4) b{animation-delay:.77s}
.is-in .nc-pack{animation:ncTile .55s cubic-bezier(.2,.7,.3,1) both}
.is-in .nc-pack:nth-child(1){animation-delay:.8s}
.is-in .nc-pack:nth-child(2){animation-delay:.92s}
.is-in .nc-pack:nth-child(3){animation-delay:1.04s}
.is-in .nc-pack.is-best:after{animation:ncSheen 2.4s ease-in-out 1.6s 2 both}
@keyframes ncRow{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:none}}
@keyframes ncLead{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes ncVal{0%{color:rgba(240,198,117,0)}60%{color:#ffe0a3}100%{color:#f0c675}}
@keyframes ncTile{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes ncSheen{to{background-position:220% 0}}

/* Просят меньше движения — показываем сразу конечным кадром. Отдельным
   правилом: общее выше гасит только .feat-art, а эти строки лежат в теле
   карточки. */
@media (prefers-reduced-motion:reduce){
  .is-in .nc-list li,.is-in .nc-list i,.is-in .nc-list b,
  .is-in .nc-pack,.is-in .nc-pack.is-best:after{animation:none!important}
}

/* Узкий экран. Специфичность двойная (.feature-card.nc-card) не случайно:
   ниже по файлу мобильный слой снимает у .feature-card рамку и делает её
   строкой «иконка + текст», а этой карточке нужен обычный карточный вид. */
@media (max-width:899px){
  .feature-card.nc-card{grid-column:auto;display:block;padding:22px;border:1px solid rgba(255,255,255,.06);
    border-radius:16px;background:var(--panel);overflow:hidden}
  .nc-lay{grid-template-columns:1fr;gap:24px}
  .nc-side-buy{padding:24px 0 0;border-left:0;border-top:1px solid rgba(255,255,255,.06)}
  /* Пакеты строками — так же, как в окне монет внутри приложения: три плитки
     в ряд на 390 точках дают колонку в сто с небольшим пикселей. */
  .nc-packs{grid-template-columns:1fr}
  .nc-pack{flex-direction:row;align-items:center;justify-content:space-between;gap:10px;padding:13px 14px}
  .nc-pack b{font-size:18px}
  .nc-pack small{margin-right:auto}
  .nc-pack strong{order:2;margin-top:0;font-size:16px}
  .nc-pack s{order:1}
  .nc-pack em{top:-9px;right:auto;left:14px}
}

/* ── сценарии ──────────────────────────────────────────────────────────────
   Мини-сцена играет ровно то, что описано рядом словами: дорожка актов
   наполняется, рассказчик предлагает ход, выбранный вариант остаётся,
   поворот отбивается разделителем главы, финал проявляется кадром. */
.scen-section,.assist-section{margin-bottom:128px}
.scen-lay{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:48px;align-items:start}
.scen-demo{display:flex;flex-direction:column;gap:14px;padding:22px;border:1px solid var(--border);
  border-radius:18px;background:var(--panel);box-shadow:0 24px 80px rgba(0,0,0,.32)}
.scen-track{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.scen-seg{display:flex;flex-direction:column;gap:8px}
.scen-seg i{position:relative;display:block;height:3px;border-radius:2px;
  background:rgba(255,255,255,.1);overflow:hidden}
.scen-seg i:after{content:"";position:absolute;inset:0 auto 0 0;width:8%;border-radius:2px;
  background:linear-gradient(90deg,rgba(201,150,79,.75),#e8c890)}
.scen-seg:not(.is-now) i:after{width:0}
.scen-seg em{font:700 9px/1 Inter,sans-serif;font-style:normal;letter-spacing:.12em;
  text-transform:uppercase;color:rgba(255,255,255,.3);text-align:center}
.scen-seg.is-now em{color:#f3dfb6}
.scen-demo.is-in .scen-seg.is-now i:after{animation:scenFill .9s cubic-bezier(.4,0,.2,1) both}
.scen-demo.is-in .scen-seg:nth-child(2) i:after{animation:scenFill .8s cubic-bezier(.4,0,.2,1) 2s both}
.scen-demo.is-in .scen-seg:nth-child(2) em{animation:scenLit .4s ease-out 2s both}
@keyframes scenFill{from{width:8%}to{width:100%}}
@keyframes scenLit{to{color:#f3dfb6}}
.scen-msg{padding:15px 17px;border:1px solid rgba(201,150,79,.35);border-radius:16px;
  background:var(--panel-deep);opacity:0;transform:translateY(14px)}
.scen-msg.is-act{border-color:rgba(201,150,79,.75)}
.scen-demo.is-in .scen-msg{animation:scenRise .5s cubic-bezier(.22,.8,.28,1) var(--d,0s) both}
@keyframes scenRise{to{opacity:1;transform:none}}
.scen-msg b{display:block;margin-bottom:7px;font:700 9px/1 Inter,sans-serif;letter-spacing:.16em;
  text-transform:uppercase;color:#f3dfb6}
.scen-msg p{margin:0;font-size:13px;line-height:1.6;font-style:italic;color:rgba(255,255,255,.8)}
.scen-chip{display:flex;align-items:center;gap:10px;margin-bottom:10px;font:700 9px/1 Inter,sans-serif;
  font-style:normal;letter-spacing:.16em;text-transform:uppercase;color:#f3dfb6}
.scen-chip:after{content:"";flex:1;height:1px;transform:scaleX(0);transform-origin:left;
  background:linear-gradient(90deg,rgba(201,150,79,.6),rgba(201,150,79,0))}
.scen-demo.is-in .scen-chip:after{animation:scenLine .42s ease-out 2.15s both}
@keyframes scenLine{to{transform:scaleX(1)}}
.scen-pick{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.scen-pick u{padding:7px 11px;border:1px solid rgba(201,150,79,.5);border-radius:10px;
  background:rgba(201,150,79,.12);color:#f3dfb6;font-size:12px;text-decoration:none;
  opacity:0;transform:translateY(8px)}
.scen-demo.is-in .scen-pick u{animation:scenRise .4s cubic-bezier(.22,.8,.28,1) var(--d,0s) both}
.scen-demo.is-in .scen-pick u.on{animation:scenRise .4s cubic-bezier(.22,.8,.28,1) var(--d,0s) both,
  scenPicked .5s ease-out 1.7s forwards}
.scen-demo.is-in .scen-pick u.off{animation:scenRise .4s cubic-bezier(.22,.8,.28,1) var(--d,0s) both,
  scenGone .4s ease-out 1.75s forwards}
@keyframes scenPicked{to{background:rgba(201,150,79,.3);border-color:rgba(201,150,79,.9);color:#fff}}
@keyframes scenGone{to{opacity:0;transform:translateY(-4px)}}
.scen-pick u.on:before{content:"✓ ";font-weight:700;opacity:0}
.scen-demo.is-in .scen-pick u.on:before{animation:scenTick .3s ease-out 1.85s forwards}
@keyframes scenTick{to{opacity:1}}
.scen-frame{display:block;aspect-ratio:16/10;border-radius:12px;border:1px solid rgba(201,150,79,.4);
  background:linear-gradient(150deg,#2b2029,#17181c 60%);opacity:0;filter:blur(8px)}
.scen-demo.is-in .scen-frame{animation:scenShot .8s ease-out var(--d,0s) both}
@keyframes scenShot{to{opacity:1;filter:blur(0)}}
.scen-points{display:flex;flex-direction:column;gap:26px;margin:0;padding:6px 0 0;list-style:none}
.scen-points li{position:relative;padding-left:28px;color:rgba(255,255,255,.42);
  font-size:13.5px;line-height:1.7}
.scen-points li:before{content:"";position:absolute;left:0;top:8px;width:9px;height:9px;
  border-radius:50%;border:2px solid rgba(201,150,79,.85)}
.scen-points b{display:block;margin-bottom:6px;font:700 16px/1.2 'Space Grotesk',sans-serif;color:#fff}

/* ── помощники ─────────────────────────────────────────────────────────── */
.assist-lead{max-width:780px;margin:0 0 34px;color:rgba(255,255,255,.5);font-size:15px;line-height:1.7}
.assist-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.assist-card{display:flex;flex-direction:column;gap:10px;padding:22px 20px 24px;
  border:1px solid rgba(255,255,255,.06);border-radius:16px;background:var(--panel);
  transition:border-color .3s,box-shadow .3s}
.assist-card:hover{border-color:rgba(96,165,250,.4);box-shadow:0 20px 50px rgba(0,0,0,.3)}
.assist-ico{display:grid;place-items:center;width:38px;height:38px;border-radius:10px;
  background:rgba(96,165,250,.12);color:var(--blue)}
.assist-card small{font:700 9.5px/1 Inter,sans-serif;letter-spacing:.14em;text-transform:uppercase;
  color:var(--blue)}
.assist-card h3{margin:0;font:700 19px/1.1 'Space Grotesk',sans-serif;color:#fff}
.assist-card p{margin:0;font-size:12.5px;line-height:1.6;color:rgba(255,255,255,.36)}
.assist-fine{max-width:840px;margin:30px 0 0;color:rgba(255,255,255,.28);font-size:12px;line-height:1.7}

@media (max-width:980px){
  .scen-lay{grid-template-columns:1fr;gap:34px}
  .assist-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
}
@media (max-width:640px){
  .scen-section,.assist-section{margin-bottom:88px}
  .scen-demo{padding:16px;gap:12px}
  .scen-points{gap:20px}
  .scen-points b{font-size:15px}
  .assist-grid{grid-template-columns:1fr 1fr;gap:12px}
  .assist-card{padding:16px 14px 18px;gap:8px}
  .assist-card h3{font-size:17px}
  .assist-lead{font-size:14px;margin-bottom:26px}
  .feat-art{height:92px;margin-bottom:20px}
}

/* Просят меньше движения — показываем сразу и конечным кадром. */
@media (prefers-reduced-motion:reduce){
  body.js-reveal [data-reveal]{opacity:1;transform:none;transition:none}
  .feat-art *,.scen-demo *,.scen-demo *:before,.scen-demo *:after{animation:none!important}
  .feat-memory i,.feat-room b{opacity:1;transform:none}
  .feat-photo b{filter:none;opacity:1}
  .scen-msg,.scen-pick u,.scen-frame{opacity:1;transform:none;filter:none}
  .scen-seg i:after,.scen-seg:not(.is-now) i:after{width:100%}
  .scen-chip:after{transform:scaleX(1)}
  .scen-pick u.on:before{opacity:1}
  .scen-pick u.off{display:none}
}

/* ── доводка миниатюр после просмотра в браузере (22.08.2026) ─────────────
   Комната на троих: фигуры были тёмными пятнами на тёмном фоне. Даём им три
   разных оттенка — это трое разных собеседников, а не три кружка. */
.feat-room b{border-color:rgba(255,255,255,.22)}
.feat-room b:nth-child(1){background:radial-gradient(circle at 36% 30%,rgba(245,85,85,.5),rgba(245,85,85,.12));
  border-color:rgba(245,85,85,.5)}
.feat-room b:nth-child(2){background:radial-gradient(circle at 36% 30%,rgba(96,165,250,.5),rgba(96,165,250,.12));
  border-color:rgba(96,165,250,.5)}
.feat-room b:nth-child(3){background:radial-gradient(circle at 36% 30%,rgba(201,150,79,.55),rgba(201,150,79,.14));
  border-color:rgba(201,150,79,.6)}

/* Монета была тусклой: золото ярче, надпись крупнее. */
.feat-coin b{width:52px;height:52px;margin:-26px 0 0 -26px;font-size:15px;color:#fff8ea;
  border-color:rgba(232,200,144,.85);
  background:radial-gradient(circle at 34% 28%,#e8c890,rgba(201,150,79,.55) 62%,rgba(201,150,79,.2));
  box-shadow:0 8px 26px -10px rgba(232,200,144,.7)}

/* Снимок должен читаться снимком, а не пустой плашкой: уголки кадра. */
.feat-photo b:before,.feat-photo b:after{content:"";position:absolute;width:14px;height:14px;
  border:2px solid rgba(255,255,255,.28)}
.feat-photo b:before{left:8px;top:8px;border-right:0;border-bottom:0;border-radius:4px 0 0 0}
.feat-photo b:after{right:8px;bottom:8px;border-left:0;border-top:0;border-radius:0 0 4px 0}

/* «Кадр на память» в сценариях: был во всю ширину и пустой — теперь ниже,
   с уголками и подписью, как настоящий кадр из сцены. */
.scen-frame{position:relative;aspect-ratio:16/9;max-height:230px;display:flex;align-items:flex-end;
  padding:12px 14px}
.scen-frame em{font-style:normal;font:700 9px/1 Inter,sans-serif;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(243,223,182,.75)}
.scen-frame:before,.scen-frame:after{content:"";position:absolute;width:16px;height:16px;
  border:2px solid rgba(201,150,79,.55)}
.scen-frame:before{left:10px;top:10px;border-right:0;border-bottom:0;border-radius:5px 0 0 0}
.scen-frame:after{right:10px;top:10px;border-left:0;border-bottom:0;border-radius:0 5px 0 0}

/* Лица помощников на лендинге (22.08.2026): у каждого свой нарисованный
   портрет — те же файлы, что в карточке помощника внутри приложения.
   Класс НЕ .assist-face: так называется кружок 40px в окне выбора помощника,
   и его правила накрыли бы портрет (та же ловушка, что со scene-act). */
.assist-portrait{display:block;width:76px;height:76px;border-radius:14px;overflow:hidden;
  border:1px solid rgba(96,165,250,.28);background:var(--panel-deep)}
.assist-portrait img{width:100%;height:100%;display:block;object-fit:cover;object-position:50% 22%}
@media (max-width:640px){.assist-portrait{width:60px;height:60px;border-radius:12px}}

/* ── «Предложить идею» (22.08.2026) ───────────────────────────────────────
   Форма справа, объяснение слева: человек сперва понимает, о чём писать, и
   только потом видит поле. Поля берут общий вид форм (.field, .choice). */
.idea-section{margin-bottom:128px}
.idea-lay{display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);gap:48px;align-items:start}
.idea-copy p{margin:0 0 16px;color:rgba(255,255,255,.5);font-size:14.5px;line-height:1.75}
.idea-copy ul{margin:0 0 16px;padding:0;list-style:none;display:flex;flex-direction:column;gap:12px}
.idea-copy li{position:relative;padding-left:26px;color:rgba(255,255,255,.42);
  font-size:13.5px;line-height:1.65}
.idea-copy li:before{content:"";position:absolute;left:0;top:7px;width:9px;height:9px;
  border-radius:50%;border:2px solid rgba(245,85,85,.75)}
.idea-copy li b{color:#fff;font-weight:600}
.idea-note{color:rgba(255,255,255,.3)!important;font-size:12.5px!important}
.idea-form{padding:26px;border:1px solid var(--border);border-radius:18px;background:var(--panel);
  box-shadow:0 24px 80px rgba(0,0,0,.32)}
.idea-form .field{margin-bottom:18px}
.idea-form textarea,.idea-form input[type=text]{width:100%;padding:14px 16px;border:1px solid var(--border);
  border-radius:13px;background:var(--panel-deep);color:#fff;font:inherit;font-size:13px;line-height:1.5}
.idea-form textarea{resize:vertical;min-height:120px}
.idea-form textarea:focus,.idea-form input[type=text]:focus{outline:0;border-color:rgba(245,85,85,.5)}
.idea-form textarea::placeholder,.idea-form input::placeholder{color:rgba(255,255,255,.2)}
.idea-form .button{width:100%;margin-top:4px}
.idea-form .button:disabled{opacity:.6;cursor:default;transform:none}
.idea-ok{margin:0 0 14px;padding:11px 13px;border:1px solid rgba(34,197,94,.35);border-radius:12px;
  background:rgba(34,197,94,.1);color:#86efac;font-size:12.5px;line-height:1.55}
@media (max-width:980px){.idea-lay{grid-template-columns:1fr;gap:30px}}
@media (max-width:640px){.idea-section{margin-bottom:88px}.idea-form{padding:18px}}

/* Блок-ссылка в кабинете. */
.cab-idea .cab-actions{margin-top:14px}

/* Обращения людей в служебном входе. */
.adm-idea{padding:14px 16px;margin-bottom:12px;border:1px solid var(--border);border-radius:14px;
  background:var(--panel-deep)}
.adm-idea.is-new{border-color:rgba(245,85,85,.45)}
.adm-idea-top{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:8px}
.adm-idea-kind{padding:3px 8px;border-radius:7px;background:rgba(245,85,85,.14);color:#ffb3b3;
  font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase}
.adm-idea-who{color:rgba(255,255,255,.6);font-size:12px}
.adm-idea-when{margin-left:auto;color:rgba(255,255,255,.3);font-size:11px}
.adm-idea p{margin:0 0 10px;color:rgba(255,255,255,.82);font-size:13.5px;line-height:1.6;
  white-space:pre-line}
.adm-idea-acts{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.adm-idea-btn{padding:5px 10px;border:1px solid var(--border);border-radius:8px;
  background:rgba(255,255,255,.04);color:rgba(255,255,255,.7);font-size:11px;cursor:pointer}
.adm-idea-btn:hover{background:rgba(255,255,255,.09);color:#fff}
.adm-idea-state{margin-left:auto;color:rgba(255,255,255,.3);font-size:11px}

/* Ссылки в шапке служебных страниц (/idea, /cabinet, /faq, документы) — один
   вид: белые, без акцента (решение владельца 22.08.2026). Перебивают правило
   лендинга `.auth-actions>a:first-child` (тусклая и скрытая на телефоне): оно
   про текстовый «Войти» рядом с кнопкой, а не про эти ссылки. */
.auth-actions>a.nav-plain{display:inline;color:#fff;font-size:13px;font-weight:600;transition:color .2s}
.auth-actions>a.nav-plain:hover{color:var(--coral)}
@media (max-width:640px){.auth-actions{gap:14px}.auth-actions>a.nav-plain{font-size:12px}}
/* Документы и справка: шапка сайта над текстом, как на остальных страницах. */
body.legal-page .site-nav{position:static}

/* ── настоящие материалы в моушн-блоках (решение владельца 22.08.2026) ─────
   Селфи, ролик из него, кадр сцены и лица персонажей — всё своё, а не
   нарисованные фигуры. Движение прежнее: вспышка и проявка для фото, плавный
   наезд для кадра; ролик двигается сам. */
.feat-photo img{position:absolute;inset:12px;width:calc(100% - 24px);height:calc(100% - 24px);
  border-radius:9px;object-fit:cover;object-position:50% 30%}
.is-in .feat-photo img{animation:featDev 4s ease-in-out 3 both}
.feat-photo b{display:none}
.feat-live video{position:absolute;inset:12px;width:calc(100% - 24px);height:calc(100% - 24px);
  border-radius:9px;object-fit:cover;object-position:50% 30%;background:#17181c}
.feat-room b{background-size:cover;background-position:50% 25%;border-width:2px}
.scen-frame img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 35%}
.scen-frame{position:relative;overflow:hidden}
.scen-frame em{position:relative;z-index:1;padding:4px 8px;border-radius:6px;background:rgba(17,18,20,.62)}
.scen-frame:before,.scen-frame:after{z-index:1}
.scen-demo.is-in .scen-frame img{animation:scenZoom 6s ease-out var(--d,0s) both}
@keyframes scenZoom{from{transform:scale(1.08)}to{transform:scale(1)}}
@media (prefers-reduced-motion:reduce){.feat-photo img,.scen-frame img{animation:none!important}}

/* Лица в «комнате на троих»: правила с nth-child (цветные рамки) задают
   background шорткатом и сбрасывают размер — аватарка рисовалась в натуральную
   величину из угла (тёмное пятно, снимок 22.08.2026). Той же силой селектора,
   позже по файлу: размер и точка привязки возвращаются. Кружки крупнее —
   в 32 px лицо не прочесть. */
.feat-room b,.feat-room b:nth-child(1),.feat-room b:nth-child(2),.feat-room b:nth-child(3){
  width:46px;height:46px;top:29px;background-size:cover;background-position:50% 22%;opacity:0}
.feat-room b:nth-child(1){left:calc(50% - 78px)}
.feat-room b:nth-child(2){left:calc(50% - 23px)}
.feat-room b:nth-child(3){left:calc(50% + 32px)}
.is-in .feat-room b{animation:featJoin 4s cubic-bezier(.22,.8,.28,1) 3 both}
@media (prefers-reduced-motion:reduce){.feat-room b,.feat-room b:nth-child(1),.feat-room b:nth-child(2),.feat-room b:nth-child(3){opacity:1}}

/* Тарифы: список шёл сразу после подписи, а не прижимался к низу карточки —
   у «Бесплатно» подпись короче, и между ней и списком зияла пустота (снимок
   владельца 22.08.2026). К низу прижимается только кнопка, если она есть. */
.price-card>.button,.price-card>button,.price-card>a.button{margin-top:auto}
.price-card ul+*{margin-top:16px}

/* Кнопка «наверх» (22.08.2026): круг на коралловом, белая галка. Появляется
   после экрана прокрутки (.is-on ставит to-top.js), до того не ловит клики. */
.to-top{position:fixed;right:22px;bottom:22px;z-index:40;width:46px;height:46px;border:0;border-radius:50%;
  display:grid;place-items:center;background:var(--coral);color:#fff;cursor:pointer;
  box-shadow:0 10px 28px -8px rgba(245,85,85,.7);opacity:0;transform:translateY(14px);pointer-events:none;
  transition:opacity .25s,transform .25s,background .2s}
.to-top.is-on{opacity:1;transform:none;pointer-events:auto}
.to-top:hover{background:var(--coral-hover)}
.to-top svg{display:block}
@media (max-width:640px){.to-top{right:16px;bottom:16px;width:42px;height:42px}}
@media (prefers-reduced-motion:reduce){.to-top{transition:none}}

/* Тарифы: ключевые строки карточки PRO (норма и монеты) — коралловым, а
   фраза «норма — не предел» под списком — тише и мельче (22.08.2026). */
.price-card li.is-key{color:#ffb3b3}
.price-card li.is-key::marker{color:var(--coral)}
.price-more{margin:14px 0 0;padding-top:12px;border-top:1px solid rgba(255,255,255,.07);
  color:rgba(255,255,255,.42);font-size:11.5px;line-height:1.6}

/* ── тарифы: моушн «дороговизны» (раскадровка 05, 22.08.2026) ─────────────
   Карточки встают волной, цена доезжает до значения (скрипт), лучший тариф
   ловит блик и значок выгоды, ключевые строки вспыхивают и остывают до
   кораллового. Один проход при появлении; повторяется только блик. */
.price-card{position:relative;transition:transform .25s,border-color .25s,box-shadow .25s}
.price-card:hover{transform:translateY(-4px);border-color:rgba(245,85,85,.35)}
body.js-reveal .price-card{opacity:0;transform:translateY(22px)}
body.js-reveal .price-card.is-in{opacity:1;transform:none;
  transition:opacity .6s cubic-bezier(.22,.8,.28,1),transform .6s cubic-bezier(.22,.8,.28,1),
  border-color .25s,box-shadow .25s;transition-delay:calc(var(--i,0)*80ms)}
body.js-reveal .price-card.is-in:hover{transform:translateY(-4px);transition-delay:0s}
.price-big{font-variant-numeric:tabular-nums}
.price-card.is-best{overflow:hidden}
.price-card.is-best:after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 40%,rgba(255,255,255,.12) 50%,transparent 60%);
  transform:translateX(-130%)}
.price-card.is-best.is-in:after{animation:priceSheen 5s cubic-bezier(.4,0,.2,1) .9s infinite}
@keyframes priceSheen{0%,60%{transform:translateX(-130%)}75%,100%{transform:translateX(130%)}}
.price-badge{position:absolute;top:14px;right:14px;padding:5px 9px;border-radius:999px;
  background:var(--coral);color:#fff;font:700 9px/1 Inter,sans-serif;letter-spacing:.12em;
  text-transform:uppercase;box-shadow:0 6px 18px -6px rgba(245,85,85,.8);opacity:0;transform:scale(.6)}
.price-card.is-in .price-badge{animation:pricePop .5s cubic-bezier(.34,1.56,.64,1) 1.1s both}
@keyframes pricePop{to{opacity:1;transform:scale(1)}}
.price-card.is-in li.is-key{animation:priceGlow 1.2s ease-out 1.4s both}
.price-card.is-in li.is-key~li.is-key{animation-delay:1.6s}
@keyframes priceGlow{0%{color:rgba(255,255,255,.5)}40%{color:#fff;text-shadow:0 0 14px rgba(245,85,85,.8)}
  100%{color:#ffb3b3;text-shadow:none}}
@media (prefers-reduced-motion:reduce){
  body.js-reveal .price-card{opacity:1;transform:none}
  .price-card.is-best.is-in:after,.price-card.is-in .price-badge,.price-card.is-in li.is-key{animation:none}
  .price-badge{opacity:1;transform:none}
}

/* Значок выгоды стоял поверх заголовка лучшей карточки (снимок 22.08.2026):
   заголовку — место справа, значку — место сверху, а не друг на друге. */
.price-card.is-best h3{padding-right:96px}
@media (max-width:640px){.price-card.is-best h3{padding-right:0;padding-top:26px}.price-badge{top:12px;right:12px}}

/* Ключевые строки тарифов — золото-медные, как у рассказчика, а не коралл
   (решение владельца 22.08.2026); вспышка тоже тёплая. */
.price-card li.is-key{color:#f3dfb6}
.price-card li.is-key::marker{color:#c9964f}
@keyframes priceGlow{0%{color:rgba(255,255,255,.5)}40%{color:#fff;text-shadow:0 0 14px rgba(232,200,144,.85)}
  100%{color:#f3dfb6;text-shadow:none}}
.pro-term-coins{display:block;margin-top:3px;font-size:11px;color:#e8c890}

/* Фильтр витрины: поиск + чипы тайтлов. Появился, когда каталог вырос до сотен
   персонажей (пакет 500 персонажей, 22.08.2026). */
.cat-filter{display:flex;flex-direction:column;gap:12px;margin:-10px 0 24px}
.cat-filter:empty{display:none}
/* Поле поиска с крестиком: гнездо нужно, чтобы кнопка легла ПОВЕРХ поля, а не рядом — иначе она отъедала бы ширину у самого поля. Свой крестик WebKit прячем: два одинаковых значка подряд читаются как сбой. */
.cat-search-box{position:relative;width:min(420px,100%)}
.cat-search{width:100%;padding:10px 36px 10px 14px;border:1px solid var(--border);border-radius:10px;background:var(--panel-deep);color:#fff;outline:0}
.cat-search::-webkit-search-cancel-button{display:none}
.cat-search-clear{position:absolute;right:6px;top:50%;transform:translateY(-50%);display:none;place-items:center;width:26px;height:26px;padding:0;border:0;border-radius:50%;background:transparent;color:rgba(255,255,255,.45);font-size:19px;line-height:1;cursor:pointer;transition:color .15s,background .15s}
.cat-search-box.has-text .cat-search-clear{display:grid}
/* Крестик для полей поиска внутри приложения — «позвать», «в комнату»,
   «в разговор». Гнездо оборачивает поле в коде, поэтому ширину не задаём:
   пусть остаётся такой, какой её сделало окно. */
.search-box{position:relative;display:block}
.search-box>input{width:100%;padding-right:34px}
.search-clear{position:absolute;right:6px;top:50%;transform:translateY(-50%);display:none;place-items:center;width:24px;height:24px;padding:0;border:0;border-radius:50%;background:transparent;color:rgba(255,255,255,.45);font-size:18px;line-height:1;cursor:pointer;transition:color .15s,background .15s}
.search-box.has-text .search-clear{display:grid}
.search-clear:hover{background:rgba(255,255,255,.08);color:#fff}
.cat-search-clear:hover{background:rgba(255,255,255,.08);color:#fff}
.cat-search::placeholder{color:rgba(255,255,255,.3)}
.cat-search:focus{border-color:rgba(245,85,85,.5)}
.cat-chips{display:flex;flex-wrap:wrap;gap:8px}
.cat-chip{padding:6px 12px;border:1px solid var(--border);border-radius:999px;background:rgba(255,255,255,.04);color:rgba(255,255,255,.62);font-size:11px;cursor:pointer;transition:background .2s,color .2s}
.cat-chip:hover{background:rgba(255,255,255,.09);color:#fff}
.cat-chip.is-on{background:rgba(245,85,85,.18);border-color:rgba(245,85,85,.6);color:#fff}
.cat-chip.is-more{color:var(--coral)}
.cat-chip b{margin-left:6px;font-weight:600;opacity:.6}
.grid-empty{grid-column:1/-1;margin:0;padding:28px 0;color:rgba(255,255,255,.4);font-size:13px}

/* Строка неотбитого чека в админке: сумма, кто и когда, поле под ссылку.
   Ссылка вводится руками, потому что выпускается она в «Мой налог», а не у нас. */
/* Боковой отступ тот же, что у ячеек таблиц и у заголовка блока (22px):
   строки чеков живут в такой же рамке, и без него они одни во всей админке
   упирались в край, а заголовок над ними стоял с отступом. */
.adm-receipt{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:10px 22px;border-bottom:1px solid rgba(255,255,255,.08)}
/* Последняя строка — без черты: она совпала бы с краем рамки блока. */
.adm-receipt:last-child{border-bottom:0}
.adm-receipt b{min-width:74px}
.adm-receipt span{flex:1 1 220px;opacity:.7;font-size:13px}
.adm-receipt input{flex:2 1 260px;padding:6px 8px;border-radius:8px;
  border:1px solid rgba(255,255,255,.16);background:transparent;color:inherit}
/* Кнопка своя, а не .button-small: та тянет за собой min-height и разрядку
   заглавными, и в строке высотой в поле ввода смотрится инородно. Цвет
   берём общий — действие тут такое же основное, как «Обновить» в шапке. */
.adm-receipt button{padding:6px 14px;border-radius:8px;border:0;cursor:pointer;
  background:var(--coral);color:#fff;font-weight:600}
.adm-receipt button:disabled{opacity:.4;cursor:not-allowed}

/* Ссылка на чек в истории оплат. Ведёт на сайт ФНС: чек по НПД живёт там,
   а не у нас, и подменять его своей страницей было бы обманом. */
.pay-receipt{display:inline-block;margin-top:2px;font-size:13px;opacity:.85}


/* ── Маркер над заголовком героя ──────────────────────────────────────────
   Строка, ради которой страницу находят, стоит внутри H1 первой строкой:
   заголовок-плакат остаётся плакатом, а фраза кластера — в заголовке, а не
   спрятана в подпись. Мельче основной строки намеренно: она вводит, а не
   спорит с ней за внимание. */
.hero-marker{display:block;margin:0 0 20px;font:700 13px/1.5 Inter,sans-serif;
  letter-spacing:.2em;text-transform:uppercase;color:rgba(255,255,255,.42)}

/* ── Вопросы и ответы ─────────────────────────────────────────────────────
   Раскрытие на <details>: без скрипта, доступно с клавиатуры, и содержимое
   остаётся в документе даже закрытым — поисковик читает ответ целиком. */
.qa-section{margin-bottom:128px}
.qa-list{display:grid;gap:12px}
.qa-item{border:1px solid rgba(255,255,255,.06);border-radius:14px;
  background:var(--panel);transition:border-color .25s}
.qa-item[open]{border-color:rgba(245,85,85,.28)}
.qa-item summary{display:flex;align-items:center;justify-content:space-between;
  gap:20px;padding:22px 26px;cursor:pointer;list-style:none;
  font-size:16px;font-weight:600;line-height:1.45}
.qa-item summary::-webkit-details-marker{display:none}
.qa-item summary i{flex:none;color:var(--coral);font-size:18px;transition:transform .25s}
.qa-item[open] summary i{transform:rotate(180deg)}
.qa-item summary:hover span{color:var(--coral)}
/* Ответ во всю ширину карточки (решение владельца 26.08.2026).
   Ограничение длины строки ради читаемости оставляло 515 px пустоты
   справа, и рядом с вопросом во всю ширину это читалось как поломка
   вёрстки, а не как забота о глазах. */
.qa-item p{margin:0;padding:0 26px 24px;
  color:rgba(255,255,255,.42);font-size:14px;line-height:1.75}

@media (max-width:640px){
  .hero-marker{margin-bottom:14px;font-size:11px;letter-spacing:.16em}
  .qa-section{margin-bottom:88px}
  .qa-item summary{padding:18px;font-size:15px;gap:14px}
  .qa-item p{padding:0 18px 20px;font-size:13.5px}
}


/* ── Посадочные страницы под кластеры ────────────────────────────────────
   Разметка у них своя, не общая с приложением: карточки приложения рисует
   app.js, и любая правка там ломала бы серверные страницы молча. Классы
   развели намеренно — общий у них только .tag-list. */
.lp-wrap{max-width:1240px}
.legal-wrap.lp-wrap p{font-size:15px;line-height:1.75}
.lp-h2{margin:52px 0 14px;font:700 23px/1.25 'Space Grotesk',sans-serif;
  letter-spacing:-.02em;color:#fff}
.lp-more{margin-top:18px}
.lp-more a{color:var(--coral);font-size:13px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase}

/* Карточка героя. Ведёт на главную с ?c= — своих страниц у героев нет. */
.lp-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:18px;margin:22px 0 0}
.lp-card{display:flex;min-height:150px;overflow:hidden;
  border:1px solid rgba(255,255,255,.07);border-radius:14px;
  background:var(--panel);transition:border-color .25s,transform .25s}
.lp-card:hover{border-color:rgba(245,85,85,.42);transform:translateY(-2px)}
.lp-shot{position:relative;display:block;flex:0 0 124px;width:124px;overflow:hidden}
.lp-shot img{width:100%;height:100%;display:block;object-fit:cover}
.lp-shot:after{content:"";position:absolute;inset:0;
  background:linear-gradient(to top,rgba(17,18,20,.55),transparent 60%)}
.lp-letter{display:grid;place-items:center;width:100%;height:100%;
  background:rgba(255,255,255,.05);color:var(--coral);
  font:700 34px/1 'Space Grotesk',sans-serif}
.lp-copy{display:flex;flex-direction:column;justify-content:center;gap:6px;
  min-width:0;padding:18px 20px}
.lp-name{font:700 18px/1.2 'Space Grotesk',sans-serif;color:#fff}
.lp-world{color:var(--coral);font-size:10px;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase}
.lp-line{color:rgba(255,255,255,.44);font-size:13px;line-height:1.5}
.lp-copy .tag-list{margin-top:2px}

/* Помощники: подпись сверху — это область, а не имя, и читают её первой. */
.lp-assists{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:16px;margin:22px 0 0}
.lp-assist{display:flex;flex-direction:column;gap:7px;padding:22px;
  border:1px solid rgba(255,255,255,.07);border-radius:14px;
  background:var(--panel);transition:border-color .25s,transform .25s}
.lp-assist:hover{border-color:rgba(245,85,85,.42);transform:translateY(-2px)}
.lp-face{display:block;width:64px;height:64px;margin-bottom:6px;
  border-radius:50%;overflow:hidden;background:rgba(255,255,255,.05)}
.lp-face img{width:100%;height:100%;display:block;object-fit:cover}
.lp-assist small{color:var(--coral);font-size:10px;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase}

/* Шаги «как это работает» — нумерация несёт порядок, он тут настоящий. */
.lp-steps{counter-reset:lp;list-style:none;margin:26px 0 0;padding:0;
  display:grid;gap:12px}
.lp-steps li{counter-increment:lp;position:relative;padding:18px 20px 18px 58px;
  border:1px solid rgba(255,255,255,.07);border-radius:14px;background:var(--panel)}
.lp-steps li:before{content:counter(lp);position:absolute;left:20px;top:18px;
  color:var(--coral);font:700 15px/1.5 'Space Grotesk',sans-serif}
.lp-steps b{display:block;margin-bottom:4px;font-size:15px;color:#fff}
.lp-steps span{color:rgba(255,255,255,.44);font-size:14px;line-height:1.6}

/* Вселенные — плитка названий: показывает широту каталога без цифр. */
.lp-chips{display:flex;flex-wrap:wrap;gap:8px;margin:20px 0 0}
.lp-chip{padding:7px 12px;border:1px solid var(--border);border-radius:999px;
  background:rgba(255,255,255,.04);color:rgba(255,255,255,.56);font-size:12px}

/* Перелинковка разделов: без неё каждая посадочная — остров. */
.lp-near{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px}
.lp-near a{padding:10px 16px;border:1px solid var(--border);border-radius:999px;
  background:rgba(255,255,255,.04);color:var(--coral);font-size:13px;font-weight:600;
  transition:border-color .2s,background .2s}
.lp-near a:hover{border-color:rgba(245,85,85,.42);background:rgba(245,85,85,.08)}

/* Список «кому подойдёт»: подлежащее выделено, объяснение — обычным текстом.
   Так строка читается сканирующим взглядом, а не только целиком. */
.legal-wrap.lp-wrap .lp-list{margin:20px 0 0;padding-left:0;list-style:none;display:grid;gap:10px}
.lp-list li{position:relative;padding-left:22px;
  color:rgba(255,255,255,.5);font-size:15px;line-height:1.65}
.lp-list li:before{content:"";position:absolute;left:2px;top:11px;
  width:7px;height:7px;border-radius:50%;background:var(--coral)}
.lp-list b{color:#fff;font-weight:600}

/* Призыв в конце страницы. Есть у всех конкурентов из ТОПа, и не зря:
   человек дочитал длинный текст, и гонять его обратно наверх за первой
   ссылкой — терять его на ровном месте. */
.lp-cta{margin-top:52px;padding:34px;border:1px solid rgba(245,85,85,.22);
  border-radius:18px;background:linear-gradient(180deg,rgba(245,85,85,.10),
  rgba(245,85,85,.02));text-align:center}
.lp-cta strong{display:block;margin-bottom:10px;
  font:700 24px/1.2 'Space Grotesk',sans-serif;letter-spacing:-.02em;color:#fff}
.legal-wrap.lp-wrap .lp-cta p{max-width:52ch;margin:0 auto 24px;
  color:rgba(255,255,255,.5)}

.lp-qa{margin-top:22px}

@media (max-width:899px){
  .lp-grid{grid-template-columns:1fr}
  .lp-assists{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:640px){
  .lp-h2{margin-top:40px;font-size:20px}
  .lp-assists{grid-template-columns:1fr}
  .lp-shot{flex-basis:104px;width:104px}
  .lp-copy{padding:14px 16px}
  .lp-steps li{padding:16px 16px 16px 50px}
}


/* ── Витрина сцен: вертикальная карточка и страницы ──────────────────────── */
.lp-wrap .scene-card{flex-direction:column;gap:12px;padding:12px}
.lp-wrap .scene-card-cover{flex:0 0 auto;width:100%;height:150px;border-radius:10px}
.lp-wrap .scene-card-text{gap:6px}
.lp-wrap .scene-card-text b{font-size:16px;line-height:1.25}

/* Номера страниц. Показываем все, пока их немного; середина сворачивается
   многоточием — полоска из сорока цифр не помогает выбрать, а мешает. */
.pager{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin:32px 0 8px}
.pager-i{display:grid;place-items:center;min-width:42px;height:42px;padding:0 12px;
  border:1px solid var(--border);border-radius:10px;background:var(--panel);
  color:rgba(255,255,255,.62);font-size:14px;font-weight:600;
  font-variant-numeric:tabular-nums;transition:border-color .2s,color .2s}
.pager-i:hover{border-color:rgba(245,85,85,.45);color:#fff}
.pager-i.is-now{border-color:transparent;background:var(--coral);color:#fff}
.pager-gap{display:grid;place-items:center;min-width:24px;height:42px;
  color:rgba(255,255,255,.3)}

@media (max-width:1100px){.scene-list{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:899px){.scene-list{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){
  .scene-list{grid-template-columns:1fr}
  .lp-wrap .scene-card-cover{height:170px}
}


/* ── Плитка тегов ────────────────────────────────────────────────────────
   По плейбуку это зона анкоров, а не перелинковка: она считается отдельно
   от текста, и у слабых сайтов там ноль. Один ряд и ниже содержания —
   чтобы не сдвигать список и не спорить с ним за внимание. */
.lp-tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:20px;padding-top:18px;
  border-top:1px solid var(--border)}
.lp-tag{padding:7px 13px;border:1px solid var(--border);border-radius:999px;
  background:rgba(255,255,255,.03);color:rgba(255,255,255,.44);font-size:12px;
  transition:color .2s,border-color .2s}
.lp-tag:hover{color:var(--coral);border-color:rgba(245,85,85,.35)}




/* ── Страница «не найдено» ────────────────────────────────────────────────
   Движение здесь своё, на голом CSS: [data-reveal] на сайте включает
   app.js через IntersectionObserver, а на служебных страницах его нет.
   Значения ровно те же, что у лендинга: сдвиг 22px, .62s, шаг 70ms. */
.e404{position:relative}
.e404 .e404-glow{position:absolute;border-radius:50%;filter:blur(2px);
  animation:float 10s ease-in-out infinite;pointer-events:none;z-index:0}
.e404 .g-blue{left:-6%;top:-190px;width:700px;height:700px;
  background:radial-gradient(circle,rgba(59,130,246,.15),transparent 70%)}
.e404 .g-violet{right:-4%;bottom:-320px;width:800px;height:800px;
  background:radial-gradient(circle,rgba(139,92,246,.15),transparent 70%);
  animation-delay:-5s}
.e404 .g-coral{left:38%;top:-40px;width:520px;height:520px;
  background:radial-gradient(circle,rgba(245,85,85,.10),transparent 70%);
  animation-delay:-2.5s}
.e404 > h1,.e404 > p,.e404 > ul,.e404 > div{position:relative;z-index:1}

@keyframes e404-in{from{opacity:0;transform:translateY(22px)}
  to{opacity:1;transform:none}}
.e404 .in{opacity:0;animation:e404-in .62s cubic-bezier(.22,.8,.28,1) forwards;
  animation-delay:calc(var(--i,0)*70ms)}

/* Цифры въезжают по одной и потом едва заметно дышат. */
@keyframes e404-digit{0%{opacity:0;transform:translateY(34px) scale(.92)}
  100%{opacity:1;transform:none}}
@keyframes e404-breathe{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
.e404 .code{display:block;margin-bottom:6px;
  font:700 clamp(96px,15vw,210px)/.82 'Space Grotesk',sans-serif;
  letter-spacing:-.075em}
.e404 .code i{display:inline-block;font-style:normal;opacity:0;
  animation:e404-digit .72s cubic-bezier(.22,.8,.28,1) forwards,
            e404-breathe 6s ease-in-out infinite;
  animation-delay:calc(var(--d)*110ms),calc(900ms + var(--d)*320ms)}
.e404 .code i.zero{color:var(--coral)}
.legal-wrap.e404 h1{max-width:760px}

.legal-wrap.e404 .lead{max-width:56ch;font-size:16px;line-height:1.7;
  color:rgba(255,255,255,.5)}
.legal-wrap.e404 .lead b{color:rgba(255,255,255,.78);font-weight:600}

.e404 .exits{margin:26px 0 34px;padding-left:0;list-style:none;display:grid;gap:10px;
  max-width:620px}
.e404 .exits li{position:relative;margin:0;padding-left:24px;
  color:rgba(255,255,255,.44);font-size:15px;line-height:1.6}
.e404 .exits li:before{content:"";position:absolute;left:2px;top:10px;
  width:7px;height:7px;border-radius:50%;background:var(--coral);
  animation:pulse 2s infinite;animation-delay:calc(var(--i,0)*260ms)}
.e404 .exits a{color:var(--coral);font-weight:600}

.e404 .actions{display:flex;flex-wrap:wrap;gap:20px;align-items:center}
.e404 .actions .button{width:auto}

/* Персонаж: карточка как в каталоге, реплика как в чате. */
.e404 .char{position:absolute;right:0;top:96px;width:330px;z-index:1}
.e404 .shot{position:relative;display:block;width:100%;aspect-ratio:4/5;
  overflow:hidden;border:1px solid var(--border);border-radius:12px}
.e404 .shot img{width:100%;height:100%;display:block;object-fit:cover}
.e404 .shot:after{content:"";position:absolute;inset:0;
  background:linear-gradient(to top,rgba(17,18,20,.9),transparent 65%)}
.e404 .who{position:absolute;left:16px;bottom:14px;z-index:1}
.e404 .who b{display:block;font:700 20px/1 'Space Grotesk',sans-serif;color:#fff}
.e404 .who span{display:block;margin-top:5px;color:var(--coral);font-size:10px;
  font-weight:700;letter-spacing:.15em;text-transform:uppercase}
.e404 .bubble{display:block;margin-top:14px;padding:16px;
  border:1px solid rgba(255,255,255,.1);border-radius:16px;
  background:linear-gradient(rgba(255,255,255,.04),rgba(255,255,255,.04)),
    rgba(46,48,56,.1);
  color:rgba(255,255,255,.8);font-size:13px;line-height:1.6}
.e404 .bubble em{color:rgba(255,255,255,.38);font-style:normal}
/* Три точки набора — как в чате, пока ответ ещё идёт. */
@keyframes e404-typing{0%,80%,100%{opacity:.2}40%{opacity:1}}
.e404 .typing{display:flex;gap:5px;margin-top:12px;justify-content:center}
.e404 .typing i{width:6px;height:6px;border-radius:50%;background:var(--coral);
  animation:e404-typing 1.4s infinite}
.e404 .typing i:nth-child(2){animation-delay:.2s}
.e404 .typing i:nth-child(3){animation-delay:.4s}

@media (max-width:899px){
  /* На телефоне сайт гасит боковые свечения — повторяем. */
  .e404 .g-blue,.e404 .g-violet{display:none}
  .e404 .g-coral{left:50%;top:-60px;width:100%;height:520px;
    transform:translateX(-50%);animation:none;
    background:radial-gradient(circle at center,rgba(255,75,75,.12),transparent 70%)}
  .e404 .char{position:static;width:auto;display:flex;gap:12px;
    align-items:flex-start;margin:0 0 24px}
  .e404 .shot{flex:0 0 84px;width:84px;aspect-ratio:4/5}
  .e404 .who{display:none}
  .e404 .bubble{margin-top:0}
  .e404 .bubble:before{content:"Зоро";display:block;margin-bottom:5px;
    color:var(--coral);font-size:10px;font-weight:700;letter-spacing:.15em;
    text-transform:uppercase}
  .e404 .typing{display:none}
  .e404 .actions{display:grid;gap:12px}
  .e404 .actions .button{width:100%}
}
@media (prefers-reduced-motion:reduce){
  .e404 .in,.e404 .code i{opacity:1;animation:none}
  .e404 .e404-glow,.e404 .typing i,.e404 .exits li:before{animation:none}
}

/* Плашка «добавить на экран» (PWA). Снизу, поверх всего, одна строка. */
.pwa-offer{position:fixed;left:12px;right:12px;bottom:12px;z-index:60;display:flex;align-items:center;gap:12px;
  padding:12px 14px;border:1px solid var(--border);border-radius:14px;background:var(--panel);
  box-shadow:0 10px 30px rgba(0,0,0,.45);font-size:13px}
.pwa-offer span{flex:1}
.pwa-offer-close{border:0;background:transparent;color:var(--muted);font-size:16px;cursor:pointer;padding:4px 6px}
@media (min-width:760px){.pwa-offer{left:auto;right:20px;bottom:20px;max-width:420px}}

/* ── первый экран: H1 → демо-чат → плакат ──────────────────────────────────
   Геройская секция разрезана надвое (см. комментарий в index.html). Отступы
   правим здесь, в конце файла, а НЕ внутри @media на 36–37 строках: те две
   строки длиной в экран, и правка вслепую там уже ломала вёрстку.
   Обе половины перечислены и в узких запросах — иначе плоское правило
   победило бы мобильный .hero по порядку следования. */
.hero-top{padding:96px 0 36px}
.hero-rest{padding:16px 0 128px}
/* H1 главной — белым и крупно, как плакат (решение владельца 30.08.2026):
   с переездом чата под заголовок маркер стал единственным крупным словом на
   первом экране, и серая капителька в 13 px там читалась как подпись.
   Правило привязано к .hero-top, чтобы не задеть .hero-marker в других
   местах. Размер чуть меньше плаката: фраза из трёх слов в 128 px не
   помещается в строку даже на широком экране. */
.hero-top .hero-marker{margin:0;font:700 clamp(40px,5.6vw,80px)/1 'Space Grotesk',sans-serif;
  letter-spacing:-.05em;text-transform:none;color:#fff}
.hero-sub{max-width:520px;margin:18px auto 0;color:rgba(255,255,255,.5);
  font-size:15px;line-height:1.5;font-weight:300}
@media (max-width:899px){
  /* На узком экране шапка fixed и лежит ПОВЕРХ потока (61 px): верхний
     отступ обязан быть больше её высоты, иначе H1 уходит под неё. */
  .hero-top{padding:98px 0 22px}
  .hero-rest{padding:8px 0 64px}
  .hero-top .hero-marker{font-size:clamp(34px,9.6vw,44px);letter-spacing:-.045em;line-height:1.02}
  .hero-sub{max-width:320px;margin-top:14px;font-size:14px}
}
@media (max-width:640px){
  .hero-top{padding:92px 0 18px}
  .hero-rest{padding:8px 0 72px}
}

/* ── демо-чат посадочных страниц ───────────────────────────────────────────
   Первый экран посадочной: работающий чат вместо кнопки «выбрать персонажа»
   (замер 29.08.2026, см. demo.js). Своя вёрстка, а не .chat-preview: тот
   блок — трёхколонное приложение, и на документной странице ему не на чем
   стоять. */
.demo{margin:0 0 42px}
.demo-card{border:1px solid rgba(255,255,255,.1);border-radius:16px;
  background:var(--panel);box-shadow:0 24px 80px rgba(0,0,0,.32);overflow:hidden}
.demo-head{display:flex;align-items:center;gap:12px;padding:14px 18px;
  border-bottom:1px solid var(--border)}
.demo-face{flex:0 0 44px;width:44px;height:44px;border-radius:50%;overflow:hidden;
  display:grid;place-items:center;background:rgba(245,85,85,.1);color:var(--coral)}
.demo-face img{width:100%;height:100%;object-fit:cover;display:block}
.demo-who{display:flex;flex-direction:column;gap:3px;min-width:0}
.demo-who b{font-size:14px}
.demo-who small{display:flex;align-items:center;gap:6px;color:rgba(255,255,255,.38);
  font-size:11px}
.demo-dot{width:6px;height:6px;border-radius:50%;background:#22c55e;flex:0 0 6px}
.demo-other{margin-left:auto;flex:0 0 auto;color:var(--coral);font-size:11px;
  font-weight:700;letter-spacing:.1em;text-transform:uppercase}
.demo-log{display:flex;flex-direction:column;gap:14px;padding:20px;
  min-height:190px;max-height:420px;overflow-y:auto}
.demo-row{display:flex;max-width:88%}
.demo-row.me{align-self:flex-end;justify-content:flex-end}
.demo-row p{margin:0;padding:13px 16px;border:1px solid rgba(255,255,255,.1);
  border-radius:16px;background:rgba(255,255,255,.04);color:rgba(255,255,255,.82);
  font-size:14px;line-height:1.6}
.demo-row.me p{border-color:rgba(245,85,85,.24);background:rgba(245,85,85,.12);color:#fff}
.demo-row em{color:rgba(255,255,255,.4);font-style:italic}
.demo-sys{max-width:100%;align-self:center}
.demo-sys p{border:0;background:transparent;padding:2px 0;color:rgba(255,255,255,.34);
  font-size:12px}
.demo-link{color:var(--coral);font-weight:700;text-decoration:underline}
.demo-form{display:flex;align-items:flex-end;gap:10px;padding:14px 18px;
  border-top:1px solid var(--border)}
.demo-form textarea{flex:1;min-width:0;resize:none;overflow-y:hidden;
  border:1px solid var(--border);border-radius:10px;background:var(--panel-deep);
  padding:13px 15px;color:#fff;font:inherit;font-size:14px;line-height:1.45;outline:0}
.demo-form textarea::placeholder{color:rgba(255,255,255,.24)}
.demo-send{flex:0 0 44px;width:44px;height:44px;display:grid;place-items:center;
  border:0;border-radius:10px;background:var(--coral);color:#fff;font-size:19px;
  cursor:pointer;box-shadow:0 8px 24px rgba(245,85,85,.22)}
.demo-send:disabled{opacity:.45;cursor:default;box-shadow:none}
.demo-note{margin:0;padding:0 18px 16px;color:rgba(255,255,255,.34);
  font-size:12px;line-height:1.55}

/* Знакомство. Открывается ПОСЛЕ первой набранной реплики (см. demo.js): до
   неё человек не должен видеть ни одной анкеты. */
.demo-gate{margin-top:14px;padding:18px;border:1px solid rgba(245,85,85,.28);
  border-radius:14px;background:rgba(245,85,85,.06)}
.demo-gate-lead{margin:0 0 14px;font-size:15px;font-weight:600}
.demo-choice{display:flex;gap:10px;margin-bottom:14px}
.demo-choice button{flex:1;min-height:44px;border:1px solid var(--border);
  border-radius:10px;background:rgba(255,255,255,.04);color:rgba(255,255,255,.7);
  font-size:14px;cursor:pointer;transition:.2s}
.demo-choice button.on{border-color:var(--coral);background:rgba(245,85,85,.16);color:#fff}
.demo-age{display:flex;align-items:center;gap:10px;margin-bottom:16px;
  font-size:14px;color:rgba(255,255,255,.72);cursor:pointer}
.demo-age input{width:18px;height:18px;accent-color:var(--coral);cursor:pointer}
.demo-gate .button{width:100%}
.demo-fine{margin:12px 0 0;color:rgba(255,255,255,.32);font-size:11px;line-height:1.5}
@media (max-width:640px){
  .demo-log{padding:16px;min-height:150px;max-height:300px}
  .demo-form{padding:12px 14px}
  .demo-note{padding:0 14px 14px}
  .demo-other{display:none}
  .demo-row{max-width:94%}
}

/* ── стена бесплатных сообщений ────────────────────────────────────────────
   Одно предложение и одна кнопка (см. openCapWall в app.js). Карточка
   намеренно узкая: всё, что не цена и не кнопка, здесь мешает. */
.capwall-card{max-width:440px}
.capwall-lead{margin:0 0 20px;color:rgba(255,255,255,.62);font-size:14px;line-height:1.6}
.capwall-offer{padding:20px;margin-bottom:20px;border:1px solid rgba(245,85,85,.3);
  border-radius:14px;background:rgba(245,85,85,.07)}
.capwall-price{display:flex;align-items:baseline;gap:10px;margin-bottom:16px}
.capwall-price b{font:700 34px/1 'Space Grotesk',sans-serif;color:#fff}
.capwall-price span{color:rgba(255,255,255,.5);font-size:13px}
.capwall-perks{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:9px}
.capwall-perks li{position:relative;padding-left:22px;color:rgba(255,255,255,.6);
  font-size:13px;line-height:1.45}
.capwall-perks li:before{content:"";position:absolute;left:4px;top:7px;width:6px;height:6px;
  border-radius:50%;background:var(--coral)}
.capwall-perks b{color:#fff;font-weight:600}
.capwall-go{width:100%}
.capwall-fine{margin:14px 0 0;color:rgba(255,255,255,.32);font-size:11px;line-height:1.5}
/* Лицо героя над заголовком и движение окна (31.08.2026). Окно прячется через
   display:none, поэтому анимации перезапускаются при каждом открытии сами. */
/* Размер и скругление — те же, что у аватарки в кабинете (.cab-face в
   cabinet.html, 168 px и 22 px): решение владельца 31.08.2026. Нарисованный
   портрет должен впечатлять, а в кружке 76 px он не читался. */
/* Реплика прижата к низу портрета, а не по центру: сверху справа висит
   крестик окна, и по центру пузырь заезжал под него. Заодно это привычная
   раскладка мессенджера — лицо, а слова у его нижнего края. */
.capwall-hero{display:flex;align-items:flex-end;gap:14px;margin:0 0 18px;padding-right:44px}
.capwall-hero.is-hidden{display:none}
.capwall-face{position:relative;width:168px;height:168px;flex:0 0 168px;border-radius:22px}
.capwall-face img,.capwall-face .letter{width:100%;height:100%;border-radius:22px;object-fit:cover;
  display:grid;place-items:center;box-sizing:border-box;border:1px solid var(--border);
  background:var(--panel-deep);box-shadow:0 18px 50px -20px rgba(0,0,0,.7)}
.capwall-face .letter{font:700 54px/1 'Space Grotesk',sans-serif;color:rgba(255,255,255,.75);
  background:linear-gradient(150deg,rgba(245,85,85,.25),rgba(96,165,250,.18))}
/* Реплика героя. Срезанный угол смотрит на портрет — так пузырь читается как
   его слова, а не как наша плашка; хвостик-треугольник тут не нужен. */
.capwall-say{position:relative;margin:0;padding:14px 16px;border:1px solid rgba(255,255,255,.1);
  border-radius:5px 16px 16px 16px;background:rgba(255,255,255,.05);
  color:rgba(255,255,255,.86);font-size:14px;line-height:1.55}
/* На телефоне окно и без того длинное: портрет ужимаем, пропорции те же. */
@media (max-width:640px){.capwall-hero{gap:12px;padding-right:40px}
  .capwall-face{width:112px;height:112px;flex-basis:112px}
  .capwall-face .letter{font-size:40px}
  .capwall-say{padding:12px 14px;font-size:13.5px}}
/* Низкий экран (ноутбук 768 px): портрет в полный рост уводил кнопку под срез,
   а окно с прокруткой к оплате не подталкивает. Меряем высоту, не ширину. */
@media (max-height:860px) and (min-width:641px){
  .capwall-card{padding:24px}
  .capwall-hero{margin-bottom:14px}
  .capwall-face{width:132px;height:132px;flex-basis:132px}
  .capwall-face .letter{font-size:44px}}
.capwall-once{margin:-8px 0 14px;color:#f3dfb6;font-size:12.5px;line-height:1.5}
.modal.open .capwall-card{animation:capwall-in .34s cubic-bezier(.2,.9,.3,1.15)}
@keyframes capwall-in{from{transform:translateY(16px) scale(.96);opacity:0}
  to{transform:none;opacity:1}}
.modal.open .capwall-price{animation:capwall-pop .45s cubic-bezier(.2,.9,.3,1.3) .08s backwards}
@keyframes capwall-pop{from{transform:scale(.82);opacity:0}to{transform:none;opacity:1}}
/* Пузырь приезжает от портрета и потом тихо «дышит» светом: это единственное
   место окна, которое продолжает жить после появления, — взгляд возвращается
   к реплике, а не к кнопке. Свечение слабое: окно и так просит денег. */
.modal.open .capwall-say{animation:capwall-say .42s ease .14s backwards,
  capwall-glow 3.4s ease-in-out 1s infinite}
@keyframes capwall-say{from{transform:translateX(-10px);opacity:0}to{transform:none;opacity:1}}
@keyframes capwall-glow{0%,100%{box-shadow:0 0 0 0 rgba(245,85,85,0);
    border-color:rgba(255,255,255,.1)}
  50%{box-shadow:0 0 20px -6px rgba(245,85,85,.45);border-color:rgba(245,85,85,.34)}}
.modal.open .capwall-perks li{opacity:0;animation:capwall-li .38s ease forwards}
.modal.open .capwall-perks li:nth-child(1){animation-delay:.14s}
.modal.open .capwall-perks li:nth-child(2){animation-delay:.2s}
.modal.open .capwall-perks li:nth-child(3){animation-delay:.26s}
.modal.open .capwall-perks li:nth-child(4){animation-delay:.32s}
.modal.open .capwall-perks li:nth-child(5){animation-delay:.38s}
@keyframes capwall-li{from{transform:translateY(7px);opacity:0}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){
  .modal.open .capwall-card,.modal.open .capwall-price,.modal.open .capwall-say{animation:none}
  .modal.open .capwall-perks li{animation:none;opacity:1}}

/* ── кнопка «попросить снимок» ─────────────────────────────────────────────
   Верхняя в столбике у реплики, над динамиком. Правила видимости те же, что
   у динамика и смайлика: проступает на наведение, на касании видна всегда и
   тише. Отличие одно — коралловый цвет: это не служебное действие вроде
   озвучки, а то, ради чего в чат и приходят (замер по первой оплате
   28.08.2026 — заплатили за фото и голос, а не упёршись в счётчик реплик). */
.photo-btn{width:26px;height:26px;
  display:grid;place-items:center;padding:0;border:1px solid rgba(245,85,85,.32);
  border-radius:50%;background:var(--panel-deep);color:var(--coral);
  line-height:1;cursor:pointer;opacity:0;transition:opacity .15s,transform .15s}
.message-row.received:hover .photo-btn,
.message-row.received:focus-within .photo-btn{opacity:.85}
.photo-btn:hover{opacity:1;transform:scale(1.12)}
/* Недоступно — блёкло и без цвета, но кнопка ЖИВАЯ: нажатие объясняет, чего
   не хватает, и ведёт куда надо (аккаунт, монеты). Мёртвая кнопка на этом
   месте оставила бы человека с вопросом без ответа. */
.photo-btn.is-off{border-color:var(--border);color:rgba(255,255,255,.28);
  background:transparent;cursor:help}
.photo-btn.is-off:hover{opacity:.6;transform:none}
.message-row.received:hover .photo-btn.is-off,
.message-row.received:focus-within .photo-btn.is-off{opacity:.5}
@media (hover:none){
  .message-row.received .photo-btn{opacity:.55}
  .message-row.received .photo-btn.is-off{opacity:.3}
}

/* ── поиск персонажа на посадочной ─────────────────────────────────────────
   Стоит перед сеткой героев. Поле крупное намеренно: на странице оно —
   второе по важности действие после демо-чата, а мелкий инпут рядом с
   картинками карточек просто не замечают. */
.chfind{margin:0 0 26px}
.chfind-box{position:relative;display:flex;align-items:center;
  width:min(560px,100%);border:1px solid rgba(255,255,255,.14);border-radius:14px;
  background:var(--panel-deep);transition:border-color .18s,box-shadow .18s}
.chfind-box:focus-within{border-color:rgba(245,85,85,.55);
  box-shadow:0 0 0 4px rgba(245,85,85,.1)}
.chfind-ico{flex:0 0 auto;margin-left:16px;color:rgba(255,255,255,.4)}
.chfind-box:focus-within .chfind-ico{color:var(--coral)}
.chfind input{flex:1;min-width:0;border:0;outline:0;background:transparent;
  padding:15px 12px;color:#fff;font:inherit;font-size:15px}
.chfind input::placeholder{color:rgba(255,255,255,.32)}
.chfind input::-webkit-search-cancel-button{display:none}
.chfind-clear{display:none;place-items:center;width:30px;height:30px;
  margin-right:10px;padding:0;border:0;border-radius:50%;background:transparent;
  color:rgba(255,255,255,.45);font-size:17px;line-height:1;cursor:pointer;
  transition:background .15s,color .15s}
.chfind-clear.is-on{display:grid}
.chfind-clear:hover{background:rgba(255,255,255,.08);color:#fff}
.chfind-hint{margin:10px 2px 0;color:rgba(255,255,255,.34);font-size:12px}
/* Пока идёт поиск, подсказка уступает место найденному: она объясняет, зачем
   поле, и после первого запроса только занимает строку. */
.chfind.is-on .chfind-hint{display:none}
/* ⚠️ Атрибут hidden ПРОИГРЫВАЕТ правилу .lp-grid{display:grid}: у браузерного
   display:none специфичность ниже классовой. Без этой строки при поиске
   видны обе сетки — своя и найденная (поймано прогоном 30.08.2026). */
.lp-grid[hidden],.chfind-out[hidden],.chfind-none[hidden]{display:none}
.chfind-out{margin-top:18px}
.chfind-none{margin:16px 2px 0;color:rgba(255,255,255,.45);font-size:14px}

/* ── поиск на витрине главной ──────────────────────────────────────────────
   Поле стоит НАД вкладками разделов и выглядит так же, как на посадочных
   (.chfind-box): приём один на весь сайт, и человек, пришедший с посадочной,
   не должен искать его заново другим взглядом. */
.cat-find{margin:0 0 22px}
.cat-find:empty{display:none}
.cat-find .cat-search-box{position:relative;display:flex;align-items:center;
  width:min(560px,100%);border:1px solid rgba(255,255,255,.14);border-radius:14px;
  background:var(--panel-deep);transition:border-color .18s,box-shadow .18s}
.cat-find .cat-search-box:focus-within{border-color:rgba(245,85,85,.55);
  box-shadow:0 0 0 4px rgba(245,85,85,.1)}
.cat-search-ico{flex:0 0 auto;margin-left:16px;color:rgba(255,255,255,.4)}
.cat-find .cat-search-box:focus-within .cat-search-ico{color:var(--coral)}
.cat-find .cat-search{flex:1;min-width:0;width:auto;border:0;border-radius:0;
  background:transparent;padding:15px 12px;font-size:15px}
.cat-find .cat-search:focus{border-color:transparent}
.cat-find .cat-search-clear{position:static;transform:none;
  width:30px;height:30px;margin-right:10px}
.cat-find-hint{margin:10px 2px 0;color:rgba(255,255,255,.34);font-size:12px}
@media (max-width:640px){
  .cat-find{margin-bottom:18px}
  .cat-find .cat-search{padding:13px 10px;font-size:14px}
}

/* ── причина открытия окна входа ──────────────────────────────────────────
   Коралловая плашка над кнопками сервисов: окно чаще открывается по отказу
   (фото, голос гостю), и человек должен видеть, зачем его позвали. */
.auth-reason{margin:0 0 18px;padding:12px 14px;border:1px solid rgba(245,85,85,.3);
  border-radius:12px;background:rgba(245,85,85,.08);color:rgba(255,255,255,.85);
  font-size:13.5px;line-height:1.5}

/* ── галочки согласий: пульс, когда нажали сервис без них ──────────────────
   Два мигания и стоп: постоянное мигание раздражает, одного не замечают. */
.consent.is-nudge{animation:consent-nudge 1.4s ease-out 2;border-radius:10px}
.consent.is-nudge input{outline:2px solid var(--coral);outline-offset:2px;border-radius:4px}
@keyframes consent-nudge{
  0%{box-shadow:0 0 0 0 rgba(245,85,85,.55);background:rgba(245,85,85,.14)}
  60%{box-shadow:0 0 0 10px rgba(245,85,85,0);background:rgba(245,85,85,.06)}
  100%{box-shadow:0 0 0 0 rgba(245,85,85,0);background:transparent}
}
@media (prefers-reduced-motion:reduce){
  .consent.is-nudge{animation:none;background:rgba(245,85,85,.12)}
}

/* ── тарифы: бесплатный — полосой, платные — одним рядом ───────────────────
   На широком экране ровно пять колонок под пять платных карточек (проба и
   четыре срока): auto-fit на 1200 px давал пять в первом ряду и годовой
   одиноко во втором. */
@media (min-width:1000px){.pricing-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}
@media (min-width:641px) and (max-width:999px){.pricing-grid{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}}
.price-free{grid-column:1/-1;flex-direction:row;align-items:center;gap:28px;flex-wrap:wrap;
  padding:22px 26px;background:linear-gradient(90deg,rgba(245,85,85,.07),transparent 60%),var(--panel)}
.price-free-head{flex:0 0 auto;min-width:200px;max-width:320px}
.price-free-head h3{margin-bottom:6px}
.price-free-head .price-note{margin-bottom:0}
.price-free ul{flex:1;display:flex;flex-wrap:wrap;gap:12px 14px;margin:0;padding:0;list-style:none}
.price-free li{display:flex;align-items:center;gap:9px;padding:9px 14px;border:1px solid rgba(255,255,255,.08);
  border-radius:10px;background:rgba(255,255,255,.03);color:rgba(255,255,255,.62);font-size:12.5px;line-height:1.3}
.price-free li b{font:700 18px/1 'Space Grotesk',sans-serif;color:#fff}
@media (max-width:640px){
  .price-free{flex-direction:column;align-items:stretch;gap:16px}
  .price-free-head{max-width:none}
  .price-free ul{gap:8px}
  .price-free li{padding:8px 12px}
}

/* Снимок механики на посадочной: одна картинка, подпись под ней. */
.lp-figure{margin:22px 0 28px}
.lp-figure img,.lp-figure video{display:block;width:min(560px,100%);height:auto;border:1px solid rgba(255,255,255,.1);
  border-radius:14px;box-shadow:0 20px 60px -24px rgba(0,0,0,.7)}
.lp-figure figcaption{margin:10px 2px 0;max-width:560px;color:rgba(255,255,255,.45);font-size:12.5px;line-height:1.5}
/* Текстовый раздел главной «Переписка с ботом» (хвост кластера, 30.08.2026). */
.home-text-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 28px}
.home-text-grid article{padding:22px 24px;border:1px solid rgba(255,255,255,.08);border-radius:16px;background:rgba(255,255,255,.02)}
.home-text-grid h3{margin:0 0 10px;font:600 17px/1.3 'Space Grotesk',sans-serif;color:#fff}
.home-text-grid p{margin:0;color:rgba(255,255,255,.62);font-size:15px;line-height:1.6}
@media (max-width:760px){.home-text-grid{grid-template-columns:1fr}}
/* Два снимка рядом, одного размера: картинки одной пропорции, колонки равные. */
.lp-figures{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;margin:8px 0 34px}
.lp-figures .lp-figure{margin:0}
.lp-figures .lp-figure img,.lp-figures .lp-figure video{width:100%;background:#111214}
.lp-figures .lp-figure figcaption{max-width:none}
.lp-figures-go{text-align:center;margin:-12px 0 40px}
.lp-figures-go .button{padding:14px 30px;font-size:16px}
@media (max-width:640px){.lp-figures{grid-template-columns:1fr}}

/* ── Тарифная сетка посадочных (landing._тарифы) ──────────────────────────
   Числа в разметку приезжают из config, вид — три карточки и полоса монет.
   PRO подсвечен рамкой как основной путь. */
.lp-price-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:14px;margin:22px 0 0}
.lp-price{padding:20px;border:1px solid rgba(255,255,255,.07);
  border-radius:14px;background:var(--panel)}
.lp-price.is-main{border-color:rgba(245,85,85,.34)}
.lp-price h3{margin:0;font:700 16px/1.3 'Space Grotesk',sans-serif;color:#fff}
.lp-price-sum{display:block;margin:6px 0 14px;
  font:700 22px/1.2 'Space Grotesk',sans-serif;color:var(--coral)}
.legal-wrap.lp-wrap .lp-price ul{margin:0;padding:0;list-style:none;
  display:grid;gap:9px}
.lp-price li{position:relative;padding-left:18px;
  color:rgba(255,255,255,.5);font-size:13.5px;line-height:1.55}
.lp-price li:before{content:"";position:absolute;left:0;top:9px;
  width:6px;height:6px;border-radius:50%;background:var(--coral)}
.lp-price li b{color:#fff;font-weight:600}
.lp-coins{margin-top:14px;padding:18px 20px;border:1px solid rgba(255,255,255,.07);
  border-radius:14px;background:var(--panel);
  color:rgba(255,255,255,.5);font-size:13.5px;line-height:1.6}
.lp-coins b{color:#fff}
.lp-coins-row{display:flex;flex-wrap:wrap;gap:10px;margin:12px 0}
.lp-coins-row span{padding:8px 14px;border:1px solid var(--border);
  border-radius:999px;background:rgba(255,255,255,.04);
  color:rgba(255,255,255,.72);font-size:13px;white-space:nowrap}
.lp-coins-row s{color:rgba(255,255,255,.3);margin-left:6px}
.legal-wrap.lp-wrap .lp-coins p{margin:0}
@media (max-width:899px){.lp-price-grid{grid-template-columns:1fr}}

/* Плашка взрослого раздела над лентой чата. Разговор там отдельный, и это
   должно быть видно: без неё он ничем не отличается от обычного, и человек,
   пришедший со страницы /dark, не понимает, куда попал. */
.dark-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:10px 20px;border-bottom:1px solid var(--border);
  background:rgba(245,85,85,.06);color:rgba(255,255,255,.62);font-size:12px}
.dark-bar b{padding:2px 7px;border-radius:5px;background:var(--coral);
  color:#fff;font-size:10px;font-weight:700;letter-spacing:.08em}
.dark-bar a{color:var(--coral);font-weight:600}

/* Значок взрослого раздела на лице в списке диалогов. Ставится в НИЖНИЙ
   правый угол: верхний уже занят меткой настройки (.tuned), и два значка
   в одном углу налезали бы друг на друга. */
.recent-item .pic-18{position:absolute;right:-3px;bottom:-3px;z-index:2;
  padding:1px 4px;border:2px solid var(--panel);border-radius:6px;
  background:var(--coral);color:#fff;font:700 8px/1.35 Inter,sans-serif;
  font-style:normal;letter-spacing:.02em}

/* Пояснение правил раздела — только в начале разговора. Тон намеренно
   спокойный: человек читает его до первого отказа, и оно должно объяснить
   характер, а не пообещать награду. */
.dark-note{margin:14px 20px 4px;padding:13px 16px;border-radius:12px;
  border:1px solid var(--border);background:rgba(255,255,255,.03);
  color:rgba(255,255,255,.5);font-size:12.5px;line-height:1.65}
.dark-note b{display:block;margin-bottom:4px;color:rgba(255,255,255,.78);
  font-weight:600}

/* Абзац про срок хранения в плашке раздела. Отделён линией, а не отступом:
   это другая тема — не про манеру разговора, а про данные человека, — и
   визуально она должна читаться отдельно, иначе сливается с советом. */
.dark-note-keep{
  margin:12px 0 0;
  padding-top:12px;
  border-top:1px solid var(--line, rgba(255,255,255,.10));
}

/* Ворота подписки на странице раздела. Возраст человек уже подтвердил —
   форму ему показывать незачем, поэтому здесь только объяснение и дверь
   в тариф. Кнопка тем же коралловым, что и остальные наши призывы: раздел
   не должен выглядеть отдельной платной пристройкой. */
.dk-pro{ margin:0 0 14px; color:var(--muted, #8a8a92); }
.dk-pro-btn{
  display:inline-block; padding:12px 26px; border-radius:10px;
  background:var(--coral, #ff4b4b); color:#fff; font-weight:700;
  text-decoration:none;
}
.dk-pro-btn:hover{ filter:brightness(1.06); }

/* Поиск по разделу. Крест внутри поля, а не рядом: снаружи он съедает
   ширину на телефоне, где строка и так впритык. */
.dk-search{ position:relative; margin:0 0 18px; }
.dk-search input{
  width:100%; padding:13px 42px 13px 16px; border-radius:12px;
  border:1px solid var(--line, rgba(255,255,255,.10));
  background:var(--card, #16161b); color:inherit; font-size:15px;
}
.dk-search input:focus{ outline:none; border-color:var(--coral, #ff4b4b); }
.dk-search-clear{
  position:absolute; right:8px; top:50%; transform:translateY(-50%);
  width:30px; height:30px; border:0; border-radius:8px; cursor:pointer;
  background:transparent; color:var(--muted, #8a8a92); font-size:14px;
}
.dk-search-clear:hover{ color:inherit; }

/* Первый абзац плашки. Отступы нулевые: он и был текстом самой плашки,
   и обёртка в абзац не должна ничего сдвинуть. */
.dark-note-main{ margin:0; }

/* Кнопка «свернуть» у плашки раздела. Мелким и приглушённым: это служебное
   действие, а не призыв — оно не должно спорить с самим текстом правил. */
.dark-note-toggle{
  display:block; margin:10px 0 0; padding:0; border:0; background:none;
  color:var(--muted, #8a8a92); font-size:12px; cursor:pointer;
  text-decoration:underline; text-underline-offset:3px;
}
.dark-note-toggle:hover{ color:inherit; }

/* Свёрнутая плашка: прячем текст, оставляем только кнопку возврата.
   Скрываем именно абзацы, а не всю плашку, — иначе исчезнет и кнопка,
   и человек не сможет вернуть правила. */
.dark-note.is-folded > .dark-note-main,
.dark-note.is-folded > p,
.dark-note.is-folded > .dark-note-keep{ display:none; }
.dark-note.is-folded{ padding-top:4px; padding-bottom:4px; }
