/*
  MTCaptcha Demo Widget (brand overrides)
  ----------------------------------------------------------------------------
  Loaded AFTER /demo/vendor/mtcaptcha-demo.css (the untouched vendor
  stylesheet). This file only restyles: it never renames or removes a class or
  id the vendor JS depends on (see specs/demo-widget.md for the full list).

  v3 design strategy (rebuilt from scratch, see specs/demo-widget.md revision
  history for the full rationale):

  1. ONE card, not three. The vendor already renders its own themed card
     (.demo-loginbox: a white/off-white/dark box with its own border and
     background, different per theme). Earlier revisions wrapped that in a
     second bordered/shadowed box (.demoscreen) inside a third card supplied
     by the page (the hero's browser-chrome frame), so every theme showed as
     nested boxes-in-boxes. Here .demoscreen and .demo-canvas are made fully
     transparent, so the vendor's own themed card is the only visible surface
     inside the page's frame. As of 2026-08-06 that card carries **no drop
     shadow on a light page**, matching production exactly; the only elevation
     rule left is a 1px ring in dark mode, which production has no answer for
     because it has no dark mode. See the "Elevation" section below.
  2. Columns share one height (`align-items: stretch` on the grid) with the tab
     area top-anchored, so a content-driven height change on one side (e.g.
     Invisible Captcha's fallback challenge growing taller) resizes the row
     without shifting any content. See the note on .mtc-demo-grid below.
  3. Every toggle (Modern Mini, Invisible Captcha, Automated Test Mode) uses
     one shared switch component (.mtc-switchrow / .mtc-switch) instead of two
     different shapes with two different alignment models.
  4. Tab bar icons get a fixed, centered, aspect-ratio-preserving box, and
     fill/stroke color rules are keyed to each icon's own id and combined with
     the *button's* id for hover/active state. This matters because the
     vendor CSS itself already has hover/active icon-color rules keyed to
     `#theme-icon`/`#developers-icon` (see mtcaptcha-demo.css), which are MORE
     specific than a generic ".icon svg path" rule and were winning on hover,
     flashing icons white against a barely-tinted hover background. Beating
     that requires matching specificity with our own id-qualified selectors.

  IMPORTANT sizing note: the vendor's own responsive rules give `.demo-loginbox`
  a real max-width up to 350px (Standard theme) with 40-45px of horizontal
  padding on top (content-box sizing), so the finished card wants roughly
  420-450px to render its captcha challenge without clipping. The right column
  below is sized to guarantee that room; don't shrink it without re-checking
  the captcha renders uncropped at every theme and at Modern Mini.
*/

/* ---------- outer container ---------- */

#mtcaptcha-main-demo {
  display: block;
  background: transparent;
  padding: 0;
  border-radius: 0;
  font-family: 'Poppins', sans-serif;
  color: var(--body);
}

.mtc-demo {
  width: 100%;
}

.mtc-demo-grid {
  display: grid;
  gap: 1.25rem;
  margin-top: 1.5rem;
  /*
    456px, not 420px (changed 2026-08-05).

    The card's natural width is 440px: the vendor gives it 350px of content plus
    40px padding and a 5px border per side, content-box. A 420px column left only
    404px of content box, and because `.demo-canvas` makes the card a flex item
    it quietly shrank to fit rather than overflowing - taking the captcha down to
    314px with it. See the `flex-shrink: 0` note on `.demo-loginbox`.

    456 = 440 + `.demo-canvas`'s 8px inline padding per side. The two changes go
    together: `flex-shrink: 0` without this room converts the squeeze into an
    overflow, which is worse.
  */
  grid-template-columns: 1fr minmax(300px, 456px);
  /*
    Equal column heights (v5). This was `start` in v3 to stop the left panel
    "jumping" when the right side grew, but that fix treated the symptom: the
    jump came from `justify-content: center` on .mtc-demo-tabarea re-centering
    its content inside a changed height, not from stretch itself. The tab area
    is now top-anchored (`flex-start`), so both columns can share a height
    without anything shifting. Do not reintroduce `center` there.
  */
  align-items: stretch;
}

