<!doctype html>
<html lang="ru">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>MONT - инфрастуктурный полигон</title>
  <link rel="stylesheet" href="/static/style.css" />
  <link rel="icon" type="image/svg+xml" href="/static/favicon.svg" />
  <link rel="icon" type="image/png" href="/static/favicon.png" />
<!-- Yandex.Metrika counter -->
<script type="text/javascript">
    (function(m,e,t,r,i,k,a){
        m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
        m[i].l=1*new Date();
        for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
        k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)
    })(window, document,"script","https://mc.yandex.ru/metrika/tag.js?id=109119977", "ym");
    ym(109119977, "init", {ssr:true, webvisor:true, clickmap:true, ecommerce:"dataLayer", referrer: document.referrer, url: location.href, accurateTrackBounce:true, trackLinks:true});
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/109119977" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
</head>
<body class="dashboard-page">
{% raw %}<style>
  #mobile-wall{display:none;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999;background:linear-gradient(135deg,#0d1b2a 0%,#1a2e45 60%,#0f2137 100%);flex-direction:column;align-items:center;justify-content:center;padding:clamp(1rem,6vw,2.5rem);text-align:center;font-family:sans-serif;box-sizing:border-box;overflow:hidden}
  @media(max-width:1023px){#mobile-wall{display:flex}}
  .mw-icon{font-size:clamp(2.2rem,12vw,3.5rem);margin-bottom:clamp(.5rem,2vw,1.2rem);filter:drop-shadow(0 0 18px rgba(42,140,214,.5))}
  .mw-title{font-size:clamp(1rem,5.5vw,1.5rem);font-weight:800;color:#fff;margin-bottom:.6rem;letter-spacing:.01em;word-break:break-word;width:100%}
  .mw-sub{font-size:clamp(.8rem,3.8vw,.95rem);color:#a0b8cc;width:100%;max-width:320px;line-height:1.6;margin-bottom:clamp(.8rem,4vw,2rem);word-break:break-word;overflow-wrap:break-word}
  .mw-badge{display:inline-flex;align-items:center;gap:.45rem;background:rgba(42,140,214,.15);border:1px solid rgba(42,140,214,.4);border-radius:999px;padding:.45rem .9rem;color:#6bbfff;font-size:clamp(.7rem,3.2vw,.85rem);font-weight:600;max-width:88vw;flex-wrap:wrap;justify-content:center;word-break:break-word}
  .mw-badge svg{width:16px;height:16px;flex-shrink:0}
  .mw-footer{position:absolute;bottom:1.2rem;left:0;width:100%;text-align:center;font-size:clamp(.65rem,2.8vw,.78rem);color:rgba(160,184,204,.45);font-family:sans-serif}
</style>{% endraw %}
<div id="mobile-wall">
  <a href="https://4mont.ru"><img src="/static/logo.png?v=2" alt="MONT" style="position:absolute;top:1.2rem;left:50%;transform:translateX(-50%);height:clamp(4rem,16vw,6rem);opacity:.9"></a>
  <div class="mw-icon">🖥️</div>
  <div class="mw-title">Только для компьютера</div>
  <div class="mw-sub">Инфраструктурный полигон MONT оптимизирован для работы на ПК.<br>Пожалуйста, откройте портал с настольного компьютера или ноутбука.</div>
  <div class="mw-badge">
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg>
    Минимальная ширина экрана: 1024 px
  </div>
  <div class="mw-footer"><a href="mailto:ruslan@ipcom.su" style="color:inherit;text-decoration:none">Made by Galyaviev</a></div>
</div>

  <header class="header">
    <div class="header-left">
      <div class="user-avatar">{{ ((user.first_name[0] if user.first_name else user.username[0]) + (user.last_name[0] if user.last_name else ''))|upper }}</div>
      <span class="header-username">{{ (user.first_name + ' ' + user.last_name)|trim or user.username }}</span>
    </div>
    <div class="header-right">
      {% if user.is_admin %}
        <a href="/admin" class="header-btn">Администрирование</a>
      {% endif %}
      <form method="post" action="/logout">
        <button type="submit" class="header-btn header-btn-logout">Выход</button>
      </form>
    </div>
  </header>
  <div class="page-logo-wrap">
    <a href="https://4mont.ru"><img src="/static/logo.png?v=2" alt="MONT" class="page-logo" /></a>
  </div>
  <main class="admin-layout">
    <section class="panel">
      <div class="admin-intro">Инфраструктурный полигон MONT</div>
      {% if session_notice %}
      <div class="session-notice">{{ session_notice }}</div>
      {% endif %}
      <div class="rules-banner" id="rules-banner">
        <div class="rules-banner-head">
          <div class="rules-banner-title">Правила работы стенда</div>
        </div>
        <div class="rules-banner-grid">
          <div class="rules-pill">Лимит: до 4 сервисов одновременно. При открытии нового сверх лимита самый старый закрывается автоматически.</div>
          <div class="rules-pill">При бездействии более 5 минут сессия закрывается автоматически.</div>
          <div class="rules-pill">Все сервисы работают в защищённом контуре с резервированием и бэкапами.</div>
          <div class="rules-pill">Состояние сервисов возвращается к базовому каждую ночь в 00:00.</div>
        </div>
        <div class="rules-banner-actions">
          <button type="button" class="rules-ack-btn" id="rules-ack-btn">Ознакомлен</button>
        </div>
      </div>
      {% if categories %}
      <div class="category-strip">
        <a class="category-chip {% if not selected_category_slug %}active{% endif %}" href="/">Все сервисы</a>
        {% for category in categories %}
          <a class="category-chip {% if selected_category_slug == category.slug %}active{% endif %}" href="/?category={{ category.slug }}">{{ category.name }}</a>
        {% endfor %}
      </div>
      {% endif %}
    </section>
    <section class="grid service-grid">
    {% for service in services %}
      {% set svc_cats = service_categories.get(service.id, []) %}
      <div class="tile-wrap">
        <a class="tile-link" href="/go/{{ service.slug }}" aria-label="{{ service.name }}"></a>
        <div class="tile">
          <div class="tile-icon-box">
            <img class="tile-icon" src="{{ service.icon_path or '/static/service-placeholder.svg' }}" alt="icon" />
          </div>
          <h3>{{ service.name }}</h3>
          <div class="tile-info-area">
            {% if service.svc_login or service.svc_password %}
            <div class="svc-credentials">
              {% if service.svc_login %}
              <div class="svc-cred-row">
                <span class="svc-cred-label">Логин</span>
                <span class="svc-cred-value">{{ service.svc_login }}</span>
              </div>
              {% endif %}
              {% if service.svc_password %}
              <div class="svc-cred-row">
                <span class="svc-cred-label">Пароль</span>
                <span class="svc-cred-value svc-cred-masked">{{ service.svc_password }}</span>
              </div>
              {% endif %}
              {% if service.svc_cred_hint %}
              <p class="svc-cred-hint">{{ service.svc_cred_hint }}</p>
              {% endif %}
            </div>
            {% endif %}
            {% if service.comment %}
              <div class="tile-comment">{{ service_comment_html.get(service.id, '') }}</div>
            {% endif %}
          </div>
          {% if svc_cats %}
            <div class="service-categories">
              {% for category in svc_cats %}
                <span class="service-cat-badge">{{ category.name }}</span>
              {% endfor %}
            </div>
          {% endif %}
        </div>
      </div>
    {% else %}
      <div class="tile">
        {% if selected_category_slug %}
          Нет сервисов в выбранной категории
        {% else %}
          Нет назначенных сервисов
        {% endif %}
      </div>
    {% endfor %}
    </section>
    <footer class="made-by-wrap"><a class="made-by" href="mailto:ruslan@ipcom.su">Made by Galyaviev</a></footer>
  </main>
  <style>
    #loading-overlay{display:none;position:fixed;inset:0;z-index:8888;background:rgba(10,18,28,.88);
      backdrop-filter:blur(4px);flex-direction:column;align-items:center;justify-content:center;gap:1.2rem}
    #loading-overlay .lo-spinner{width:52px;height:52px;border:4px solid rgba(220,232,245,.15);
      border-top-color:#2a8cd6;border-radius:50%;animation:lo-spin .85s linear infinite}
    #loading-overlay .lo-text{color:#a0b8cc;font:600 1rem sans-serif}
    @keyframes lo-spin{to{transform:rotate(360deg)}}
  </style>
  <div id="loading-overlay">
    <div class="lo-spinner"></div>
    <div class="lo-text">Ожидайте...</div>
  </div>
  <script>
    (function () {
      const username = {{ user.username|tojson }};
      const key = `rules_ack_${username}`;
      const banner = document.getElementById('rules-banner');
      const btn = document.getElementById('rules-ack-btn');
      if (!banner || !btn) return;
      if (localStorage.getItem(key) === '1') {
        banner.style.display = 'none';
        return;
      }
      btn.addEventListener('click', function () {
        localStorage.setItem(key, '1');
        banner.style.display = 'none';
      });
    })();

    (function () {
      function clamp(value, min, max) {
        return Math.max(min, Math.min(max, value));
      }

      function currentScreenParams() {
        const screenWidth =
          window.screen && Number.isFinite(window.screen.width) && window.screen.width > 0
            ? window.screen.width
            : null;
        const screenHeight =
          window.screen && Number.isFinite(window.screen.height) && window.screen.height > 0
            ? window.screen.height
            : null;
        const viewportWidth =
          (window.visualViewport && window.visualViewport.width) ||
          window.innerWidth ||
          document.documentElement.clientWidth ||
          1280;
        const viewportHeight =
          (window.visualViewport && window.visualViewport.height) ||
          window.innerHeight ||
          document.documentElement.clientHeight ||
          720;
        // Prefer stable screen dimensions; viewport is fallback.
        const width = clamp(Math.round(screenWidth || viewportWidth), 320, 7680);
        const height = clamp(Math.round(screenHeight || viewportHeight), 240, 4320);
        const sp = new URLSearchParams();
        sp.set('sw', String(width));
        sp.set('sh', String(height));
        return sp;
      }

      const loadingOverlay = document.getElementById('loading-overlay');

      document.querySelectorAll('a.tile[href^="/go/"]').forEach(function (link) {
        link.addEventListener('click', function (e) {
          e.preventDefault();
          let href = link.getAttribute('href');
          try {
            const url = new URL(href, window.location.origin);
            const params = currentScreenParams();
            url.search = params.toString();
            href = url.pathname + '?' + url.searchParams.toString();
          } catch (e) {}
          if (loadingOverlay) loadingOverlay.style.display = 'flex';
          requestAnimationFrame(function () {
            requestAnimationFrame(function () {
              window.location.href = href;
            });
          });
        }, { capture: true });
      });

      window.addEventListener('pageshow', function (e) {
        if (loadingOverlay) loadingOverlay.style.display = 'none';
      });
    })();
  </script>
</body>
</html>
