/* Doorman age gate — storefront styles.
 *
 * This is the first thing a shopper sees, often before any of the merchant's
 * own design, so it has to look deliberate rather than like a security warning.
 * Everything is scoped under #doorman-root and uses its own font stack, because
 * a theme's body font may not have loaded yet when the gate paints.
 */

#doorman-root[hidden] {
  display: none !important;
}

html.dm-locked,
html.dm-locked body {
  overflow: hidden !important;
}

#doorman-root {
  --dm-bg: #ffffff;
  --dm-ink: #0e1116;
  /* Raised from #5b6472: at 11.5px the old value composited to 4.27:1 on white,
     under AA — and the text it carries is the consent small print. */
  --dm-muted: #4d5666;
  --dm-line: #e6e9ef;
  /* A cool-tinted neutral rather than a plain grey, biased very slightly toward
     the accent so the surfaces read as chosen rather than inherited. */
  --dm-surface-2: #f5f7fb;
  --dm-success: #059669;
  /* Two layers: a tight contact shadow that seats the card, and a wide soft one
     that lifts it off the storefront behind. One shadow does one or the other. */
  --dm-shadow: 0 1px 2px rgba(12, 18, 28, 0.18), 0 28px 70px -16px rgba(12, 18, 28, 0.42);
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
    Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

@media (prefers-color-scheme: dark) {
  #doorman-root {
    --dm-bg: #14171c;
    --dm-ink: #f4f6f9;
    --dm-muted: #a9b3c1;
    --dm-line: #272c35;
    --dm-surface-2: #1b2027;
    --dm-success: #34d399;
    --dm-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 28px 70px -16px rgba(0, 0, 0, 0.7);
  }
}

#doorman-root .dm-backdrop {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(8, 11, 17, 0.68);
  backdrop-filter: blur(8px) saturate(0.9);
  animation: dm-fade 0.18s ease-out;
}

#doorman-root .dm-card {
  width: 100%;
  max-width: 420px;
  /* Two declarations, not one. On a phone, 100vh is the viewport WITHOUT the
     browser's own chrome, so the last 60-90px of a "fitting" card sit under the
     address bar — and because the card fits its own max-height, it does not
     scroll to reveal them. On the consent screen that hidden strip is the
     button. 100dvh is the visible height; the vh line stays underneath it for
     browsers that do not know dvh. */
  max-height: calc(100vh - 40px);
  max-height: calc(100dvh - 40px);
  overflow-y: auto;
  /* Scrolling the card must not start scrolling the store behind it. */
  overscroll-behavior: contain;
  background: var(--dm-bg);
  color: var(--dm-ink);
  border-radius: var(--dm-radius, 16px);
  box-shadow: var(--dm-shadow);
  animation: dm-rise 0.22s cubic-bezier(0.2, 0.8, 0.3, 1);
}

@keyframes dm-fade {
  from { opacity: 0; }
}
@keyframes dm-rise {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
}

@media (prefers-reduced-motion: reduce) {
  #doorman-root .dm-backdrop,
  #doorman-root .dm-card {
    animation: none;
  }
}

#doorman-root .dm-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 20px;
  background: var(--dm-surface-2);
  border-bottom: 1px solid var(--dm-line);
  border-radius: var(--dm-radius, 16px) var(--dm-radius, 16px) 0 0;
}

/* The badge slot. A shop with a logo gets its logo; a shop without gets a
   shield, so the row never renders as a bare shop handle on a white field. */
#doorman-root .dm-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 9px;
  color: var(--dm-accent, #1d4ed8);
  background: color-mix(in srgb, var(--dm-accent, #1d4ed8) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dm-accent, #1d4ed8) 22%, transparent);
}

#doorman-root .dm-mark {
  width: 18px;
  height: 18px;
  display: block;
}

/* Says what this window is, in the corner where a form says what form it is. */
#doorman-root .dm-tag {
  margin-inline-start: auto;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--dm-bg);
  border: 1px solid var(--dm-line);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dm-muted);
  white-space: nowrap;
}

#doorman-root .dm-logo {
  height: 26px;
  width: auto;
  max-width: 120px;
  object-fit: contain;
}

