/* /ouvi/ — генератор карточки строки (14.10.2026). Токены и вид — как у открытых страниц песен
   (lib/seo/render.js, CSS): тёмная тема продукта, сирень #C79EE8, золото у главной кнопки, слои строки цветом
   (хангыль — сирень, звучание — роза, смысл — мята). Телефон 400 px — главный экран.

   ШРИФТЫ. Латиница — свой файл Pretendard (как на главной: /fonts/pretendard-lat-cyr.woff2), хангыль —
   Pretendard с jsDelivr (таблицу подключает ouvi.js, без блокировки отрисовки), тайский — свой Noto Sans Thai,
   традиционные иероглифы — /fonts/noto-sans-tc.css (тоже ouvi.js, только для zh-hant). Те же имена берёт
   холст карточки — поэтому они объявлены здесь, а не только в стеке. */
@font-face{font-family:"Ouvi Pretendard";font-style:normal;font-weight:100 900;font-display:swap;
  src:url("/fonts/pretendard-lat-cyr.woff2") format("woff2");
  unicode-range:U+0000-024F,U+0400-04FF,U+2000-206F,U+2190-21FF,U+2600-26FF}
@font-face{font-family:"Noto Sans Thai";font-style:normal;font-weight:100 900;font-display:swap;
  src:url("/fonts/noto-sans-thai-var.woff2") format("woff2-variations");
  unicode-range:U+02D7,U+0303,U+0331,U+0E01-0E5B,U+200C-200D,U+25CC}

:root{color-scheme:dark;--bg:#120D1B;--panel:#1B1427;--panel2:#231A32;--line:rgba(199,158,232,.18);--line2:rgba(199,158,232,.32);
--ink:#F6F1FA;--mut:#D3C6E2;--dim:#A99BC2;--brand:#C79EE8;--gold:linear-gradient(135deg,#FBE6D2,#EDC7A2 46%,#DFA97F);--gold-ink:#2A1520;
--ko:#C79EE8;--snd:#FF93C4;--mean:#6EE7B0;--err:#FF9DB0;--r:16px;--r-sm:12px;--ease:cubic-bezier(.16,1,.3,1);
--f:"Ouvi Pretendard",system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans Thai","Noto Sans TC","Noto Sans CJK JP",sans-serif;
--f-ko:"Pretendard Variable","Apple SD Gothic Neo","Noto Sans KR","Malgun Gothic",sans-serif}
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--ink);font:400 17px/1.55 var(--f);overflow-wrap:anywhere;
  background-image:radial-gradient(900px 520px at 12% -8%,rgba(199,158,232,.13),transparent 60%)}
html:lang(ja) body{font-family:"Ouvi Pretendard","Hiragino Sans","Hiragino Kaku Gothic ProN","Noto Sans JP","Yu Gothic UI",Meiryo,sans-serif}
html:lang(th) body{font-family:"Ouvi Pretendard","Noto Sans Thai","Leelawadee UI",Thonburi,Tahoma,sans-serif;line-height:1.7}
html:lang(zh-Hant) body{font-family:"Ouvi Pretendard","Noto Sans TC","PingFang TC","Microsoft JhengHei",sans-serif}
html:lang(zh-Hans) body{font-family:"Ouvi Pretendard","Noto Sans SC","PingFang SC","Microsoft YaHei",sans-serif}
html:lang(ko) body{font-family:"Ouvi Pretendard","Pretendard Variable","Apple SD Gothic Neo","Noto Sans KR","Malgun Gothic",sans-serif}
/* Название языка в списке — своим письмом при любом языке страницы (14.10: у ko и zh «ไทย» выходил квадратиками —
   в их наборах шрифтов не было тайского, а системного тайского у части устройств нет). */
