/* Стили приложения. Были внутри index.html; вынесены, чтобы страницу можно было
   читать и править по частям. Подключение и номер версии — в index.html. */

:root{
  --bg:#0B0D1A; --card:#141830; --ink:#EEF1FF; --ink-2:#C9CEE8; --muted:#8A90B0;
  --line:#242A4A; --line-2:#3A4270; --accent:#FF7A6B; --on-accent:#1A0D0C; --alarm:#FFD36B; --ok:#7EE0A5; --danger:#FF5A5A; --on-danger:#1A0708;
  /* Отступы под системные полосы. env() честно отвечает на iPhone и в новых Chrome, но часть Chrome на Android 15
     в режиме во весь экран отвечает нулём — и полоса с кнопками ложится на нижнюю кнопку. Мерить окно ненадёжно
     (открытое из оповещения, оно дорастает до полного экрана позже), поэтому на телефонах запас оставлен всегда:
     снизу не меньше высоты полосы с тремя кнопками (48), сверху в установленном приложении — статусной (24). */
  --safe-t:env(safe-area-inset-top); --safe-b:env(safe-area-inset-bottom);
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --tap:44px;
  --ease:cubic-bezier(.2,.7,.3,1);
  /* Тёплое сияние вверху экрана — одно на все экраны. Центр опущен от верхнего края ровно настолько,
     чтобы свет успел погаснуть до него: при центре у самого края эллипс срезается, и вместо сияния
     получается светлая полоса с ровной границей. */
  --glow-top:radial-gradient(78% 22% at 50% 22%, color-mix(in srgb, var(--accent) 20%, transparent), transparent 70%);
  color-scheme:dark;   /* иначе система считает страницу светлой и красит системные полосы (в том числе нижнюю с кнопками Android) белым */
}
@media (pointer:coarse){ :root{ --safe-b:max(env(safe-area-inset-bottom), 48px); } }
@media (pointer:coarse) and (display-mode:standalone), (pointer:coarse) and (display-mode:fullscreen){ :root{ --safe-t:max(env(safe-area-inset-top), 24px); } }