@media (max-width: 860px) {
  .mtc-demo-grid {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
}

/* ---------- tab bar (segmented control) ---------- */

.mtc-demo-tabbar {
  display: flex;
  gap: 0.25rem;
  padding: 0.3rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 0.9rem;
}

/*
  setActiveTab() in the vendor JS overwrites these three buttons' className
  wholesale (to "badge-secondary category-badges w-inline-block[ w--current]"),
  so any custom class we put in the markup gets clobbered on the very first
  render. Target the stable ids instead, they're never touched by the JS.
*/
#demo-tabbtn-themes-a,
#demo-tabbtn-accessibility-a,
#demo-tabbtn-developers-a {
  display: flex !important;
  width: auto !important;
  height: auto !important;
  flex: 1 1 0;
  flex-direction: row !important;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  padding: 0.6rem 0.5rem;
  margin-left: 0 !important;
  border-radius: 0.6rem;
  border: none;
  background: transparent;
  cursor: pointer;
  transition: background-color 0.15s ease, box-shadow 0.15s ease, color 0.15s ease;
}

#demo-tabbtn-themes-a:hover,
#demo-tabbtn-accessibility-a:hover,
#demo-tabbtn-developers-a:hover {
  background: color-mix(in oklab, var(--surface) 60%, transparent);
}

#demo-tabbtn-themes-a.w--current,
#demo-tabbtn-accessibility-a.w--current,
#demo-tabbtn-developers-a.w--current {
  background: var(--surface);
  box-shadow: var(--shadow-card);
}

.mtc-demo-tabbar .demo-tabbtn {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
  line-height: 1;
  transition: color 0.15s ease;
}

#demo-tabbtn-themes-a.w--current .demo-tabbtn,
#demo-tabbtn-accessibility-a.w--current .demo-tabbtn,
#demo-tabbtn-developers-a.w--current .demo-tabbtn {
  color: var(--color-brand-600);
}

/*
  axe, 2026-08-08, dark mode, active tab label ("Themes" is active by
  default so it is the one caught at first paint, but all three share this
  rule and would fail identically once clicked): brand-600 text on the dark
  canvas measured 3.08:1, under 4.5:1. Same root cause and same fix already
  applied to `.mtc-demo-cta` above and to LangSwitcher.astro - brand-600 is
  tuned for light backgrounds, brand-300 is its dark-mode counterpart.
*/
.dark #demo-tabbtn-themes-a.w--current .demo-tabbtn,
.dark #demo-tabbtn-accessibility-a.w--current .demo-tabbtn,
.dark #demo-tabbtn-developers-a.w--current .demo-tabbtn {
  color: var(--color-brand-300);
}

/*
  Fixed, centered, aspect-ratio-preserving icon slot. The vendor injects three
  differently-proportioned SVGs (40x40, 30x40, 36x34) with hardcoded width/
  height attributes straight into these spans via innerHTML on load; forcing
  them to an identical square with `width/height` in CSS would distort the
  narrower accessibility glyph. Constraining with max-width/max-height instead
  keeps every icon's own aspect ratio while giving all three the same visual
  footprint, which is what actually makes the row read as aligned.
*/
.mtc-demo-tabicon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.35rem;
  height: 1.35rem;
  flex-shrink: 0;
}

.mtc-demo-tabicon svg {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
}

/*
  Icon color, keyed per icon id rather than a blanket "svg path" rule, for two
  reasons found by reading the vendor CSS directly:
  1. The developers icon is a stroke-only line glyph (`fill="none"` on its own
     <svg>, drawn entirely with `stroke`). A shared `fill: var(--muted)` rule
     silently fills it solid, turning a thin "</>" bracket into a dark blob.
  2. The vendor CSS itself ships hover/active color rules scoped to
     `#theme-icon`/`#accessibility-icon`/`#developers-icon` (an id selector),
     which outrank a generic class-based rule on specificity and were winning
     on hover, flashing the icon white against our barely-tinted hover
     background. Matching specificity requires our own id-qualified selectors.
*/
#theme-icon-container svg path,
#accessibility-icon-container svg path {
  fill: var(--muted);
  stroke: none;
  transition: fill 0.15s ease;
}

#developers-icon-container svg path {
  fill: none;
  stroke: var(--muted);
  transition: stroke 0.15s ease;
}

#demo-tabbtn-themes-a:hover #theme-icon-container svg path,
#demo-tabbtn-themes-a.w--current #theme-icon-container svg path,
#demo-tabbtn-accessibility-a:hover #accessibility-icon-container svg path,
#demo-tabbtn-accessibility-a.w--current #accessibility-icon-container svg path {
  fill: var(--color-brand-600);
}

#demo-tabbtn-developers-a:hover #developers-icon-container svg path,
#demo-tabbtn-developers-a.w--current #developers-icon-container svg path {
  stroke: var(--color-brand-600);
}