#doorman-root .dm-brand {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--dm-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#doorman-root .dm-body {
  padding: 22px 20px 20px;
}

#doorman-root .dm-title {
  margin: 0 0 9px;
  font-size: 22px;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -0.015em;
  text-wrap: balance;
  color: var(--dm-ink);
}

#doorman-root .dm-lede {
  margin: 0 0 16px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--dm-muted);
}

#doorman-root .dm-facts {
  margin: 0 0 18px;
  padding: 12px 14px;
  list-style: none;
  display: grid;
  gap: 10px;
  background: var(--dm-surface-2);
  border: 1px solid var(--dm-line);
  border-radius: 12px;
}

#doorman-root .dm-facts li {
  position: relative;
  /* Logical, so the tick and its text mirror together and without an override.
     They used to be physical with a right-to-left rule flipping only the circle
     — the checkmark stroke had no such rule, so in every RTL locale the circle
     sat on the right and its tick floated on the left, across the text. */
  padding-inline-start: 28px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--dm-ink);
}

/* A drawn tick rather than an emoji: emoji render differently per platform and
   look accidental next to a legal notice. */
#doorman-root .dm-facts li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 1px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--dm-accent, #1d4ed8) 14%, transparent);
}

#doorman-root .dm-facts li::after {
  content: "";
  position: absolute;
  inset-inline-start: 6.5px;
  top: 5px;
  width: 4px;
  height: 8px;
  border: solid var(--dm-accent, #1d4ed8);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* Shopify's Dawn theme — and most themes derived from it — ship a rule in
   base.css that reads `a:empty, ul:empty, div:empty, section:empty, ... {
   display: none }`. Three of our elements are deliberately empty because they
   are drawn entirely in CSS: the framing oval, its ring, and the spinner. On a
   Dawn storefront all three silently vanished. The camera guide was invisible —
   detection worked and the shopper had nothing to aim at — and the "checking"
   screen had no spinner.

   Declaring `display` here is enough; `#doorman-root .dm-oval` outranks
   `div:empty` on specificity, so no !important is needed. It only lost because
   we never declared it at all.

   Anything added to this app that renders as an empty element needs a line
   here too. */
#doorman-root .dm-oval,
#doorman-root .dm-ovalring,
#doorman-root .dm-spinner {
  display: block;
}

#doorman-root .dm-stage {
  position: relative;
  aspect-ratio: 1 / 1;
  margin: 0 0 14px;
  border-radius: calc(var(--dm-radius, 16px) - 4px);
  overflow: hidden;
  background: #0d1014;
}

#doorman-root .dm-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Mirrored so moving left moves the reflection left — an unmirrored selfie
     view makes people fight the camera. */
  transform: scaleX(-1);
}

/* The framing guide.
   A thin dashed outline is invisible against a bright room — the first live
   tester did not notice it at all. Dimming everything outside the oval makes
   the target unmistakable and is what ID apps do for the same reason. */
#doorman-root .dm-oval {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* Punch an ellipse out of a dark overlay. */
  background: rgba(6, 10, 16, 0.55);
  -webkit-mask: radial-gradient(ellipse 30% 38% at 50% 50%, transparent 98%, #000 100%);
  mask: radial-gradient(ellipse 30% 38% at 50% 50%, transparent 98%, #000 100%);
}

#doorman-root .dm-ovalring {
  position: absolute;
  inset: 12% 20%;
  border: 3px solid rgba(255, 255, 255, 0.92);
  border-radius: 50%;
  pointer-events: none;
  box-shadow: 0 0 0 1px rgba(6, 10, 16, 0.35);
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}

/* A slow sweep across the oval while we are still looking. It says the check is
   live and working, which a static outline does not — a shopper staring at a
   frozen ring assumes it has hung. */
#doorman-root .dm-stage[data-framing="looking"] .dm-ovalring::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 3px solid transparent;
  border-top-color: rgba(255, 255, 255, 0.95);
  animation: dm-sweep 1.6s linear infinite;
}

@keyframes dm-sweep {
  to { transform: rotate(360deg); }
}