*{ box-sizing:border-box; margin:0; padding:0; -webkit-tap-highlight-color:transparent; }
html{ font-size:100%; font:-apple-system-body; }   /* кегли ниже в rem: увеличил человек текст в системе или в браузере — вырастет и Toccami; на iPhone это Dynamic Type */
html,body{ height:100%; background:#0B0D1A; }   /* фон и на html: под нижней полосой Android в установленном приложении видно его, а не белый холст */
body{
  background:var(--bg); color:var(--ink);
  font:400 1.0625rem/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing:antialiased; -webkit-user-select:none; user-select:none; overscroll-behavior:none;
}
button{ font:inherit; color:inherit; cursor:pointer; }
input,textarea{ font:inherit; color:inherit; }
[hidden]{ display:none !important; }

.app{ width:100%; max-width:480px; margin:0 auto; height:100%; height:100dvh; display:flex; flex-direction:column; position:relative; overflow:hidden; }
.top{ flex:0 0 auto; padding:calc(var(--s4) + var(--safe-t)) var(--s4) var(--s3); display:flex; align-items:flex-start; justify-content:space-between; gap:var(--s3); }
.top .title{ margin-top:var(--s2); }
.title{ font-size:min(1.875rem, 7.5vw); font-weight:200; letter-spacing:.28em; text-transform:uppercase; line-height:1; white-space:nowrap; overflow:hidden; text-overflow:clip; }   /* заголовок-бренд не растёт шире экрана: при крупном системном шрифте он упирался в кнопку меню и сдвигал всё приложение */
.top > div:first-child{ min-width:0; }
.sub{ font-size:0.75rem; color:var(--muted); margin-top:var(--s2); letter-spacing:.06em; text-transform:uppercase; }
.icon-btn{ width:var(--tap); height:var(--tap); border-radius:50%; border:1px solid var(--line-2); background:none; color:var(--ink-2); display:flex; align-items:center; justify-content:center; flex:0 0 auto; }
.icon-btn:active{ background:var(--card); }
.body{ flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; padding:var(--s2) var(--s4) calc(120px + var(--safe-b)); scrollbar-width:none; display:flex; flex-direction:column; gap:var(--s3); }
.body:not([data-fit]) > *{ flex:0 0 auto; }   /* содержимое не сжимается под экран: длинный список прокручивается пальцем, а не обрезается */
.body:not([data-fit]) > .onb{ flex:1 1 auto; }   /* но экран входа занимает всю высоту: он один и стоит по центру */
.body[data-onb]{ padding-bottom:calc(var(--s4) + var(--safe-b)); }   /* и без запаса снизу: нижней панели с кнопками на нём нет */
.body[data-fit]{ overflow:hidden; touch-action:pan-y; padding:0 var(--s4) calc(var(--s4) + var(--safe-b)); gap:0; justify-content:space-between; }
.body::-webkit-scrollbar{ display:none; }

.hint{ width:100%; display:flex; align-items:center; gap:var(--s3); padding:var(--s3) var(--s3) var(--s3) var(--s4); border-radius:16px; background:#1d1b22; border:1px solid #5a5236; background:color-mix(in srgb, var(--alarm) 8%, var(--bg)); border:1px solid color-mix(in srgb, var(--alarm) 30%, transparent); font-size:0.8125rem; line-height:1.4; color:var(--ink); text-align:left; }
.hint > span{ flex:1; }
.hint > svg{ flex:0 0 auto; color:var(--alarm); }
button.hint{ cursor:pointer; min-height:var(--tap); }
button.hint:active{ background:color-mix(in srgb, var(--alarm) 16%, var(--bg)); }
.btn[data-pwa-install]{ display:inline-flex; }
.hint[data-err]{ background:color-mix(in srgb, var(--accent) 10%, var(--bg)); border-color:color-mix(in srgb, var(--accent) 35%, transparent); }


/* Карточка готовности над списком: две способности — приложение на экране и уведомления.
   Каждая строка нажимается в любом браузере; что делать, если системного окна нет, рассказывает шторка.
   Строки, по которой нечего делать, в карточке нет — поэтому у кого всё включено, карточки не видно. */
.ready{ border:1px solid var(--line); border-radius:22px; background:var(--card); overflow:hidden; }
.rr{ width:100%; display:flex; align-items:center; gap:var(--s3); padding:var(--s3) var(--s3) var(--s3) 18px; min-height:64px;
     border:0; background:none; color:inherit; font:inherit; text-align:left; }
.rr:active{ background:var(--line); }
.rr-ic{ flex:0 0 40px; height:40px; border-radius:12px; background:var(--line); border:1px solid var(--line-2); display:flex; align-items:center; justify-content:center; color:var(--ink); }
.rr-t{ flex:1; min-width:0; font-size:0.9375rem; font-weight:500; }
.rr-t small{ display:block; font-size:0.8125rem; font-weight:400; color:var(--muted); margin-top:1px; }
.rr-mark{ flex:0 0 auto; color:var(--muted); display:flex; }
/* строка, где дело не в одном нажатии (запрет, окно мессенджера): тот же жёлтый, что у подсказок */
.rr[data-state="bad"] .rr-ic{ background:color-mix(in srgb, var(--alarm) 14%, var(--card)); border-color:color-mix(in srgb, var(--alarm) 35%, transparent); color:var(--alarm); }
.rr[data-state="bad"] .rr-t small, .rr[data-state="bad"] .rr-mark{ color:var(--alarm); }
.ht-steps{ display:flex; flex-direction:column; gap:var(--s2); margin-top:var(--s3); }

.list{ background:var(--card); border:1px solid var(--line); border-radius:22px; overflow:hidden; }
.row-f{ display:grid; grid-template-columns:minmax(0,1fr) auto 52px; gap:var(--s3); align-items:center; min-height:64px; padding:var(--s2) var(--s2) var(--s2) 20px; border-bottom:1px solid var(--line); cursor:pointer; }
.row-f:last-child{ border-bottom:0; }
.row-f:active{ background:var(--line); }
.row-f[data-gone="1"] .row-name{ color:var(--muted); text-decoration:line-through; }
.row-name{ font-size:1.1875rem; font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; display:flex; align-items:center; gap:10px; }
.row-name > span{ overflow:hidden; text-overflow:ellipsis; }
.tick{ flex:none; width:18px; height:14px; color:var(--muted); opacity:.35; transition:color .3s, opacity .3s; }
.tick[data-on="1"]{ color:var(--ok); opacity:1; }
.row-name small{ display:block; font-size:0.875rem; font-weight:400; color:color-mix(in srgb, var(--muted) 82%, var(--bg)); margin-top:1px; }   /* «не на связи», «пока не получено»: 14 px и бледнее имени — это примечание, а не новость */
.count{ display:inline-flex; align-items:center; gap:var(--s1); min-width:52px; justify-content:flex-end; font-variant-numeric:tabular-nums; }
.count svg, .count .sign{ width:18px; height:18px; }
.count-n{ font-size:1.0625rem; font-weight:600; }
.count[data-zero="1"] .count-n{ color:var(--muted); font-weight:400; }
.more{ width:40px; height:40px; margin-inline:10px 2px; border:1px solid var(--line-2); background:none; color:var(--muted); display:flex; align-items:center; justify-content:center; border-radius:50%; flex:none; }
.more svg{ width:18px; height:18px; }
.more:active{ background:var(--line); color:var(--ink-2); }
.empty-dial{ width:88px; height:88px; align-self:center; border-radius:50%; border:1px solid var(--line); background:var(--card); display:flex; align-items:center; justify-content:center; opacity:.8; }
.empty-dial .arrow{ width:44px; height:44px; }
/* Пока никого: над списком две строки, а сам список — четыре бледные заглушки. Как только есть первый человек, строк нет.
   Последняя заглушка не исчезает никогда: внизу списка всегда ждёт свободное место */
.lead{ display:flex; flex-direction:column; gap:var(--s2); padding:var(--s3) var(--s2) var(--s2); text-align:center; }
.lead-h{ font-size:1.375rem; font-weight:300; line-height:1.25; color:var(--ink); text-wrap:balance; }
.lead-p{ font-size:0.875rem; color:var(--muted); line-height:1.5; text-wrap:balance; }
/* Заглушка: та же сетка, что у настоящего человека, но без имени. Галочка бледная, вместо имени плашка своей ширины,
   место знака пустое, и «+» вместо «i». Нажатие открывает приглашение.
   Пустая .count держит свой столбец, чтобы «+» стоял там же, где у людей */
.row-f[data-ghost] .tick{ opacity:.22; }
.blank{ display:block; height:14px; border-radius:7px; background:linear-gradient(90deg, var(--line-2), color-mix(in srgb, var(--line-2) 55%, var(--card))); opacity:.55; width:var(--w, 120px); max-width:100%; }
/* Затихшие: свёрнутый раздел под списком. Шапка стоит на той же сетке, что .row-f: луна — в столбце галочек,
   число — в столбце знака, стрелка в кружке — над кнопками «i». Строки бледнеют по --fade (7…14 дней),
   в самом разделе они приглушены одинаково: там степень уже не важна */
.row-f{ opacity:var(--fade, 1); transition:opacity .4s var(--ease); }
.hush{ background:color-mix(in srgb, var(--card) 70%, var(--bg)); border:1px solid var(--line); border-radius:22px; overflow:hidden; }
.hush-h{ width:100%; display:grid; grid-template-columns:minmax(0,1fr) auto 52px; gap:var(--s3); align-items:center; min-height:64px; padding:var(--s2) var(--s2) var(--s2) 20px; border:0; background:none; color:inherit; text-align:left; }
.hush-h:active{ background:var(--line); }
.hush-t{ min-width:0; font-size:1.1875rem; font-weight:500; color:var(--ink-2); display:flex; align-items:center; gap:10px; }
.hush-t > span{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.hush-ic{ flex:none; width:18px; height:18px; display:flex; align-items:center; justify-content:center; color:var(--muted); }
.hush-t small{ display:block; font-size:0.875rem; font-weight:400; color:color-mix(in srgb, var(--muted) 82%, var(--bg)); margin-top:1px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.hush-n{ display:inline-flex; align-items:center; justify-content:flex-end; min-width:52px; color:var(--muted); font-variant-numeric:tabular-nums; font-size:1.0625rem; }
.hush-chev{ width:40px; height:40px; margin-inline:10px 2px; border:1px solid var(--line-2); border-radius:50%; display:flex; align-items:center; justify-content:center; color:var(--muted); flex:none; }
.hush-chev svg{ width:18px; height:18px; transition:transform .25s var(--ease); }
.hush[data-open="1"] .hush-chev svg{ transform:rotate(90deg); }
.hush-body{ display:grid; grid-template-rows:0fr; transition:grid-template-rows .3s var(--ease); }
.hush[data-open="1"] .hush-body{ grid-template-rows:1fr; }
.hush-in{ min-height:0; overflow:hidden; }
.hush .row-f{ border-top:1px solid var(--line); border-bottom:0; opacity:.7; }
.hush .row-f .row-name{ color:var(--ink-2); font-weight:400; }
.hush-note{ padding:var(--s3) 20px var(--s4); font-size:0.8125rem; color:var(--muted); line-height:1.5; border-top:1px solid var(--line); }
.more[data-invite]{ border-style:dashed; border-color:color-mix(in srgb, var(--accent) 45%, transparent); color:color-mix(in srgb, var(--accent) 80%, transparent); }
.bar{ position:absolute; left:0; right:0; bottom:calc(var(--s5) + var(--safe-b)); display:flex; flex-wrap:wrap; justify-content:center; gap:var(--s3); padding:0 var(--s4); }   /* при крупном шрифте вторая кнопка переносится строкой выше, а не вылезает за экран */
.fab{ min-height:56px; padding:0 24px 0 20px; border:0; border-radius:28px; background:var(--accent); color:var(--on-accent); font-size:1rem; font-weight:600; display:flex; align-items:center; gap:var(--s2); box-shadow:0 12px 32px color-mix(in srgb, var(--accent) 35%, transparent); }
.fab:active{ filter:brightness(.92); }

/* онбординг */
.onb{
  flex:1; display:flex; flex-direction:column; justify-content:center; gap:var(--s4); padding:var(--s5) var(--s2);
  background:var(--glow-top);
}
/* Экран входа — три равные части по вертикали: сердце, текст, кнопки. В каждой содержимое стоит по центру
   и по вертикали, и по горизонтали. Если текста больше, чем треть экрана (шрифт 200 %, шаги установки на iPhone),
   эта часть растёт по содержимому, и экран прокручивается. */
.onb{ justify-content:flex-start; gap:0; }
.onb-top, .onb-mid, .onb-bot{ flex:1 1 0; min-height:fit-content; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:var(--s4); }
.onb-bot > .row, .onb-bot > .onb-step{ width:100%; }
.onb .w-steps{ gap:var(--s4); margin-top:0; align-self:center; }
.onb-h{ font-size:1.625rem; font-weight:300; line-height:1.25; text-align:center; }
.onb-p{ font-size:0.9375rem; color:var(--ink-2); line-height:1.55; }
.onb-step{ display:flex; gap:var(--s3); align-items:flex-start; font-size:0.9375rem; color:var(--ink-2); line-height:1.5; }
/* шаги установки на iPhone: значок того, что нужно нажать, жирная строка «что», серая «где» */
.onb-step[data-ios]{ align-items:center; gap:var(--s4); padding:var(--s3) var(--s3); border-radius:16px; background:var(--card); border:1px solid var(--line); }
.onb-step[data-ios] b{ display:block; font-weight:500; color:var(--ink); }
.onb-step[data-ios] small{ display:block; font-size:0.8125rem; color:var(--muted); line-height:1.4; margin-top:2px; }
.onb-ic{ flex:0 0 44px; height:44px; border-radius:12px; background:var(--line); border:1px solid var(--line-2); display:flex; align-items:center; justify-content:center; color:var(--ink); }

/* экран человека */
.p-bar{ flex:0 0 auto; display:flex; align-items:center; justify-content:space-between; gap:var(--s3); padding:calc(var(--s5) + var(--safe-t)) 0 var(--s3); }
.p-mid{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; justify-content:center; }
.p-name{ flex:1 1 auto; min-width:0; text-align:center; font-size:1.25rem; font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* «+7» рядом с именем: сколько пришло сегодня от этого человека. Плоский круг в цвете последнего знака, нажатие открывает карточку */
.p-name{ display:flex; align-items:center; justify-content:center; gap:var(--s2); }
.p-name > span{ min-width:0; overflow:hidden; text-overflow:ellipsis; }
.p-plus{ flex:0 0 auto; width:28px; height:28px; padding:0; border-radius:50%; border:0; background:color-mix(in srgb, var(--glow, var(--accent)) 28%, var(--card)); color:var(--ink); font-size:0.6875rem; font-weight:600; font-variant-numeric:tabular-nums; letter-spacing:.01em; display:inline-flex; align-items:center; justify-content:center; animation:pop .45s var(--ease); }
.p-plus[data-big="1"]{ font-size:0.625rem; letter-spacing:0; }   /* «+100» и больше: чуть мельче, чтобы остаться в круге */
.p-plus:active{ transform:scale(.94); }
.p-dial{ width:240px; height:240px; border-radius:50%; margin:var(--s5) auto 0; border:1px solid var(--line-2); background:radial-gradient(circle, color-mix(in srgb, var(--card) 60%, var(--line-2)), var(--card) 70%); display:flex; align-items:center; justify-content:center; position:relative; box-shadow:0 0 0 12px color-mix(in srgb, var(--accent) 6%, transparent), inset 0 0 40px rgba(0,0,0,.35); }
.arrow{ width:150px; height:150px; transition:transform .5s var(--ease); }
.p-n{ position:absolute; top:50%; left:50%; transform:translate(-50%,-50%) translateY(-101px); font-size:0.6875rem; letter-spacing:.2em; color:var(--muted); }
/* где север на самом деле: маленькая точка бежит по кругу, пока телефон поворачивают.
   Совместил её с меткой N — стоишь лицом на север, и стрелка на экране смотрит на человека по-настоящему. */
.p-north{ position:absolute; top:50%; left:50%; width:9px; height:9px; border-radius:50%; background:var(--accent); box-shadow:0 0 12px color-mix(in srgb, var(--accent) 70%, transparent); transform:translate(-50%,-50%) rotate(var(--h,0deg)) translateY(-101px); transition:transform .5s var(--ease); display:none; }
.p-dial[data-comp="1"] .p-north{ display:block; }
.p-dial[data-comp="1"] .p-n{ color:var(--accent); opacity:.75; }
.p-heart{ display:flex; justify-content:center; margin-top:var(--s3); filter:drop-shadow(0 0 36px color-mix(in srgb, var(--glow, var(--accent)) 70%, transparent)); animation:soft 2.6s ease-in-out infinite; }
.p-heart .sign{ width:min(150px, 22vh); height:min(150px, 22vh); width:min(150px, 22dvh); height:min(150px, 22dvh); }
.p-heart[data-pop="1"]{ animation:pop .45s var(--ease); }
@keyframes pop{ 0%{ transform:scale(.6); opacity:.3; } 60%{ transform:scale(1.12); opacity:1; } 100%{ transform:scale(1); } }
.p-heart{ touch-action:pan-y; user-select:none; -webkit-user-select:none; }
/* листание большой картинки: новый знак въезжает с той стороны, куда ушёл палец */
.p-heart[data-slide="l"], .p-mine[data-slide="l"]{ animation:slide-l .32s var(--ease); }
.p-heart[data-slide="r"], .p-mine[data-slide="r"]{ animation:slide-r .32s var(--ease); }
@keyframes slide-l{ from{ transform:translateX(40%); opacity:0; } to{ transform:none; opacity:1; } }
@keyframes slide-r{ from{ transform:translateX(-40%); opacity:0; } to{ transform:none; opacity:1; } }
.p-mine{ user-select:none; -webkit-user-select:none; text-align:center; font-size:1.25rem; font-weight:300; margin-top:var(--s4); min-height:30px; }
/* выбор знака: окно на три кружка, ряд листается пальцем и стрелками */
.picker{ display:flex; align-items:center; justify-content:center; gap:2px; margin-top:var(--s5); padding:0 var(--s2); }
.pick-win{ flex:1 1 auto; max-width:264px; overflow:hidden; touch-action:pan-y; }
.pick-track{ display:flex; transition:transform .32s var(--ease); will-change:transform; }
.pick-page{ flex:0 0 100%; display:flex; justify-content:space-around; gap:var(--s2); padding:10px 2px; }   /* 10 пикселей вокруг: выбранный знак вырастает на 12 % и несёт ободок в 4 пикселя — окно не должно их срезать */
.pick-nav{ width:var(--tap); height:var(--tap); flex:0 0 auto; border-radius:50%; border:0; background:none; color:var(--ink-2); display:flex; align-items:center; justify-content:center; transition:opacity .2s, transform .12s, background .2s; }
.pick-nav:disabled{ opacity:.22; }
.pick-nav:not(:disabled):active{ transform:scale(.88); background:var(--card); }
.pick{ width:56px; height:56px; border-radius:50%; border:1px solid var(--line-2); background:var(--card); display:flex; align-items:center; justify-content:center; transition:transform .18s var(--ease), border-color .18s, background .18s; }
.pick .sign{ width:34px; height:34px; }
.pick[data-on="1"]{ border-color:var(--glow); background:color-mix(in srgb, var(--glow) 18%, var(--card)); transform:scale(1.12); box-shadow:0 0 0 4px color-mix(in srgb, var(--glow) 18%, transparent); }
.pick:active{ transform:scale(.94); }
.pick:disabled{ opacity:.4; }
/* плюс — следующий кружок за последним знаком; если страница досталась ему одному, он посередине */
.pick-page[data-more]{ justify-content:center; }
.pick-plus{ border-style:dashed; color:var(--ink-2); }
/* витрина наборов: знаки крупно и без подложки, во всю ширину экрана; листается пальцем.
   Стрелки стоят по краям экрана на одном уровне с точками, цена и кнопка — внизу. */
.sets{ display:flex; flex-direction:column; align-items:center; gap:var(--s4); min-height:min(72vh, 620px); min-height:min(72dvh, 620px); }
.sets-win{ width:calc(100% + var(--s5) * 2); margin:0 calc(var(--s5) * -1); flex:1 1 auto; display:flex; align-items:center; overflow:hidden; touch-action:pan-y; }
.sets-track{ flex:0 0 100%; min-width:0; display:flex; transition:transform .32s var(--ease); will-change:transform; }
.set-page{ flex:0 0 100%; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:var(--s4); padding:3px var(--s5); }
.set-grid{ display:flex; justify-content:center; width:100%; }
.set-i{ display:flex; align-items:center; justify-content:center; filter:drop-shadow(0 0 20px color-mix(in srgb, var(--glow) 50%, transparent)); }
.set-page[data-on="0"] .set-i{ filter:none; }   /* свечение — примета открытого набора; закрытый виден как есть, в полный цвет */
.set-name{ font-size:1.25rem; font-weight:300; }
.set-say{ font-size:0.875rem; color:var(--muted); margin-top:-10px; }
.pick-hole{ width:56px; height:56px; flex:none; }   /* пустое место на неполной странице: кружки не расползаются */
/* стрелки по краям экрана, точки посередине — одной строкой */
.sets-bar{ display:flex; align-items:center; width:calc(100% + var(--s5) * 2); margin:0 calc(var(--s5) * -1); padding:0 var(--s1); }
.set-dots{ flex:1 1 auto; display:flex; gap:7px; justify-content:center; }
.set-dot{ width:6px; height:6px; border-radius:50%; background:var(--line-2); transition:background .2s, transform .2s; }
.set-dot[data-on="1"]{ background:var(--ink-2); transform:scale(1.25); }
.set-foot{ display:flex; flex-direction:column; align-items:center; gap:var(--s3); width:100%; }
.set-price{ font-size:0.9375rem; color:var(--muted); }
.set-foot .btn{ width:100%; }
.set-foot .btn[data-on="1"]{ background:color-mix(in srgb, #C86BD6 18%, var(--card)); border-color:color-mix(in srgb, #C86BD6 34%, transparent); color:#F3CCFF; font-weight:500; opacity:1; }
/* лимит на день */
.limit{ text-align:center; font-size:0.8125rem; color:var(--ink-2); line-height:1.5; padding:var(--s3) var(--s4); border-radius:16px; background:#1d1b22; border:1px solid #5a5236; background:color-mix(in srgb, var(--alarm) 8%, var(--bg)); border:1px solid color-mix(in srgb, var(--alarm) 30%, transparent); margin-top:var(--s2); }
/* вечерний ряд в карточке человека */
.ev{ margin-top:var(--s4); border-radius:20px; border:1px solid var(--line); background:var(--card); padding:14px 16px; display:flex; flex-direction:column; gap:10px; transition:border-color .25s, background .25s; }
.ev[data-on="1"]{ border-color:color-mix(in srgb, #C86BD6 34%, transparent); background:linear-gradient(135deg, color-mix(in srgb, #C86BD6 11%, var(--bg)), var(--card) 75%); }
.ev-top{ display:flex; align-items:center; gap:12px; }
.ev-t{ flex:1 1 auto; font-size:1rem; }
.ev-t small{ display:block; color:var(--muted); font-size:0.7812rem; line-height:1.4; margin-top:2px; }
.sw{ width:50px; height:29px; border-radius:15px; border:1px solid var(--line-2); background:var(--bg); position:relative; flex:0 0 auto; transition:background .22s, border-color .22s; }
.sw::after{ content:""; position:absolute; top:3px; left:3px; width:21px; height:21px; border-radius:50%; background:var(--muted); transition:transform .22s var(--ease), background .22s; }
.sw[aria-checked="true"]{ background:color-mix(in srgb, #C86BD6 34%, var(--card)); border-color:#C86BD6; }
.sw[aria-checked="true"]::after{ transform:translateX(21px); background:#F3CCFF; }
.sw[data-wait="1"]::after{ background:#C86BD6; animation:sw-wait 1.4s ease-in-out infinite; }
@keyframes sw-wait{ 0%,100%{ transform:translateX(7px) scale(.86); opacity:.7; } 50%{ transform:translateX(13px) scale(1); opacity:1; } }
.sw[data-locked="1"]{ opacity:.45; }
.ev-row{ display:flex; align-items:flex-start; gap:10px; font-size:0.8125rem; color:var(--muted); border-top:1px solid var(--line); padding-top:10px; line-height:1.45; }
.ev-row span{ flex:1 1 auto; }
.ev-row span b{ display:block; color:var(--ink-2); font-weight:400; }
.ev-row button{ background:none; border:0; font:inherit; font-size:0.8125rem; color:#C86BD6; padding:0; text-decoration:underline; text-underline-offset:3px; white-space:nowrap; }
.ev-acts{ display:flex; gap:10px; }
.ev-acts .btn{ flex:1 1 0; min-height:42px; font-size:0.9375rem; }
/* карточка человека: последнее место, две сетки знаков */
.place{ display:grid; grid-template-columns:auto minmax(0,1fr); align-items:center; gap:var(--s4); width:100%; text-align:left; margin-top:var(--s4); padding:var(--s3) var(--s4) var(--s3) var(--s3); border-radius:20px; border:1px solid color-mix(in srgb, var(--glow, var(--accent)) 26%, transparent); background:color-mix(in srgb, var(--glow, var(--accent)) 10%, var(--bg)); }
.place:active{ background:color-mix(in srgb, var(--glow, var(--accent)) 18%, var(--bg)); }
.place-dial{ width:64px; height:64px; border-radius:50%; border:1px solid var(--line-2); background:radial-gradient(circle, color-mix(in srgb, var(--card) 60%, var(--line-2)), var(--card) 70%); display:flex; align-items:center; justify-content:center; flex:none; filter:drop-shadow(0 0 12px color-mix(in srgb, var(--glow, var(--accent)) 60%, transparent)); }
.place-dial .sign{ width:40px; height:40px; }
.place-t{ display:block; font-size:1.0625rem; font-weight:500; }
.place-d{ display:block; font-size:0.8125rem; color:var(--muted); margin-top:2px; line-height:1.4; }
.place-go{ display:inline-flex; align-items:center; gap:6px; font-size:0.8125rem; color:var(--glow, var(--accent)); margin-top:var(--s2); }
.place-none{ margin-top:var(--s4); font-size:0.8125rem; color:var(--muted); line-height:1.5; }
/* «Последнее от меня»: знак крупно, когда ушло, и честный статус доставки цветом */
.mine{ display:grid; grid-template-columns:auto minmax(0,1fr); align-items:center; gap:var(--s4); margin-top:var(--s4); padding:var(--s3) var(--s4) var(--s3) var(--s3); border-radius:20px; border:1px solid color-mix(in srgb, var(--glow, var(--accent)) 26%, transparent); background:color-mix(in srgb, var(--glow, var(--accent)) 10%, var(--bg)); }
.mine-ic{ width:64px; height:64px; border-radius:50%; border:1px solid var(--line-2); background:radial-gradient(circle, color-mix(in srgb, var(--card) 60%, var(--line-2)), var(--card) 70%); display:flex; align-items:center; justify-content:center; flex:none; filter:drop-shadow(0 0 12px color-mix(in srgb, var(--glow, var(--accent)) 60%, transparent)); }
.mine-s{ display:flex; align-items:flex-start; gap:6px; font-size:0.8125rem; line-height:1.4; margin-top:var(--s2); }
.mine-s svg{ flex:none; width:18px; height:14px; margin-top:3px; }
.mine[data-st="ok"] .mine-s{ color:var(--ok); }
.mine[data-st="wait"] .mine-s{ color:var(--muted); }
.mine[data-st="alarm"] .mine-s{ color:var(--alarm); }
/* граница между чужими знаками и моими: отступ вдвое больше, чтобы блоки не слипались с сеткой выше */
.sec-h[data-gap]{ margin-top:48px; }
.sec-h{ display:flex; align-items:baseline; justify-content:space-between; gap:var(--s3); font-size:0.75rem; letter-spacing:.14em; text-transform:uppercase; color:var(--muted); margin:var(--s5) 0 var(--s3); }
.sec-h b{ font-size:0.75rem; letter-spacing:0; text-transform:none; color:var(--ink-2); font-weight:500; }
.sec-p{ font-size:0.8125rem; color:var(--muted); line-height:1.5; margin-top:var(--s2); }

/* статистика: что присылает этот человек */
.stats{ margin-top:0; }
.off-row{ display:flex; justify-content:center; margin-top:var(--s4); }
.off{ min-height:36px; padding:0 14px; border-radius:18px; border:1px solid var(--line-2); background:none; color:var(--muted); font-size:0.8125rem; }
.off:active{ background:var(--line); }
.stats-grid{ display:grid; grid-template-columns:repeat(3, 1fr); gap:var(--s2); }
.stat{ display:flex; flex-direction:column; align-items:center; gap:2px; padding:var(--s3) var(--s1) var(--s2); border-radius:18px; background:color-mix(in srgb, var(--glow) 9%, var(--bg)); border:1px solid color-mix(in srgb, var(--glow) 22%, transparent); }
.stat .sign{ width:34px; height:34px; filter:drop-shadow(0 0 10px color-mix(in srgb, var(--glow) 60%, transparent)); }
.stat-n{ font-size:1.625rem; font-weight:600; line-height:1.1; font-variant-numeric:tabular-nums; margin-top:var(--s1); }
.stat-l{ font-size:0.6875rem; color:var(--muted); letter-spacing:.03em; }
.stat[data-zero="1"]{ opacity:.45; }
.stat[data-zero="1"] .stat-n{ font-weight:400; color:var(--muted); }
/* знак в «что отправил я» нажимается: открывает отправку с уже выбранным знаком */
button.stat{ font:inherit; color:inherit; border-color:color-mix(in srgb, var(--glow) 40%, transparent); }
button.stat:active{ background:color-mix(in srgb, var(--glow) 20%, var(--bg)); }
.p-heart[data-wait="1"]{ animation:beat 1.1s ease-in-out infinite; }
.p-heart[data-fly="1"]{ animation:fly-away 1.1s cubic-bezier(.3,.7,.3,1) forwards; }
@keyframes soft{ 0%,100%{ transform:scale(1); opacity:.95; } 50%{ transform:scale(1.06); opacity:1; } }
@keyframes fly-away{ 0%{ transform:scale(1); opacity:1; } 30%{ transform:scale(1.18); opacity:1; } 100%{ transform:translateY(-320px) scale(.4); opacity:0; } }
.p-off{ display:block; font-size:0.75rem; font-weight:400; color:var(--muted); line-height:1.2; }
.lnk{ color:var(--accent); text-decoration:none; border-bottom:1px solid color-mix(in srgb, var(--accent) 40%, transparent); }
button.lnk{ background:none; border:0; border-bottom:1px solid color-mix(in srgb, var(--accent) 40%, transparent); padding:0; font-size:inherit; }
.p-dist{ text-align:center; font-size:3.5rem; font-weight:200; letter-spacing:-.01em; font-variant-numeric:tabular-nums; margin-top:var(--s5); line-height:1; }
.p-unit{ font-size:1.25rem; color:var(--muted); margin-left:var(--s2); }
.p-actions{ flex:0 0 auto; display:flex; flex-direction:column; align-items:center; gap:var(--s2); margin-top:var(--s3); }
.p-send{ display:flex; align-items:stretch; gap:var(--s2); width:min(100%, 300px); }
.p-send .btn{ flex:1 1 auto; min-width:0; display:inline-flex; align-items:center; justify-content:center; gap:var(--s2); }
.geo{ flex:0 0 auto; display:inline-flex; align-items:center; gap:var(--s2); min-height:52px; padding:0 10px 0 12px; border-radius:14px; border:1px solid var(--line-2); background:var(--line); color:var(--ink); font-size:0.9375rem; font-weight:500; transition:background .22s, border-color .22s, color .22s; }
.geo[aria-checked="true"]{ background:color-mix(in srgb, var(--accent) 14%, var(--card)); border-color:color-mix(in srgb, var(--accent) 60%, transparent); }
.geo svg{ flex:0 0 auto; color:var(--muted); transition:color .22s; }
.geo[aria-checked="true"] svg{ color:var(--accent); }
.geo .sw{ width:40px; height:24px; border-radius:12px; pointer-events:none; }
.geo .sw::after{ width:18px; height:18px; top:2px; left:2px; }
.geo[aria-checked="true"] .sw{ background:color-mix(in srgb, var(--accent) 40%, var(--card)); border-color:var(--accent); }
.geo[aria-checked="true"] .sw::after{ transform:translateX(16px); background:#FFD9D3; }
.geo:disabled{ opacity:.4; }

/* шторки */
.sheet{ position:absolute; inset:0; display:flex; align-items:flex-end; justify-content:center; background:rgba(5,6,14,.6); backdrop-filter:blur(4px); z-index:20; }
.sheet-in[data-still]{ animation:none; }
#app:has(.sheet) .p-heart{ animation-play-state:paused; }   /* под размытой шторкой сердце не пульсирует: иначе blur пересчитывается каждый кадр */
.sheet-in{ width:100%; background:color-mix(in srgb, var(--card) 85%, var(--bg)); border-radius:28px 28px 0 0; border-top:1px solid var(--line); padding:0 var(--s5) calc(var(--s5) + var(--safe-b)); animation:up .28s var(--ease); max-height:92%; overflow-y:auto; scrollbar-width:none; }
.sheet-in::-webkit-scrollbar{ display:none; }
.sheet-head{ position:sticky; top:0; z-index:1; background:inherit; display:flex; align-items:center; justify-content:flex-end; padding:var(--s3) 0 var(--s2); }
.sheet-head .grip{ position:absolute; left:50%; top:var(--s3); transform:translateX(-50%); margin:0; }
@keyframes up{ from{ transform:translateY(40px); opacity:0; } to{ transform:none; opacity:1; } }
.grip{ width:40px; height:4px; border-radius:2px; background:var(--line-2); margin:0 auto 20px; }
.h2{ font-size:1.25rem; font-weight:500; margin-bottom:var(--s2); }
.h2-edit{ display:flex; align-items:center; justify-content:center; gap:var(--s2); width:100%; min-height:var(--tap); border:0; background:none; color:var(--ink); }
.h2-edit svg{ color:var(--muted); flex:none; }
.h2-edit:active{ opacity:.7; }
.desc[data-center]{ text-align:center; margin-top:calc(-1 * var(--s4)); }
.desc{ font-size:0.8125rem; color:var(--muted); line-height:1.5; margin-bottom:var(--s4); }
.linkbox{ font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:0.75rem; line-height:1.4; word-break:break-all; padding:var(--s3) var(--s4); border-radius:16px; background:var(--line); color:var(--ink-2); max-height:96px; overflow:hidden; margin-bottom:var(--s3); -webkit-user-select:text; user-select:text; }
.row{ display:flex; gap:var(--s2); flex-wrap:wrap; }
.btn[data-big]{ min-height:72px; font-size:1.125rem; gap:var(--s3); }
.btn .logo{ width:36px; height:36px; flex:0 0 auto; }
.btn{ flex:1; min-height:52px; padding:var(--s2) var(--s4); border:1px solid transparent; border-radius:14px; background:var(--accent); color:var(--on-accent); font-size:0.9375rem; font-weight:600; transition:opacity .18s var(--ease); display:inline-flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:var(--s2); }   /* при крупном системном шрифте подпись и время на кнопке переносятся, а не вылезают за край */
.btn:active{ opacity:.8; }
.btn svg{ flex:none; display:block; }
/* знак — картинка из img/signs: рисуется как есть, а на светлой кнопке «Отправить» становится чёрным */
.sign{ display:block; flex:none; object-fit:contain; pointer-events:none; -webkit-user-drag:none; }   /* картинку нельзя тянуть: иначе браузер начинает перетаскивание и свайп по ряду знаков срывается */
.sign[data-dark="1"]{ filter:brightness(0); }
.btn[data-soft]{ background:var(--line); color:var(--ink); border-color:var(--line-2); font-weight:500; }
.btn[data-ghost]{ background:none; color:var(--muted); border-color:transparent; font-weight:500; }   /* «Сначала осмотреться»: предложение, а не действие */
/* срок жизни приглашения — в скобках на самой кнопке: отдельная строка под ней отвлекала от «Поделиться» */
.btn-t{ font-size:0.875rem; font-weight:500; opacity:.6; font-variant-numeric:tabular-nums; white-space:nowrap; }
.btn[data-danger]{ background:none; color:var(--accent); border-color:color-mix(in srgb, var(--accent) 35%, transparent); font-weight:500; }
.btn:disabled{ opacity:.4; }
.inp{ width:100%; min-height:52px; padding:0 var(--s4); border-radius:14px; background:var(--line); border:1px solid var(--line-2); font-size:1.0625rem; outline:none; -webkit-user-select:text; user-select:text; }
.inp:focus{ border-color:var(--accent); }
textarea.inp{ min-height:96px; padding:var(--s3) var(--s4); font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:0.75rem; resize:vertical; }
.err{ color:var(--accent); font-size:0.8125rem; margin-top:var(--s2); min-height:20px; }
/* второй вопрос на одном экране («Как тебя представить?») — отбит сверху, набран как строка, а не как заголовок */
.q2{ font-size:1rem; font-weight:500; margin:var(--s4) 0 var(--s2); }
.kv{ display:flex; justify-content:space-between; gap:var(--s3); padding:var(--s3) 0; border-bottom:1px solid var(--line); font-size:0.875rem; }
.kv-v{ color:var(--muted); font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:0.75rem; text-align:right; word-break:break-all; -webkit-user-select:text; user-select:text; }
.gap{ height:var(--s4); }

.help{ position:absolute; inset:0; z-index:25; background:var(--bg); display:flex; flex-direction:column; animation:fade .25s var(--ease); }
.help[data-still]{ animation:none; }
.help-bar{ flex:0 0 auto; display:flex; align-items:center; justify-content:space-between; gap:var(--s3); padding:calc(var(--s4) + var(--safe-t)) var(--s4) 0 var(--s5); }
/* шапка карточки человека: слева стрелка назад, имя посередине — нажатие переименовывает */
.help-bar[data-friend]{ padding:calc(var(--s5) + var(--safe-t)) var(--s4) var(--s3); gap:var(--s2); }
.help-bar[data-friend] .h2-edit{ flex:1 1 auto; min-width:0; margin:0; font-size:1.25rem; font-weight:500; }
.help-bar[data-friend] .h2-edit > span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.help-bar[data-friend] .inp{ min-height:var(--tap); font-size:1.0625rem; }
.bar-gap{ flex:0 0 var(--tap); }
.help-in{ flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; scrollbar-width:none; padding:var(--s3) var(--s5) calc(var(--s6) + var(--safe-b)); }
/* Экран без заголовка: кнопки лежат поверх содержимого, содержимое идёт от самого верха. Так подсветка
   под сердцем не упирается в нижний край шапки, а уходит за край экрана. */
.help[data-bare] .help-bar{ position:absolute; top:0; left:0; right:0; z-index:2; pointer-events:none; }
.help[data-bare] .help-bar .icon-btn{ pointer-events:auto; }
.help[data-bare] .help-in{ padding-top:calc(var(--s4) + var(--safe-t) + var(--tap)); }
.help-in .desc{ font-size:0.9375rem; }
.help-in .help-q:first-child{ margin-top:var(--s2); }
.help-in::-webkit-scrollbar{ display:none; }
.help-h{ font-size:1.5rem; font-weight:300; line-height:1.25; }
/* «Добавить» — те же три равные части по вертикали, что и на экране входа: сверху знак, в середине заголовок
   с двумя строками, снизу действия. Содержимое каждой части стоит по центру; если текста или кнопок больше,
   чем треть экрана (крупный системный шрифт), часть растёт по содержимому, и экран прокручивается. */
.inv{ min-height:100%; display:flex; flex-direction:column; align-items:stretch; text-align:center; gap:var(--s3); padding-bottom:var(--s2); }
.inv[data-glow]{ background:var(--glow-top); }
.inv-top, .inv-mid, .inv-bot{ flex:1 1 0; min-height:fit-content; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:var(--s4); }
.inv-bot{ gap:var(--s3); }

/* QR ссылки-приглашения: светлая подложка со скруглением — тёмные модули на светлом, как требуют сканеры
   (часть камер не берёт обратное). Поле вокруг модулей в четыре модуля рисует сам код, подложке остаётся
   небольшой отступ и тень, чтобы плашка не висела в воздухе на тёмном экране. */
.inv-qr{ width:min(56vw, 208px); aspect-ratio:1; padding:6px; border-radius:18px; background:#fff; box-shadow:0 10px 30px rgba(0,0,0,.35); }
.inv-qr svg{ display:block; border-radius:12px; }
.inv-qr-note{ display:block; margin-top:calc(-1 * var(--s2)); font-size:0.75rem; color:var(--muted); line-height:1.45; max-width:260px; }
.inv-mark{ width:64px; height:64px; border-radius:50%; border:1px solid var(--line-2); background:var(--card); color:var(--accent); display:flex; align-items:center; justify-content:center; }
.inv-h{ font-size:1.625rem; font-weight:300; line-height:1.2; text-wrap:balance; }
.inv-p{ font-size:0.9375rem; color:var(--ink-2); line-height:1.55; max-width:300px; text-wrap:balance; }
.chip{ width:100%; max-width:320px; min-height:56px; display:flex; align-items:center; gap:var(--s3); padding:var(--s2) var(--s3) var(--s2) var(--s4); border-radius:16px; border:1px solid var(--line-2); background:var(--card); color:var(--ink-2); text-align:left; }
.chip:active{ background:var(--line); }
.chip[data-wait]{ color:var(--muted); justify-content:center; }
.chip code{ flex:1 1 auto; min-width:0; font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:0.8125rem; line-height:1.4; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; background:none; padding:0; margin:0; max-height:none; color:inherit; -webkit-user-select:text; user-select:text; }   /* .linkbox внутри плашки — только имя для тестов, не рамка */
.chip[data-wait] code{ font-family:inherit; font-size:0.9375rem; }
.chip svg{ flex:none; color:var(--muted); }
/* три элемента подряд — ссылка, «Поделиться» и «Мне прислали ссылку» — одной ширины, высоты и скругления */
.inv .btn{ flex:none; width:100%; max-width:320px; min-height:56px; border-radius:16px; font-size:1rem; }
.inv .inp{ max-width:320px; min-height:56px; border-radius:16px; background:var(--card); font-size:1rem; text-align:center; }
.inv .err{ margin-top:calc(-1 * var(--s2)); min-height:0; }
.inv .hint{ max-width:320px; }
/* «Мне прислали ссылку» — второй вход на этот экран, и половина людей приходит именно за ним: не мелкая
   подпись у нижнего края, а кнопка того же размера, что приглашение. На iPhone и у того, кто сам пришёл
   по ссылке, она ещё и подсвечена акцентом. */
.inv .btn[data-hi]{ background:color-mix(in srgb, var(--accent) 15%, var(--card)); border-color:color-mix(in srgb, var(--accent) 55%, transparent); color:var(--ink); }
.inv .off{ border:0; min-height:var(--tap); font-size:0.875rem; text-decoration:underline; text-underline-offset:3px; }
.inv-note{ display:block; font-size:0.75rem; color:var(--muted); line-height:1.45; max-width:300px; opacity:.8; }

/* переключатель языка: кнопка с кодом языка и выпадающее меню на три строки */
.help-acts{ flex:0 0 auto; display:flex; align-items:center; gap:var(--s2); }
/* меню главного экрана: три точки, под ними справка, настройки и копия */
.menu{ position:relative; flex:0 0 auto; }
.menu[data-open="1"] .icon-btn{ border-color:var(--accent); color:var(--accent); }
/* уведомления не обновились: вместо полоски на весь экран — точка на кнопке меню, а подробности внутри */
.menu[data-alarm="1"] .icon-btn{ border-color:color-mix(in srgb, var(--alarm) 60%, transparent); }
.menu[data-alarm="1"]::after{ content:""; position:absolute; top:2px; right:2px; width:9px; height:9px; border-radius:50%; background:var(--alarm); box-shadow:0 0 0 2px var(--bg); }
.menu-list{ position:absolute; z-index:6; top:calc(100% + 6px); right:0; min-width:246px; padding:6px; border-radius:16px; border:1px solid var(--line-2); background:var(--card); box-shadow:0 18px 40px rgba(0,0,0,.45); animation:langIn .16s var(--ease); }
.menu-i{ width:100%; min-height:44px; padding:0 12px; white-space:nowrap; border:0; border-radius:11px; background:none; color:var(--ink); display:flex; align-items:center; gap:var(--s3); font-size:1rem; text-align:left; }
.menu-i:active{ background:var(--line); }
.menu-i svg{ flex:none; color:var(--muted); }
.lang{ position:relative; flex:0 0 auto; font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }   /* в настройках строка рядом набрана моноширинным: меню не должно его наследовать */
.lang-btn{ min-height:36px; padding:0 8px 0 12px; border-radius:18px; border:1px solid var(--line-2); background:var(--card); color:var(--ink); display:flex; align-items:center; gap:2px; font-size:0.8125rem; font-weight:600; letter-spacing:.1em; text-transform:uppercase; }
.lang-btn:active{ background:var(--line); }
.lang-btn svg{ transition:transform .2s var(--ease); opacity:.7; }
.lang[data-open="1"] .lang-btn{ border-color:var(--accent); color:var(--accent); }
.lang[data-open="1"] .lang-btn svg{ transform:rotate(180deg); }
.lang-menu{ position:absolute; z-index:5; top:calc(100% + 6px); right:0; min-width:172px; padding:6px; border-radius:16px; border:1px solid var(--line-2); background:var(--card); box-shadow:0 18px 40px rgba(0,0,0,.45); animation:langIn .16s var(--ease); }
@keyframes langIn{ from{ opacity:0; transform:translateY(-6px); } }
.lang-i{ width:100%; min-height:40px; padding:0 10px 0 8px; border:0; border-radius:11px; background:none; color:var(--ink-2); display:flex; align-items:center; gap:var(--s2); font-size:0.9375rem; text-align:left; }
.lang-i:active{ background:var(--line); }
.lang-i > span:first-of-type{ flex:1; }
.lang-i svg{ flex:none; opacity:0; color:var(--accent); }
.lang-i[data-on="1"]{ color:var(--ink); font-weight:600; }
.lang-i[data-on="1"] svg{ opacity:1; }
.lang-code{ flex:none; font-size:0.6875rem; letter-spacing:.12em; text-transform:uppercase; color:var(--muted); }
.kv .lang-btn{ min-height:32px; }
.set-g{ margin-top:var(--s5); }
.set-h{ font-size:0.75rem; color:var(--muted); letter-spacing:.08em; text-transform:uppercase; margin:0 0 var(--s2) var(--s3); }
.set-card{ background:var(--card); border:1px solid var(--line); border-radius:18px; padding:0 var(--s4); }
.set-card .kv:last-child{ border-bottom:0; }
.set-card > .desc{ margin:0; padding:var(--s3) 0; }
.set-card > .desc.set-note{ padding-top:0; margin-top:calc(-1 * var(--s1)); }
.set-card .kv + .set-act{ border-top:0; }
.set-act{ padding:var(--s3) 0 var(--s4); }
.set-card > .desc + .set-act{ padding-top:var(--s1); }
.set-card .err{ margin:0 0 var(--s2); }
.set-sep{ height:1px; background:var(--line); margin:0 calc(-1 * var(--s4)); }
.set-sub{ font-size:0.875rem; font-weight:500; padding:var(--s4) 0 0; }
.set-sub + .desc{ padding-top:var(--s1); }
/* история знаков: список сроков, один отмечен */
.keep{ display:flex; flex-direction:column; }
.keep-i{ width:100%; min-height:var(--tap); padding:var(--s2) 0; border:0; border-bottom:1px solid var(--line); border-radius:0; background:none; display:grid; grid-template-columns:minmax(0,1fr) auto; gap:var(--s3); align-items:center; text-align:left; font-size:15px; color:var(--ink-2); }
.keep-i:last-child{ border-bottom:0; }
.keep-i:active{ background:color-mix(in srgb, var(--line) 60%, transparent); }
.keep-i > span:first-child{ display:flex; flex-direction:column; }
.keep-i small{ font-size:12px; color:var(--muted); }
.keep-i[aria-checked="true"]{ color:var(--ink); font-weight:600; }
.keep-i[aria-checked="true"] small{ font-weight:400; }
.keep-dot{ width:22px; height:22px; border-radius:50%; border:1px solid var(--line-2); display:flex; align-items:center; justify-content:center; color:var(--accent); transition:border-color .2s; }
.keep-dot svg{ opacity:0; transition:opacity .2s; }
.keep-i[aria-checked="true"] .keep-dot{ border-color:var(--accent); }
.keep-i[aria-checked="true"] .keep-dot svg{ opacity:1; }
.keep-now{ padding:var(--s3) 0; font-size:13px; color:var(--muted); border-top:1px solid var(--line); line-height:1.45; }
/* Экран PIN: внутри рамки, выше шторок (20), ниже пришедшего знака (30) и предупреждения (35) — знак виден и без кода */
.pin{ position:absolute; inset:0; z-index:25; background:var(--bg); display:flex; flex-direction:column; overflow-y:auto; scrollbar-width:none;
  padding:calc(var(--s4) + var(--safe-t)) var(--s5) calc(var(--s5) + var(--safe-b)); animation:fade .25s var(--ease); }
.pin[data-flow="lock"]{ background:var(--glow-top), var(--bg); }
.pin[data-still]{ animation:none; }   /* перерисовка при вводе не проигрывает появление заново */
.pin-top{ display:flex; justify-content:flex-end; flex:0 0 auto; }
.pin-body{ flex:1 0 auto; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; gap:var(--s2); }   /* не сжимается: на низком экране .pin прокручивается */
.pin-brand{ display:flex; flex-direction:column; align-items:center; gap:var(--s3); color:var(--accent); margin-bottom:var(--s5); }
.pin-brand .title{ color:var(--ink); font-size:1.375rem; }
.pin-h{ font-size:1.5rem; font-weight:300; line-height:1.2; }
.pin-p{ font-size:0.875rem; color:var(--muted); line-height:1.5; max-width:280px; }
.pin-dots{ display:flex; gap:18px; margin:var(--s5) 0 var(--s2); }
.pin-dots[data-shake="1"]{ animation:pin-shake .4s var(--ease); }
.pin-dot{ width:16px; height:16px; border-radius:50%; border:1.5px solid var(--line-2); background:none; transition:background .15s, border-color .15s, transform .15s; }
.pin-dot[data-on="1"]{ background:var(--accent); border-color:var(--accent); transform:scale(1.08); box-shadow:0 0 14px color-mix(in srgb, var(--accent) 55%, transparent); }
.pin-err{ min-height:24px; font-size:0.9375rem; font-weight:500; color:var(--danger); }
.pin-key:disabled{ opacity:.35; }
.pin-keys{ display:grid; grid-template-columns:repeat(3, 76px); gap:14px 22px; margin-top:var(--s3); }
.pin-key{ width:76px; height:76px; border-radius:50%; border:1px solid var(--line); background:var(--card); color:var(--ink); font-size:1.75rem; font-weight:300;
  display:flex; align-items:center; justify-content:center; transition:background .12s, transform .12s; }
.pin-key:active{ background:var(--line-2); transform:scale(.96); }
.pin-key[data-id="del"]{ background:none; border-color:transparent; color:var(--muted); }
.pin-forgot{ margin-top:var(--s5); border:0; background:none; color:var(--muted); font-size:0.875rem; text-decoration:underline; text-underline-offset:3px; min-height:var(--tap); }
.pin-forgot-p{ font-size:0.8125rem; color:var(--muted); line-height:1.5; max-width:300px; }
.kv.pin-row > span:first-child, .kv:has(> .sw) > span:first-child{ display:flex; flex-direction:column; gap:2px; justify-content:center; }
.kv.pin-row small, .kv:has(> .sw) small{ font-size:0.75rem; color:var(--muted); }
.kv.pin-row, .kv:has(> .sw){ align-items:center; }
@keyframes pin-shake{ 0%,100%{ transform:none } 20%{ transform:translateX(-10px) } 40%{ transform:translateX(9px) } 60%{ transform:translateX(-6px) } 80%{ transform:translateX(4px) } }
@media (max-height:700px){ .pin-key{ width:64px; height:64px; font-size:1.5rem; } .pin-keys{ grid-template-columns:repeat(3, 64px); gap:10px 18px; } }
.help-q{ font-size:1.0625rem; font-weight:600; margin-top:var(--s5); margin-bottom:var(--s2); }
.help-a{ font-size:0.9375rem; color:var(--ink-2); line-height:1.6; }
.help-a[data-lead]{ font-size:1.0625rem; color:var(--ink); }
.help-end{ margin-top:var(--s6); text-align:center; font-size:1.0625rem; color:var(--accent); font-weight:300; }
.help-heart{ display:flex; justify-content:center; margin-top:var(--s4); opacity:.9; }

.w-heart, .inv-heart{ display:flex; justify-content:center; filter:drop-shadow(0 0 28px color-mix(in srgb, var(--accent) 70%, transparent)); animation:soft 2.6s ease-in-out infinite; }   /* одно сердце на весь вход: экран приглашения светится так же, как первый экран */
.w-h{ text-align:center; font-size:1.75rem; font-weight:300; line-height:1.2; }
.w-steps{ display:flex; flex-direction:column; gap:var(--s3); margin-top:calc(var(--s2) * -1); }
.w-step{ display:flex; gap:var(--s3); align-items:flex-start; font-size:1rem; line-height:1.45; color:var(--ink-2); }
.w-dot{ flex:0 0 28px; height:28px; display:flex; align-items:center; justify-content:center; color:var(--accent); }

/* сердечко */
/* предупреждение перед отключением: во весь экран, мимо не пройдёшь */
.warn{ position:absolute; inset:0; z-index:35; background:radial-gradient(78% 22% at 50% 22%, color-mix(in srgb, var(--danger) 26%, transparent), transparent 70%), var(--bg); display:flex; flex-direction:column; align-items:center; justify-content:center; gap:var(--s4); text-align:center; padding:calc(var(--s5) + var(--safe-t)) var(--s5) calc(var(--s5) + var(--safe-b)); animation:fade .25s var(--ease); overflow-y:auto; }
.warn-ic{ width:88px; height:88px; flex:none; border-radius:50%; border:1px solid color-mix(in srgb, var(--danger) 45%, transparent); background:color-mix(in srgb, var(--danger) 14%, var(--bg)); color:var(--danger); display:flex; align-items:center; justify-content:center; filter:drop-shadow(0 0 30px color-mix(in srgb, var(--danger) 45%, transparent)); }
.warn-h{ font-size:1.75rem; font-weight:300; line-height:1.2; }
.warn-who{ font-size:1.375rem; font-weight:600; color:var(--danger); word-break:break-word; }
.warn-p{ font-size:1rem; line-height:1.55; color:var(--ink-2); max-width:320px; }
.warn-acts{ width:100%; max-width:320px; display:flex; flex-direction:column; gap:var(--s3); margin-top:var(--s2); }
.warn-acts .btn{ width:100%; }
.btn[data-erase]{ background:none; color:var(--danger); border-color:color-mix(in srgb, var(--danger) 45%, transparent); font-weight:500; }
.heart{ position:absolute; inset:0; z-index:30; display:flex; flex-direction:column; align-items:center; justify-content:flex-start; text-align:center; overflow-y:auto; scrollbar-width:none; padding:var(--s5); padding-bottom:calc(var(--s5) + var(--safe-b)); padding-top:calc(var(--s5) + var(--safe-t)); background:radial-gradient(ellipse at 50% 42%, color-mix(in srgb, var(--accent) 38%, var(--bg)), var(--bg) 72%); animation:fade .3s var(--ease); }
@keyframes fade{ from{ opacity:0; } to{ opacity:1; } }
.heart[data-still]{ animation:none; }                        /* перерисовка того же сердечка не проигрывает появление заново */
.heart[data-out="1"]{ animation:dissolve .55s var(--ease) forwards; pointer-events:none; }
@keyframes dissolve{ from{ opacity:1; transform:scale(1); filter:blur(0); } to{ opacity:0; transform:scale(1.06); filter:blur(10px); } }
.heart-big{ width:150px; height:150px; filter:drop-shadow(0 0 36px color-mix(in srgb, var(--glow, var(--accent)) 85%, transparent)); animation:beat 1.1s ease-in-out infinite; }
.heart-big .sign{ width:100%; height:100%; }
.heart{ background:radial-gradient(ellipse at 50% 42%, color-mix(in srgb, var(--glow, var(--accent)) 38%, var(--bg)), var(--bg) 72%); }
@keyframes beat{ 0%,100%{ transform:scale(1); } 25%{ transform:scale(1.14); } 45%{ transform:scale(.98); } 65%{ transform:scale(1.1); } }
.heart-ic{ margin-top:var(--s4); filter:drop-shadow(0 0 16px color-mix(in srgb, var(--glow, var(--accent)) 80%, transparent)); animation:soft 2.6s ease-in-out infinite; }
.heart-ic + .heart-who{ margin-top:var(--s2); }
.heart-who{ font-size:2.375rem; font-weight:300; margin-top:28px; line-height:1.1; }
.heart-txt{ font-size:1.0625rem; color:var(--ink-2); margin-top:var(--s2); }
.heart-note{ font-size:0.8125rem; color:var(--muted); margin-top:var(--s3); }
.heart-when{ font-size:0.75rem; color:var(--muted); margin-top:var(--s5); letter-spacing:.02em; font-variant-numeric:tabular-nums; opacity:.85; }   /* когда отправлен: тихо, под всем остальным */
.heart-actions{ display:flex; flex-direction:column; align-items:center; gap:var(--s3); margin-top:40px; width:100%; flex:none; }
.heart > *{ flex:none; }   /* при нехватке высоты содержимое не сжимается, а прокручивается */
.heart::before, .heart::after{ content:""; flex:1 1 0; min-height:0; }   /* центровка распорками: при переполнении верх не обрезается, как было бы с justify-content:center */
.heart::-webkit-scrollbar{ display:none; }
@media (max-height:700px){ .heart .p-dial{ width:200px; height:200px; } .heart .p-n{ transform:translate(-50%,-50%) translateY(-81px); } .heart .p-north{ transform:translate(-50%,-50%) rotate(var(--h,0deg)) translateY(-81px); } .heart-actions{ margin-top:var(--s5); } .heart-who{ margin-top:var(--s4); } }
.heart-actions .btn{ flex:none; width:min(100%, 280px); display:inline-flex; align-items:center; justify-content:center; }
.heart-x{ position:absolute; top:calc(var(--s4) + var(--safe-t)); right:var(--s4); width:var(--tap); height:var(--tap); border-radius:50%; border:1px solid var(--line-2); background:color-mix(in srgb, var(--bg) 60%, transparent); color:var(--ink-2); display:flex; align-items:center; justify-content:center; }
.spark{ position:absolute; width:18px; height:18px; animation:fly 2.6s ease-out forwards; pointer-events:none; }
@keyframes fly{ from{ opacity:0; transform:translateY(0) scale(.6); } 20%{ opacity:1; } to{ opacity:0; transform:translateY(-260px) scale(1.2); } }
.toast{ position:absolute; left:50%; bottom:calc(96px + var(--safe-b)); transform:translateX(-50%); background:color-mix(in srgb, var(--card) 60%, var(--line-2)); border:1px solid var(--line-2); padding:var(--s3) 20px; border-radius:16px; font-size:0.875rem; text-align:center; max-width:88%; z-index:40; pointer-events:none; animation:fade .25s var(--ease); }
@media (prefers-reduced-motion:reduce){ *{ animation:none !important; transition:none !important; } }

/* Ссылка-приглашение вне установленного Toccami: код крупно, под ним три шага. Код нажимается — копируется */
.gate .onb-top{ gap:var(--s3); }
.gate .w-h{ font-size:1.5rem; }
.gate .onb-mid{ width:100%; gap:var(--s3); }
.gate .ht-steps{ width:100%; margin-top:0; }
.gate-code{ width:100%; display:flex; flex-direction:column; align-items:center; gap:var(--s1); padding:var(--s3) var(--s4); border-radius:16px; border:1px dashed var(--line-2); background:var(--card); color:var(--ink); }
.gate-code:active{ background:var(--line); }
.gate-code small{ font-size:0.75rem; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.gate-code code{ font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:1.75rem; letter-spacing:.06em; color:var(--ink); -webkit-user-select:all; user-select:all; }
.gate-inst{ margin-top:var(--s1); padding:0; border:0; background:none; color:var(--accent); font:inherit; font-size:0.8125rem; text-decoration:underline; text-underline-offset:3px; min-height:24px; }
/* у пригласившего — тот же код крупно, а не длинная ссылка */
.chip[data-code] code{ font-size:1.375rem; letter-spacing:.06em; color:var(--ink); text-align:center; }
/* шаги по порядку — цифрами, а не значками */
.onb-ic[data-num]{ font-size:1.25rem; font-weight:500; color:var(--accent); font-variant-numeric:tabular-nums; }
/* шаги инструкции и кнопка под ними не слипаются */
.ht-steps + .row{ margin-top:var(--s5); }

/* Вёрстка текста: заголовки делятся на строки поровну (никаких «полутора строк»), в абзацах и шагах
   нет коротких хвостов из одного слова. Браузер без этих свойств просто переносит, как раньше */
.h2, .w-h, .onb-h, .q2, .onb-step b, .rr-t, .hint span{ text-wrap:balance; }
.desc, .onb-p, .onb-step small, .inv-note, .err{ text-wrap:pretty; }

/* Инструкции читают, а не пробегают глазами: шаги установки и экран с кодом — крупнее остального
   приложения (16 px строка шага, 15 px подпись), а главные экраны остаются в своих изящных кеглях */
.ht-steps .onb-step{ font-size:1rem; }
.ht-steps .onb-step[data-ios] small{ font-size:0.9375rem; }
.desc:has(+ .ht-steps){ font-size:0.9375rem; }
.gate-inst{ font-size:0.9375rem; }
/* шаги: текст занимает всю ширину рядом с цифрой, ссылка «Установить» — слева, как и строки над ней */
.onb-step[data-ios] > span:last-child{ flex:1 1 auto; min-width:0; text-align:left; }
.gate-inst{ display:block; text-align:left; }
.gate .w-h{ font-size:1.375rem; }
/* открыли на телефоне мимо экрана Домой: под кнопкой «Установить» — тихая строка для тех, у кого уже стоит */
.h-note{ width:100%; text-align:center; font-size:0.9375rem; color:var(--muted); line-height:1.5; text-wrap:balance; }

/* «Добавить» одной страницей: QR поменьше, два раздела с короткими заголовками и «или» между ними */
.add1{ justify-content:flex-start; gap:var(--s4); padding-bottom:var(--s5); }
.add1 .inv-top{ flex:none; gap:var(--s3); }
.add1 .inv-qr{ width:min(44vw, 168px); }
.add-sec{ display:flex; flex-direction:column; align-items:center; gap:var(--s3); width:100%; }
.add-h{ font-size:1.125rem; font-weight:400; color:var(--ink); }
.add-or{ display:flex; align-items:center; gap:var(--s3); width:100%; max-width:320px; align-self:center; color:var(--muted); font-size:0.8125rem; }
.add-or::before, .add-or::after{ content:''; flex:1; height:1px; background:var(--line-2); }
.add-row{ display:flex; gap:var(--s2); width:100%; max-width:320px; }
.add-row .inp{ flex:1 1 auto; min-width:0; letter-spacing:.04em; }
.inv .add-row .btn{ width:auto; flex:none; padding:0 var(--s4); }
.add-msg{ font-size:0.875rem; color:var(--muted); }
.add1 .err{ margin-top:0; }
/* QR — сколько позволит экран: страница ровно в высоту окна, QR забирает всё свободное по высоте и не шире экрана,
   остальное (код, «Пригласить», «или», поле) своего размера. Прокрутки нет; на совсем низком окне QR не меньше 120 px */
.add1{ height:100%; min-height:0; gap:var(--s3); padding-bottom:0; }
.add1 .inv-top{ flex:1 1 0; min-height:150px; justify-content:center; gap:var(--s2); }
.add1{ container-type:inline-size; }
.add1 .inv-qr{ flex:1 1 0; min-height:120px; width:auto; max-width:100%; max-height:min(100%, 360px, 100cqw); aspect-ratio:1; }   /* 100cqw — ширина страницы: QR всегда квадрат */
.add1 .inv-qr svg{ width:100%; height:100%; }
.add1 .inv-qr-note{ margin-top:0; flex:none; }
.add1 .add-sec, .add1 .add-or{ flex:none; }
/* на «Добавить» снизу запас над системной полосой: поле кода не прячется под нижним меню Android и до него легко дотянуться */
.help[data-bare] .help-in:has(.add1){ padding-bottom:calc(var(--s6) + var(--s4) + var(--safe-b)); }
@container (max-width:300px){ .inv .add-row .btn span{ display:none; } }   /* совсем узко: «Вставить» — одним значком, поле кода целиком */

/* Toccami не запустился: короткий заголовок, одна фраза и три карточки «что помогает», техническая причина — свёрнута */
.fatal .onb-top{ gap:var(--s4); }
.fatal .onb-h{ font-size:1.5rem; text-wrap:balance; }
.fatal .onb-p{ text-align:center; color:var(--ink-2); text-wrap:pretty; }
.fatal .onb-mid{ width:100%; gap:var(--s4); }
.fatal .ht-steps{ width:100%; margin-top:0; }
.fatal .onb-ic{ color:var(--accent); }
.fatal-why{ width:100%; font-size:0.8125rem; color:var(--muted); line-height:1.5; text-align:center; word-break:break-word; }
.fatal-why summary{ cursor:pointer; list-style:none; min-height:var(--tap); display:flex; align-items:center; justify-content:center; text-decoration:underline; text-underline-offset:3px; }
.fatal-why summary::-webkit-details-marker{ display:none; }
.fatal{ justify-content:center; gap:var(--s5); }
.fatal .onb-top, .fatal .onb-mid, .fatal .onb-bot{ flex:none; }
.fatal .empty-dial{ width:64px; height:64px; }
.fatal .onb-h{ font-size:1.375rem; }
.fatal .onb-ic svg{ width:20px; height:20px; }

/* Барабан: главный список растворяется в тени под шапкой и под «Добавить» — только градиент, без наклона строк */
.body[data-drum]{ --drum-top:0px; -webkit-mask-image:linear-gradient(to bottom, transparent 0, #000 calc(var(--drum-top) * 1.6), #000 calc(100% - 128px - var(--safe-b)), transparent calc(100% - 40px - var(--safe-b))); mask-image:linear-gradient(to bottom, transparent 0, #000 calc(var(--drum-top) * 1.6), #000 calc(100% - 128px - var(--safe-b)), transparent calc(100% - 40px - var(--safe-b))); }

/* Самые близкие: тёплая строка цветом сердца, «i» в золотом круге, тонкая черта под последним из них */
:root{ --gold:#FFC94D; }
.row-f[data-close]{ background:linear-gradient(90deg, color-mix(in srgb, var(--accent) 16%, var(--card)), var(--card) 75%); }
.row-f[data-close] .more{ border-color:var(--gold); color:var(--gold); background:color-mix(in srgb, var(--gold) 10%, transparent); box-shadow:0 0 12px color-mix(in srgb, var(--gold) 30%, transparent); }
.row-f[data-close-last]{ border-bottom-color:var(--line-2); }
/* золотое сердечко в шапке страницы человека: контур — не отмечен, залито — отмечен; нажатие чуть подпрыгивает */
.close-mark{ flex:none; border-color:color-mix(in srgb, var(--gold) 45%, var(--line-2)); }
.close-mark[aria-pressed="true"]{ border-color:var(--gold); background:color-mix(in srgb, var(--gold) 12%, transparent); box-shadow:0 0 14px color-mix(in srgb, var(--gold) 35%, transparent); }
.close-mark[aria-pressed="true"] svg{ animation:closePop .45s var(--ease); }
@keyframes closePop{ 0%{ transform:scale(.6); } 60%{ transform:scale(1.18); } 100%{ transform:scale(1); } }
/* «⋯» в шапке — на одной вертикали с кнопками «i» в списке: центр «i» = край экрана − 16 (поле) − 1 (рамка) − 8 (отступ строки)
   − 2 (поле кнопки) − 20 (полкнопки) = −47; у «⋯» шириной 44 это поле справа 47 − 22 = 25 */
.top{ padding-right:25px; }
/* та же вертикаль у правых кнопок всех экранов: «Добавить», настройки, справка, страница человека (на 9 px левее прежнего) */
.help-bar, .help-bar[data-friend]{ padding-right:25px; }
.p-bar{ padding-right:9px; }
.sheet-head .icon-btn{ margin-right:1px; }   /* крестик шторок — на той же вертикали, что «i» в списке */
/* круглые кнопки шапок всех страниц — на одной высоте со страницей человека: отступ сверху как у неё, а длинный
   заголовок рядом растёт вниз и кнопку не сдвигает */
.help-bar{ padding-top:calc(var(--s5) + var(--safe-t)); align-items:flex-start; }
.help-bar .help-h{ align-self:center; }
.help[data-bare] .help-in{ padding-top:calc(var(--s5) + var(--safe-t) + var(--tap)); }   /* содержимое — под опущенной шапкой, QR не заходит под кнопки */
.top .menu{ margin-top:calc(var(--s5) - var(--s4)); }   /* «⋯» — на той же высоте, что правые кнопки всех страниц; заголовок не двигается */