@media (max-width: 480px) {
  .mtc-demo-tabbar {
    flex-direction: column;
  }
  #demo-tabbtn-themes-a,
  #demo-tabbtn-accessibility-a,
  #demo-tabbtn-developers-a {
    justify-content: flex-start !important;
    padding: 0.7rem 0.75rem;
  }
}

#mtcaptcha-main-demo hr {
  display: none;
}

/* ---------- tab pages (left column) ---------- */

.mtc-demo-tabarea {
  display: flex;
  flex-direction: column;
  /* Top-anchored, not centered: content keeps its position when the shared
     column height changes (see the .mtc-demo-grid note above). */
  justify-content: flex-start;
  gap: 1.1rem;
  min-height: 21rem;
  height: 100%;
  border-radius: 1rem;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  padding: 1.5rem;
}

.demo-tabpage {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.demo-tabpage-invisible {
  display: none !important;
}

/* Icon + heading pairing reused by the Accessibility and Developers panels,
   so both read as one deliberate design system instead of two ad hoc ones. */
.mtc-demo-panel-head {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
}

.mtc-demo-panel-title {
  margin: 0 0 0.3rem;
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
}

.mtc-demo-panel-intro {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--body);
}

#options-container {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0;
  min-height: 0;
  font-size: 0.9rem;
  margin: 0;
}

/* ---------- unified switch component ---------- */
/*
  Shared by Modern Mini, Invisible Captcha, and the Developers tab's test-mode
  toggle. One track size, one dot size, one alignment model (label on the
  left, switch on the right) everywhere a toggle appears in this widget.
*/
.mtc-switchrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-left: 0 !important;
  margin-bottom: 0;
  font-size: 0.9rem;
  color: var(--ink);
  cursor: pointer;
}

.mtc-switchrow-label {
  font-weight: 600;
  color: var(--ink);
}

/*
  Track and knob.

  Reshaped 2026-08-05 after review ("this switch needs better shape, not looking
  good"). Four changes, each for a reason:

  1. **Bigger.** 44x26 with a 20px knob, up from 38x22/16. The old one was
     under the 24x24 minimum that WCAG 2.5.8 asks of a pointer target, and it
     read as an afterthought beside a full-size label.
  2. **The off state is legible on its own.** It was `--surface-2` inside a
     `--line-strong` border, which on the light theme is a pale box on a pale
     panel: whether it was off or simply disabled was a guess. A filled track a
     clear step darker than the panel reads as "off", not "absent".
  3. **`translateX` rather than animating `left`.** Same movement, but it is
     composited, so the knob does not jitter on a slow frame. Paired with an
     ease-out curve that settles rather than stopping dead.
  4. **A focus ring, which did not exist.** The real checkbox is `opacity: 0`,
     so a keyboard user had no indication of which switch they were on. The ring
     is on `:focus-visible`, so it appears for keyboard use and not on click.
*/
.mtc-switch {
  position: relative;
  flex-shrink: 0;
  width: 44px;
  height: 26px;
  border-radius: 999px;
  border: 1px solid transparent;
  background-color: var(--line-strong);
  /*
    Only the colour transitions. `box-shadow` is deliberately excluded: it draws
    the keyboard focus ring, and fading that in over 180ms means a keyboard user
    tabbing quickly moves on before the indicator has finished appearing. Focus
    indication has to be immediate.
  */
  transition: background-color 0.18s ease;
}

.mtc-switchrow input:checked ~ .mtc-switch {
  background-color: var(--color-brand-600);
  border-color: transparent;
}

.mtc-switchrow:hover input:not(:checked) ~ .mtc-switch {
  background-color: color-mix(in oklab, var(--line-strong) 70%, var(--ink));
}

.mtc-switchrow:hover input:checked ~ .mtc-switch {
  background-color: var(--color-brand-500);
}

/*
  Keyboard focus. `:focus-visible` on the hidden input, drawn on the track, so
  it appears when tabbing and not when clicking - a ring that shows on every
  mouse click reads as a rendering fault.
*/
.mtc-switchrow input:focus-visible ~ .mtc-switch {
  box-shadow:
    0 0 0 2px var(--canvas),
    0 0 0 4px var(--color-brand-500);
}