/* Well framed — the shutter is about to unlock. */
#doorman-root .dm-stage[data-framing="ready"] .dm-ovalring {
  border-color: #34d399;
  box-shadow: 0 0 0 1px rgba(6, 10, 16, 0.3), 0 0 0 6px rgba(52, 211, 153, 0.22);
}

@media (prefers-reduced-motion: reduce) {
  #doorman-root .dm-stage[data-framing="looking"] .dm-ovalring::after {
    animation-duration: 5s;
  }
}

/* Coaching line, over the preview so the eye does not have to leave the frame. */
#doorman-root .dm-coach {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  max-width: 88%;
  margin: 0;
  padding: 7px 13px;
  border-radius: 999px;
  background: rgba(6, 10, 16, 0.72);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
  text-align: center;
  pointer-events: none;
}

#doorman-root .dm-stage[data-framing="ready"] .dm-coach {
  background: rgba(5, 105, 75, 0.92);
}

/* A confirmation mark that draws itself once the check has passed. A result
   screen that is only words reads as a form response; this reads as a decision. */
/* Centred as a block, so the title beneath it stays left-aligned with the rest
   of the card rather than the whole screen turning into a centred layout. */
#doorman-root .dm-seal {
  width: 56px;
  height: 56px;
  margin: 2px auto 16px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--dm-success);
  background: color-mix(in srgb, var(--dm-success) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dm-success) 30%, transparent);
  animation: dm-pop 0.32s cubic-bezier(0.2, 0.9, 0.3, 1.4);
}

#doorman-root .dm-seal svg {
  width: 28px;
  height: 28px;
}

#doorman-root .dm-seal path {
  stroke-dasharray: 26;
  stroke-dashoffset: 26;
  animation: dm-draw 0.4s 0.14s ease-out forwards;
}

@keyframes dm-pop {
  from { transform: scale(0.72); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

@keyframes dm-draw {
  to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
  #doorman-root .dm-seal { animation: none; }
  #doorman-root .dm-seal path { animation-delay: 0s; animation-duration: 0.01s; }
}

#doorman-root .dm-hint {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--dm-muted);
}

#doorman-root .dm-hint--warn {
  color: #b4341f;
}

@media (prefers-color-scheme: dark) {
  #doorman-root .dm-hint--warn {
    color: #ff8f76;
  }
}

#doorman-root .dm-label {
  display: block;
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--dm-ink);
}

#doorman-root .dm-input {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 11px 12px;
  font: inherit;
  font-size: 15px;
  color: var(--dm-ink);
  background: var(--dm-bg);
  border: 1px solid var(--dm-line);
  border-radius: 10px;
}

#doorman-root .dm-badge:focus-visible,
#doorman-root .dm-input:focus-visible,
#doorman-root .dm-btn:focus-visible,
#doorman-root .dm-link:focus-visible {
  outline: 2px solid var(--dm-accent, #1f6feb);
  outline-offset: 2px;
}

#doorman-root .dm-actions {
  display: grid;
  gap: 10px;
  margin-top: 4px;
}