[lang=th]{font-family:"Ouvi Pretendard","Noto Sans Thai","Leelawadee UI",Thonburi,Tahoma,sans-serif}
[lang=ko]{font-family:var(--f-ko)}
a{color:var(--brand)}a:hover{color:#E4CDF5}
:focus-visible{outline:2px solid var(--brand);outline-offset:3px;border-radius:8px}
.wrap{max-width:1120px;margin:0 auto;padding:0 16px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip{position:absolute;left:-9999px;top:8px;z-index:10;padding:10px 14px;border-radius:10px;background:var(--panel2);color:var(--ink)}
.skip:focus{left:8px}

/* Пока ouvi.js не подставил язык человека, подписи скрыты (иначе мигает португальский у японца).
   Не загрузился скрипт — через 1,5 с всё равно показываем: страница без JS не должна остаться пустой. */
body[data-ready="0"] [data-t]{visibility:hidden;animation:ov-show 0s 1.5s forwards}
@keyframes ov-show{to{visibility:visible}}

.top{position:sticky;top:0;z-index:5;background:rgba(18,13,27,.9);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
.top .wrap{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:56px}
.brand{font-weight:800;font-size:20px;letter-spacing:-.01em;text-decoration:none;color:var(--brand);white-space:nowrap}
.brand b{color:#EDC7A2;font-weight:900}
.brand i{font-style:normal;color:#fff}
.top nav a{display:inline-flex;align-items:center;min-height:44px;padding:0 12px;border-radius:999px;text-decoration:none;color:var(--mut);font-size:15px;white-space:nowrap}
.top nav a:hover{color:var(--ink);background:var(--panel)}
.top nav a.app-btn{color:#EDC7A2;border:1.5px solid currentColor;min-height:40px;font-weight:600}
.top nav a.app-btn:hover{color:var(--ink);border-color:var(--ink);background:transparent}
.top nav a.app-btn:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.top-r{display:flex;align-items:center;gap:4px;min-width:0}

/* Язык — вверху справа (14.10). Кнопка: флаг + «Português» + стрелка — читается как «тут язык» без подписи.
   Список — ссылки ?lang=… с флагами (href ставит ouvi.js: сохраняет line и mode). Выпадает плавно: opacity +
   сдвиг 180 мс ease-out туда и обратно (класс .on, не hidden — иначе закрытие без анимации); закрытый список
   visibility:hidden — вне фокуса и вне дерева доступности. reduced-motion — сразу (общее правило внизу). */
.lang{position:relative}
.lang-btn{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:0 12px 0 11px;border-radius:999px;border:1px solid var(--line2);
  background:var(--panel);color:var(--ink);font:600 15px/1 var(--f);cursor:pointer;white-space:nowrap;
  transition:border-color .15s var(--ease),background .15s var(--ease)}
.lang-btn:hover,.lang-btn[aria-expanded=true]{border-color:var(--brand);background:var(--panel2)}
.lang-btn svg{flex:none;width:18px;height:18px;color:var(--brand)}
.flag{flex:none;display:block;width:22px;height:15px;border-radius:3px;box-shadow:0 0 0 1px rgba(255,255,255,.16);object-fit:cover}
.lang-btn .ic-chev{width:14px;height:14px;color:var(--dim);transition:transform .3s cubic-bezier(.22,1,.36,1)}
.lang-btn[aria-expanded=true] .ic-chev{transform:rotate(180deg)}
/* Выезд списка (третий круг: «плавно, а не резко»): шторка сверху вниз — clip-path открывает панель за 320 мс
   (поля −40 px, чтобы тень не срезалась), плюс прозрачность и сдвиг на 10 px; пункты догоняют лесенкой по 22 мс.
   Закрытие быстрее — 200 мс, без лесенки. visibility выключается в конце закрытия: закрытый список вне фокуса. */
.lang-pop{position:absolute;right:0;top:calc(100% + 8px);z-index:20;min-width:220px;max-height:calc(100vh - 80px);overflow:auto;
  padding:6px;border-radius:var(--r);background:var(--panel2);border:1px solid var(--line2);
  box-shadow:0 22px 48px -14px rgba(0,0,0,.8),0 2px 8px rgba(0,0,0,.4);
  opacity:0;transform:translateY(-10px);visibility:hidden;clip-path:inset(-40px -40px 100% -40px);
  transition:opacity .2s ease-in,transform .2s ease-in,clip-path .2s ease-in,visibility 0s linear .2s}
.lang-pop.on{opacity:1;transform:none;visibility:visible;clip-path:inset(-40px -40px -60px -40px);
  transition:opacity .24s ease-out,transform .32s cubic-bezier(.22,1,.36,1),clip-path .32s cubic-bezier(.22,1,.36,1),visibility 0s}
.lang-pop li,.lang-pop .lang-h{opacity:0;transform:translateY(-6px);transition:opacity .12s ease-in,transform .12s ease-in}
.lang-pop.on li,.lang-pop.on .lang-h{opacity:1;transform:none;transition:opacity .26s ease-out,transform .32s cubic-bezier(.22,1,.36,1)}
.lang-pop.on .lang-h{transition-delay:30ms}
.lang-pop.on li:nth-child(1){transition-delay:50ms}.lang-pop.on li:nth-child(2){transition-delay:72ms}
.lang-pop.on li:nth-child(3){transition-delay:94ms}.lang-pop.on li:nth-child(4){transition-delay:116ms}
.lang-pop.on li:nth-child(5){transition-delay:138ms}.lang-pop.on li:nth-child(6){transition-delay:160ms}
.lang-pop.on li:nth-child(7){transition-delay:182ms}.lang-pop.on li:nth-child(8){transition-delay:204ms}
.lang-pop.on li:nth-child(9){transition-delay:226ms}
.lang-h{margin:6px 12px 4px;color:var(--dim);font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.lang-pop ul{list-style:none;margin:0;padding:0}
.lang-pop a{display:flex;align-items:center;gap:12px;min-height:48px;padding:0 14px 0 12px;border-radius:10px;
  color:var(--mut);text-decoration:none;font-size:16px;font-weight:500}
.lang-pop a span{flex:1}
.lang-pop a:hover,.lang-pop a:focus-visible{background:rgba(199,158,232,.12);color:var(--ink)}
.lang-pop a:focus-visible{outline-offset:-2px}
.lang-pop a[aria-current]{color:var(--ink);font-weight:700}
.lang-pop a[aria-current]::after{content:"";flex:none;width:16px;height:16px;background:var(--brand);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5l3.2 3.2L13 4.8' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5l3.2 3.2L13 4.8' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat}
/* Узкий телефон (360–389): знак, «Músicas» и «Português» с глобусом не влезают в 328 px — ужимаем отступы. */
@media (max-width:389px){
  .top .wrap{gap:6px}
  .brand{font-size:18px}
  .top nav a{padding:0 8px;font-size:14px}
  .lang-btn{padding:0 9px;gap:5px;font-size:14px}
  .lang-btn .flag{width:20px;height:14px}
}

.ov-hero{padding:18px 0 0}
h1{font-size:clamp(28px,7.6vw,46px);line-height:1.1;letter-spacing:-.02em;margin:0;font-weight:850;text-wrap:balance}
html:lang(ja) h1,html:lang(zh-Hant) h1,html:lang(zh-Hans) h1{word-break:keep-all;line-break:strict;letter-spacing:0}
html:lang(ko) h1,html:lang(ko) .su-bub,html:lang(ko) .cat b{word-break:keep-all}
.nw{white-space:nowrap}

/* ── Сухён-гид (14.10). Плитка тела не деформируется (правка 28.09): только сдвиг, поворот целиком и прыжок.
   Каждое движение — одно на смену шага, потом поза держится; «дыхание» — три вдоха и тишина
   (ui-ux-pro-max: бесконечная анимация — только для загрузки). Позы — растр 512, на экране 88–112 px:
   запас ×3 для DPR 3, без мыла. .su-act — действия, .su-br — дыхание, у каждого свой transform. */
.su{display:flex;align-items:center;gap:8px;margin:12px 0 2px}
.su-fig{flex:none;width:80px;height:80px;margin:-4px -2px -4px -8px}
.su-act,.su-br{width:100%;height:100%;transform-origin:50% 82%}
.su-fig img{display:block;width:100%;height:100%;filter:drop-shadow(0 6px 10px rgba(0,0,0,.45))}
.su-bub{position:relative;display:grid;flex:1;min-width:0;max-width:460px;padding:11px 14px 12px;border-radius:18px 18px 18px 6px;
  background:var(--panel2);border:1px solid var(--line2);color:var(--ink);font-size:15px;line-height:1.45;font-weight:500}
.su-bub::before{content:"";position:absolute;left:-7px;top:50%;width:12px;height:12px;margin-top:-6px;background:var(--panel2);
  border-left:1px solid var(--line2);border-bottom:1px solid var(--line2);transform:rotate(45deg);border-bottom-left-radius:3px}
.su-bub>*{grid-area:1/1;margin:0;min-width:0;align-self:center}
.su-sz{visibility:hidden}
/* До ouvi.js гид невидим, но место под ним уже занято (2 строки облачка) — страница не прыгает. */
.ov-su .su-bub{min-height:calc(2 * 1.45em + 23px)}
body[data-ready="0"] .ov-su{visibility:hidden;animation:ov-show 0s 1.5s forwards}
body[data-ready="0"] #ov-lang-flag{visibility:hidden;animation:ov-show 0s 1.5s forwards}
html:lang(ja) .su-bub,html:lang(zh-Hant) .su-bub,html:lang(zh-Hans) .su-bub{word-break:keep-all;line-break:strict}
.su-act.wave{animation:su-in .45s var(--ease) both,su-wave 1.15s ease-in-out .5s}
.su-act.hop{animation:su-hop .62s cubic-bezier(.33,0,.25,1)}
.su-act.spin{animation:su-spin .9s cubic-bezier(.45,.05,.2,1)}
.su-act.laugh{animation:su-in .35s var(--ease) both,su-laugh .9s ease-in-out .3s}
.su-br.on{animation:su-breathe 3.2s ease-in-out 3}
/* Покой гида (15.10): поза-обёртка поворачивается/сдвигается целиком вокруг ступней (тело не деформируется),
   новая поза проявляется поверх старой; в покое «дыхание» не кончается; вне экрана и в фоне — пауза (ouvi.js). */
.su-pose{position:relative;width:100%;height:100%;transform-origin:50% 81%;transition:transform .7s cubic-bezier(.45,.05,.25,1)}
.su-pose .su-x{position:absolute;inset:0;opacity:0;transition:opacity .32s ease}
.su-pose .su-x.on{opacity:1}
.su-br.idle{animation:su-breathe 3.2s ease-in-out infinite}
.ov-su.paused .su-br,.ov-su.paused .su-act{animation-play-state:paused}
.su-say.new{animation:su-txt .35s var(--ease)}
@keyframes su-in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes su-wave{0%,100%{transform:rotate(0)}25%{transform:rotate(-8deg)}60%{transform:rotate(7deg)}85%{transform:rotate(-2deg)}}
@keyframes su-hop{0%{transform:translateY(0)}38%{transform:translateY(-22px)}68%{transform:translateY(0)}82%{transform:translateY(-5px)}100%{transform:translateY(0)}}
@keyframes su-spin{0%{transform:translateY(0) rotate(0)}50%{transform:translateY(-26px) rotate(180deg)}100%{transform:translateY(0) rotate(360deg)}}
@keyframes su-laugh{0%,100%{transform:rotate(0)}15%{transform:rotate(-9deg)}32%{transform:rotate(8deg)}50%{transform:rotate(-6deg)}68%{transform:rotate(4deg)}84%{transform:rotate(-2deg)}}
@keyframes su-breathe{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
@keyframes su-txt{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
/* Реплика на ослышку — под полем ввода: появляется ниже поля, поэтому само поле не прыгает под пальцем. */
.su-mini{margin:12px 0 0}
.su-mini .su-fig{width:68px;height:68px}
.su-mini .su-bub{font-size:14px;padding:9px 12px 10px}

/* ── Подборки (14.10, второй круг): 4 крупные плашки 2×2 на телефоне, 4 в ряд на компьютере. Значок — эмодзи,
   у «как говорят корейцы» — флаг SVG (эмодзи-флаг Windows рисует буквами «KR»). aria-pressed — выбранная. */
.ov-pick{margin:14px 0 0}
.cats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0 0 12px}
.cat{display:flex;align-items:center;gap:10px;min-height:56px;padding:8px 12px;border-radius:14px;border:1px solid var(--line);
  background:var(--panel);color:var(--mut);font:700 16px/1.2 var(--f);text-align:left;cursor:pointer;min-width:0;
  transition:border-color .15s var(--ease),background .15s var(--ease),color .15s var(--ease),transform .15s var(--ease)}
.cat i{flex:none;display:grid;place-items:center;width:30px;height:30px;font-style:normal;font-size:24px;line-height:1;
  font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif}
.cat i img{width:26px;height:18px;border-radius:3px;box-shadow:0 0 0 1px rgba(255,255,255,.2)}
.cat b{font-weight:inherit;min-width:0;overflow-wrap:normal;word-break:normal}
html:lang(ja) .cat b,html:lang(zh-Hant) .cat b,html:lang(zh-Hans) .cat b{word-break:keep-all}
.cat:hover{border-color:var(--line2);color:var(--ink)}
.cat[aria-pressed=true]{border-color:var(--brand);background:rgba(199,158,232,.16);color:var(--ink);box-shadow:inset 0 0 0 1px var(--brand)}
.cat:active{transform:scale(.98)}
/* Песня — вторым планом: мелкий селект-«ссылка» под строками. */
.by-song{margin:8px 0 18px}
.by-song select{width:auto;max-width:100%;min-height:44px;padding:0 36px 0 14px;border-radius:999px;border:1px solid var(--line);
  background-color:transparent;color:var(--mut);font:600 15px/1.2 var(--f);background-position:right 12px center;background-size:16px 16px}
.by-song select.on{border-color:var(--brand);color:var(--ink);background-color:rgba(199,158,232,.12)}
.by-song select option{background:var(--panel);color:var(--ink)}
.field{margin:0 0 18px;padding:0;border:0;min-width:0}
.field>label,.lbl{display:block;padding:0;margin:0 0 8px;font-weight:700;font-size:15px;color:var(--ink)}
.field small{font-weight:500;color:var(--dim);font-size:14px}
.note{margin:0 0 10px;color:var(--dim);font-size:15px}

select,input[type=text]{width:100%;min-height:52px;padding:0 44px 0 16px;border-radius:var(--r-sm);border:1px solid var(--line2);background:var(--panel);color:var(--ink);font:500 17px/1.3 var(--f);appearance:none;-webkit-appearance:none}
select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 6l4.5 4.5L12.5 6' fill='none' stroke='%23C79EE8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 14px center;background-size:18px 18px}
input[type=text]{padding:0 16px;font-size:18px}
select:hover,input[type=text]:hover{border-color:var(--brand)}
select:focus-visible,input[type=text]:focus-visible{outline:2px solid var(--brand);outline-offset:1px;border-color:var(--brand)}
input::placeholder{color:#8F82A8;opacity:1}
.hint{margin:6px 0 0;color:var(--dim);font-size:13px;font-variant-numeric:tabular-nums}
.err{margin:8px 0 0;color:var(--err);font-size:15px;font-weight:600}

/* Строки — радиокнопки-плашки: дословный перевод (он же хук) крупно, песня мелко. На телефоне — две ленты
   со свайпом вбок (31 строка столбиком уводила карточку на 3000 px вниз); жест «назад» в ленте выключен
   (data-noback, public/swipe-back.js). */
.chips{display:grid;grid-auto-flow:column;grid-template-rows:repeat(2,auto);grid-auto-columns:max-content;gap:8px;
  overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x proximity;scroll-padding:0 16px;margin:0 -16px;padding:2px 16px 8px;scrollbar-width:none}
.chips::-webkit-scrollbar{display:none}
.chip{position:relative;display:block;scroll-snap-align:start;min-width:140px;max-width:236px}
.chip input{position:absolute;opacity:0;inset:0;width:100%;height:100%;margin:0;cursor:pointer}
.chip span{display:flex;flex-direction:column;justify-content:center;height:100%;min-height:56px;padding:8px 12px;border-radius:var(--r-sm);border:1px solid var(--line);background:var(--panel);line-height:1.3;transition:border-color .15s var(--ease),background .15s var(--ease),transform .15s var(--ease)}
.chip b{font-weight:700;font-size:15px;color:var(--ink);overflow-wrap:normal;word-break:normal;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden}
.chip b[lang=ko]{color:var(--ko)}
.chip small{color:var(--dim);font-size:13px;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.chip:hover span{border-color:var(--line2)}
.chip input:checked+span{border-color:var(--brand);background:rgba(199,158,232,.15);box-shadow:inset 0 0 0 1px var(--brand)}
.chip input:checked+span small{color:var(--mut)}
.chip input:focus-visible+span{outline:2px solid var(--brand);outline-offset:2px}
.chip input:active+span{transform:scale(.98)}

/* Выбранная строка: хангыль, секунда в клипе (человек сам вырезает звук для поста) и разбор песни. */
.sel{margin:20px 0;padding:14px 16px 6px;border-radius:var(--r);background:var(--panel2);border:1px solid var(--line)}
.sel-snd{display:flex;align-items:flex-start;gap:8px;margin:2px 0 0;font-size:15px;line-height:1.45;color:var(--mut)}
.sel-snd svg{flex:none;width:16px;height:16px;margin-top:3px;fill:var(--snd)}
.sel-snd a{display:inline-block;padding:0 0 4px;color:var(--mut);text-decoration-color:rgba(199,158,232,.5);text-underline-offset:3px}
.sel-snd a:hover{color:var(--ink)}
.sel-snd b{color:var(--snd);font-variant-numeric:tabular-nums;white-space:nowrap}
.sel-credit{margin:6px 0 0;color:var(--dim);font-size:13px;line-height:1.45}
.more{display:inline-flex;align-items:center;gap:6px;min-height:44px;font-weight:700;font-size:16px;text-decoration:none}
.more:hover{text-decoration:underline}

.custom input[type=text]{border-style:dashed}
.custom input[type=text]:not(:placeholder-shown){border-style:solid;border-color:var(--brand)}

/* Карточка: холст 1080×1920, на экране ужат CSS — края чёткие на любом DPR. */
.ov-out{margin:4px 0 0}
.frame{position:relative;width:min(100%,320px);margin:0 auto;border-radius:22px;overflow:hidden;background:var(--panel);
  box-shadow:0 18px 50px -18px rgba(0,0,0,.75),0 2px 8px rgba(0,0,0,.35);outline:1px solid var(--line)}
.frame canvas{display:block;width:100%;height:auto;aspect-ratio:9/16}
/* Квадрат 1:1 (21.10.2026) — та же ширина рамки, высота по формату. */
.frame[data-fmt=square] canvas{aspect-ratio:1/1}

/* Формат: две плашки над карточкой, значок-рамка показывает пропорцию — читается без подписи. */
.fmt{display:flex;gap:8px;width:min(100%,320px);margin:0 auto 10px}
.fmt button{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:0 12px;border-radius:999px;
  border:1px solid var(--line2);background:var(--panel);color:var(--mut);font:700 15px/1 var(--f);cursor:pointer;transition:background .15s var(--ease),border-color .15s var(--ease),color .15s var(--ease)}
.fmt button small{font-weight:600;font-size:12px;color:var(--dim)}
.fmt button:hover{border-color:var(--brand);color:var(--ink)}
.fmt button[aria-pressed=true]{background:rgba(199,158,232,.16);border-color:var(--brand);color:var(--ink)}
.fmt button[aria-pressed=true] small{color:var(--brand)}
.fmt .fr{flex:none;display:block;border:2px solid currentColor;border-radius:3px}
.fmt .fr-s{width:10px;height:17px}.fmt .fr-q{width:15px;height:15px}
.frame.swap canvas{animation:ov-in .38s var(--ease)}
/* Холодная загрузка: пока шрифты, знак и Сухён не доехали — крутилка, а не пустая плашка. */
.frame.wait::after{content:"";position:absolute;left:50%;top:50%;width:30px;height:30px;margin:-15px 0 0 -15px;border-radius:50%;
  border:3px solid var(--line2);border-top-color:var(--brand);animation:ov-spin .8s linear infinite}
@keyframes ov-spin{to{transform:rotate(360deg)}}
@keyframes ov-in{from{opacity:.55;transform:scale(.985)}to{opacity:1;transform:none}}

/* Телефон: кнопка «Поделиться» закреплена внизу экрана — она под пальцем, где бы человек ни был. */
.actions{position:fixed;left:0;right:0;bottom:0;z-index:6;padding:10px 16px calc(12px + env(safe-area-inset-bottom));
  background:rgba(18,13,27,.94);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-top:1px solid var(--line)}
body{padding-bottom:calc(92px + env(safe-area-inset-bottom))}
.actions .row{display:flex;gap:10px;max-width:520px;margin:0 auto}
.status{margin:0 auto 8px;max-width:520px;color:var(--mean);font-size:15px;font-weight:600;text-align:center}
.status:empty{display:none}
.status.bad{color:var(--err)}
/* После «Поделиться», если гид за экраном: маленький Сухён и su_done прямо у кнопки (ouvi.js, готово()). */
.st-m{display:inline-flex;align-items:center;gap:6px;text-align:left}
.st-m img{flex:none;width:34px;height:34px;margin:-6px 0;animation:su-hop .62s cubic-bezier(.33,0,.25,1)}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;flex:1;min-height:54px;padding:0 24px;border:0;border-radius:999px;font:800 17px/1 var(--f);cursor:pointer;text-decoration:none;transition:transform .15s var(--ease),filter .15s var(--ease),background .15s var(--ease)}
.btn.primary{background:var(--gold);color:var(--gold-ink);box-shadow:0 10px 24px -10px rgba(223,169,127,.55)}
.btn.primary:hover{filter:brightness(1.06)}
.btn.ghost{flex:none;border:1px solid var(--line2);background:var(--panel);color:var(--ink)}
.btn.ghost:hover{border-color:var(--brand);background:var(--panel2)}
.btn.icon{width:54px;padding:0}
.btn:active{transform:scale(.98)}
.btn:disabled{cursor:default;filter:grayscale(.5) brightness(.75)}
.btn svg{width:20px;height:20px;fill:currentColor}
.btn .ic-dl{display:none}
a.btn.icon{color:var(--ink)}
/* Узкий телефон: главная кнопка + три значка (скачать, ссылка, X) — значки 48 px, чтобы «Поделиться» не сжалась. */
@media (max-width:389px){.actions .row{gap:8px}.btn.icon{width:48px;min-height:50px}.btn{padding:0 16px;font-size:16px}}

/* Коллекция и петля (21.10.2026). */
.ov-col{margin:22px 0;padding:16px;border:1px solid var(--line);border-radius:var(--r);background:var(--panel)}
.ov-col h2{margin:0 0 10px;font-size:17px;line-height:1.3;font-weight:800}
.ov-col h2 b{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:24px;padding:0 7px;margin-left:4px;border-radius:999px;
  background:rgba(199,158,232,.18);color:var(--brand);font-size:14px}
.ov-col h2 b:empty{display:none}
.col-st{margin:-4px 0 10px;color:var(--mean);font-size:14px;font-weight:600}
.col-list{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;margin:0 -16px;padding:0 16px 2px;scroll-snap-type:x proximity}
.col-list::-webkit-scrollbar{display:none}
.col-list:empty{display:none}
.col-it{flex:none;display:flex;flex-direction:column;align-items:flex-start;gap:3px;max-width:220px;min-height:56px;padding:9px 12px;border-radius:var(--r-sm);
  border:1px solid var(--line2);background:var(--panel2);color:var(--ink);font:inherit;text-align:left;cursor:pointer;scroll-snap-align:start}
.col-it b{font:700 16px/1.25 var(--f-ko);color:var(--ko);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:196px}
.col-it small{font-size:12px;color:var(--dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:196px}
.col-it[aria-current=true]{border-color:var(--brand);background:rgba(199,158,232,.14)}
.col-reg{margin-top:14px}
.col-reg-h{margin:0 0 4px;font-weight:800;font-size:16px;line-height:1.35}
.col-reg-p{margin:0 0 12px;color:var(--mut);font-size:14px;line-height:1.5}
.col-reg .btn{width:100%;flex:none;min-height:50px;font-size:16px}
.col-name{display:flex;align-items:center;gap:10px;min-height:44px;margin-top:10px;color:var(--mut);font-size:15px;cursor:pointer}
.col-name input{width:20px;height:20px;accent-color:#C79EE8;flex:none}
.btn[data-kind=download] .ic-share{display:none}.btn[data-kind=download] .ic-dl{display:block}

footer{margin-top:32px;border-top:1px solid var(--line);padding:20px 0 36px;color:var(--dim);font-size:14px}
footer p{margin:0 0 8px}footer a{color:var(--mut)}

/* Компьютер: слева выбор, справа карточка с кнопкой — карточка не уезжает при прокрутке списка. */
@media (min-width:900px){
  .ov-grid{display:grid;grid-template-columns:minmax(0,1fr) 400px;column-gap:56px;align-items:start;
    grid-template-areas:"hero out" "su out" "pick out" "sel out" "col out" "custom out";grid-template-rows:auto auto auto auto auto 1fr}
  .ov-col{grid-area:col}
  .fmt{width:var(--cw)}
  .ov-hero{grid-area:hero;padding-top:44px}
  .cats{grid-template-columns:repeat(4,minmax(0,1fr))}
  .cat{flex-direction:column;align-items:flex-start;justify-content:center;gap:6px;min-height:84px;padding:12px 14px}
  .ov-su{grid-area:su;margin-top:20px}
  .ov-su .su-fig{width:112px;height:112px}
  .ov-su .su-bub{font-size:16px;padding:13px 16px 14px}
  .ov-pick{grid-area:pick}
  .ov-sel{grid-area:sel;margin-top:2px}
  .ov-custom{grid-area:custom}
  /* Карточка с кнопкой целиком в окне: ширина от высоты окна (9:16), не шире 400. */
  .ov-out{--cw:min(400px,calc((100vh - 254px) * .5625));grid-area:out;position:sticky;top:72px;margin-top:28px;justify-self:center}
  .frame{width:var(--cw)}
  .actions .row{width:var(--cw);gap:8px}
  .actions .btn.primary{white-space:nowrap;padding:0 14px;font-size:16px;gap:8px}
  .actions .btn.icon{width:50px}
  .chips{grid-auto-flow:row;grid-template-rows:none;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));overflow:visible;margin:0;padding:2px 0 0;max-height:none}
  .chip{max-width:none}
  .actions{position:static;margin:16px 0 0;padding:0;background:none;border:0;backdrop-filter:none;-webkit-backdrop-filter:none}
  body{padding-bottom:0}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}body[data-ready="0"] [data-t],body[data-ready="0"] .ov-su{visibility:visible}}