/*
  The knob. The two-class selector is load-bearing, not decoration.

  This element is `class="demo-checkmark mtc-switch"`, so the vendor styles it
  too - as a *checkmark*:

      .demo-chkcontainer .demo-checkmark:after   (0,2,0)
        left: 6px; top: 2px; width: 5px; height: 10px;
        border: solid #fcfcfc; border-width: 0 3px 3px 0;
        transform: rotate(45deg);

  A bare `.mtc-switch:after` is (0,1,0) and loses to that on every property it
  does not mark `!important`. That is what shipped until 2026-08-05: `content`,
  `border` and `transform` were marked, which stripped the tick's borders and
  rotation but left its **5x10 geometry** intact - so the knob rendered as a thin
  white sliver pinned to the left of the track. Two rounds of "reshaping the
  switch" adjusted the track and never touched the actual fault, because the
  declaration here was correct the whole time and simply lost the cascade.

  Qualifying with `.mtc-switchrow` makes this (0,2,0), equal to the vendor rule,
  and demo-overrides.css loads after mtcaptcha-demo.css (see DemoWidget.astro),
  so equal specificity resolves our way. Geometry therefore needs no `!important`.
  The three that remain are still required: `content` and `border` because the
  vendor sets them from an equally specific rule, and `transform` because the
  checked state has to beat the vendor's `rotate(45deg)`.
*/
.mtc-switchrow .mtc-switch:after {
  content: '' !important;
  position: absolute;
  left: 3px;
  top: 3px;
  width: 18px;
  height: 18px;
  border: none !important;
  border-radius: 50%;
  background: #fff;
  transform: translateX(0) !important;
  transition: transform 0.18s cubic-bezier(0.2, 0.9, 0.3, 1);
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.28),
    0 0 0 1px rgba(0, 0, 0, 0.04);
}

.mtc-switchrow input:checked ~ .mtc-switch:after {
  transform: translateX(18px) !important;
}

/*
  The vendor also re-draws the checkmark's border on the checked state, from
  `.demo-chkcontainer input:checked ~ .demo-checkmark:after` (0,3,0). Matching
  that specificity here keeps the knob a plain dot when the switch is on;
  without it the knob grows two white edges the moment it is toggled.
*/
.mtc-switchrow input:checked ~ .mtc-switch:after {
  border: none !important;
}

/* A small press response, so the control feels answerable rather than inert. */
.mtc-switchrow:active .mtc-switch:after {
  width: 21px;
}

/*
  Respect a reduced-motion preference: the knob still moves, it just arrives
  immediately rather than sliding.
*/
@media (prefers-reduced-motion: reduce) {
  .mtc-switch,
  .mtc-switch:after {
    transition: none;
  }
}


/*
  Vendor bug we're exposing, not introducing: `.demo-chkcontainer
  .demo-checkmark:after` draws its checkmark border unconditionally
  (border-color #fcfcfc), relying on it being invisible against the vendor's
  own light-gray unchecked background. Our surface color is darker, so that
  "invisible" mark becomes visible. Hide it explicitly when unchecked.
*/
.demo-chkcontainer input:not(:checked) ~ .demo-checkmark:after {
  border-color: transparent;
}

/* ---------- theme swatches + buttons ---------- */

.theme-name {
  font-size: 0.85rem;
  color: var(--body);
  white-space: nowrap;
}

.mtc-demo-themebtns {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.mtc-demo-themebtns .category-badges.theme-btn {
  width: auto;
  height: auto;
  flex-direction: row;
  align-items: center;
  padding: 0.5rem 1rem 0.5rem 0.6rem;
  margin-left: 0 !important;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--canvas);
  color: var(--ink);
  font-size: 0.85rem;
  font-weight: 600;
  gap: 0.55rem;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.mtc-demo-themebtns .category-badges.theme-btn:hover {
  border-color: var(--color-brand-500);
}

.mtc-demo-themebtns .category-badges.theme-btn.w--current {
  background: var(--color-brand-600);
  border-color: var(--color-brand-600);
  color: #fff;
}

/*
  Rounded-square color chips, not circles: a plain filled circle (especially
  Blackmoon's near-black one) reads as an ambiguous bullet or stray dot next
  to a label, not as an intentional color swatch. A chip shape with a visible
  ring reads unambiguously as "this button previews this color."
*/
.mtc-demo-swatch {
  display: inline-block;
  width: 0.95rem;
  height: 0.95rem;
  border-radius: 0.3rem;
  box-shadow: 0 0 0 1px var(--line-strong);
  flex-shrink: 0;
}

.mtc-demo-swatch--standard {
  background: #f5f7fa;
}

.mtc-demo-swatch--neowhite {
  background: #ffffff;
}

.mtc-demo-swatch--blackmoon {
  background: #1a1a1a;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.35);
}

.mtc-demo-themebtns .category-badges.theme-btn.w--current .mtc-demo-swatch {
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.6);
}

/* ---------- fields (select) ---------- */