#doorman-root .dm-btn {
  width: 100%;
  padding: 14px 18px;
  font: inherit;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.005em;
  color: var(--dm-accent-ink, #fff);
  background: var(--dm-accent, #1d4ed8);
  /* Derived from the merchant's own accent, so a custom colour still gets the
     same treatment instead of falling back to a flat block. */
  background-image: linear-gradient(
    180deg,
    color-mix(in srgb, var(--dm-accent, #1d4ed8) 88%, #ffffff) 0%,
    var(--dm-accent, #1d4ed8) 100%
  );
  border: 0;
  border-radius: 12px;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(12, 18, 28, 0.16),
    0 8px 20px -8px color-mix(in srgb, var(--dm-accent, #1d4ed8) 55%, transparent);
  transition: transform 0.12s ease, box-shadow 0.18s ease, filter 0.15s ease;
}

#doorman-root .dm-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  filter: brightness(1.05);
  box-shadow: 0 2px 4px rgba(12, 18, 28, 0.18),
    0 12px 26px -8px color-mix(in srgb, var(--dm-accent, #1d4ed8) 62%, transparent);
}

#doorman-root .dm-btn:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: 0 1px 2px rgba(12, 18, 28, 0.2);
}

/* Reads as "not yet", not as broken: the shutter unlocks the moment framing is
   right, so this state is transient and should look like it is waiting. */
#doorman-root .dm-btn:disabled {
  opacity: 1;
  color: var(--dm-muted);
  background: var(--dm-surface-2);
  background-image: none;
  box-shadow: inset 0 0 0 1px var(--dm-line);
  cursor: default;
}

#doorman-root .dm-link {
  width: 100%;
  padding: 8px;
  font: inherit;
  font-size: 13.5px;
  color: var(--dm-muted);
  background: none;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

#doorman-root .dm-fine {
  margin: 16px 0 0;
  padding-top: 13px;
  border-top: 1px solid var(--dm-line);
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--dm-muted);
}

#doorman-root .dm-spinner {
  width: 34px;
  height: 34px;
  margin: 18px auto;
  border: 3px solid var(--dm-line);
  border-top-color: var(--dm-accent, #1f6feb);
  border-radius: 50%;
  animation: dm-spin 0.8s linear infinite;
}

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

@media (prefers-reduced-motion: reduce) {
  #doorman-root .dm-spinner {
    animation-duration: 2.4s;
  }
}

/* Right-to-left languages.
   Only the handful of properties that are genuinely directional are flipped —
   the layout itself is flex/grid with logical gaps, so it mirrors on its own. */
/* No flex-direction override here. The head is a plain flex row, and a flex row
   already lays its items right-to-left inside dir="rtl" — `row-reverse` flipped
   them back, so the header was the one part of an Arabic or Hebrew gate running
   left-to-right. The facts list needs no override either now that it is
   positioned with logical properties. */

#doorman-root[dir="rtl"] .dm-title,
#doorman-root[dir="rtl"] .dm-lede,
#doorman-root[dir="rtl"] .dm-hint,
#doorman-root[dir="rtl"] .dm-fine,
#doorman-root[dir="rtl"] .dm-label {
  text-align: right;
}

/* The camera preview is mirrored so the shopper's movements feel natural; that
   is about the mirror, not the language, so it must NOT flip again for RTL. */
#doorman-root[dir="rtl"] .dm-video {
  transform: scaleX(-1);
}

/* ---------------------------------------------------------------------------
   Templates
   Four looks, because merchants genuinely want opposite things: a vape shop
   wants the store hidden completely, a wine merchant wants the lightest touch
   that still counts. All four share the same markup — only presentation moves.
   --------------------------------------------------------------------------- */

/* Full screen — the store is not visible at all behind it. */
#doorman-root.dm-tpl-fullscreen .dm-backdrop {
  background: var(--dm-bg);
  backdrop-filter: none;
  padding: 0;
}

#doorman-root.dm-tpl-fullscreen .dm-card {
  max-width: 520px;
  /* Bounded by the backdrop rather than unbounded. `none` removed the only
     limit the card had, and since the page scroll is locked and the backdrop
     does not scroll either, anything taller than the screen was simply cut off
     — centred, so cut off at BOTH ends. On a short phone the camera screen lost
     its shutter button and there was no way to reach it. */
  max-height: 100%;
  box-shadow: none;
  border-radius: 0;
  background: transparent;
}

#doorman-root.dm-tpl-fullscreen .dm-head {
  justify-content: center;
  border-bottom: 0;
  padding-top: 8px;
}

#doorman-root.dm-tpl-fullscreen .dm-body {
  padding: 8px 28px 28px;
}

/* Minimal — no blur, no shadow, a hairline card. Least intrusive. */
#doorman-root.dm-tpl-minimal .dm-backdrop {
  background: rgba(10, 14, 20, 0.45);
  backdrop-filter: none;
}

#doorman-root.dm-tpl-minimal .dm-card {
  box-shadow: none;
  border: 1px solid var(--dm-line);
}

#doorman-root.dm-tpl-minimal .dm-title {
  font-size: 18px;
  font-weight: 650;
}

/* Bold — the accent colour carries the whole panel. */
#doorman-root.dm-tpl-bold .dm-card {
  background: var(--dm-accent, #1f6feb);
  color: var(--dm-accent-ink, #fff);
}

#doorman-root.dm-tpl-bold .dm-head {
  border-bottom-color: rgba(255, 255, 255, 0.22);
}

