@font-face { font-family: "Twemoji Country Flags"; src: url("https://cdn.jsdelivr.net/npm/country-flag-emoji-polyfill@0.1/dist/TwemojiCountryFlags.woff2") format("woff2"); font-display: swap; unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E0063, U+E0065, U+E0067, U+E006C, U+E006E, U+E0073-E0074, U+E0077, U+E007F; } :root { --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif; --font-mono: "JetBrains Mono", "Fira Code", monospace; color-scheme: dark; --accent: #00fe7a; --bg: #03070b; --panel: #111820; --panel-2: #0b1118; --panel-3: #17212b; --border: rgba(255, 255, 255, 0.12); --border-strong: rgba(255, 255, 255, 0.2); --text: #f2f7f4; --muted: #a9b4b0; --dim: #68736f; --danger: #ff6b6b; --blue: #2d9cff; --radius: 8px; /* Admin design tokens — kept on :root so portal-rendered admin surfaces (dialogs, bits-ui Select.Portal content) inherit them. */ --admin-bg: var(--bg); --admin-surface: var(--panel); --admin-surface-2: var(--panel-2); --admin-elev: var(--panel-3); --admin-border: var(--border); --admin-border-strong: var(--border-strong); --admin-text: var(--text); --admin-muted: var(--muted); --admin-dim: var(--dim); --admin-ring: color-mix(in srgb, var(--accent) 50%, transparent); --screen-gutter: 18px; --safe-inline: max(env(safe-area-inset-left), env(safe-area-inset-right)); --nav-inline-gutter: max(var(--screen-gutter), var(--safe-inline)); --bottom-nav-height: 64px; --bottom-nav-offset: 10px; --bottom-nav-left: calc(max(0px, (100% - 440px) / 2) + var(--nav-inline-gutter)); --bottom-nav-width: min( calc(100% - (var(--nav-inline-gutter) * 2)), calc(440px - (var(--nav-inline-gutter) * 2)) ); font-family: var(--font-sans); } * { box-sizing: border-box; } html, body, #app { min-height: 100%; margin: 0; overflow-x: clip; } body { background: #02070b; color: var(--text); -webkit-font-smoothing: antialiased; letter-spacing: 0; } button, input { font: inherit; letter-spacing: 0; } button { cursor: pointer; } button:disabled { cursor: progress; opacity: 0.58; } a { color: inherit; } .app-shell { min-height: 100dvh; background: #02070b !important; } .phone-screen { position: relative; width: min(100%, 440px); min-height: 100dvh; margin: 0 auto; overflow-x: hidden; padding: max(16px, env(safe-area-inset-top)) max(var(--screen-gutter), var(--safe-inline)) max(18px, env(safe-area-inset-bottom)) max(var(--screen-gutter), var(--safe-inline)); } .content { display: grid; gap: 10px; animation: section-enter 0.22s ease-out both; } .content.with-nav { padding-bottom: 86px; } .loader { display: grid; min-height: 100dvh; place-items: center; align-content: center; gap: 14px; color: var(--muted); font-weight: 800; } .app-header, .preview-header, .screen-head { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 12px; min-height: 48px; } .screen-head { grid-template-columns: 42px minmax(0, 1fr) 42px; margin-bottom: 6px; } .center-title { align-items: start; } .center-copy { min-width: 0; text-align: center; } .screen-head h1, .center-copy h1 { margin: 0; color: var(--text); font-size: 18px; line-height: 1.16; font-weight: 850; } .screen-head p, .center-copy p { margin: 3px 0 0; color: var(--muted); font-size: 12px; line-height: 1.3; } .screen-head strong { color: var(--accent); } .brand-row { display: flex; min-width: 0; align-items: center; gap: 10px; } .brand-row strong { min-width: 0; overflow: hidden; color: var(--text); font-size: 15px; font-weight: 850; font-family: var(--font-mono); text-overflow: ellipsis; white-space: nowrap; } .accent-title .brand-row strong { color: var(--accent); } .brand-mark { position: relative; display: grid; width: 38px; height: 38px; flex: 0 0 auto; overflow: hidden; place-items: center; color: var(--accent); font-size: 26px; line-height: 1; } .brand-mark img { width: 100%; height: 100%; object-fit: contain; opacity: 0; transition: opacity 0.18s ease; } .brand-mark img.loaded { opacity: 1; } .brand-mark-spinner { position: absolute; width: 42%; height: 42%; border: 2px solid color-mix(in srgb, var(--accent) 24%, transparent); border-top-color: var(--accent); border-radius: 999px; animation: brand-mark-spin 0.72s linear infinite; } @keyframes brand-mark-spin { to { transform: rotate(360deg); } } .brand-mark-lg { width: 66px; height: 66px; font-size: 46px; } .brand-mark-xl { width: 96px; height: 96px; font-size: 70px; } .card { position: relative; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius); background: linear-gradient(135deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.018)), var(--panel); box-shadow: 0 18px 48px rgba(0, 0, 0, 0.22), inset 0 1px 0 rgba(255, 255, 255, 0.05); padding: 14px; } .card-active { border-color: color-mix(in srgb, var(--accent) 76%, var(--border)); box-shadow: 0 18px 48px rgba(0, 0, 0, 0.22), 0 0 0 1px color-mix(in srgb, var(--accent) 38%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.05); } .card-compact { padding: 11px; } .status-card { padding: 16px; } .status-card-inactive { border-color: color-mix(in srgb, var(--danger) 58%, var(--border)); background: linear-gradient(135deg, color-mix(in srgb, var(--danger) 14%, rgba(255, 255, 255, 0.03)), rgba(255, 255, 255, 0.012)), var(--panel); } .status-card-inactive .sub-status { color: var(--danger); } .sub-status-inactive { min-height: 0; justify-content: flex-start; } .sub-status { display: flex; align-items: center; gap: 12px; color: var(--accent); } .sub-status h2 { margin: 0; font-size: 15px; line-height: 1.16; } .sub-status p { margin: 5px 0 0; color: var(--text); font-size: 12px; opacity: 0.82; } .sub-status .current-tariff-line { font-weight: 850; opacity: 1; } .traffic-top, .total-card { display: flex; align-items: center; justify-content: space-between; gap: 12px; } .traffic-top span, .card-label, .total-card span, .settings-row small, .method-card small { color: var(--muted); font-size: 12px; } .traffic-top strong { font-size: 12px; font-weight: 850; } .card-heading { margin: 0 0 10px; color: var(--text); font-size: 15px; font-weight: 850; line-height: 1.2; } .card-heading-accent { color: var(--accent); } .promo-heading { display: inline-flex; align-items: center; gap: 8px; } .progress { position: relative; height: 8px; margin-top: 12px; overflow: hidden; border-radius: 999px; background: rgba(255, 255, 255, 0.08); } .progress span { position: absolute; inset: 0 auto 0 0; width: 0; border-radius: inherit; background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 72%, white)); box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 40%, transparent); } .traffic-meta { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 6px; color: var(--muted); font-size: 11px; } .traffic-percent { margin-top: 0; text-align: right; color: var(--muted); font-size: 11px; } .traffic-card-clickable { cursor: pointer; } .card-click-target { position: absolute; z-index: 2; inset: 0; width: 100%; border: 0; background: transparent; cursor: pointer; -webkit-tap-highlight-color: transparent; } .card-click-target:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; } .premium-traffic-card { display: grid; gap: 10px; } .premium-traffic-card-limited { border-color: rgba(255, 193, 7, 0.34); } .premium-progress span { background: linear-gradient(90deg, #38bdf8, var(--accent)); } .premium-detail-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } .premium-detail-grid span { display: grid; gap: 3px; min-width: 0; } .premium-detail-grid small, .premium-server-list small, .topup-summary-card small { color: var(--muted); font-size: 11px; line-height: 1.3; } .premium-detail-grid strong { font-size: 12px; line-height: 1.2; } .premium-server-list { display: grid; gap: 6px; } .premium-server-list > div { display: flex; flex-wrap: wrap; gap: 6px; } .premium-server-list span { max-width: 100%; padding: 4px 8px; overflow: hidden; border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 999px; color: var(--text); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; } .topup-summary-card { display: grid; gap: 10px; padding: 12px; } .topup-summary-card > div:not(.premium-server-list) { display: grid; gap: 3px; } .topup-summary-card strong { font-size: 12px; line-height: 1.2; } .premium-server-list-modal { margin-top: 0; } .trial-card { padding: 13px 14px; } .trial-card-head { display: flex; align-items: center; gap: 11px; } .trial-card-head > svg { flex: 0 0 auto; color: var(--accent); } .trial-card-head span { display: grid; min-width: 0; gap: 3px; } .trial-card-head strong { font-size: 13px; line-height: 1.18; } .trial-card-head small { color: var(--muted); font-size: 11px; line-height: 1.28; } .devices-summary-card { display: grid; gap: 10px; } .devices-summary-head, .device-card-head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 11px; } .devices-summary-head > svg { color: var(--accent); } .devices-summary-head span, .device-card-head span { display: grid; min-width: 0; gap: 3px; } .devices-summary-head strong, .device-card-head strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; } .devices-summary-head small, .device-card-head small, .device-meta span, .device-meta small, .devices-empty-card small { color: var(--muted); font-size: 11px; line-height: 1.3; } .devices-progress { margin-top: 0; } .devices-list { display: grid; gap: 8px; } .device-card { display: grid; gap: 12px; } .device-card-head { grid-template-columns: 38px minmax(0, 1fr); } .device-icon { display: grid; width: 38px; height: 38px; place-items: center; border: 1px solid color-mix(in srgb, var(--accent) 38%, var(--border)); border-radius: var(--radius); background: color-mix(in srgb, var(--accent) 9%, rgba(255, 255, 255, 0.03)); color: var(--accent); } .device-meta { display: grid; gap: 7px; } .device-meta div { display: grid; gap: 2px; } .device-meta strong, .device-meta code { overflow: hidden; color: var(--text); font-size: 12px; font-weight: 800; text-overflow: ellipsis; white-space: nowrap; } .device-meta code { font-family: var(--font-mono); } .device-user-agent small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .device-disconnect-button, .device-danger-button { border-color: color-mix(in srgb, var(--danger) 62%, var(--border)); color: #ffb8b8; } .devices-empty-card { display: grid; justify-items: center; gap: 7px; text-align: center; } .devices-empty-card svg { color: var(--accent); } .action-stack { display: grid; gap: 8px; } .btn { display: inline-flex; min-height: 44px; min-width: 0; align-items: center; justify-content: center; gap: 8px; border: 1px solid transparent; border-radius: var(--radius); padding: 10px 14px; text-align: center; text-decoration: none; font-size: 14px; font-weight: 850; line-height: 1.1; transition: transform 0.16s ease, border-color 0.16s ease, background 0.16s ease, color 0.16s ease; } .btn:hover { transform: translateY(-1px); } .btn-primary { border-color: color-mix(in srgb, var(--accent) 72%, transparent); background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 94%, white), var(--accent)); color: #031009; box-shadow: 0 14px 34px color-mix(in srgb, var(--accent) 20%, transparent); } .btn-secondary, .btn-outline { border-color: var(--border-strong); background: rgba(255, 255, 255, 0.045); color: var(--text); } .btn-outline { border-color: color-mix(in srgb, var(--accent) 60%, var(--border)); color: var(--accent); } .btn-ghost { background: transparent; color: var(--muted); } .btn-telegram { border-color: #2d9cff; background: linear-gradient(180deg, #2f9ff4, #1786df); color: white; } .btn-icon { border-color: var(--border); background: rgba(255, 255, 255, 0.04); color: var(--text); } .btn-square { width: 42px; min-width: 42px; height: 42px; padding: 0; } .btn-sm { min-height: 36px; padding: 8px 10px; font-size: 12px; } .wide { width: 100%; } .input { width: 100%; min-height: 44px; min-width: 0; border: 1px solid var(--border); border-radius: var(--radius); background: rgba(4, 8, 11, 0.48); color: var(--text); outline: none; padding: 11px 12px; font-size: 13px; font-weight: 700; } .input:focus { border-color: color-mix(in srgb, var(--accent) 68%, var(--border)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 12%, transparent); } .input.muted { display: flex; align-items: center; color: var(--dim); } .bottom-action { margin-top: 4px; } .period-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; } .period-grid-two-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); } .period-card, .method-card, .settings-row { border: 1px solid var(--border); border-radius: var(--radius); background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.018)); color: var(--text); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.045); } .period-card { position: relative; display: grid; min-height: 82px; place-items: center; gap: 4px; padding: 10px 8px; } .period-card strong { font-size: 12px; line-height: 1.12; text-align: center; overflow-wrap: anywhere; } .period-card span { font-size: 16px; font-weight: 850; } .period-card em { color: var(--muted); font-size: 10px; font-style: normal; font-weight: 750; } .period-card small { color: var(--muted); font-size: 10px; } .period-card svg { position: absolute; top: 8px; right: 8px; color: var(--accent); } .period-card.active, .method-card.active { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, rgba(255, 255, 255, 0.035)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 50%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.06); } .total-card { padding: 12px 14px; } .total-card strong { font-size: 22px; font-weight: 900; } .method-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } .option-list { display: grid; gap: 8px; } .option-row, .tariff-selected-card { display: flex; width: 100%; min-height: 66px; align-items: center; justify-content: space-between; gap: 12px; border: 1px solid var(--border); border-radius: var(--radius); background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.018)); color: var(--text); padding: 12px; text-align: left; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.045); } .option-row-main, .tariff-selected-card span { display: grid; gap: 4px; min-width: 0; } .option-row-main strong, .tariff-selected-card strong { font-size: 13px; font-weight: 900; line-height: 1.2; overflow-wrap: anywhere; } .option-row-main small, .tariff-selected-card small { color: var(--muted); font-size: 11px; line-height: 1.35; overflow-wrap: anywhere; } .option-row-meta { display: grid; justify-items: end; gap: 3px; flex: 0 0 auto; max-width: 42%; text-align: right; } .option-row-meta em, .tariff-selected-card em { color: var(--accent); font-size: 12px; font-style: normal; font-weight: 900; line-height: 1.2; overflow-wrap: anywhere; } .option-row-meta small { color: var(--muted); font-size: 10px; line-height: 1.2; } .option-row.active { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, rgba(255, 255, 255, 0.035)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 50%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.06); } .tariff-row { min-height: 74px; } .plan-row, .change-action-row { min-height: 62px; } .change-action-row { align-items: flex-start; } .change-action-row > svg { flex: 0 0 auto; margin-top: 1px; color: var(--accent); } .dialog-skeleton { display: grid; gap: 12px; } .topup-carryover-note { display: grid; gap: 6px; padding: 10px 12px; border: 1px solid rgba(255, 255, 255, 0.08); border-radius: var(--radius); background: rgba(255, 255, 255, 0.035); } .topup-carryover-note p { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.35; } .skeleton-row, .skeleton-method, .skeleton-pay-button { pointer-events: none; } .skeleton-line, .skeleton-dot, .skeleton-pay-button { display: block; overflow: hidden; border-radius: 999px; background: linear-gradient( 90deg, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0.14) 42%, rgba(255, 255, 255, 0.07) 84% ); background-size: 220% 100%; animation: skeleton-shimmer 1.15s ease-in-out infinite; } .skeleton-line-title { width: 118px; height: 13px; } .skeleton-line-short { width: 76px; height: 10px; opacity: 0.75; } .skeleton-line-price { width: 58px; height: 12px; } .skeleton-line-tiny { width: 34px; height: 9px; opacity: 0.7; } .skeleton-line-method { width: 72px; height: 12px; } .skeleton-dot { width: 18px; height: 18px; flex: 0 0 auto; } .skeleton-method { gap: 8px; } .skeleton-pay-button { width: 100%; height: 46px; border-radius: var(--radius); } @keyframes skeleton-shimmer { 0% { background-position: 120% 0; } 100% { background-position: -120% 0; } } .back-inline { display: inline-flex; width: fit-content; align-items: center; gap: 6px; border: 0; background: transparent; color: var(--muted); padding: 0; font-size: 12px; font-weight: 850; } .tariff-step-caption, .section-kicker { margin: 0; color: var(--muted); font-size: 12px; font-weight: 800; line-height: 1.3; } .section-kicker { color: var(--dim); text-transform: uppercase; } .tariff-selected-card { min-height: 58px; background: color-mix(in srgb, var(--accent) 7%, rgba(255, 255, 255, 0.035)); } .tariff-action-list { display: grid; gap: 8px; } .tariff-action-card, .tariff-warning-card { display: flex; align-items: center; justify-content: space-between; gap: 10px; border: 1px solid var(--border); border-radius: var(--radius); background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.018)); color: var(--text); padding: 12px; text-align: left; } .tariff-action-card span { display: grid; gap: 4px; min-width: 0; } .tariff-action-card strong, .tariff-warning-card span { font-size: 13px; font-weight: 850; } .tariff-action-card small { color: var(--muted); font-size: 11px; } .tariff-action-card em { color: var(--accent); font-size: 10px; font-style: normal; font-weight: 850; white-space: nowrap; } .tariff-action-card.active { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, rgba(255, 255, 255, 0.035)); } .tariff-warning-card { justify-content: flex-start; color: var(--warning, #ffd166); } .confirm-summary-card { display: grid; gap: 8px; } .confirm-summary-card p { margin: 0; color: var(--text); font-size: 13px; font-weight: 750; line-height: 1.35; } .method-card { display: flex; width: 100%; min-height: 56px; align-items: center; justify-content: center; background: rgba(255, 255, 255, 0.035); padding: 10px; text-align: center; } .method-card svg { flex: 0 0 auto; } .method-card-main { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-width: 0; } .method-card strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center; } .method-card strong { font-size: 12px; } .settings-list { display: grid; gap: 8px; } .settings-list.settings-list--language-open .settings-row:not(.settings-row-language) { pointer-events: none; } .language-select-guard { appearance: none; -webkit-tap-highlight-color: transparent; position: fixed; inset: 0; z-index: 100; border: 0; background: transparent; box-shadow: none; outline: none; padding: 0; pointer-events: auto; touch-action: manipulation; } .copy-row, .email-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: center; } .field-error-wrap { position: relative; min-width: 0; } .input.input-error { border-color: var(--danger); box-shadow: 0 0 0 1px color-mix(in srgb, var(--danger) 70%, transparent); } .field-error-icon { color: var(--danger); pointer-events: none; } .field-error-trigger { position: absolute; top: 50%; right: 10px; transform: translateY(-50%); display: grid; width: 20px; height: 20px; place-items: center; border: 0; background: transparent; padding: 0; cursor: help; } .field-error-tooltip { z-index: 120; max-width: 280px; border: 1px solid color-mix(in srgb, var(--danger) 60%, var(--border)); border-radius: 8px; background: #2a1010; color: #ffd8d8; padding: 8px 10px; font-size: 12px; line-height: 1.3; transform-origin: top center; } .field-error-tooltip[data-state="delayed-open"], .field-error-tooltip[data-state="instant-open"] { animation: tooltip-in 0.16s ease-out both; } .field-error-tooltip[data-state="closed"] { animation: tooltip-out 0.12s ease-in both; } @keyframes tooltip-in { from { opacity: 0; transform: translateY(4px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes tooltip-out { from { opacity: 1; transform: translateY(0) scale(1); } to { opacity: 0; transform: translateY(2px) scale(0.98); } } .copy-row code { min-width: 0; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius); background: rgba(0, 0, 0, 0.2); color: var(--text); padding: 12px; font-size: 12px; text-overflow: ellipsis; white-space: nowrap; } .referral-copy-row { align-items: stretch; } .referral-copy-button { height: 100%; } .bonus-card { display: grid; gap: 10px; } .bonus-card-head { display: flex; align-items: center; gap: 14px; } .bonus-card-head > svg { flex: 0 0 auto; color: var(--accent); } .bonus-card strong { display: block; color: var(--accent); font-size: 17px; } .bonus-card p { margin: 4px 0 0; color: var(--muted); font-size: 12px; } .referral-bonus-list { display: grid; gap: 8px; } .referral-bonus-intro { margin: 2px 2px 0; color: var(--muted); font-size: 12px; } .referral-bonus-row { display: grid; gap: 3px; border: 1px solid var(--border); border-radius: var(--radius); background: rgba(255, 255, 255, 0.02); padding: 10px 11px; } .referral-bonus-row strong { font-size: 13px; } .referral-bonus-row small { color: var(--muted); font-size: 12px; } .settings-profile { display: flex; align-items: center; gap: 12px; } .settings-avatar { display: grid; width: 58px; height: 58px; flex: 0 0 auto; place-items: center; overflow: hidden; border: 1px solid var(--border); border-radius: 999px; background: rgba(255, 255, 255, 0.03); } .settings-avatar img { width: 100%; height: 100%; object-fit: cover; } .settings-avatar svg { color: var(--accent); } .settings-profile-meta { display: grid; min-width: 0; gap: 3px; } .settings-profile-meta strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; } .settings-profile-meta small { overflow: hidden; color: var(--muted); text-overflow: ellipsis; white-space: nowrap; font-size: 12px; } .settings-links-block { display: grid; gap: 8px; } .settings-divider { height: 1px; background: var(--border); } .settings-row { display: grid; grid-template-columns: 28px minmax(0, 1fr) 18px; align-items: center; gap: 10px; min-height: 50px; padding: 9px 10px; text-align: left; background: rgba(255, 255, 255, 0.03); } .settings-row > svg:first-child { color: var(--text); opacity: 0.9; } .settings-row > svg:last-child { color: var(--muted); } .settings-row span { display: grid; min-width: 0; gap: 2px; } .settings-row strong, .settings-row small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .settings-row strong { font-size: 12px; } .settings-row-linked { grid-template-columns: 28px minmax(0, 1fr); border-color: color-mix(in srgb, var(--accent) 38%, var(--border)); background: color-mix(in srgb, var(--accent) 11%, rgba(255, 255, 255, 0.03)); } .settings-row-linked > svg:first-child { color: var(--accent); } .settings-row-linked strong { color: var(--accent); } .emoji-flag { font-family: "Twemoji Country Flags", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", sans-serif; font-variant-emoji: emoji; line-height: 1; } .settings-row-language { grid-template-columns: 28px minmax(0, 1fr); padding: 7px 10px; } .language-select-trigger { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 10px; width: 100%; min-height: 34px; border: 0; background: transparent; color: var(--text); text-align: left; padding: 0; } .language-select-trigger:focus-visible { outline: 0; box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent); border-radius: 6px; } .language-select-trigger > svg { color: var(--muted); } .language-select-copy { display: grid; min-width: 0; gap: 2px; } .language-select-copy strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; } .language-select-current { display: inline-flex; align-items: center; gap: 7px; min-width: 0; } .language-select-current .emoji-flag { font-size: 14px; } .language-select-content { z-index: 140; width: min(210px, calc(100vw - 28px)); min-width: 170px; max-width: min(210px, calc(100vw - 28px)); border: 1px solid var(--border-strong); border-radius: var(--radius); background: var(--panel-3); box-shadow: 0 20px 34px rgba(0, 0, 0, 0.42); overflow: hidden; box-sizing: border-box; transform-origin: top right; animation: dropdown-enter 0.16s ease-out both; } .language-select-viewport { max-height: min(220px, 45dvh); padding: 6px; } .language-select-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 36px; border-radius: 6px; padding: 7px 9px; color: var(--text); font-size: 13px; cursor: pointer; } .language-select-item[data-highlighted] { background: rgba(255, 255, 255, 0.06); } .language-select-item[data-selected] { color: var(--text) !important; } .language-select-item[data-selected] .language-select-item-check { color: var(--text); } .language-select-item-main { display: inline-flex !important; align-items: center; flex-wrap: nowrap !important; gap: 11px; min-width: 0; white-space: nowrap !important; overflow: hidden; text-overflow: ellipsis; } .language-select-item-main > span { display: inline-block !important; } .language-select-item-main > span:last-child { margin-left: 6px; white-space: nowrap !important; overflow: hidden; text-overflow: ellipsis; } .language-select-item-main .emoji-flag { font-size: 14px; } .language-select-item-check { opacity: 0; color: var(--accent); } .language-select-item[data-selected] .language-select-item-check { opacity: 1; } .settings-telegram-link-btn { justify-content: center; } .attention-wrap { position: relative; } .attention-dot { position: absolute; top: 0; right: 0; width: 13px; height: 13px; transform: translate(50%, -50%); border-radius: 999px; background: #ff4b4b; box-shadow: 0 0 0 0 rgba(255, 75, 75, 0.75); animation: attention-pulse 1.6s ease-out infinite; pointer-events: none; } .nav-attention-dot { top: 6px; right: 10px; transform: none; } .bottom-nav button.attention-wrap { padding-right: 6px; } @keyframes attention-pulse { 0% { box-shadow: 0 0 0 0 rgba(255, 75, 75, 0.75); } 70% { box-shadow: 0 0 0 8px rgba(255, 75, 75, 0); } 100% { box-shadow: 0 0 0 0 rgba(255, 75, 75, 0); } } .bottom-nav { position: fixed !important; left: var(--bottom-nav-left); right: auto; width: var(--bottom-nav-width); max-width: none; transform: none; bottom: max(var(--bottom-nav-offset), env(safe-area-inset-bottom)); z-index: 80; display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; min-height: 64px; border: 1px solid var(--border); border-radius: var(--radius); background: rgba(7, 12, 17, 0.88); box-shadow: 0 16px 38px rgba(0, 0, 0, 0.36); backdrop-filter: blur(16px); } .bottom-nav-devices { grid-template-columns: repeat(4, 1fr); } .bottom-nav.static { position: fixed; } .bottom-nav button { display: grid; place-items: center; align-content: center; gap: 4px; border: 0; background: transparent; color: var(--muted); font-size: 10px; font-weight: 800; } .bottom-nav button.active { color: var(--accent); } .rail-admin-entry { display: none !important; } .home-layout { display: grid; min-height: calc(100dvh - 34px); grid-template-rows: minmax(0, 1fr) auto; gap: 18px; padding-bottom: 86px; animation: section-enter 0.24s ease-out both; } .home-brand { align-self: center; padding-top: 0; } .home-bottom { display: grid; gap: 10px; align-self: end; } .auth-screen { display: grid; align-content: center; } .auth-card-wrap { display: grid; gap: 24px; } .login-brand { display: grid; justify-items: center; gap: 10px; text-align: center; } .login-brand.small { gap: 5px; } .login-brand-auth .brand-mark.brand-mark-xl { width: 116px; height: 116px; font-size: 84px; } .login-brand h1 { margin: 0; overflow-wrap: anywhere; color: var(--accent); font-size: 32px; font-weight: 900; font-family: var(--font-mono); line-height: 1.04; } .login-brand p { margin: 0; color: var(--muted); font-size: 13px; } .auth-card { display: grid; gap: 14px; } .auth-pane { display: grid; gap: 10px; } .auth-email-stack { display: grid; gap: 12px; } .auth-pane .field-label, .auth-card .field-label { color: var(--text); font-size: 13px; font-weight: 850; } .auth-bottom { text-align: center; color: var(--muted); font-size: 13px; } .telegram-login-button { justify-content: center; padding-left: 14px; padding-right: 14px; } .telegram-login-button.unavailable:disabled { cursor: not-allowed; } .telegram-login-button.checking:disabled { opacity: 0.82; } .telegram-login-text { display: inline-flex; align-items: center; justify-content: center; gap: 8px; width: 100%; } .telegram-button-spinner { width: 17px; height: 17px; border: 2px solid rgba(255, 255, 255, 0.35); border-top-color: #fff; border-radius: 999px; animation: telegram-button-spin 0.72s linear infinite; } @keyframes telegram-button-spin { to { transform: rotate(360deg); } } .auth-legal { display: grid; justify-items: center; gap: 6px; } .auth-legal-intro, .auth-legal-links { color: var(--muted); font-size: 12px; text-align: center; } .auth-legal-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; } .auth-legal a { color: inherit; text-decoration: underline; text-underline-offset: 2px; } .auth-legal a:hover { color: var(--accent); } .auth-bottom strong { color: var(--accent); } .or-line { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; color: var(--muted); font-size: 12px; } .or-line span { height: 1px; background: var(--border); } .otp-wrap { display: grid; align-content: center; gap: 20px; min-height: calc(100dvh - 120px); } .otp-input-wrap { position: relative; display: block; } .otp-input-wrap input { position: absolute; inset: 0; z-index: 2; width: 100%; border: 0; background: transparent; color: transparent; caret-color: transparent; outline: none; } .otp-slots { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; } .otp-slots span { display: grid; aspect-ratio: 1; place-items: center; border: 1px solid color-mix(in srgb, var(--accent) 74%, var(--border)); border-radius: var(--radius); background: rgba(255, 255, 255, 0.035); font-size: 25px; font-weight: 900; } .otp-slots span.filled { background: color-mix(in srgb, var(--accent) 9%, rgba(255, 255, 255, 0.04)); } .link-button { display: inline-flex; align-items: center; justify-content: center; gap: 8px; border: 0; background: transparent; color: var(--muted); font-size: 13px; } .status-line { color: var(--accent); font-size: 12px; line-height: 1.4; } .auth-login-status { justify-self: center; text-align: center; width: 100%; } .status-line.error, .error { color: var(--danger); } .empty-card { grid-column: 1 / -1; color: var(--muted); font-size: 13px; } .dialog { position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; overflow: hidden; padding: 16px var(--screen-gutter) calc(var(--bottom-nav-height) + var(--bottom-nav-offset) + 16px + env(safe-area-inset-bottom)); } .dialog-backdrop { position: absolute; inset: 0; border: 0; background: rgba(2, 7, 11, 0.54); backdrop-filter: blur(10px); animation: fade-in 0.18s ease-out both; } .dialog-card { position: relative; z-index: 1; display: grid; width: min(100%, 420px); gap: 12px; border: 1px solid var(--border-strong); border-radius: var(--radius); background: var(--panel); box-shadow: 0 28px 70px rgba(0, 0, 0, 0.5); padding: 14px; transform-origin: center; animation: modal-enter 0.2s ease-out both; } .dialog-head { display: grid; grid-template-columns: minmax(0, 1fr) 42px; align-items: start; gap: 10px; } .dialog-head h2 { margin: 0; color: var(--text); font-size: 18px; line-height: 1.16; font-weight: 850; } .dialog-head p { margin: 4px 0 0; color: var(--muted); font-size: 12px; line-height: 1.3; } .payment-dialog-card { max-height: 100%; overflow-y: auto; } .link-email-dialog-card { display: grid; grid-template-rows: auto minmax(0, 1fr); height: min(100%, 560px); max-height: 100%; overflow: hidden; } .link-email-dialog-card .dialog-head { position: relative; z-index: 2; } .link-email-dialog-card .payment-dialog-body { min-height: 0; } .link-email-code-layout { display: grid; min-height: 0; height: 100%; grid-template-rows: minmax(0, 1fr) auto; } .link-email-code-center { align-self: center; } .link-email-resend { align-self: end; } .payment-dialog-body { display: grid; gap: 10px; } .payment-divider { height: 1px; width: 100%; background: var(--border); } .payment-submit-button { border-color: color-mix(in srgb, var(--accent) 72%, transparent); background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 94%, white), var(--accent)); color: #031009; box-shadow: 0 16px 38px color-mix(in srgb, var(--accent) 28%, transparent), 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent), 0 0 26px color-mix(in srgb, var(--accent) 42%, transparent); } .toast { position: fixed; right: 16px; bottom: 16px; z-index: 120; max-width: min(420px, calc(100vw - 32px)); border: 1px solid color-mix(in srgb, var(--accent) 46%, var(--border)); border-radius: var(--radius); background: rgba(15, 21, 27, 0.92); box-shadow: 0 16px 42px rgba(0, 0, 0, 0.42); color: var(--text); padding: 12px 14px; font-size: 13px; font-weight: 800; animation: toast-enter 0.22s ease-out both; } @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } @keyframes section-enter { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } @keyframes dropdown-enter { from { opacity: 0; transform: translateY(-6px) scale(0.97); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes modal-enter { from { opacity: 0; transform: translateY(10px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes toast-enter { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .preview-board { display: grid; width: max-content; min-height: 100vh; grid-template-columns: repeat(3, auto); gap: 22px 38px; align-items: start; padding: 18px 74px 28px; background: linear-gradient(180deg, #06100c 0%, #02060b 32%, #010407 100%); } .preview-phone-wrap { display: grid; gap: 9px; } .preview-phone-wrap h2 { margin: 0; text-align: center; font-size: 18px; line-height: 1.1; } .preview-phone-wrap h2 span { color: var(--accent); } .preview-phone { position: relative; display: grid; width: 430px; min-height: 318px; align-content: start; gap: 8px; overflow: hidden; border: 1px solid rgba(255, 255, 255, 0.22); border-radius: 18px; background: linear-gradient(135deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.015)), #071017; box-shadow: 0 28px 80px rgba(0, 0, 0, 0.54), inset 0 1px 0 rgba(255, 255, 255, 0.08); padding: 15px 16px 16px; } .preview-phone-wrap.wide .preview-phone { width: 510px; } .preview-phone .bottom-nav { right: 16px; bottom: 8px; left: 16px; width: auto; min-height: 50px; box-shadow: none; } .preview-phone .bottom-nav span { font-size: 9px; } .preview-phone .card { padding: 12px; } .preview-phone .status-card { padding: 14px; } .preview-phone .btn { min-height: 38px; font-size: 12px; padding: 8px 10px; } .preview-phone .btn-square { width: 36px; min-width: 36px; height: 36px; padding: 0; } .preview-phone .period-card { min-height: 72px; } .preview-phone .method-card { min-height: 42px; } .preview-phone .settings-row { min-height: 39px; } .preview-phone .settings-avatar { width: 46px; height: 46px; } .preview-phone .settings-profile-meta strong { font-size: 12px; } .preview-phone .settings-profile-meta small { font-size: 10px; } .preview-phone .brand-mark { width: 34px; height: 34px; font-size: 23px; } .preview-phone .brand-mark-lg { width: 56px; height: 56px; font-size: 39px; } .preview-phone .brand-mark-xl { width: 78px; height: 78px; font-size: 56px; } .preview-phone .home-layout { min-height: 300px; gap: 12px; padding-bottom: 58px; } .preview-phone .home-brand { padding-top: 0; } .preview-phone .login-brand h1 { font-size: 24px; } .preview-modal { position: absolute; right: 18px; bottom: 18px; display: grid; width: 178px; gap: 8px; justify-items: center; border: 1px solid var(--border-strong); border-radius: 14px; background: rgba(20, 29, 35, 0.94); box-shadow: 0 18px 52px rgba(0, 0, 0, 0.46); padding: 16px; text-align: center; } .preview-modal svg { color: var(--accent); } .preview-modal strong { font-size: 13px; } .preview-modal p { margin: 0; color: var(--muted); font-size: 10px; line-height: 1.35; } @media (max-width: 460px) { :root { --screen-gutter: 10px; } .period-grid, .method-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .copy-row, .email-row { grid-template-columns: 1fr; } } @media (prefers-reduced-motion: reduce) { .content, .home-layout, .language-select-content, .dialog-backdrop, .dialog-card, .toast { animation: none !important; } } @supports not (color: color-mix(in srgb, #000 50%, #fff)) { .btn-primary { background: var(--accent); } } /* ============================================================ Desktop layout for the user-facing Mini App (≥ 1024px) A full-bleed dashboard: brand + nav rail on the left (the mobile bottom-nav is repositioned, no markup changes), main content area takes the rest of the viewport with a generous max-width. Auth screens are kept centered. Mobile (≤ 1023px) is intentionally untouched. ============================================================ */ :root { --desktop-rail-width: 252px; --desktop-page-gutter: clamp(28px, 4vw, 72px); } @media (min-width: 1024px) { body { background: #02070b; } .app-shell { min-height: 100dvh; display: block; padding: 0; background: transparent !important; } /* Full-width canvas: the side rail is a fixed sibling, so we leave room for it on the left and center content inside the right-hand work area. */ .phone-screen { width: auto; max-width: none; min-height: 100dvh; margin: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; padding: max(28px, env(safe-area-inset-top)) var(--desktop-page-gutter) 40px calc(var(--desktop-rail-width) + var(--desktop-page-gutter)); overflow-x: visible; } /* Centre and cap the width of the actual content blocks. */ .phone-screen > .app-header, .phone-screen > main, .phone-screen > .home-layout, .phone-screen > nav.bottom-nav ~ * { max-width: 1080px; margin-left: auto; margin-right: auto; } /* Auth screen: keep it as a focused card in the centre, hide rail. */ .phone-screen.auth-screen { width: min(100%, 460px); min-height: 100dvh; padding: max(48px, env(safe-area-inset-top)) clamp(24px, 4vw, 48px) 48px; margin: 0 auto; } .phone-screen.auth-screen ~ .bottom-nav, .auth-screen .bottom-nav { display: none !important; } .phone-screen.home-screen { display: grid; grid-template-columns: minmax(0, 1fr); align-items: stretch; min-height: 100dvh; padding: max(32px, env(safe-area-inset-top)) var(--desktop-page-gutter) 42px calc(var(--desktop-rail-width) + var(--desktop-page-gutter)); } /* Home: keep the phone-style vertical flow, but center it in the right-hand desktop area and let the action block sit on the bottom. */ .home-layout { width: min(100%, 680px); min-height: calc(100dvh - 74px); grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(280px, 1fr) auto; justify-self: center; gap: clamp(24px, 4vh, 52px); max-width: none; margin: 0; padding-bottom: 0; align-items: stretch; } .home-layout > .home-brand { grid-column: auto; align-self: center; justify-items: center; text-align: center; gap: 22px; } .home-brand h1 { max-width: 560px; font-size: clamp(36px, 4vw, 58px); letter-spacing: 0; line-height: 1.02; } /* Make the brand mark a focal element on desktop. */ .home-brand .brand-mark, .home-brand .brand-mark-lg, .home-brand .brand-mark-xl { width: clamp(180px, 18vw, 260px); height: clamp(180px, 18vw, 260px); font-size: clamp(124px, 13vw, 184px); } .home-bottom { align-self: end; width: min(100%, 560px); justify-self: center; gap: 12px; } /* Top header (brand on settings/invite/devices) becomes a flat strip. */ .app-header.accent-title { display: none; } /* Reset clearance — the bottom-nav is now a sidebar. */ .content.with-nav { padding-bottom: 32px; } /* Transform the mobile bottom-nav into a fixed-left vertical rail. */ .bottom-nav { position: fixed !important; left: 0 !important; top: 0 !important; bottom: 0 !important; right: auto !important; width: var(--desktop-rail-width) !important; height: 100dvh !important; transform: none !important; display: grid !important; grid-template-columns: 1fr !important; grid-template-rows: none !important; grid-auto-rows: auto !important; align-content: start !important; gap: 2px !important; padding: 28px 14px !important; border: 0 !important; border-right: 1px solid var(--border) !important; border-radius: 0 !important; background: rgba(7, 12, 17, 0.55) !important; backdrop-filter: blur(14px) !important; box-shadow: inset -1px 0 0 rgba(255, 255, 255, 0.02) !important; z-index: 40; } .bottom-nav-devices { grid-template-columns: 1fr !important; } .bottom-nav button { display: grid !important; grid-template-columns: 22px 1fr !important; grid-template-rows: auto !important; align-items: center !important; justify-items: start !important; gap: 12px !important; padding: 12px 14px !important; border-radius: 10px !important; text-align: left !important; font-size: 13px !important; color: var(--muted); border: 1px solid transparent; transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease; } .bottom-nav button > svg { width: 20px; height: 20px; } .bottom-nav button > span { text-align: left !important; font-size: 13px !important; font-weight: 600; } .bottom-nav button:hover { background: rgba(255, 255, 255, 0.04); color: var(--text); } .bottom-nav button.active { background: color-mix(in srgb, var(--accent) 16%, transparent); border-color: color-mix(in srgb, var(--accent) 30%, transparent); color: var(--text); } .bottom-nav .nav-attention-dot { top: 14px; right: 14px; } .bottom-nav .rail-admin-entry { display: grid !important; } .settings-admin-block { display: none !important; } .phone-screen > main.content.with-nav { padding-top: 0; } .settings-profile { padding: 12px; } .settings-links-block { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; } .settings-links-block .settings-divider { display: none; } .settings-links-block .settings-row, .settings-links-block .settings-telegram-link-btn { min-height: 48px; } .settings-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; } .settings-list .settings-row { min-height: 48px; } .settings-row-language, .settings-row-support, .settings-row-logout { grid-column: 1 / -1; } /* Wider modals on desktop. */ .dialog-card { width: min(100%, 560px); } .payment-dialog-card, .link-email-dialog-card { width: min(100%, 640px); } } @media (min-width: 1280px) { :root { --desktop-rail-width: 264px; } } /* Brand block sits at the top of the desktop side rail; hidden on mobile. */ .rail-brand { display: none; } @media (min-width: 1024px) { .bottom-nav .rail-brand { display: flex; align-items: center; gap: 12px; padding: 4px 12px 18px; margin-bottom: 8px; border-bottom: 1px solid var(--border); color: var(--text); } .bottom-nav .rail-brand strong { font-size: 14px; font-weight: 800; letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; } } /* ============================================================ Admin panel — shadcn-svelte dashboard treatment Sidebar + sticky header + cards + semantic tables. ============================================================ */ .admin-screen-wrap { --admin-sidebar-w: 248px; --admin-header-h: 60px; position: fixed; inset: 0; width: 100vw; height: 100dvh; background: var(--admin-bg); color: var(--admin-text); overflow: hidden; overscroll-behavior: contain; z-index: 60; display: flex; flex-direction: row; /* Forces a new compositing layer — required for reliable scrolling inside position:fixed on iOS Safari. */ transform: translateZ(0); } .admin-sidebar { flex: 0 0 var(--admin-sidebar-w); min-height: 0; height: 100%; display: flex; flex-direction: column; gap: 4px; padding: 14px 12px 18px; border-right: 1px solid var(--admin-border); background: var(--admin-surface); overflow-y: auto; } .admin-sidebar > *:not(.admin-sidebar-footer) { flex-shrink: 0; } .admin-sidebar-brand { display: grid; grid-template-columns: 36px minmax(0, 1fr) 32px; align-items: center; gap: 10px; padding: 6px 6px 14px; margin-bottom: 6px; border-bottom: 1px solid var(--admin-border); } .admin-sidebar-brand .admin-brand-mark { width: 36px; height: 36px; display: grid; place-items: center; color: var(--accent); } .admin-sidebar-brand strong { display: block; font-size: 13px; font-weight: 700; letter-spacing: -0.01em; } .admin-sidebar-brand small { display: block; color: var(--admin-muted); font-size: 11px; } .admin-sidebar-section-label { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--admin-dim); padding: 14px 12px 6px; } .admin-nav { display: grid; gap: 1px; } .admin-nav-item { position: relative; display: grid; grid-template-columns: 18px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 8px; border: 0; background: transparent; color: var(--admin-muted); font-size: 13px; font-weight: 500; text-align: left; width: 100%; cursor: pointer; transition: background 0.12s ease, color 0.12s ease; } .admin-nav-item:hover { background: var(--admin-surface-2); color: var(--admin-text); } .admin-nav-item.active { background: var(--admin-elev); color: var(--admin-text); font-weight: 600; } .admin-nav-item.active::before { content: ""; position: absolute; width: 3px; height: 18px; left: -4px; top: 50%; transform: translateY(-50%); border-radius: 2px; background: var(--accent); } .admin-sidebar-footer { margin-top: auto; padding: 10px 6px 0; border-top: 1px solid var(--admin-border); font-size: 11px; color: var(--admin-dim); display: grid; gap: 10px; } .admin-language-switch { display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: center; gap: 8px; } .admin-language-switch > svg { color: var(--admin-muted); } .admin-language-trigger { display: flex; width: 100%; min-width: 0; align-items: center; justify-content: space-between; gap: 8px; border: 1px solid var(--admin-border); border-radius: 8px; background: var(--admin-surface-2); color: var(--admin-text); padding: 8px 10px; text-align: left; cursor: pointer; } .admin-language-trigger:focus-visible { outline: 2px solid var(--admin-ring); outline-offset: 2px; } .admin-language-trigger > span { display: grid; min-width: 0; gap: 2px; } .admin-language-trigger strong { overflow: hidden; font-size: 12px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; } .admin-language-trigger small { display: inline-flex; min-width: 0; align-items: center; gap: 5px; overflow: hidden; color: var(--admin-muted); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; } .admin-version-link { order: 2; display: grid; gap: 2px; max-width: 100%; overflow: hidden; color: var(--admin-muted); font-family: var(--font-mono); font-size: 11px; text-decoration: none; text-overflow: ellipsis; white-space: nowrap; transition: color 0.12s ease; } .admin-version-link span { overflow: hidden; text-overflow: ellipsis; } .admin-version-link:hover { color: var(--accent); } .admin-content { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; min-height: 0; height: 100%; overflow: hidden; } .admin-header { flex: 0 0 auto; min-height: var(--admin-header-h); z-index: 5; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 16px; padding: 0 24px; border-bottom: 1px solid var(--admin-border); background: var(--admin-bg); } .admin-header-title { display: grid; gap: 2px; min-width: 0; } .admin-header-title h2 { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; } .admin-header-title small { color: var(--admin-muted); font-size: 12px; } .admin-header-actions { display: flex; align-items: center; gap: 8px; } .admin-mobile-toggle { display: none; width: 36px; height: 36px; border-radius: 8px; border: 1px solid var(--admin-border); background: var(--admin-surface); color: var(--admin-text); align-items: center; justify-content: center; } .admin-main { flex: 1 1 auto; min-height: 0; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; overflow-y: auto; overflow-x: hidden; padding: 22px 24px 32px; display: flex; flex-direction: column; gap: 16px; } /* Flex children must NOT shrink — otherwise they collapse to fit the container and the main never overflows, breaking scroll. */ .admin-main > * { flex-shrink: 0; } .admin-card { border: 1px solid var(--admin-border); background: var(--admin-surface); border-radius: 12px; display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; overflow: hidden; } .admin-card-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 14px 18px; border-bottom: 1px solid var(--admin-border); min-width: 0; } .admin-card-head h3 { margin: 0; font-size: 13px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--admin-text); word-break: break-word; } .admin-card-head small { color: var(--admin-muted); font-size: 12px; word-break: break-word; } .admin-card-body { padding: 16px 18px; display: grid; gap: 12px; min-width: 0; } .admin-empty { display: grid; place-items: center; padding: 48px 16px; border: 1px dashed var(--admin-border); border-radius: 12px; background: var(--admin-surface); color: var(--admin-muted); font-size: 13px; } .admin-muted { color: var(--admin-muted); font-size: 12px; } .admin-stat-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; } @media (min-width: 560px) { .admin-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (min-width: 1024px) { .admin-stat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } } @media (min-width: 1440px) { .admin-stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } } .admin-stat-card { border: 1px solid var(--admin-border); background: var(--admin-surface); border-radius: 12px; padding: 16px 18px; display: grid; gap: 6px; min-height: 96px; } .admin-stat-card .admin-stat-label { display: flex; align-items: center; gap: 8px; color: var(--admin-muted); font-size: 12px; font-weight: 500; } .admin-stat-card .admin-stat-value { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; color: var(--admin-text); } .admin-stat-card .admin-stat-trend { color: var(--admin-muted); font-size: 12px; } .admin-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; } .admin-toolbar-users { display: grid; grid-template-columns: minmax(260px, 1fr); gap: 10px; padding: 12px; border: 1px solid var(--admin-border); border-radius: 12px; background: var(--admin-surface); } .admin-toolbar-card { display: grid; grid-template-columns: minmax(260px, 1fr) auto; align-items: end; gap: 8px; padding: 12px; border: 1px solid var(--admin-border); border-radius: 12px; background: var(--admin-surface); } .admin-toolbar-search { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px; min-width: 0; } .admin-toolbar-search-actions { grid-template-columns: minmax(0, 1fr) auto auto; } .admin-toolbar-search .input, .admin-toolbar-search .admin-btn { height: 36px; } .admin-toolbar-controls { display: grid; grid-template-columns: repeat(3, minmax(150px, 1fr)) minmax(96px, auto); align-items: end; gap: 8px; } .admin-toolbar > .input, .admin-toolbar input[type="text"], .admin-toolbar input[type="number"], .admin-toolbar input[type="search"] { flex: 1 1 200px; min-width: 180px; } .admin-toolbar > .admin-btn { height: 36px; } .admin-toolbar-field { display: grid; align-items: start; gap: 6px; min-width: 0; } .admin-toolbar-field-label { color: var(--admin-muted); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap; } .admin-toolbar-select { height: 36px; min-width: 0; } .admin-toolbar-summary { display: grid; min-height: 36px; min-width: 96px; align-content: center; justify-items: end; gap: 2px; padding: 0 2px; white-space: nowrap; } .admin-toolbar-summary strong { color: var(--admin-text); font-size: 14px; font-weight: 650; line-height: 1; } @media (max-width: 900px) { .admin-toolbar-controls { grid-template-columns: repeat(2, minmax(150px, 1fr)); } .admin-toolbar-summary { justify-items: start; } } @media (max-width: 560px) { .admin-toolbar-search, .admin-toolbar-search-actions, .admin-toolbar-card, .admin-toolbar-controls { grid-template-columns: minmax(0, 1fr); } .admin-toolbar-summary { justify-items: start; } } .admin-table-wrap { border: 1px solid var(--admin-border); border-radius: 12px; background: var(--admin-surface); overflow: hidden; } .admin-table-wrap > .admin-card-head { border-bottom: 1px solid var(--admin-border); } .admin-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; } .admin-table thead th { text-align: left; font-weight: 500; color: var(--admin-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; padding: 12px 16px; background: var(--admin-surface-2); border-bottom: 1px solid var(--admin-border); white-space: nowrap; } .admin-table tbody td { padding: 12px 16px; border-bottom: 1px solid var(--admin-border); vertical-align: middle; color: var(--admin-text); } .admin-table tbody tr:last-child td { border-bottom: 0; } .admin-table tbody tr { transition: background 0.08s ease; } .admin-table tbody tr:hover { background: color-mix(in srgb, var(--admin-elev) 50%, transparent); } .admin-table td.admin-cell-mono { font-family: var(--font-mono); font-size: 12px; } .admin-table td.admin-cell-actions { text-align: right; white-space: nowrap; } .admin-table td.admin-cell-actions .admin-btn { margin-left: 4px; } .admin-table td.admin-cell-wrap { white-space: normal; max-width: 320px; word-break: break-word; color: var(--admin-muted); font-size: 12px; } .admin-table td.admin-cell-id { color: var(--admin-muted); font-family: var(--font-mono); font-size: 12px; width: 80px; } .admin-table tbody tr.is-clickable { cursor: pointer; } .admin-user-list { display: grid; list-style: none; margin: 0; padding: 0; gap: 0; } .admin-user-list > li { border-bottom: 1px solid var(--admin-border); } .admin-user-list > li:last-child { border-bottom: 0; } .admin-user-row { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: center; gap: 12px; width: 100%; border: 0; background: transparent; color: var(--admin-text); /* Card height = avatar (36px) + padding-y * 2 = 52px. */ padding: 8px 14px; text-align: left; cursor: pointer; transition: background 0.12s ease; } .admin-user-row:hover { background: color-mix(in srgb, var(--admin-elev) 60%, transparent); } .admin-user-row:focus-visible { outline: 2px solid var(--admin-ring); outline-offset: -2px; } .admin-user-side { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; white-space: nowrap; } .admin-user-tertiary { color: var(--admin-dim); font-size: 11px; white-space: nowrap; } .admin-avatar.admin-avatar-sm { width: 36px; height: 36px; font-size: 11px; } @media (max-width: 480px) { /* On very narrow screens, drop the date but keep the badge inline so the row still fits within `avatar + padding` height. */ .admin-user-tertiary { display: none; } .admin-user-row { gap: 10px; } } .admin-avatar { display: inline-grid; width: 42px; height: 42px; flex: 0 0 auto; place-items: center; overflow: hidden; border-radius: 8px; border: 1px solid var(--admin-border); background: color-mix(in srgb, var(--accent) 16%, var(--admin-surface-2)); color: var(--accent); font-size: 12px; font-weight: 700; letter-spacing: 0; } .admin-avatar img { width: 100%; height: 100%; object-fit: cover; } .admin-avatar-lg { width: 58px; height: 58px; font-size: 16px; } .admin-user-main, .admin-user-meta, .admin-user-profile-head > div { display: grid; gap: 3px; min-width: 0; } .admin-user-main strong, .admin-user-profile-head strong { overflow: hidden; color: var(--admin-text); font-size: 13px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; } .admin-user-main small, .admin-user-profile-head small, .admin-user-meta span { overflow: hidden; color: var(--admin-muted); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; } .admin-user-meta strong { overflow: hidden; color: var(--admin-text); font-size: 12px; font-weight: 500; text-overflow: ellipsis; white-space: nowrap; } .admin-user-status { justify-self: end; } .admin-user-profile-head { display: flex; align-items: center; gap: 12px; min-width: 0; padding-bottom: 12px; border-bottom: 1px solid var(--admin-border); } .admin-mini-list { display: grid; gap: 0; } .admin-mini-list-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--admin-border); } .admin-mini-list-row:last-child { border-bottom: 0; } .admin-mini-list-row div { display: grid; gap: 3px; min-width: 0; } .admin-mini-list-row strong { overflow: hidden; color: var(--admin-text); font-size: 13px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; } .admin-mini-list-row small { overflow: hidden; color: var(--admin-muted); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; } .admin-pagination { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 4px 0; } .admin-pagination .admin-pagination-meta { color: var(--admin-muted); font-size: 12px; } .admin-pagination-buttons { display: flex; gap: 6px; } .admin-screen-wrap input, .admin-screen-wrap textarea, .admin-screen-wrap select, .admin-screen-wrap .input { min-width: 0; max-width: 100%; } .admin-screen-wrap .input, .admin-screen-wrap input[type="text"], .admin-screen-wrap input[type="number"], .admin-screen-wrap input[type="email"], .admin-screen-wrap input[type="search"], .admin-screen-wrap input[type="password"], .admin-screen-wrap input[type="url"], .admin-screen-wrap select { height: 36px; border-radius: 8px; border: 1px solid var(--admin-border-strong); background: var(--admin-bg); color: var(--admin-text); padding: 0 12px; font-size: 13px; outline: none; transition: border-color 0.12s ease, box-shadow 0.12s ease; } .admin-screen-wrap .input::placeholder, .admin-screen-wrap input::placeholder, .admin-screen-wrap textarea::placeholder { color: var(--admin-dim); } .admin-screen-wrap .input:focus, .admin-screen-wrap input:focus, .admin-screen-wrap select:focus { border-color: var(--admin-ring); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent); } .admin-select { width: 100%; appearance: auto; } .admin-textarea, .admin-screen-wrap textarea { width: 100%; min-height: 110px; border-radius: 10px; border: 1px solid var(--admin-border-strong); background: var(--admin-bg); color: var(--admin-text); padding: 12px; font: inherit; font-size: 13px; resize: vertical; outline: none; transition: border-color 0.12s ease, box-shadow 0.12s ease; } .admin-textarea:focus { border-color: var(--admin-ring); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent); } .admin-form { display: grid; gap: 12px; } .admin-form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; } .admin-form-row.admin-form-row-3 { grid-template-columns: minmax(180px, 1.1fr) minmax(160px, 0.8fr) minmax(140px, 0.6fr); } .admin-form label { display: grid; gap: 6px; font-size: 12px; color: var(--admin-muted); font-weight: 500; } .admin-form label > span { color: var(--admin-text); font-weight: 500; } .admin-form label > small { color: var(--admin-dim); font-weight: 400; } .admin-switch.admin-switch-field { align-self: end; min-height: 36px; display: flex; } .admin-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 34px; padding: 0 14px; border-radius: 8px; border: 1px solid var(--admin-border); background: var(--admin-surface-2); color: var(--admin-text); font-size: 13px; font-weight: 500; cursor: pointer; white-space: nowrap; transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease; } .admin-btn:hover:not(:disabled) { background: var(--admin-elev); } .admin-btn:disabled { opacity: 0.5; cursor: not-allowed; } .admin-btn.admin-btn-primary { background: var(--accent); color: #02110a; border-color: color-mix(in srgb, var(--accent) 70%, #000); font-weight: 600; } .admin-btn.admin-btn-primary:hover:not(:disabled) { background: color-mix(in srgb, var(--accent) 90%, #fff); } .admin-btn.admin-btn-ghost { background: transparent; border-color: transparent; color: var(--admin-muted); } .admin-btn.admin-btn-ghost:hover:not(:disabled) { background: var(--admin-surface-2); color: var(--admin-text); } .admin-btn.admin-btn-danger { background: color-mix(in srgb, #ff5757 80%, #000); color: #fff; border-color: color-mix(in srgb, #ff5757 60%, #000); font-weight: 600; } .admin-btn.admin-btn-danger:hover:not(:disabled) { background: #ff5757; border-color: #ff5757; } .admin-btn.admin-btn-danger-soft { color: #ffb4b4; background: var(--admin-surface-2); border-color: color-mix(in srgb, #ff6b6b 30%, transparent); } .admin-btn.admin-btn-danger-soft:hover:not(:disabled) { background: color-mix(in srgb, #ff6b6b 14%, var(--admin-surface)); border-color: color-mix(in srgb, #ff6b6b 50%, transparent); } .admin-btn.admin-btn-icon { width: 34px; padding: 0; } .admin-btn.admin-btn-sm { height: 28px; padding: 0 10px; font-size: 12px; border-radius: 6px; } /* ============================================================ Admin skeletons (users list, payments / logs / promos / ads tables). Rendered while data is loading to soften the empty state. Kept aria-hidden in markup; purely decorative. ============================================================ */ .admin-skeleton { display: inline-block; background: linear-gradient( 90deg, var(--admin-surface-2) 0%, color-mix(in srgb, var(--admin-elev) 65%, transparent) 50%, var(--admin-surface-2) 100% ); background-size: 200% 100%; border-radius: 6px; animation: admin-skeleton-shimmer 1.2s ease-in-out infinite; } .admin-skeleton-line { display: block; width: 100%; height: 10px; border-radius: 4px; } .admin-skeleton-line-strong { height: 12px; width: 60%; } .admin-skeleton-line-soft { height: 9px; width: 40%; opacity: 0.7; } .admin-skeleton-line-short { width: 50%; } .admin-skeleton-line-tiny { width: 32%; } .admin-skeleton-avatar { width: 36px; height: 36px; border-radius: 50%; } .admin-skeleton-badge { width: 64px; height: 18px; border-radius: 999px; } .admin-user-row-skeleton { cursor: default; pointer-events: none; } .admin-user-row-skeleton .admin-user-main { display: grid; gap: 6px; } .admin-user-row-skeleton .admin-user-side { gap: 8px; } .admin-table-skeleton td { padding: 12px 16px; } @keyframes admin-skeleton-shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } } @media (prefers-reduced-motion: reduce) { .admin-skeleton { animation: none; } } .admin-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--admin-border); background: var(--admin-surface-2); color: var(--admin-muted); white-space: nowrap; } .admin-badge.admin-badge-success { border-color: color-mix(in srgb, var(--accent) 36%, transparent); color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, var(--admin-surface)); } .admin-badge.admin-badge-danger { border-color: color-mix(in srgb, #ff6b6b 32%, transparent); color: #ffb4b4; background: color-mix(in srgb, #ff6b6b 12%, var(--admin-surface)); } .admin-badge.admin-badge-warning { border-color: color-mix(in srgb, #ffd166 32%, transparent); color: #ffd166; background: color-mix(in srgb, #ffd166 12%, var(--admin-surface)); } .admin-badge.admin-badge-muted { color: var(--admin-muted); } .admin-detail-grid { display: grid; grid-template-columns: 1fr; gap: 14px; } @media (min-width: 900px) { .admin-detail-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } } .admin-meta-list { list-style: none; margin: 0; padding: 0; display: grid; } .admin-meta-list li { display: grid; grid-template-columns: 130px minmax(0, 1fr); align-items: baseline; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--admin-border); font-size: 13px; } .admin-meta-list li:last-child { border-bottom: 0; } .admin-meta-list li > span { color: var(--admin-muted); font-size: 12px; } .admin-meta-list li > strong { font-weight: 500; color: var(--admin-text); word-break: break-word; } .admin-accordion { display: grid; gap: 10px; } .admin-accordion-item.admin-card { display: block; min-width: 0; } .admin-accordion-header { margin: 0; display: block; } .admin-accordion-trigger { appearance: none; background: transparent; border: 0; text-align: left; padding: 14px 18px; display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 12px; color: var(--admin-text); cursor: pointer; font: inherit; width: 100%; transition: background 0.12s ease; outline: none; } .admin-accordion-trigger:hover { background: var(--admin-surface-2); } .admin-accordion-trigger:focus-visible { background: var(--admin-surface-2); box-shadow: inset 0 0 0 2px var(--admin-ring); } .admin-accordion-trigger[data-state="open"] { border-bottom: 1px solid var(--admin-border); } .admin-accordion-title { font-size: 13px; font-weight: 600; color: var(--admin-text); text-transform: capitalize; word-break: break-word; min-width: 0; } .admin-accordion-meta { color: var(--admin-muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; } .admin-accordion-chev { transition: transform 0.2s ease; color: var(--admin-muted); flex: 0 0 auto; } .admin-accordion-trigger[data-state="open"] .admin-accordion-chev { transform: rotate(90deg); } .admin-accordion-content { overflow: hidden; } .admin-accordion-content[data-state="closed"] { display: none; } @media (max-width: 720px) { .admin-accordion-trigger { padding: 12px 14px; gap: 8px; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "title chev" "meta meta"; } .admin-accordion-title { grid-area: title; } .admin-accordion-chev { grid-area: chev; } .admin-accordion-meta { grid-area: meta; white-space: normal; font-size: 11px; } } .admin-setting { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 24px; padding: 16px 18px; border-bottom: 1px solid var(--admin-border); align-items: center; } .admin-setting:last-child { border-bottom: 0; } .admin-setting.is-overridden { background: color-mix(in srgb, var(--accent) 5%, transparent); } .admin-setting-meta { display: grid; gap: 4px; min-width: 0; } .admin-setting-meta strong { font-size: 13px; font-weight: 600; color: var(--admin-text); display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; word-break: break-word; } .admin-setting-meta code { font-family: var(--font-mono); font-size: 11px; color: var(--admin-dim); word-break: break-all; overflow-wrap: anywhere; } .admin-setting-meta small { color: var(--admin-muted); font-size: 12px; line-height: 1.5; overflow-wrap: anywhere; } .admin-setting-control { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; } .admin-setting-control .input, .admin-setting-control input[type="text"], .admin-setting-control input[type="number"] { flex: 1 1 160px; min-width: 0; width: 100%; } .admin-setting-control .admin-color { width: 36px; height: 36px; flex: 0 0 36px; border-radius: 8px; border: 1px solid var(--admin-border); background: var(--admin-surface-2); padding: 0; cursor: pointer; } .admin-setting-switch { display: inline-flex; min-height: 36px; align-items: center; gap: 10px; color: var(--admin-text); font-size: 12px; font-weight: 500; } .admin-tabs { display: inline-flex; border-bottom: 1px solid var(--admin-border); gap: 2px; } .admin-tabs button { padding: 9px 12px; border: 0; background: transparent; color: var(--admin-muted); font-size: 13px; font-weight: 500; cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; } .admin-tabs button.active { color: var(--admin-text); border-bottom-color: var(--accent); } /* Admin dialogs don't share the user-facing bottom-nav, so reset the .dialog wrapper's padding (which reserves space for the mobile nav) and let the card use the full viewport for its scroll area. */ .dialog:has(.admin-dialog) { padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left)); z-index: 90; } .admin-dialog { max-height: 100%; width: 100%; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; } /* User-detail dialog: constrain on desktop and lay out as a two-column sidebar (profile facts) + main content (tabs). On mobile it stacks. */ .admin-user-dialog { width: min(100%, 1040px); max-height: min(100%, 760px); } .admin-user-dialog-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; min-width: 0; } .admin-user-aside { display: flex; flex-direction: column; gap: 12px; min-width: 0; } .admin-user-main { display: flex; flex-direction: column; min-width: 0; } .admin-user-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } .admin-user-stat { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--admin-border); background: var(--admin-surface); min-width: 0; } .admin-user-stat span { color: var(--admin-muted); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; } .admin-user-stat strong { color: var(--admin-text); font-size: 15px; font-weight: 700; word-break: break-word; } .admin-link-list { display: flex; flex-direction: column; gap: 6px; } .admin-link-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 8px; border: 1px solid var(--admin-border); background: var(--admin-surface); min-width: 0; } .admin-link-row-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; } .admin-link-row-label { color: var(--admin-muted); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; } .admin-link-row-url { color: var(--admin-text); font-family: var(--font-mono); font-size: 11px; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; } .admin-link-row-url:hover { color: var(--accent); text-decoration: underline; } .admin-btn.admin-btn-icon { width: 30px; height: 30px; padding: 0; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; } .admin-meta-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .admin-traffic-summary { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; } .admin-traffic-card { display: flex; flex-direction: column; gap: 8px; min-width: 0; padding: 12px; border: 1px solid var(--admin-border); border-radius: 10px; background: color-mix(in srgb, var(--admin-surface-2) 54%, var(--admin-bg)); } .admin-traffic-card-premium { border-color: color-mix(in srgb, var(--accent) 30%, var(--admin-border)); } .admin-traffic-card-warning { border-color: color-mix(in srgb, #ffb454 46%, var(--admin-border)); } .admin-traffic-head, .admin-traffic-meta { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 0; } .admin-traffic-head span { color: var(--admin-muted); font-size: 12px; font-weight: 600; } .admin-traffic-head strong { color: var(--admin-text); font-size: 13px; font-weight: 700; text-align: right; } .admin-traffic-bar { height: 8px; border-radius: 999px; background: var(--admin-bg); overflow: hidden; box-shadow: inset 0 0 0 1px var(--admin-border); } .admin-traffic-bar span { display: block; height: 100%; max-width: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 55%, #ffffff)); } .admin-traffic-bar-premium span { background: linear-gradient(90deg, #66e3ff, var(--accent)); } .admin-traffic-card-warning .admin-traffic-bar span { background: linear-gradient(90deg, #ffb454, #ff6b6b); } .admin-traffic-meta { color: var(--admin-muted); font-size: 11px; font-weight: 600; } @media (min-width: 860px) { .admin-user-dialog-body { grid-template-columns: minmax(260px, 320px) minmax(0, 1fr); gap: 20px; align-items: start; } .admin-user-aside { position: sticky; top: 0; } } .admin-tariff-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; } @media (min-width: 720px) { .admin-tariff-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (min-width: 1280px) { .admin-tariff-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } } .admin-tariff-card { display: grid; gap: 12px; min-width: 0; border: 1px solid var(--admin-border); border-radius: 8px; background: var(--admin-surface-2); padding: 14px; } .admin-tariff-card.is-disabled { opacity: 0.72; } .admin-tariff-top, .admin-tariff-title, .admin-tariff-actions, .admin-editor-section-head { display: flex; align-items: center; gap: 8px; } .admin-tariff-top { justify-content: space-between; } .admin-tariff-title { min-width: 0; flex-wrap: wrap; } .admin-tariff-title strong { color: var(--admin-text); font-size: 15px; } .admin-tariff-card code { display: block; margin-top: 4px; color: var(--admin-dim); font-family: var(--font-mono); font-size: 11px; } .admin-tariff-card p { margin: 0; color: var(--admin-muted); font-size: 13px; line-height: 1.45; } .admin-tariff-facts { display: grid; gap: 6px; color: var(--admin-muted); font-size: 12px; } .admin-tariff-facts span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .admin-tariff-actions { flex-wrap: wrap; } .admin-tariff-dialog { width: min(980px, calc(100vw - 32px)); } .admin-editor-section { display: grid; gap: 10px; border: 1px solid var(--admin-border); border-radius: 8px; background: color-mix(in srgb, var(--admin-surface-2) 62%, transparent); padding: 12px; } .admin-editor-section-head { justify-content: space-between; min-height: 28px; } .admin-editor-section-head strong { color: var(--admin-text); font-size: 13px; } .admin-editor-section-head > div { display: flex; gap: 6px; flex-wrap: wrap; } /* Section title block: stacks `` heading + `` description. Higher specificity than `.admin-editor-section-head > div` (which would otherwise force flex-row on the wrapper). */ .admin-editor-section-head > .admin-editor-section-title { display: flex; flex-direction: column; gap: 2px; flex: 1 1 200px; min-width: 0; } .admin-editor-section-head > .admin-editor-section-title small { color: var(--admin-muted); font-size: 12px; line-height: 1.4; font-weight: 400; text-transform: none; letter-spacing: 0; } /* Column headers above an `.admin-row-editor` list — visually distinct, inherits the same grid template as input rows so columns line up. */ .admin-row-editor-line.admin-row-editor-header { color: var(--admin-muted); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; padding: 0 4px; } .admin-row-editor-line.admin-row-editor-header span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .admin-row-editor { display: grid; gap: 8px; min-width: 0; } .admin-row-editor-line { display: grid; grid-template-columns: minmax(90px, 1fr) minmax(110px, 1fr) 32px; gap: 8px; align-items: center; } .admin-row-editor-line.admin-row-editor-4 { grid-template-columns: minmax(80px, 0.8fr) minmax(100px, 1fr) minmax(100px, 1fr) 32px; } .admin-row-editor-line .admin-btn { width: 32px; padding: 0; } .admin-package-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } .admin-dialog-actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 2px; } @media (max-width: 1023px) { .admin-screen-wrap { --admin-header-h: 56px; } .admin-sidebar { position: fixed; inset: 0 auto 0 0; width: 280px; flex: 0 0 auto; z-index: 80; transform: translateX(-100%); transition: transform 0.22s ease; box-shadow: 0 32px 80px rgba(0, 0, 0, 0.6); } .admin-screen-wrap.is-sidebar-open .admin-sidebar { transform: translateX(0); } .admin-sidebar-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); z-index: 70; border: 0; cursor: pointer; } .admin-mobile-toggle { display: inline-flex; } .admin-header { padding: 8px 16px; grid-template-columns: minmax(0, 1fr); grid-auto-flow: row; grid-auto-rows: auto; align-content: center; gap: 6px; min-height: var(--admin-header-h); } .admin-header-actions { overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; } .admin-header-actions::-webkit-scrollbar { display: none; } .admin-main { padding: 16px; } } @media (max-width: 720px) { .admin-setting { grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 14px 14px; } .admin-card-head { padding: 12px 14px; } .admin-card-body { padding: 14px; } .admin-tariff-card { padding: 12px; } .admin-tariff-actions .admin-btn { flex: 1 1 calc(50% - 4px); } .admin-tariff-actions .admin-btn[aria-label] { flex: 0 0 auto; } /* (legacy three-row user-row layout removed in favour of the compact single-row layout defined above) */ .admin-user-meta strong { font-size: 11px; } .admin-form-row.admin-form-row-3, .admin-package-columns, .admin-row-editor-line, .admin-row-editor-line.admin-row-editor-4 { grid-template-columns: 1fr; } .admin-dialog-actions { justify-content: stretch; flex-direction: column-reverse; } .admin-dialog-actions .admin-btn { width: 100%; } .admin-table thead { display: none; } .admin-table tbody td { display: block; padding: 6px 16px; border: 0; } .admin-table tbody tr { display: block; padding: 10px 0; border-bottom: 1px solid var(--admin-border); } .admin-table tbody tr:last-child { border-bottom: 0; } .admin-table tbody td::before { content: attr(data-label); display: inline-block; min-width: 110px; color: var(--admin-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; margin-right: 8px; } .admin-table td.admin-cell-actions { text-align: left; } } .settings-admin-block { display: grid; gap: 10px; margin: 6px 0 0; } .settings-row.settings-row-admin { border: 1px solid color-mix(in srgb, #f59e0b 42%, transparent); background: color-mix(in srgb, #f59e0b 12%, transparent); border-radius: var(--radius); padding: 10px 12px; width: 100%; cursor: pointer; transition: background 0.12s ease, border-color 0.12s ease; } .settings-row.settings-row-admin:hover { background: color-mix(in srgb, #f59e0b 18%, transparent); border-color: color-mix(in srgb, #f59e0b 58%, transparent); } .settings-row.settings-row-admin > svg:first-child { color: #fbbf24; opacity: 1; } .settings-row.settings-row-admin strong { color: var(--text); } /* ============================================================ shadcn-svelte primitives: Tabs / Select / Switch / Label bits-ui exposes data-state attributes; styling here matches shadcn-svelte defaults adapted to the dark admin palette. ============================================================ */ .admin-tabs-root { display: flex; flex-direction: column; gap: 14px; min-width: 0; } .admin-tabs-list { display: inline-flex; align-items: center; gap: 4px; padding: 4px; border-radius: 10px; background: var(--admin-surface-2); border: 1px solid var(--admin-border); overflow-x: auto; scrollbar-width: none; flex: 0 0 auto; } .admin-tabs-list::-webkit-scrollbar { display: none; } .admin-tabs-trigger { appearance: none; border: 0; background: transparent; color: var(--admin-muted); font: inherit; font-size: 13px; font-weight: 500; padding: 7px 14px; border-radius: 7px; cursor: pointer; white-space: nowrap; transition: background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease; outline: none; } .admin-tabs-trigger:hover { color: var(--admin-text); } .admin-tabs-trigger[data-state="active"] { background: var(--admin-surface); color: var(--admin-text); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); } .admin-tabs-trigger:focus-visible { box-shadow: 0 0 0 2px var(--admin-ring); } .admin-tabs-content { display: flex; flex-direction: column; gap: 14px; outline: none; } .admin-tabs-content[data-state="inactive"] { display: none; } .admin-user-tabs-root { gap: 0; } .admin-user-tabs-root .admin-tabs-list { gap: 2px; padding: 4px 4px 0; border-radius: 10px 10px 0 0; background: color-mix(in srgb, var(--admin-surface-2) 74%, var(--admin-bg)); border-bottom: 0; width: fit-content; max-width: 100%; } .admin-user-tabs-root .admin-tabs-trigger { padding: 8px 14px 9px; border-radius: 7px 7px 0 0; } .admin-user-tabs-root .admin-tabs-trigger[data-state="active"] { position: relative; z-index: 1; box-shadow: 0 -1px 0 var(--admin-border), 1px 0 0 var(--admin-border), -1px 0 0 var(--admin-border), 0 1px 0 var(--admin-surface); } .admin-user-tabs-root .admin-tabs-content { margin-top: -1px; padding: 16px; border: 1px solid var(--admin-border); border-radius: 0 10px 10px 10px; background: var(--admin-surface); } /* Switch (bits-ui Switch.Root + Thumb) */ .admin-switch-root { appearance: none; position: relative; display: inline-flex; align-items: center; width: 40px; height: 22px; flex: 0 0 auto; padding: 0; border-radius: 999px; border: 1px solid var(--admin-border); background: var(--admin-elev); cursor: pointer; transition: background 0.18s ease, border-color 0.18s ease; outline: none; } .admin-switch-root[data-state="checked"] { background: color-mix(in srgb, var(--accent) 80%, var(--admin-elev)); border-color: color-mix(in srgb, var(--accent) 50%, transparent); } .admin-switch-root:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent); } .admin-switch-root:disabled { opacity: 0.5; cursor: not-allowed; } .admin-switch-thumb { display: block; width: 16px; height: 16px; border-radius: 999px; background: #fff; margin-left: 2px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); transition: transform 0.18s ease; } .admin-switch-root[data-state="checked"] .admin-switch-thumb { transform: translateX(18px); } /* Select (bits-ui Select.Root + Trigger + Content + Item) */ .admin-select-trigger { display: inline-flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; height: 36px; padding: 0 12px; border: 1px solid var(--admin-border-strong); border-radius: 8px; background: var(--admin-bg); color: var(--admin-text); font: inherit; font-size: 13px; cursor: pointer; text-align: left; outline: none; transition: border-color 0.12s ease, box-shadow 0.12s ease; } .admin-select-trigger:hover { border-color: var(--admin-border-strong); } .admin-select-trigger:focus-visible, .admin-select-trigger[data-state="open"] { border-color: var(--admin-ring); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent); } .admin-select-icon { color: var(--admin-muted); transition: transform 0.18s ease; flex: 0 0 auto; } .admin-select-trigger[data-state="open"] .admin-select-icon { transform: rotate(180deg); } .admin-select-content { z-index: 90; min-width: var(--bits-select-anchor-width); max-height: var(--bits-select-content-available-height, 320px); overflow-y: auto; border: 1px solid var(--admin-border); border-radius: 10px; background: var(--admin-surface); padding: 4px; box-shadow: 0 16px 36px rgba(0, 0, 0, 0.45); outline: none; display: flex; flex-direction: column; gap: 1px; } .admin-select-item { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 10px; border-radius: 7px; font-size: 13px; color: var(--admin-text); cursor: pointer; outline: none; user-select: none; } .admin-select-item[data-highlighted], .admin-select-item:hover { background: var(--admin-surface-2); } .admin-select-item-check { color: var(--accent); opacity: 0; } .admin-select-item[data-state="checked"] .admin-select-item-check { opacity: 1; } .admin-chip-list { display: flex; flex-wrap: wrap; gap: 6px; min-height: 0; } .admin-chip { display: inline-flex; align-items: center; gap: 6px; min-height: 28px; max-width: 100%; padding: 5px 8px; border: 1px solid var(--admin-border); border-radius: 8px; background: var(--admin-surface-2); color: var(--admin-text); font: inherit; font-size: 12px; cursor: pointer; } .admin-chip:hover { border-color: var(--admin-border-strong); } /* Label primitive (bits-ui Label.Root) */ .admin-field-label { display: flex; flex-direction: column; gap: 6px; font-size: 12px; color: var(--admin-muted); font-weight: 500; min-width: 0; } .admin-field-label > span { color: var(--admin-text); font-weight: 500; font-size: 13px; } .admin-field-label > small { color: var(--admin-dim); font-weight: 400; font-size: 12px; line-height: 1.45; } .admin-field-label > small code, .admin-editor-section-title small code { display: inline-block; padding: 0 4px; border-radius: 4px; background: color-mix(in srgb, var(--admin-elev) 70%, transparent); color: var(--admin-text); font-family: var(--font-mono); font-size: 11px; } .admin-field-label > small b, .admin-editor-section-title small b { color: var(--admin-text); font-weight: 600; } /* Action rows in dialogs */ .admin-action-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; min-width: 0; } .admin-action-row-bordered { border: 1px solid var(--admin-border); border-radius: 10px; padding: 12px 14px; background: var(--admin-surface-2); } .admin-action-label { display: flex; flex-direction: column; gap: 2px; min-width: 0; font-size: 13px; color: var(--admin-text); cursor: pointer; } .admin-action-label > strong { font-weight: 600; } .admin-action-label > small { color: var(--admin-muted); font-size: 12px; line-height: 1.4; } .admin-action-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; align-items: end; } .admin-action-grid > .admin-btn { width: 100%; height: 36px; align-self: end; } .admin-user-quick-actions { display: grid; grid-template-columns: minmax(180px, 0.75fr) minmax(260px, 1.25fr); gap: 12px; align-items: end; } .admin-reset-trial-btn { width: 100%; height: 36px; } .admin-extend-field { gap: 6px; min-width: 0; } .admin-action-inline-field { gap: 6px; } .admin-extend-control { display: grid; grid-template-columns: minmax(72px, 1fr) auto; align-items: stretch; min-width: 0; height: 36px; border: 1px solid var(--admin-border-strong); border-radius: 8px; background: var(--admin-bg); overflow: hidden; } .admin-extend-control .input { height: 100%; min-height: 0; border: 0; border-radius: 0; background: transparent; padding: 0 12px; line-height: 34px; box-shadow: none; } .admin-extend-control .input:focus { box-shadow: none; } .admin-extend-control .admin-btn { display: inline-flex; align-items: center; justify-content: center; height: 100%; min-height: 0; padding: 0 12px; border-width: 0 0 0 1px; border-radius: 0; border-color: var(--admin-border-strong); background: var(--admin-surface-2); line-height: 1; white-space: nowrap; } .admin-extend-control .admin-btn svg { flex: 0 0 auto; } .admin-extend-control:focus-within { border-color: var(--admin-ring); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent); } .admin-input-row { display: grid; grid-template-columns: minmax(72px, 1fr) auto; gap: 8px; align-items: stretch; min-width: 0; } .admin-input-row .input, .admin-input-row .admin-btn { height: 36px; } .admin-actions-tab > .admin-btn { width: 100%; height: 36px; } .admin-message-actions { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; } .admin-message-actions .admin-btn { height: 36px; } .admin-confirm-message-preview { max-height: min(280px, 45vh); overflow: auto; padding: 12px 14px; border: 1px solid var(--admin-border); border-radius: 10px; background: var(--admin-bg); color: var(--admin-text); font-size: 13px; line-height: 1.45; white-space: pre-wrap; word-break: break-word; } @media (max-width: 640px) { .admin-action-grid, .admin-user-quick-actions, .admin-message-actions, .admin-input-row { grid-template-columns: minmax(0, 1fr); } .admin-extend-control { grid-template-columns: minmax(0, 1fr); height: auto; } .admin-extend-control .input, .admin-extend-control .admin-btn { height: 36px; } .admin-extend-control .admin-btn { border-width: 1px 0 0; } } /* Two-column variant of admin-form-row */ .admin-form-row.admin-form-row-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } @media (max-width: 720px) { .admin-form-row.admin-form-row-2 { grid-template-columns: minmax(0, 1fr); } } /* User summary header inside the user dialog */ .admin-user-summary { display: grid; grid-template-columns: 56px minmax(0, 1fr); align-items: center; gap: 14px; padding: 14px 14px 16px; border-radius: 12px; background: var(--admin-surface-2); border: 1px solid var(--admin-border); min-width: 0; } .admin-user-summary-meta { display: grid; gap: 4px; min-width: 0; } .admin-user-summary-meta strong { font-size: 15px; font-weight: 700; color: var(--admin-text); word-break: break-word; } .admin-user-summary-meta small { color: var(--admin-muted); font-size: 12px; word-break: break-word; } .admin-user-summary-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; } .admin-avatar.admin-avatar-lg { width: 56px; height: 56px; border-radius: 16px; overflow: hidden; display: grid; place-items: center; background: color-mix(in srgb, var(--accent) 18%, var(--admin-surface)); color: var(--accent); font-weight: 700; font-size: 18px; flex: 0 0 auto; } .admin-avatar.admin-avatar-lg img { width: 100%; height: 100%; object-fit: cover; display: block; } .admin-subsection-title { font-size: 12px; font-weight: 600; color: var(--admin-muted); text-transform: uppercase; letter-spacing: 0.05em; } .admin-separator { height: 1px; background: var(--admin-border); border: 0; margin: 4px 0; } /* Editor section header tweaks */ .admin-editor-section-actions { display: flex; flex-wrap: wrap; gap: 6px; } .admin-row-editor-caption { font-size: 11px; font-weight: 600; color: var(--admin-muted); text-transform: uppercase; letter-spacing: 0.05em; } .admin-danger-zone { border: 1px solid color-mix(in srgb, #ff6b6b 32%, transparent); border-radius: 12px; background: color-mix(in srgb, #ff6b6b 6%, var(--admin-surface)); padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; margin-top: 4px; } .admin-danger-zone-head { display: flex; flex-direction: column; gap: 2px; } .admin-danger-zone-head strong { font-size: 13px; font-weight: 700; color: #ffb4b4; text-transform: uppercase; letter-spacing: 0.04em; } .admin-danger-zone-head small { color: color-mix(in srgb, #ffb4b4 70%, var(--admin-muted)); font-size: 12px; line-height: 1.45; } /* Subsection grouping inside settings sections (per-payment-provider). Each subsection is a nested Accordion.Item that defaults to closed — users see provider names and expand only the one they want to edit. */ .admin-subsection-accordion { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; } .admin-settings-subsection { border: 1px solid var(--admin-border); border-radius: 10px; background: color-mix(in srgb, var(--admin-surface-2) 40%, transparent); overflow: hidden; } .admin-settings-subsection-trigger { appearance: none; background: transparent; border: 0; text-align: left; width: 100%; padding: 10px 14px; display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 12px; color: var(--admin-text); font: inherit; cursor: pointer; outline: none; transition: background 0.12s ease; } .admin-settings-subsection-trigger:hover { background: var(--admin-surface); } .admin-settings-subsection-trigger[data-state="open"] { background: var(--admin-surface); border-bottom: 1px solid var(--admin-border); } .admin-settings-subsection-trigger:focus-visible { background: var(--admin-surface); box-shadow: inset 0 0 0 2px var(--admin-ring); } .admin-settings-subsection-trigger strong { font-size: 12px; font-weight: 700; color: var(--admin-text); text-transform: uppercase; letter-spacing: 0.06em; min-width: 0; } .admin-settings-subsection-meta { color: var(--admin-muted); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .admin-settings-subsection-trigger .admin-accordion-chev { color: var(--admin-muted); transition: transform 0.18s ease; flex: 0 0 auto; } .admin-settings-subsection-trigger[data-state="open"] .admin-accordion-chev { transform: rotate(90deg); } .admin-settings-subsection-body .admin-setting:last-child { border-bottom: 0; } @media (max-width: 720px) { .admin-settings-subsection-trigger { padding: 9px 12px; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "title chev" "meta meta"; row-gap: 4px; } .admin-settings-subsection-trigger strong { grid-area: title; } .admin-settings-subsection-trigger .admin-accordion-chev { grid-area: chev; } .admin-settings-subsection-meta { grid-area: meta; white-space: normal; } }