.mtc-demo-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.mtc-demo-fieldlabel {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--muted);
}

/*
  The vendor pins .mtselect to `height: 30px` (mtcaptcha-demo.css). With our
  own vertical padding and Poppins' line box on top of that fixed height, the
  selected option was rendering taller than its own box and getting visually
  cut in half. Height is released to `auto` with a min-height floor so the
  text always has room, whatever the font or zoom level.
*/
.mtselect {
  height: auto;
  min-height: 2.5rem;
  line-height: 1.5;
  border-radius: 0.6rem;
  border: 1px solid var(--line-strong);
  background-color: var(--canvas);
  color: var(--ink);
  /*
    Symmetric 1rem sides, matching the contact form's `px-4` on every field.
    2026-08-06.

    Was `0.5rem 1.9rem 0.5rem 0.7rem` - 11.2px on the left against 30.4px on the
    right, so the label sat close to the border while a wide empty band ran down
    the right. Next to the Purpose select on /contact, which is an even 16px on
    both sides, the two read as different components rather than one control
    used twice.

    Both use the browser's native arrow, so nothing here has to reserve room for
    a custom icon - that asymmetric 1.9rem was never buying anything.

    Vertical padding stays 0.5rem rather than the form's 0.75rem: this select
    lives in a compact widget panel, and the horizontal alignment is what was
    inconsistent.
  */
  /*
    Every gap is 0.75rem (12px), matching the contact form's select:

        12px  gap from the right edge      (background-position)
        12px  the arrow itself             (background-size)
        12px  gap between text and arrow
        ----
        36px  = 2.25rem padding-right

    `appearance: none` is the load-bearing line. A native <select> paints its
    own arrow at an inset the browser chooses, which `padding-right` cannot
    move and which differs across Chrome, Safari and Firefox - so this select
    and the contact form's could never be made to match while both used it.

    These properties duplicate `.form-select` in global.css deliberately. This
    file is loaded by <link>, so it is unlayered and outranks Tailwind's utility
    layer; applying that class here would lose to the padding above. The icon is
    shared through `--select-chevron`, so the two cannot drift apart.
  */
  padding: 0.5rem 2.25rem 0.5rem 0.75rem;
  appearance: none;
  background-image: var(--select-chevron);
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 0.75rem 0.75rem;
  font-family: inherit;
  font-size: 0.85rem;
}

.mtselect:focus {
  outline: 2px solid color-mix(in oklab, var(--color-brand-500) 50%, transparent);
  outline-offset: 1px;
}

/* ---------- help / comment text + CTA buttons ---------- */

.demo-comment {
  color: var(--muted);
  background: var(--subtle);
  border: 1px solid var(--line);
  border-radius: 0.85rem;
  padding: 1rem 1.1rem;
  line-height: 1.6;
  font-size: 0.9rem;
}

.demo-comment p {
  margin: 0 0 0.6rem;
}

.demo-comment p:last-child {
  margin-bottom: 0;
}

.mtc-demo-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: none;
  border-radius: 999px;
  padding: 0.5rem 0.9rem;
  background: color-mix(in oklab, var(--color-brand-500) 14%, transparent);
  color: var(--color-brand-600);
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.15s ease;
}

.mtc-demo-cta:hover {
  background: color-mix(in oklab, var(--color-brand-500) 22%, transparent);
  transform: translateX(1px);
}

/*
  brand-600 text on this pill's tinted background measures fine in light mode
  (the 14% brand-500-over-white mix is light), but the same mix over dark
  mode's near-black canvas is a dark purple, and brand-600 text on it drops to
  2.8:1 (found via axe-core, 2026-08-06). brand-300 is the site's established
  swap for exactly this: LangSwitcher.astro and the footer already use
  dark:text-brand-300 for 14px text needing the AAA 7:1 this site publishes.
*/
.dark .mtc-demo-cta {
  color: var(--color-brand-300);
}

.mtc-demo-cta--filled {
  background: var(--color-brand-600);
  color: #fff;
  align-self: flex-start;
}

.mtc-demo-cta--filled:hover {
  background: var(--color-brand-700, var(--color-brand-600));
}

.mtc-demo-cta-icon {
  width: 0.9em;
  height: 0.9em;
  flex-shrink: 0;
}

/* ---------- accessibility tab ---------- */

.mtc-demo-a11y {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  color: var(--body);
}

.mtc-demo-a11y-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.75rem;
  background: color-mix(in oklab, var(--color-brand-500) 14%, transparent);
  color: var(--color-brand-600);
  flex-shrink: 0;
}