#doorman-root.dm-tpl-bold .dm-brand,
#doorman-root.dm-tpl-bold .dm-title,
#doorman-root.dm-tpl-bold .dm-lede,
#doorman-root.dm-tpl-bold .dm-facts li,
#doorman-root.dm-tpl-bold .dm-hint,
#doorman-root.dm-tpl-bold .dm-fine,
#doorman-root.dm-tpl-bold .dm-label,
#doorman-root.dm-tpl-bold .dm-link,
#doorman-root.dm-tpl-bold .dm-terms {
  color: var(--dm-accent-ink, #fff);
}

#doorman-root.dm-tpl-bold .dm-title {
  font-size: 26px;
  letter-spacing: -0.015em;
}

#doorman-root.dm-tpl-bold .dm-lede,
#doorman-root.dm-tpl-bold .dm-facts li,
#doorman-root.dm-tpl-bold .dm-fine {
  opacity: 0.88;
}

/* The button has to invert or it disappears into the panel. */
#doorman-root.dm-tpl-bold .dm-btn {
  background: var(--dm-accent-ink, #fff);
  color: var(--dm-accent, #1f6feb);
}

#doorman-root.dm-tpl-bold .dm-facts li::before {
  border-color: var(--dm-accent-ink, #fff);
}

/* The spinner needs a ring AND a contrasting head, or it turns into a static
   circle: the base rule paints the head with `border-top-color`, and a
   `border-color` here has the same specificity and comes later, so it flattened
   all four sides to the same white. A shopper waiting on a document check
   watched a ring that never appeared to move. */
#doorman-root.dm-tpl-bold .dm-spinner {
  border-color: rgba(255, 255, 255, 0.32);
  border-top-color: var(--dm-accent-ink, #fff);
}

/* A disabled button has to stay visibly disabled here too. The inverted rule
   above matches `.dm-btn` with the same specificity as the base `:disabled`
   rule and sits later in the file, so it won: a disabled control rendered
   exactly like a live one, and tapping it did nothing with no explanation. */
#doorman-root.dm-tpl-bold .dm-btn:disabled {
  background: rgba(255, 255, 255, 0.22);
  color: var(--dm-accent-ink, #fff);
  opacity: 0.7;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);
  cursor: default;
}

#doorman-root.dm-tpl-bold .dm-facts li::before {
  border-width: 0 2px 2px 0;
}

/* ---------------------------------------------------------------------------
   Terms tickbox
   --------------------------------------------------------------------------- */
#doorman-root .dm-terms {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0 0 16px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--dm-muted);
  cursor: pointer;
}

#doorman-root .dm-terms input {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  margin: 1px 0 0;
  accent-color: var(--dm-accent, #1f6feb);
  cursor: pointer;
}

#doorman-root .dm-terms a {
  color: inherit;
  text-underline-offset: 2px;
}

#doorman-root[dir="rtl"] .dm-terms {
  text-align: right;
}

/* Bottom sheet — rises from the bottom edge, the way a native mobile prompt
   does. On a phone this is reachable with a thumb; a centred modal is not.
   Competitors advertise "15+ templates" that resolve to three or four real
   layouts, so each of ours is a genuinely different arrangement rather than a
   colour swap. */
#doorman-root.dm-tpl-sheet .dm-backdrop {
  align-items: flex-end;
  padding: 0;
}

#doorman-root.dm-tpl-sheet .dm-card {
  max-width: 100%;
  border-radius: var(--dm-radius, 16px) var(--dm-radius, 16px) 0 0;
  animation: dm-sheet 0.26s cubic-bezier(0.2, 0.8, 0.3, 1);
}

@keyframes dm-sheet {
  from { transform: translateY(100%); }
}

@media (prefers-reduced-motion: reduce) {
  #doorman-root.dm-tpl-sheet .dm-card { animation: none; }
}

/* A grab handle, so it reads as a sheet rather than a stuck panel. */
#doorman-root.dm-tpl-sheet .dm-head::before {
  content: "";
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 36px;
  height: 4px;
  border-radius: 2px;
  background: var(--dm-line);
}

