/* ============================================================ ЗОВ MiniApp — design system v3 ("Architectural Clean") Гибрид Architectural Clean (Claude.ai Frontend Design) + бренд-палитра ЗОВ + редакторская типографика ============================================================ */ :root { /* ====== Brand ====== */ --zov-blue: #003E7E; --zov-green: #76BD22; --zov-warning: #C0392B; /* ====== Paper palette (ВАРИАНТ A — светлая «бумага») ====== */ --paper: var(--tg-theme-bg-color, #FAFAF7); --paper-2: var(--tg-theme-secondary-bg-color, #F0EDE5); --card: var(--tg-theme-section-bg-color, #FFFFFF); --ink: var(--tg-theme-text-color, #0F0F0E); --ink-2: #2A2622; --muted: var(--tg-theme-hint-color, #6E6A62); --muted-2: #A09C92; --line: rgba(15, 15, 14, 0.08); --line-strong: rgba(15, 15, 14, 0.16); /* ====== Status ====== */ --status-active: var(--zov-green); --status-active-bg: rgba(118, 189, 34, 0.10); --status-lapsed: var(--zov-warning); --status-lapsed-bg: rgba(192, 57, 43, 0.08); --status-grace: #B07E00; --status-grace-bg: rgba(176, 126, 0, 0.08); /* ====== Radii (architectural — небольшие скругления) ====== */ --r-tag: 4px; --r-btn: 12px; --r-card: 14px; --r-pill: 999px; /* ====== Spacing ====== */ --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 20px; --s6: 24px; --s7: 32px; --s8: 40px; /* ====== Type ====== */ --font-ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif; --font-display: "Instrument Serif", Georgia, "Times New Roman", serif; --font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; } /* ====== Dark theme — both via OS preference and Telegram-driven [data-theme="dark"] ====== */ @media (prefers-color-scheme: dark) { :root { color-scheme: dark; } } html[data-theme="dark"], @media (prefers-color-scheme: dark) { :root, html[data-theme="dark"] { --paper: var(--tg-theme-bg-color, #14130E); --paper-2: var(--tg-theme-secondary-bg-color, #1F1D17); --card: var(--tg-theme-section-bg-color, #1C1A14); --ink: var(--tg-theme-text-color, #F4F1EA); --ink-2: #C8C3B5; --muted: var(--tg-theme-hint-color, #A5A299); --muted-2: #807D74; --line: rgba(255, 255, 255, 0.10); --line-strong: rgba(255, 255, 255, 0.20); --status-active-bg: rgba(118, 189, 34, 0.22); --status-lapsed-bg: rgba(220, 38, 38, 0.22); --status-grace-bg: rgba(217, 119, 6, 0.22); } } /* Force light theme when explicitly set (overrides OS dark) */ html[data-theme="light"] { --paper: var(--tg-theme-bg-color, #FAFAF7); --paper-2: var(--tg-theme-secondary-bg-color, #F0EDE5); --card: var(--tg-theme-section-bg-color, #FFFFFF); --ink: var(--tg-theme-text-color, #0F0F0E); --ink-2: #2A2622; --muted: var(--tg-theme-hint-color, #6E6A62); --muted-2: #A09C92; --line: rgba(15, 15, 14, 0.08); --line-strong: rgba(15, 15, 14, 0.16); } /* ============================================================ Reset ============================================================ */ * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; } html, body { margin: 0; padding: 0; } body { font-family: var(--font-ui); font-size: 15px; font-weight: 400; line-height: 1.45; letter-spacing: -0.01em; color: var(--ink); background: var(--paper); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; font-feature-settings: "ss01", "cv01", "cv11"; } a { color: inherit; text-decoration: none; } button { font: inherit; cursor: pointer; border: none; background: none; color: inherit; padding: 0; } /* ============================================================ Layout ============================================================ */ #app { max-width: 560px; margin: 0 auto; padding: var(--s5) var(--s4) calc(var(--s8) + env(safe-area-inset-bottom)); min-height: 100vh; } /* ============================================================ Loader ============================================================ */ .loader { display: grid; place-items: center; min-height: 60vh; } .spinner { width: 32px; height: 32px; border: 1.5px solid var(--line-strong); border-top-color: var(--zov-blue); border-radius: 50%; animation: spin 0.7s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* ============================================================ Profile card (header) — editorial premium ============================================================ */ .profile-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); padding: var(--s6) var(--s5) var(--s5); margin-bottom: var(--s7); position: relative; overflow: hidden; } /* Тонкая брендовая «лента» сверху карточки */ .profile-card::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(90deg, var(--zov-blue) 0%, var(--zov-green) 100%); } .profile-card .role-tag { font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-bottom: var(--s2); display: inline-flex; align-items: center; gap: var(--s2); } .profile-card .role-tag::after { content: ""; display: inline-block; width: 24px; height: 1px; background: var(--line-strong); vertical-align: middle; } .profile-card .head-row { display: flex; align-items: flex-start; gap: var(--s4); margin-bottom: var(--s4); } .profile-card .info { flex: 1; min-width: 0; } .profile-card .name { font-family: var(--font-display); font-style: italic; font-size: 30px; font-weight: 400; line-height: 1.05; letter-spacing: -0.02em; color: var(--ink); margin-bottom: var(--s2); word-break: break-word; } .profile-card .meta { font-size: 14px; color: var(--ink-2); } .profile-card .avatar { width: 52px; height: 52px; border-radius: 50%; background: var(--paper-2); display: grid; place-items: center; flex-shrink: 0; font-family: var(--font-display); font-style: italic; font-size: 26px; font-weight: 400; color: var(--zov-blue); border: 1px solid var(--line-strong); } .profile-card .meta-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin-top: var(--s4); padding-top: var(--s4); border-top: 1px solid var(--line); } .profile-card .meta-row .sep { color: var(--muted-2); } .profile-card .status-row { display: inline-flex; align-items: center; gap: var(--s2); } .profile-card .status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--zov-green); box-shadow: 0 0 0 3px rgba(118, 189, 34, 0.18); animation: pulse 2.5s ease-in-out infinite; } @keyframes pulse { 0%, 100% { box-shadow: 0 0 0 3px rgba(118, 189, 34, 0.18); } 50% { box-shadow: 0 0 0 6px rgba(118, 189, 34, 0); } } .profile-card .status-dot.lapsed { background: var(--zov-warning); box-shadow: 0 0 0 3px rgba(192, 57, 43, 0.20); animation: none; } .profile-card .status-dot.grace { background: var(--status-grace); box-shadow: 0 0 0 3px rgba(176, 126, 0, 0.20); } /* ============================================================ Section label ============================================================ */ .section-label { font-family: var(--font-mono); font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.14em; color: var(--muted); padding: 0 var(--s4); margin: var(--s7) 0 var(--s3); display: flex; align-items: center; gap: var(--s3); } .section-label::after { content: ""; flex: 1; height: 1px; background: var(--line); } .section-label:first-child { margin-top: 0; } /* ============================================================ Menu (grouped list — minimal architectural) ============================================================ */ .menu { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); overflow: hidden; } .menu + .menu { margin-top: var(--s4); } .menu-item { display: flex; align-items: center; gap: var(--s4); padding: var(--s4) var(--s5); min-height: 64px; color: var(--ink); cursor: pointer; transition: background 0.12s; position: relative; } .menu-item + .menu-item::before { content: ""; position: absolute; top: 0; left: var(--s5); right: 0; height: 1px; background: var(--line); } .menu-item:active { background: var(--paper-2); } .menu-item .icon { width: 32px; height: 32px; display: grid; place-items: center; flex-shrink: 0; color: var(--ink); } .menu-item .icon svg { width: 22px; height: 22px; stroke-width: 1.6; } /* Тонкие цветовые акценты для ключевых разделов — без «таблеток» */ .menu-item .icon.green { color: var(--zov-green); } .menu-item .icon.blue { color: var(--zov-blue); } .menu-item .icon.gold { color: var(--status-grace); } .menu-item .text { flex: 1; min-width: 0; } .menu-item .label { font-family: var(--font-ui); font-size: 15px; font-weight: 500; letter-spacing: -0.01em; display: flex; align-items: center; gap: var(--s2); } .menu-item .sub { font-family: var(--font-mono); font-size: 11px; font-weight: 400; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); margin-top: 4px; } .menu-item .chevron { color: var(--muted-2); flex-shrink: 0; display: flex; align-items: center; } .menu-item .chevron svg { width: 18px; height: 18px; } .menu-item.disabled { cursor: not-allowed; } .menu-item.disabled .label, .menu-item.disabled .icon { color: var(--muted); opacity: 0.7; } html[data-theme="dark"] .menu-item.disabled .label, html[data-theme="dark"] .menu-item.disabled .icon { opacity: 0.85; } .badge { display: inline-block; font-family: var(--font-mono); font-size: 9.5px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.1em; padding: 2px 8px; border-radius: var(--r-tag); background: var(--paper-2); color: var(--muted); vertical-align: 2px; } /* ============================================================ Footer hint — editorial signature ============================================================ */ .footer-hint { text-align: center; margin-top: var(--s8); padding: var(--s5) var(--s4) 0; border-top: 1px solid var(--line); } .footer-hint .signature { font-family: var(--font-display); font-style: italic; font-size: 16px; color: var(--ink-2); margin-bottom: var(--s2); } .footer-hint .meta { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); } .footer-hint a { color: var(--zov-blue); } @media (prefers-color-scheme: dark) { .footer-hint a { color: #6FA0D6; } } /* ============================================================ Error state ============================================================ */ .error { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); padding: var(--s7) var(--s5); text-align: center; color: var(--muted); } .error h3 { font-family: var(--font-display); font-style: italic; font-size: 22px; font-weight: 400; margin: 0 0 var(--s2); color: var(--ink); }