.mtc-demo-a11y-icon svg {
  width: 1.3rem;
  height: 1.3rem;
}

/* Keyboard shortcuts as a short, scannable list instead of one run-on
   sentence stitched together from several translation strings, that read as
   machine-generated filler rather than crafted UI copy. */
.mtc-demo-shortcuts {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mtc-demo-shortcuts li {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: 0.88rem;
  color: var(--body);
}

.mt-keybox {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.7rem;
  height: 1.7rem;
  padding: 0 0.4rem;
  border-radius: 0.45rem;
  border: 1px solid var(--line-strong);
  background: var(--canvas);
  box-shadow: 0 1px 0 var(--line-strong);
  /*
    Poppins, like everything else. 2026-08-06, by instruction: one typeface
    across the whole site, no exceptions.

    These are keycaps showing a literal keyboard key, and they were previously
    monospace on purpose - a keycap reads as a key rather than as prose, and the
    stack was spelled out so every platform rendered the same glyphs. That
    reasoning was sound but is now overridden by the single-typeface rule. The
    border, padding and background still carry the "this is a key" signal, so
    the cue survives the font change.
  */
  font-family: inherit;
  font-size: 0.85rem;
  flex-shrink: 0;
}

.mtc-demo-invisible-status {
  margin-top: 0.75rem;
}

.mtc-demo-spinner {
  display: inline-block;
  width: 0.9em;
  height: 0.9em;
  margin-right: 0.4em;
  border: 2px solid color-mix(in oklab, var(--color-brand-500) 35%, transparent);
  border-top-color: var(--color-brand-600);
  border-radius: 50%;
  vertical-align: -0.15em;
}

.mtc-demo-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.1em;
  height: 1.1em;
  margin-right: 0.4em;
  border-radius: 50%;
  background: var(--color-brand-600);
  color: #fff;
  font-size: 0.75em;
  vertical-align: -0.1em;
}

/* ---------- developer tab ---------- */

#demo-tabpage-developers {
  gap: 1.1rem !important;
}

.demo-devmodecomments {
  color: var(--body);
}

.demo-devmodecomments > p:first-child {
  margin: 0 0 0.85rem;
  font-size: 0.9rem;
}

.demo-devmodecomments code,
.demo-devmodecomments p code {
  background: var(--surface-2);
  border-radius: 0.35rem;
  padding: 0.1em 0.4em;
  font-size: 0.9em;
}

/* ---------- live demo screen (right column) ---------- */

/* The right column is a flex chain down to .demo-canvas so it fills the shared
   row height. The login card itself is never stretched, it stays its natural
   vendor size and centers in whatever height the row ends up being. */
/*
  The right column gets the same frame as the left (.mtc-demo-tabarea), added
  2026-08-06 by instruction: border, radius and surface so the two halves of the
  demo read as a matched pair instead of one card floating beside loose content.

  Border and background only - **no box-shadow**. The left panel carries
  `--shadow-card`, but the vendor's own login card (.demo-loginbox) already has
  its own elevation one level down; adding a second shadow here is what produced
  the "three layers of background" this file warns about below. One border, one
  surface, and the inner card keeps its own depth.
*/
.mtc-demo-screen-container {
  width: 100%;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  border-radius: 1rem;
  border: 1px solid var(--line);
  background: var(--surface);
  padding: 1.5rem;
}

/*
  No border, background, or shadow on .demoscreen or .demo-canvas: the vendor
  already renders its own themed card one level down (.demo-loginbox), and
  stacking our own card around it produced the "three layers of background"
  effect, most visible on Blackmoon where a dark card sat inside a light
  vendor canvas inside our own bordered/shadowed frame. Depth now comes from a
  single box-shadow applied directly to .demo-loginbox further down, so there
  is exactly one visible surface per state.
*/
.demoscreen,
.demo-theme-standard .demo-canvas,
.demo-theme-neowhite .demo-canvas,
.demo-theme-blackmoon .demo-canvas {
  background: transparent;
}

