.elementor-19012 .elementor-element.elementor-element-fa97eaa{--display:flex;--flex-direction:column;--container-widget-width:100%;--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;}.elementor-widget .tippy-tooltip .tippy-content{text-align:center;}/* Start custom CSS */<div id="cgpost">
<style>
/* Brand colors and the two layout knobs, all in one place.
   --cg-slash  = depth of the TOP diagonal. The bottom edge of the band is straight, so
                 this value only shapes the top.
   --cg-overlap = how far the band rides up over the video. Must stay larger than
                 --cg-slash, or the left end of the diagonal drops below the video.
   --cg-band-art = the image laid over the blue. Swap the URL here, nowhere else. */
#cgpost {
  --cg-blue: #007dba;
  --cg-navy: #064481;
  --cg-teal: #02a8a5;
  --cg-red: #da291c;
  --cg-gold: #eaba09;
  --cg-lighter-blue: #95d3e9;
  --cg-slash: min(5vw, 140px);
  /* Overlap is derived so the diagonal's midpoint lands on the video's vertical center:
     half the video height, plus half the slash. --cg-video-h is measured by the script;
     the fallback in the var() call is the same figure worked out from the column width. */
  --cg-overlap: calc(var(--cg-video-h, calc(min(868px, 100vw - 32px) * 0.5625)) / 2 + var(--cg-slash) / 2);
  --cg-band-art: url('https://cell-gate.com/wp-content/uploads/2025/10/Rectangle-14-copy-11.png');
  max-width: 900px; margin: 0 auto; padding: 0 16px; font-family: 'Open Sans', sans-serif; color: #333333;
}
#cgpost * { box-sizing: border-box; }

/* Compact header row across the top (title + meta), stays on white so the H1 reads
   normally on a standard Google visit. Does NOT push the video down much. */
#cgpost .cgpost-head { padding: 8px 0 16px; text-align: center; }
/* H1 at the standard CellGate scale: 28-32px, weight 700, navy */
#cgpost .cgpost-title { font-size: 30px; line-height: 1.22; font-weight: 700; color: var(--cg-navy); margin: 0 0 8px; }
#cgpost .cgpost-meta { font-size: 13px; color: #8a94a0; margin: 0; }
#cgpost .cgpost-meta a { color: var(--cg-teal); text-decoration: none; font-weight: 600; }
#cgpost .cgpost-meta a:hover { text-decoration: underline; }

/* Bare mode (opened in the lightbox or embedded with ?bare=1): hide the clickable meta
   line and the bottom link row so they can't be clicked, and keep the focus purely on the
   video + article. The WPCode snippet hides these two server-side as well on any ?bare=1
   URL; this copy is what covers a partner embed loaded without the parameter. */
#cgpost.cgpost-bare .cgpost-meta { display: none; }
#cgpost.cgpost-bare .cgpost-cats { display: none; }

/* In bare/embed mode, give the scrollable article a clear, on-brand scrollbar so it
   reads as a self-contained widget rather than blending into the host page. */