#doorman-root.dm-tpl-sheet .dm-head {
  position: relative;
  padding-top: 22px;
}

/* Wide screens: keep it a sheet, but stop it spanning a desktop monitor. */
@media (min-width: 700px) {
  #doorman-root.dm-tpl-sheet .dm-card {
    max-width: 520px;
    margin: 0 auto;
  }
}

/* ---------------------------------------------------------------------------
   Four more layouts.
   ---------------------------------------------------------------------------
   Every one of these changes the SHAPE of the gate, not its colour — a merchant
   choosing a "style" and getting the same card in a different shade would
   rightly feel sold something that is not there.

   They are also the four shapes competitors ship that we did not have: a corner
   card that does not block the page, a wide banner across the top, a framed
   "certificate" look for spirits and tobacco, and a soft rounded card.
   --------------------------------------------------------------------------- */

/* Corner — sits in the bottom corner and leaves the store readable. For shops
   that want the gate present without taking the page hostage. */
#doorman-root.dm-tpl-corner .dm-backdrop {
  background: none;
  backdrop-filter: none;
  align-items: flex-end;
  justify-content: flex-end;
  padding: 20px;
  pointer-events: none;
}

#doorman-root.dm-tpl-corner .dm-card {
  max-width: 360px;
  pointer-events: auto;
  box-shadow: 0 2px 6px rgba(12, 18, 28, 0.14), 0 24px 48px -16px rgba(12, 18, 28, 0.5);
}

#doorman-root.dm-tpl-corner .dm-title {
  font-size: 19px;
}

/* Banner — a full-width strip across the top, the least interrupting shape
   there is while still being unmissable. */
#doorman-root.dm-tpl-banner .dm-backdrop {
  background: rgba(8, 11, 17, 0.45);
  align-items: flex-start;
  padding: 0;
}

#doorman-root.dm-tpl-banner .dm-card {
  max-width: 100%;
  width: 100%;
  border-radius: 0;
  box-shadow: 0 8px 24px -8px rgba(12, 18, 28, 0.4);
}

#doorman-root.dm-tpl-banner .dm-body {
  max-width: 720px;
  margin: 0 auto;
  padding: 20px;
}

#doorman-root.dm-tpl-banner .dm-head {
  max-width: 720px;
  margin: 0 auto;
  border-radius: 0;
}

/* Certificate — a framed, formal look. Reads as a licence check rather than a
   marketing interruption, which is what a spirits or tobacco shop wants. */
#doorman-root.dm-tpl-certificate .dm-card {
  max-width: 440px;
  border-radius: 4px;
  border: 1px solid var(--dm-accent, #1d4ed8);
  box-shadow: 0 0 0 6px var(--dm-bg), 0 0 0 7px var(--dm-line), var(--dm-shadow);
}

#doorman-root.dm-tpl-certificate .dm-head {
  background: none;
  border-bottom: 1px solid var(--dm-accent, #1d4ed8);
  border-radius: 0;
  justify-content: center;
}

#doorman-root.dm-tpl-certificate .dm-tag {
  display: none;
}

#doorman-root.dm-tpl-certificate .dm-title,
#doorman-root.dm-tpl-certificate .dm-lede {
  text-align: center;
}

#doorman-root.dm-tpl-certificate .dm-btn {
  border-radius: 4px;
}

/* Soft — rounder, lighter, friendlier. For shops whose brand is not formal. */
#doorman-root.dm-tpl-soft .dm-card {
  border-radius: 26px;
  max-width: 400px;
}

#doorman-root.dm-tpl-soft .dm-head {
  border-radius: 26px 26px 0 0;
}

#doorman-root.dm-tpl-soft .dm-btn,
#doorman-root.dm-tpl-soft .dm-input {
  border-radius: 999px;
}

#doorman-root.dm-tpl-soft .dm-facts {
  border-radius: 18px;
}

#doorman-root.dm-tpl-soft .dm-stage {
  border-radius: 20px;
}

/* The corner and banner layouts do not cover the page, so they do not take the
   scroll lock the covering shapes need — see open() in doorman.js, which is
   where that decision is actually made. An empty rule used to sit here claiming
   the same thing while the lock was applied unconditionally. */