.demoscreen {
  width: 100% !important;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.demo-canvas {
  min-height: 300px;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.5rem;
  overflow: visible;
  transition: min-height 0.2s ease;
}

/* Modern Mini's form is much shorter; without this the canvas keeps its full
   min-height and the compact form looks lost in a mostly-empty box. Reading
   the mini state straight off the DOM (:has()) instead of adding a JS hook
   keeps every vendor className assignment untouched. */
.demo-canvas:has(.demo-captchabox-mini) {
  min-height: 190px;
}

/*
  Deliberately NOT adding overflow-x:auto/hidden anywhere in this ancestor
  chain (.demo-loginbox, .demo-captchabox, .demoscreen, .demo-canvas): any of
  them would clip or force-scroll Modern Mini's intentionally-overflowing
  compact layout. Verified via direct measurement that the captcha iframe
  (real width) stays within .demo-loginbox at both mobile (375px) and desktop
  widths; keep re-verifying this after any width change.
*/

.demo-loginbox {
  /*
    `flex-shrink: 0` is the load-bearing line here, added 2026-08-05.

    `.demo-canvas` above is `display: flex`, which is ours - production's is a
    plain block. That one difference makes this card a **flex item**, and a flex
    item's default `flex-shrink: 1` lets the layout compress it below its
    declared size. It was being compressed by exactly 36px: the vendor sizes the
    card `width: 100%; max-width: 350px` (content-box) in its
    `@media (min-width: 371px)` bucket, so it wants 350 + 40px padding + 5px
    border per side = 440px, and the available content box was 404px. The card
    landed at 314px of content, and **the captcha inside it rendered at 314px
    instead of 350px** - about 10% narrower than the vendor designs for, on every
    desktop view. Nothing clipped, so nothing looked broken.

    On production the card is a block box: it takes its 350px and simply
    overflows its 384px parent, which is why it keeps its full size there.

    Note the vendor's `min-width: 350px !important` (line ~785) is NOT what
    protects this - the vendor cancels it itself for the Standard theme with
    `min-width: unset !important` (~line 239). There is no floor to fall back on,
    which is why the shrink has to be disabled at the flex level.

    Pairs with the 456px column in `.mtc-demo-grid`: without the room, refusing
    to shrink just turns the squeeze into an overflow.
  */
  flex-shrink: 0;
  /* Let the vendor's own responsive max/min-width rules govern the size itself;
     they're already tuned to fit the captcha challenge without clipping. We only
     guarantee the surrounding boxes (above) never squeeze it smaller. */
  margin-inline: auto;
  transition: box-shadow 0.2s ease;
}

/*
  Real mobile clipping, found after a screenshot showed the captcha's audio
  icon, text input, and footer cut off on the right at 375px, even though the
  outer page had zero horizontal scroll (document.scrollWidth === clientWidth).
  That measurement was the wrong check: the captcha itself renders inside a
  cross-origin iframe, so if its own content needs more width than we give
  its container, the overflow happens *inside the iframe's own browsing
  context* and never touches the parent page's scrollWidth at all, while the
  hero section's own `overflow-hidden` (needed for its decorative background
  blobs) visibly clips it. The actual bug was a width *budget* problem: by the
  time you subtract the page gutter (container-page, 24px/side), the hero
  card's own padding, and this canvas's padding, `.demo-loginbox` was only
  reaching vendor's >=371px breakpoint (40px padding + 5px border/side) with
  as little as ~179px left for the captcha itself, well under what the vendor
  designed for. Reclaim width specifically at narrow viewports: the vendor's
  own breakpoints already assume a generous parent, so this overrides its
  padding down near its own <350px bucket instead of the >=371px one a 375px
  screen would otherwise land in.
*/
@media (max-width: 600px) {
  .demo-canvas {
    padding-inline: 0;
  }

  .demo-loginbox,
  .demo-theme-standard .demo-loginbox,
  .demo-theme-neowhite .demo-loginbox,
  .demo-theme-blackmoon .demo-loginbox {
    padding: 14px !important;
    border-width: 2px !important;
  }
}

/*
  Elevation: none on a light page, matching production.

  Removed 2026-08-06. This block previously carried one box-shadow per
  (widget theme x site mode) pairing - six rules. Measured against the real card
  on www.mtcaptcha.com:

      production   radius 24px   border 5px solid #fff   bg rgba(255,255,255,.9)
                   padding 25px 40px 20px   box-shadow: NONE

  Every one of those already matches what the vendor CSS produces here. The
  shadow was the only thing we had added to the card, and therefore the only
  thing making it look unlike production's.

  The dark-mode 1px ring that used to live here is gone too, 2026-08-06.

  It existed for a real reason: the Standard theme adopts the site's dark
  surface, so on a dark page the card was a dark box on a dark background with a
  5px border of nearly the same colour - no visible edge at all. The ring
  restored that boundary.

  `.mtc-demo-screen-container` now carries a border of its own, matching the
  left panel, and that supplies the edge instead. Keeping both drew **two
  concentric lines** around the login card, which is what it looked like: a
  frame inside a frame. One boundary per card.
*/

/* ---------- Standard theme follows the site's own light/dark mode ---------- */
/*
  Standard is the demo's default theme and the only one that tracks the host
  page: white card on a light page (the vendor's own look, untouched), and the
  site's dark surface on a dark page, so it doesn't sit there as a white slab.
  Neowhite and Blackmoon are deliberately left exactly as the vendor ships
  them, since those two exist to show the product's own fixed themes.

  The vendor's own rules are `.demo-theme-standard .demo-*` (specificity 0,2,0)
  and some sit inside media queries; adding `.dark` in front (0,3,0) beats them
  everywhere without !important.

  Known limit: the captcha challenge itself renders in a cross-origin iframe
  whose styling comes from `mtcaptchaConfig.theme`, which the vendor's setTheme()
  sets to null (its default light look) for Standard. CSS in this file cannot
  reach inside that iframe, so the challenge block stays light within the
  darkened card. Changing it would mean overriding the vendor's captcha config
  for Standard, which would misrepresent what the product's Standard theme
  actually looks like to a customer evaluating it.
*/
/* The vendor gives this card `border: 5px solid #ffffff`, which is invisible
   on a white page and a glaring white frame on a dark one. It is really just
   inset spacing, so it takes the card's own color rather than being removed
   (removing it would shrink the card and squeeze the captcha). */
.dark .demo-theme-standard .demo-loginbox {
  background-color: var(--surface);
  border-color: var(--surface);
}

.dark .demo-theme-standard .demo-welcomesm {
  color: var(--ink);
}

/*
  Vendor's own Standard-theme label color (#777777 on white) measures 4.47:1,
  just under the 4.5:1 AA threshold for normal text (found via axe-core,
  2026-08-06). #707070 is visually indistinguishable from the vendor's
  original at this size and clears 4.95:1. Not gated on .dark, since the
  vendor's own light-mode color was the one failing; the .dark override
  below still wins in dark mode on selector specificity.
*/
.demo-theme-standard .demo-label {
  color: #707070;
}

/*
  Vendor's own Standard-theme submit button (#666BFF background, white text)
  measures 4.1:1, also under 4.5:1 (same audit). var(--color-brand-600) is
  the same blue every other primary button on the site already uses and
  clears 6.2:1; using it here instead of a one-off hex keeps this button
  consistent with the rest of the page's palette, not just compliant.
*/
.demo-theme-standard .demo-submitbtn {
  background-color: var(--color-brand-600);
}

.demo-theme-standard .demo-submitbtn:active {
  background-color: var(--color-brand-700, var(--color-brand-600));
}

.dark .demo-theme-standard .demo-label {
  color: var(--muted);
}

.dark .demo-theme-standard .demo-inputtxt {
  background-color: var(--canvas);
  border-color: var(--line-strong);
  color: var(--ink);
}

/*
  Vendor forces the invisible-mode captcha box to a fixed 23px (tall enough
  for just a "verifying..." line). In this demo, invisible mode can still fall
  back to a visible challenge (no real behavioral signal to judge), which then
  overflowed into the Sign In button below. Let it grow instead of overlap.
*/
.demo-captchabox-invisible {
  height: auto !important;
  min-height: 23px;
  margin-bottom: 0.5rem;
}

/* ---------- video modal ---------- */

.mtc-demo-videomodal {
  position: fixed;
  inset: 0;
  z-index: 100;
}

.mtc-demo-videomodal-backdrop {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(4, 9, 26, 0.72);
  backdrop-filter: blur(2px);
}

.mtc-demo-videomodal .video-mod-box {
  width: 100%;
  max-width: 48rem;
  border-radius: 1rem;
  overflow: hidden;
  background: #000;
  box-shadow: var(--shadow-lift);
  aspect-ratio: 16 / 9;
  display: flex;
  flex-direction: column;
}

.mtc-demo-videomodal-bar {
  display: flex;
  justify-content: flex-end;
  padding: 0.5rem 0.75rem;
  background: #000;
}

.mt-videoclosebtn {
  border: none;
  background: transparent;
  color: #fff;
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
  opacity: 0.8;
  cursor: pointer;
}

.mt-videoclosebtn:hover {
  opacity: 1;
}

.mtc-demo-videomodal iframe {
  flex: 1;
  width: 100%;
  border: 0;
}

/* ---------- dark mode (general text colors) ---------- */

.dark .demo-comment,
.dark .demo-chkcontainer,
.dark .theme-name,
.dark .mtc-demo-a11y,
.dark .demo-devmodecomments {
  color: var(--body);
}