html.cgpost-bare-html { scrollbar-width: thin; scrollbar-color: #02a8a5 #eaeef2; }
html.cgpost-bare-html::-webkit-scrollbar { width: 11px; }
html.cgpost-bare-html::-webkit-scrollbar-track { background: #eaeef2; }
html.cgpost-bare-html::-webkit-scrollbar-thumb { background: #02a8a5; border-radius: 6px; border: 2px solid #eaeef2; }
html.cgpost-bare-html::-webkit-scrollbar-thumb:hover { background: #029390; }
#cgpost.cgpost-bare { padding-bottom: 24px; }

/* Video stacks above the band, so the diagonal passes behind it: top half on white,
   bottom half on blue. */
#cgpost .cgpost-video { position: relative; z-index: 2; width: 100%; aspect-ratio: 16 / 9; background: #000; border-radius: 12px; overflow: hidden; box-shadow: 0 16px 42px rgba(0,0,0,0.30); }
#cgpost .cgpost-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ===== The blue band =====
   ONE full-bleed element, so the image behind the article is a single unbroken layer
   with no seam at the video. It rides up over the video by --cg-overlap and its
   top edge is cut on a diagonal. The bottom edge is straight, so the band runs flush
   into whatever follows it with no white wedge underneath.
   Two measured values place it: --cg-vw is the real viewport width (100vw would be wider
   than the visible page whenever a scrollbar exists), and --cg-bleed-left is the distance
   from the viewport's left edge to this column, pulled off as a negative margin. Measuring
   that offset instead of assuming the column is centered is what keeps the band from
   running off the right edge inside the lightbox and inside partner embeds, where the
   content area can sit off center. The calc() fallback is the centered assumption, used
   only when the script does not run. */
#cgpost .cgpost-band { position: relative; z-index: 1; width: var(--cg-vw, 100vw); margin-left: var(--cg-bleed-left, calc(50% - 50vw)); margin-top: calc(-1 * var(--cg-overlap)); background: linear-gradient(to right, var(--cg-red), var(--cg-navy)); -webkit-clip-path: polygon(0 var(--cg-slash), 100% 0, 100% 100%, 0 100%); clip-path: polygon(0 var(--cg-slash), 100% 0, 100% 100%, 0 100%); }

/* The fill sits 7px inside the top and bottom, so the gradient underneath shows as a thin
   rule along the top diagonal and as a straight rule across the bottom edge. Backgrounds paint image first, color last: the artwork
   lays over CellGate blue.
   To soften the artwork for legibility, add a scrim as the FIRST background layer:
     linear-gradient(rgba(0,125,186,0.55), rgba(0,125,186,0.55)),
   Other sizing options in place of "cover": "100% auto" (full width, no crop) or
   "contain" (whole image visible, may letterbox). */
#cgpost .cgpost-band::before {
  content: ''; position: absolute; left: 0; right: 0; top: 7px; bottom: 7px;
  background: var(--cg-band-art) center top / cover no-repeat, var(--cg-blue);
  -webkit-clip-path: polygon(0 var(--cg-slash), 100% 0, 100% 100%, 0 100%);
  clip-path: polygon(0 var(--cg-slash), 100% 0, 100% 100%, 0 100%);
}

/* Re-constrain the copy to the reading column inside the full-width band */
#cgpost .cgpost-band-inner { position: relative; z-index: 1; max-width: 900px; margin: 0 auto; padding: calc(var(--cg-overlap) + 34px) 16px 52px; }

/* Everything that could push the video down lives BELOW it, on the blue */
#cgpost .cgpost-lede { font-size: 17.5px; line-height: 1.6; color: #ffffff; margin: 0; font-weight: 600; }
#cgpost .cgpost-body { margin-top: 26px; }
/* Subheaders sit in their own navy box: white on navy reads at about 9:1, so the
   headings stay crisp even where the artwork lightens the blue behind them. The box
   hugs its text (inline-block) rather than spanning the column, and the red left edge
   keeps the warm accent. To go back to a plain heading, drop the background, padding,
   and border, then re-enable the ::after bar below. */
#cgpost .cgpost-body h2 { display: table; margin-left: auto; margin-right: auto; text-align: center; position: relative; font-size: 21px; font-weight: 700; color: #ffffff; background: var(--cg-navy); border-left: 4px solid var(--cg-red); border-radius: 0 5px 5px 0; padding: 10px 18px; margin: 34px 0 16px; line-height: 1.3; box-shadow: 0 6px 18px rgba(0,0,0,0.18); }
#cgpost .cgpost-body h2::after { display: none; }
/* Headings with a colon break onto a second line. A block-level span does it instead of
   a <br>, so the source text keeps its space and nothing reads the two halves as one
   joined word. Add class="cgpost-hb" to whatever follows the colon. */
#cgpost .cgpost-hb { display: block; }
#cgpost .cgpost-title .cgpost-hb { font-size: 0.8em; font-weight: 600; color: var(--cg-blue); margin-top: 5px; }
#cgpost .cgpost-body h2 .cgpost-hb { font-size: 0.93em; font-weight: 600; margin-top: 2px; }
/* Icon rows keep their headings left-aligned: the icon already anchors that column, and
   a centered box beside a left-hand icon reads as a mistake. Delete this rule to center
   those too. */
#cgpost .cgpost-feature-body > h2 { margin-left: 0; margin-right: 0; text-align: left; }
#cgpost .cgpost-body p { font-size: 15.5px; line-height: 1.75; color: #ffffff; margin: 0 0 14px; }
#cgpost .cgpost-body ul, #cgpost .cgpost-body ol { margin: 0 0 16px; padding-left: 22px; }
#cgpost .cgpost-body li { font-size: 15.5px; line-height: 1.7; color: #ffffff; margin-bottom: 8px; }
#cgpost .cgpost-body li::marker { color: var(--cg-red); }
/* Numbered lists are the exception: there the marker is content, not decoration, and red on
   CellGate blue measures about 1.08:1. Numbers stay white. */
#cgpost .cgpost-body ol li::marker { color: #ffffff; font-weight: 700; }

/* ===== "What this video covers" card =====
   This block summarizes the video rather than continuing the argument, so it inverts the
   page: a white card with navy type sitting on the blue field. The inversion is the
   differentiator, so keep the rest of the article white-on-blue. The heading stays an
   <h2> for document structure but is styled down to an eyebrow label, and the bullets
   become teal checks. */
#cgpost .cgpost-covers { background: #ffffff; border-left: 5px solid var(--cg-teal); border-radius: 0 10px 10px 0; padding: 22px 26px 24px; box-shadow: 0 12px 32px rgba(0,0,0,0.22); }
#cgpost .cgpost-body .cgpost-covers h2 { display: flex; align-items: center; gap: 9px; background: none; border: 0; border-radius: 0; box-shadow: none; padding: 0; margin: 0 0 15px; color: var(--cg-navy); font-size: 13px; font-weight: 800; letter-spacing: 0.09em; text-transform: uppercase; line-height: 1.2; }
#cgpost .cgpost-body .cgpost-covers h2 svg { flex: 0 0 auto; width: 17px; height: 17px; fill: var(--cg-teal); }
#cgpost .cgpost-covers-list { list-style: none; margin: 0; padding: 0; }
#cgpost .cgpost-body .cgpost-covers-list li { position: relative; margin: 0 0 10px; padding-left: 30px; color: #333333; font-size: 15px; line-height: 1.6; }
#cgpost .cgpost-body .cgpost-covers-list li:last-child { margin-bottom: 0; }
/* Contents links: the card is white, so these go navy and pick up teal on hover.
   They need to out-specify the white-on-blue link rule used in the article body. */
#cgpost .cgpost-body .cgpost-covers-list a { color: var(--cg-navy); font-weight: 600; text-decoration: none; border-bottom: 1px solid transparent; transition: color 0.15s ease, border-color 0.15s ease; }
#cgpost .cgpost-body .cgpost-covers-list a:hover { color: var(--cg-teal); border-bottom-color: var(--cg-teal); }
/* Jump targets stop clear of the site's fixed header. In bare mode there is no header,
   so the offset shrinks to a small breathing gap. */
#cgpost [id] { scroll-margin-top: 100px; }
#cgpost.cgpost-bare [id] { scroll-margin-top: 16px; }

/* ===== Jump focus =====
   Clicking a contents link hides the rest of the article outright, so you arrive with
   only the destination section on screen, then everything eases back in. The hide is
   instant (transition: none while the class is on) and the return is slow: the resting
   rule below carries the timing, so removing the class IS the fade. Retime it there.
   The state is script-driven, so with JavaScript off, or with reduced motion requested,
   nothing hides and the links still jump. */
#cgpost .cgpost-lede,
#cgpost .cgpost-cats,
#cgpost .cgpost-body > * { transition: opacity 1.6s ease; }
#cgpost .cgpost-band-inner.cgpost-focusing > .cgpost-lede,
#cgpost .cgpost-band-inner.cgpost-focusing > .cgpost-cats,
#cgpost .cgpost-band-inner.cgpost-focusing > .cgpost-body > * { opacity: 0; transition: none; }
#cgpost .cgpost-band-inner.cgpost-focusing > .cgpost-body > .cgpost-focus { opacity: 1; }
#cgpost .cgpost-body .cgpost-covers-list li::marker { content: none; }
#cgpost .cgpost-body .cgpost-covers-list li::before { content: ''; position: absolute; left: 0; top: 0.2em; width: 18px; height: 18px; border-radius: 50%; background: var(--cg-teal) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12.5l4.5 4.5L19 6.5'/></svg>") center / 11px 11px no-repeat; }
/* Links stay white for contrast on blue and lean on the underline to read as links */
#cgpost .cgpost-body a { color: #ffffff; text-decoration: none; font-weight: 700; border-bottom: 2px solid rgba(255,255,255,0.55); }
#cgpost .cgpost-body a:hover { color: var(--cg-lighter-blue); border-bottom-color: var(--cg-lighter-blue); }

/* ===== Pull quote =====
   A voice from outside the article's own argument, so it gets a field of its own: a
   translucent white panel with a navy edge. Deliberately lighter than the contents card,
   which is a solid white inversion, so the two never compete. */
#cgpost .cgpost-quote { margin: 0 0 30px; padding: 20px 24px; background: rgba(255,255,255,0.12); border-left: 4px solid var(--cg-navy); border-radius: 0 8px 8px 0; }
#cgpost .cgpost-body .cgpost-quote p { font-size: 18px; line-height: 1.55; font-weight: 600; font-style: italic; color: #ffffff; margin: 0; }
#cgpost .cgpost-quote cite { display: block; margin-top: 12px; font-size: 12.5px; font-weight: 800; font-style: normal; letter-spacing: 0.06em; text-transform: uppercase; color: var(--cg-lighter-blue); }

/* ===== Inline note =====
   A short aside the reader needs in order to reconcile the video, or the app itself, with
   current naming. Quieter than the pull quote on purpose: no panel, just a light rule, so it
   reads as a footnote rather than a feature. One per post. */
#cgpost .cgpost-note { margin: 0 0 26px; padding: 3px 0 3px 16px; border-left: 3px solid var(--cg-lighter-blue); }
#cgpost .cgpost-body .cgpost-note p { font-size: 14.5px; line-height: 1.6; color: rgba(255,255,255,0.90); margin: 0; }
#cgpost .cgpost-note strong { color: #ffffff; font-weight: 700; }

/* ===== Icon rows =====
   For sections that read better with a mark than a wall of text: a large stroked icon
   on the left, heading box and copy on the right. Icons are inline SVG using
   stroke="currentColor", so they take their color from .cgpost-feature-icon (white here,
   var(--cg-red) if you want them warm). The drop-shadow keeps the strokes readable
   wherever the artwork behind the blue goes light. Copy the wrapper to add more. */
#cgpost .cgpost-feature { display: flex; align-items: flex-start; gap: 24px; margin-top: 36px; }
#cgpost .cgpost-feature-icon { flex: 0 0 auto; width: 74px; height: 74px; margin-top: 4px; color: #ffffff; filter: drop-shadow(0 3px 8px rgba(0,0,0,0.35)); }
/* The icon column takes either an inline SVG or an <img>. object-fit keeps a PNG's
   proportions inside the square instead of stretching it. */
#cgpost .cgpost-feature-icon svg,
#cgpost .cgpost-feature-icon img { display: block; width: 100%; height: 100%; }
#cgpost .cgpost-feature-icon img { object-fit: contain; }
#cgpost .cgpost-feature-body { flex: 1 1 auto; min-width: 0; }
#cgpost .cgpost-feature-body > h2:first-child { margin-top: 0; }
#cgpost .cgpost-feature-body > p:last-child { margin-bottom: 0; }

/* Bottom link row: the same four links on every post, laid out as a horizontal chip row */
#cgpost .cgpost-cats { margin-top: 38px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,0.28); }
#cgpost .cgpost-cats-label { font-size: 12px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: rgba(255,255,255,0.75); margin: 0 0 12px; }
#cgpost .cgpost-cats-list { display: flex; flex-wrap: wrap; gap: 8px; }
#cgpost .cgpost-cat { display: inline-block; padding: 7px 14px; border-radius: 50px; background: rgba(255,255,255,0.14); border: 1px solid rgba(255,255,255,0.35); color: #ffffff; font-size: 13px; font-weight: 700; text-decoration: none; transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease; }
#cgpost .cgpost-cat:hover { background: #ffffff; border-color: #ffffff; color: var(--cg-blue); }

/* Narrow screens: 5vw of a phone is almost invisible, so steepen the slash and pull
   the overlap in. Both edges still read from --cg-slash, so they stay parallel. */
@media (max-width: 700px) {
  #cgpost { --cg-slash: 8vw; }
  #cgpost .cgpost-band-inner { padding: calc(var(--cg-overlap) + 26px) 16px 36px; }
}
@media (max-width: 600px) {
  #cgpost .cgpost-title { font-size: 24px; }
  #cgpost .cgpost-lede { font-size: 15.5px; }
  #cgpost .cgpost-body h2 { font-size: 18.5px; padding: 8px 14px; margin: 28px 0 14px; }
  #cgpost .cgpost-feature { gap: 14px; margin-top: 28px; }
  #cgpost .cgpost-feature-icon { width: 48px; height: 48px; margin-top: 2px; }
  #cgpost .cgpost-covers { padding: 18px 18px 20px; }
}
</style>

<!-- Compact header across the top, centered. Colon break uses a block span, never a <br>. -->
<div class="cgpost-head">
  <h1 class="cgpost-title">Simplify Visitor Management with Visitor Passes: <span class="cgpost-hb">QR or PIN Codes, Issued Straight from the CellGate App</span></h1>
  <p class="cgpost-meta">Jul 17, 2024 &nbsp;|&nbsp; <a href="https://cell-gate.com/category/cellgate-solutions/">CellGate Solutions</a>, <a href="https://cell-gate.com/category/watchman/">Watchman</a></p>
</div>

<!-- Video: the focus, autoplays (mute=1 so browsers allow autoplay).
     YouTube params: mute=1 is REQUIRED for autoplay (YouTube spells it "mute", not
     "muted" like Vimeo did). rel=0 keeps end-screen suggestions to our own channel,
     playsinline=1 stops iOS from hijacking to fullscreen, and youtube-nocookie.com is
     the privacy-preserving host (the equivalent of Vimeo's dnt=1). start=5 carries over
     the t=5s on the source link, which skips the opening titles.
     Source: youtube.com/watch?v=h1qkKTRoz4k (replaces vimeo.com/1131395934). -->
<div class="cgpost-video">
  <iframe
    src="https://www.youtube-nocookie.com/embed/h1qkKTRoz4k?autoplay=1&mute=1&playsinline=1&rel=0&modestbranding=1&start=5"
    allow="autoplay; fullscreen; encrypted-media; picture-in-picture"
    allowfullscreen
    title="Simplify visitor management with Visitor Passes"></iframe>
</div>

<!-- Full-width blue band: cuts through the center of the video, article in white.
     NOTE on the links below: every outbound link in the article carries target="_blank"
     rel="noopener" in the markup as well as getting it from the bare-mode script. That is
     deliberate belt and braces. Nothing but the script can retarget a link, so if the script
     ever fails to run, a link clicked inside the lightbox would navigate INSIDE the frame and
     strand the visitor in a chrome-less page. Contents-card links (href="#...") are
     deliberately left alone: they must keep scrolling within the frame. -->
<div class="cgpost-band">
  <div class="cgpost-band-inner">

    <p class="cgpost-lede">Visitor Passes let you hand a guest, vendor, or delivery driver a QR or PIN Code that opens the gate, and take it back whenever you want. They are issued from the CellGate app in about a minute, and they come in three kinds depending on how long the access should last.</p>

    <div class="cgpost-body">

      <div class="cgpost-note">
        <p><strong>A note on naming.</strong> Visitor Passes are one type of access credential, and the term replaced the older &ldquo;Virtual Keys&rdquo; branding. Some versions of the app still show <strong>Virtual Keys</strong> in the menu, and the video uses that label too. Same feature, current name.</p>
      </div>

      <div class="cgpost-covers">
        <h2><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8 5v14l11-7z"/></svg> What this video covers</h2>
        <ul class="cgpost-covers-list">
          <li><a href="#find-in-app">Where to find Visitor Passes in the CellGate app</a></li>
          <li><a href="#individual-passes">Individual passes for the people who come back every week</a></li>
          <li><a href="#event-passes">Event passes covering one hour up to seven days</a></li>
          <li><a href="#single-use-passes">Single-use passes that expire the moment they are used</a></li>
          <li><a href="#choosing-a-pass">Choosing between QR and PIN, and where the records live</a></li>
        </ul>
      </div>

      <div class="cgpost-sec" id="find-in-app">
        <h2>Finding Visitor Passes in the app</h2>
        <ol>
          <li>Open the <a href="https://cell-gate.com/cellgate-app/" target="_blank" rel="noopener">CellGate app</a> and tap the menu icon in the top left corner.</li>
          <li>Choose <strong>Visitor Passes</strong> from the menu. On some systems this still reads <strong>Virtual Keys</strong>.</li>
          <li>That page is the hub. Every pass, of all three kinds, is created and revoked from there.</li>
        </ol>
      </div>

      <div class="cgpost-feature" id="individual-passes">
        <div class="cgpost-feature-icon"><img src="https://cell-gate.com/wp-content/uploads/2025/09/Recurring-Key.png" alt="" aria-hidden="true" loading="lazy"></div>
        <div class="cgpost-feature-body">
          <h2>Individual Visitor Passes</h2>
          <p>For one person who needs to come back: a dog walker, a housekeeper, a maintenance contact you call regularly. Issue a QR or PIN Code once and it keeps working.</p>
          <p>Add restrictions on days and times if the visit should only happen Tuesday mornings, or leave it open if the person needs the run of the week.</p>
        </div>
      </div>

      <div class="cgpost-feature" id="event-passes">
        <div class="cgpost-feature-icon"><img src="https://cell-gate.com/wp-content/uploads/2025/09/Temorary-Key.png" alt="" aria-hidden="true" loading="lazy"></div>
        <div class="cgpost-feature-body">
          <h2>Temporary Event Visitor Passes</h2>
          <p>For a window of time rather than a person. Configure a QR or PIN Code to cover anything from one hour to seven days, which handles a party, a contractor&rsquo;s work week, or a family visit without issuing anyone permanent access.</p>
        </div>
      </div>

      <div class="cgpost-feature" id="single-use-passes">
        <div class="cgpost-feature-icon"><img src="https://cell-gate.com/wp-content/uploads/2025/09/One-Time-Key.png" alt="" aria-hidden="true" loading="lazy"></div>
        <div class="cgpost-feature-body">
          <h2>Single-Use Visitor Passes</h2>
          <p>For access that should happen exactly once: a delivery, a one-time repair call. The QR or PIN Code expires the moment it is used, so there is nothing left to reuse or forward.</p>
        </div>
      </div>

      <div class="cgpost-sec" id="choosing-a-pass">
        <h2>Choosing a pass, and where the records live</h2>
        <p>Match the pass to the visit rather than the visitor. Recurring access wants an individual pass, a defined window wants an event pass, and anything that should happen once wants a single-use pass. QR or PIN is a matter of what the visitor can manage: a QR Code is the more secure of the two, and a PIN works for anyone who would rather key in a number than open a photo.</p>
        <p>Every pass issued, and every time one is used, is recorded in the <a href="https://cell-gate.com/truecloud-connect/" target="_blank" rel="noopener">TrueCloud Connect platform</a>, which is where the whole <a href="https://cell-gate.com/access-credentials/" target="_blank" rel="noopener">access credentials</a> picture comes together.</p>
        <p>Questions are welcome. The <a href="https://cell-gate.com/gold-key-service/" target="_blank" rel="noopener">Gold Key Service</a> team is ready to help, and single-family customers can reach <a href="https://cell-gate.com/customer-care/" target="_blank" rel="noopener">Customer Care</a>. Welcome to the CellGate family.</p>
      </div>

    </div>

    <!-- Bottom link row: the same four links on every post, hidden in bare mode -->
    <div class="cgpost-cats">
      <p class="cgpost-cats-label">Categories</p>
      <div class="cgpost-cats-list">
        <a class="cgpost-cat" href="https://cell-gate.com/news/">CellGate News &amp; Product Updates</a>
        <a class="cgpost-cat" href="https://cell-gate.com/blog/">Blog</a>
        <a class="cgpost-cat" href="https://cell-gate.com/dealer-resources/">Dealer Resources</a>
        <a class="cgpost-cat" href="https://cell-gate.com/resources/">Self-Help Resources</a>
      </div>
    </div>

  </div>
</div>

<script>
(function () {
  var root = document.getElementById('cgpost');
  if (!root) return;

  // Measure the real viewport width (excludes the scrollbar) and publish it as --cg-vw.
  // The full-bleed blue band is sized from this instead of 100vw, which would be wider
  // than the visible area whenever a scrollbar is present and add a horizontal scroll.
  var videoEl = root.querySelector('.cgpost-video');
  function setMetrics() {
    var de = document.documentElement;
    de.style.setProperty('--cg-vw', de.clientWidth + 'px');

    // Distance from the viewport's left edge to this column's content box, published as a
    // negative margin. The full-bleed band uses it instead of a left: 50% / translateX
    // pair, which silently assumes the column is centered. Inside the lightbox and inside
    // partner embeds it often is not, and the band then hangs off the right edge.
    var hostRect = root.getBoundingClientRect();
    var padLeft = parseFloat(window.getComputedStyle(root).paddingLeft) || 0;
    de.style.setProperty('--cg-bleed-left', -(hostRect.left + padLeft) + 'px');
    // The band positions its diagonal off the video's real rendered height, rather than
    // assuming the column is the full 900px. A theme container narrower than that would
    // otherwise put the slash below the video's center.
    if (videoEl) {
      de.style.setProperty('--cg-video-h', Math.round(videoEl.getBoundingClientRect().height) + 'px');
    }
  }
  setMetrics();
  window.addEventListener('resize', setMetrics);
  window.addEventListener('orientationchange', setMetrics);
  window.addEventListener('load', setMetrics);
  if (window.ResizeObserver && videoEl) { new ResizeObserver(setMetrics).observe(videoEl); }

  // Contents links in the "What this video covers" card glide to their section instead
  // of jumping. Hash links are deliberately skipped by the new-tab pass below, so these
  // keep working inside the lightbox and inside a partner's embed.
  var bandInner = root.querySelector('.cgpost-band-inner');
  var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  var focusTimer = null;
  var cleanupTimer = null;
  var FOCUS_HOLD = 2200;  // beat spent fully hidden before the fade back begins
  var FADE_BACK = 1600;   // must match the opacity transition in the CSS above

  function focusSection(target) {
    if (!bandInner || reduceMotion) return;
    clearTimeout(focusTimer);
    clearTimeout(cleanupTimer);
    var prev = bandInner.querySelector('.cgpost-focus');
    if (prev) prev.classList.remove('cgpost-focus');
    target.classList.add('cgpost-focus');

    // Hide everything else with no transition, then force a reflow so the hidden state
    // actually paints before the class comes off. Removing the class is what starts the
    // slow fade back, since the resting rule owns the timing.
    bandInner.classList.add('cgpost-focusing');
    void bandInner.offsetHeight;

    focusTimer = setTimeout(function () {
      bandInner.classList.remove('cgpost-focusing');
      cleanupTimer = setTimeout(function () {
        target.classList.remove('cgpost-focus');
      }, FADE_BACK);
    }, FOCUS_HOLD);
  }

  var tocLinks = root.querySelectorAll('.cgpost-covers-list a[href^="#"]');
  for (var t = 0; t < tocLinks.length; t++) {
    tocLinks[t].addEventListener('click', function (e) {
      var target = document.getElementById(this.getAttribute('href').slice(1));
      if (!target) return;
      e.preventDefault();
      target.scrollIntoView({ behavior: reduceMotion ? 'auto' : 'smooth', block: 'start' });
      focusSection(target);
    });
  }

  // Detect bare mode: either ?bare=1 in the URL, OR the page is loaded inside a frame
  // (a partner's embed). Both cases mean "we're in a popup/embed, not a normal visit."
  var params = new URLSearchParams(window.location.search);
  var isBare = params.get('bare') === '1';
  var isFramed = false;
  try { isFramed = window.self !== window.top; } catch (e) { isFramed = true; }

  if (isBare || isFramed) {
    root.classList.add('cgpost-bare');
    document.documentElement.classList.add('cgpost-bare-html');

    // Make every link in the article open in a new tab, so clicking a link never
    // navigates inside the little popup/embed frame (which feels broken). The new
    // page opens fresh in its own tab with the normal header/footer.
    var links = root.querySelectorAll('a[href]');
    for (var i = 0; i < links.length; i++) {
      var href = links[i].getAttribute('href');
      if (href && href.charAt(0) !== '#') {
        links[i].setAttribute('target', '_blank');
        links[i].setAttribute('rel', 'noopener');
      }
    }
  }
})();
</script>

</div>/* End custom CSS */