/* ===========================================================================
 * Create Your Honeybot — v2 (Joi-style wizard)
 * ---------------------------------------------------------------------------
 * Scoped to .create-honey2. Uses CSS custom properties for Joi-style tokens
 * mapped onto Honeybot's brand palette. All rules go through the
 * component layer; no inline styles in templates.
 *
 * Token source: docs/features/joi_extraction/DESIGN_TOKENS.md
 * Component source: docs/features/joi_extraction/key_component_rules.css
 * =========================================================================== */

html:has(body.create-your-honeybot2-page),
body.create-your-honeybot2-page {
  /* Full-screen wizard — lock the body AND html to the viewport so only the
   * stage scrolls. Both must be locked: when the iOS soft keyboard opens,
   * Safari can scroll the document up and expose the html background unless
   * html itself is fixed-height with overflow hidden. Same dark fill as the
   * wizard prevents any white flash if it does shift one frame. */
  overflow: hidden;
  height: 100dvh;
  background: #0f0f0f;
  overscroll-behavior: none;
}
/* The site-wide reset.css applies `scroll-behavior: smooth` to every element
 * (`* { scroll-behavior: smooth }`). On iOS, that turns the browser's native
 * auto-scroll-to-focused-input into a slow tween, making the input appear to
 * slide down from the top as the keyboard opens. Force `auto` everywhere
 * inside the wizard — including html (which is a scroll container too) and
 * descendants — so focus → in-place, no smooth descent. */
html:has(body.create-your-honeybot2-page),
body.create-your-honeybot2-page,
body.create-your-honeybot2-page * {
  scroll-behavior: auto !important;
}
body.create-your-honeybot2-page {
  /* Pin the body so iOS can't scroll it up under the keyboard. position: fixed
   * + inset:0 keeps the document anchored regardless of the visual viewport. */
  position: fixed;
  inset: 0;
}
/* Mobile: hide site chrome entirely so the wizard owns the full viewport. */
@media (max-width: 767px) {
  body.create-your-honeybot2-page .header-sticky,
  body.create-your-honeybot2-page .bottom-navbar,
  body.create-your-honeybot2-page .page-footer {
    display: none !important;
  }
}

@layer components {
  .create-honey2 {
    /* Joi-style scale: the wizard is authored against a 10px unit.
     * Setting font-size: 10px here + using `em` everywhere below keeps the
     * scale local — the site navbar (which uses `rem`) is unaffected. */
    font-size: 10px;

    --ch2-radius-xs: 1.2em;
    --ch2-radius-m: 2em;
    --ch2-radius-xl: 4em;

    --ch2-gap-s: 0.4em;
    --ch2-gap-m: 0.8em;
    --ch2-gap-l: 1.2em;
    --ch2-gap-xl: 2em;

    --ch2-bg: #0f0f0f;
    --ch2-surface: #1a1a1a;
    --ch2-border: #303030;
    --ch2-text: #ffffff;
    --ch2-text-muted: #858585;
    --ch2-white-xxs: rgba(255, 255, 255, 0.08);
    --ch2-white-xs: rgba(255, 255, 255, 0.1);
    --ch2-white-s: rgba(255, 255, 255, 0.12);

    /* Map Joi accent to Honeybot primary */
    --ch2-accent: theme('colors.primary');

    /* Honeybot brand gradient — used to circle selected chips, tiles, swatches,
     * and voice cards. Matches --gre-primary / --gre-secondary in variables.css. */
    --ch2-sel-gradient: linear-gradient(to right, #FF36F7, #FFBA2F);
    --ch2-sel-glow: 0 0 0 1px rgba(255, 54, 247, 0.25);

    /* Site navbar height — set dynamically by the wizard script so the
     * wrapper fills the remaining viewport (0 on mobile where it's hidden). */
    --ch2-topnav: 0px;

    /* Effective wizard height. JS overrides this with the live
     * `window.visualViewport.height` when the iOS soft keyboard opens, so the
     * whole wizard frame (header + stage + footer) shrinks to the area above
     * the keyboard. Default = 100dvh so non-JS / desktop / Android-without-vv
     * paths keep the previous behaviour. */
    --ch2-app-h: 100dvh;

    font-family: 'Outfit', 'Inter', sans-serif;
    background: var(--ch2-bg);
    color: var(--ch2-text);
    height: calc(var(--ch2-app-h) - var(--ch2-topnav));
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  /* ---------- Header ---------- */
  .create-honey2__header {
    flex: 0 0 auto;
    z-index: 10;
    background: var(--ch2-bg);
    padding: 1.2em 2em 0.8em;
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 1em;
    border-bottom: 1px solid transparent;
  }

  .create-honey2__back {
    width: 4em;
    height: 4em;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--ch2-white-xs);
    border: none;
    color: var(--ch2-text);
    cursor: pointer;
    transition: background-color 0.2s;
  }
  .create-honey2__back:hover { background: var(--ch2-white-s); }
  .create-honey2__back:disabled { opacity: 0.4; cursor: not-allowed; }

  /* Close affordance — mobile only. Takes the 3rd grid column so the title
   * stays centered. Desktop hides it (users exit via the site navbar). */
  .create-honey2__close {
    display: none;
    grid-column: 3;
    width: 4em;
    height: 4em;
    border-radius: 999px;
    align-items: center;
    justify-content: center;
    background: var(--ch2-white-xs);
    border: none;
    color: var(--ch2-text);
    cursor: pointer;
    transition: background-color 0.2s;
  }
  .create-honey2__close:hover { background: var(--ch2-white-s); }
  @media (max-width: 767px) {
    .create-honey2__close { display: inline-flex; }
  }

  .create-honey2__title {
    grid-column: 2;
    font-size: 1.8em;
    font-weight: 600;
    text-align: center;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    margin: 0;
  }

  .create-honey2__progress {
    grid-column: 1 / -1;
    grid-row: 2;
    display: flex;
    gap: 0.4em;
    padding: 0.6em 0 0;
  }
  .create-honey2__dot {
    flex: 1;
    height: 1.2em;
    display: flex;
    align-items: center;
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
  }
  .create-honey2__dot[disabled] { cursor: default; }
  .create-honey2__dot > span {
    flex: 1;
    height: 3px;
    border-radius: 2px;
    background: var(--ch2-white-xs);
    transition: height 0.2s, background-color 0.2s;
  }
  .create-honey2__dot.is-done > span,
  .create-honey2__dot.is-current > span { background: var(--ch2-text); }
  .create-honey2__dot.is-done:hover > span { height: 1em; }

  /* ---------- Stage ---------- */
  .create-honey2__stage {
    flex: 1 1 auto;
    min-height: 0;
    /* Wide enough to fit 5 chips per row (e.g. hair styles) and the voice
     * step's 3-column card grid without needing per-step overrides. */
    max-width: 880px;
    width: 100%;
    margin: 0 auto;
    padding: 1.6em 2em;
    display: flex;
    flex-direction: column;
    gap: 1.6em;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
  }
  .create-honey2__stage::-webkit-scrollbar { width: 0; }

  .ch2-step {
    display: flex;
    flex-direction: column;
    gap: 1.6em;
  }

  .ch2-section {
    display: flex;
    flex-direction: column;
    gap: 1em;
  }

  .ch2-label {
    text-align: center;
    font-size: 1.4em;
    line-height: 2em;
    font-weight: 500;
    color: var(--ch2-text);
    margin: 0;
  }
  .ch2-label--small {
    font-size: 1.2em;
    opacity: 0.7;
  }

  .ch2-hint {
    text-align: center;
    font-size: 1.2em;
    color: var(--ch2-text-muted);
    margin: 0;
  }

  /* ---------- Chip (text button) ---------- */
  .ch2-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 1.6em;
    min-height: 4em;
    border-radius: var(--ch2-radius-xl);
    background: var(--ch2-white-xs);
    color: var(--ch2-text);
    border: 2px solid transparent;
    font: inherit;
    font-size: 1.3em;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.2s, border-color 0.2s, color 0.2s;
    white-space: nowrap;
  }
  .ch2-chip:hover { background: var(--ch2-white-s); }
  .ch2-chip {
    position: relative;
  }
  .ch2-chip.is-selected {
    background: var(--ch2-white-s);
    border-color: transparent;
  }
  .ch2-chip.is-selected::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 2px;
    background: var(--ch2-sel-gradient);
    -webkit-mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    pointer-events: none;
  }
  .ch2-chip--ghost {
    background: transparent;
    border-color: var(--ch2-border);
    color: var(--ch2-text-muted);
  }
  .ch2-chip--ghost:hover { color: var(--ch2-text); border-color: var(--ch2-text); }
  .ch2-chip--wide {
    flex: 1;
    max-width: 280px;
    min-height: 4.4em;
  }
  .ch2-chip--small {
    padding: 0 1em;
    min-height: 3.2em;
    font-size: 1.2em;
    gap: 0.6em;
  }
  .ch2-chip--custom {
    border-style: dashed;
  }
  .ch2-chip--full { align-self: center; margin-top: 0.4em; }
  .ch2-chip__x {
    font-size: 1.6em;
    line-height: 1;
    opacity: 0.8;
  }

  .ch2-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch2-gap-l);
    justify-content: center;
  }
  .ch2-chip-row--wide {
    gap: var(--ch2-gap-l);
  }
  .ch2-chip-row--selected:empty { display: none; }

  /* ---------- Photo tile ---------- */
  .ch2-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 0;
    background: var(--ch2-surface);
    border: 2px solid var(--ch2-bg);
    border-radius: var(--ch2-radius-m);
    overflow: hidden;
    cursor: pointer;
    color: var(--ch2-text);
    transition: box-shadow 0.2s, border-color 0.2s;
  }
  .ch2-tile:hover:not(.is-selected) {
    box-shadow: 0 0 0 2px var(--ch2-white-xs);
  }
  .ch2-tile:focus-visible:not(.is-selected) {
    outline: none;
    border-color: transparent;
    box-shadow: 0 0 0 3px var(--ch2-accent);
  }
  .ch2-tile.is-selected {
    /* Keep the existing border transparent — the gradient ring is painted by
     * an ::after overlay that honours `border-radius`. `border-image` would
     * flatten the corners. */
    border-color: transparent;
    box-shadow: var(--ch2-sel-glow);
  }
  .ch2-tile.is-selected::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 3px;
    background: var(--ch2-sel-gradient);
    -webkit-mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    pointer-events: none;
    z-index: 2;
  }

  .ch2-tile--tall  { aspect-ratio: 2 / 3; }
  .ch2-tile--wide  { aspect-ratio: 1; }
  .ch2-tile--square { aspect-ratio: 1; }
  .ch2-tile--small { width: 15em; flex: 0 0 auto; }

  .ch2-tile__img {
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, #2a1a2e 0%, #1a1a2e 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2em;
    color: var(--ch2-text-muted);
    letter-spacing: 0.04em;
  }
  .ch2-tile__img::before { content: attr(data-ch2-placeholder); }

  /* Inline-SVG tile artwork (orientation symbols, etc.). The wrapping span keeps
   * the dark gradient; the inner <svg> is centered, sized to ~60% of tile height,
   * and inherits text color via stroke="currentColor". */
  .ch2-tile__img--symbol::before { content: none; }
  .ch2-tile__img--symbol > svg {
    position: relative;
    width: 64%;
    height: 56%;
    color: var(--ch2-text);
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4));
  }

  /* Selection check — plain white feather icon (no circle background),
   * right-aligned. Matches the my-honeybot-gallery polyline shape. */
  .ch2-tile__check {
    position: absolute;
    top: 0.8em;
    right: 0.8em;
    width: 24px;
    height: 24px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 24px 24px;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6));
    opacity: 0;
    transition: opacity 0.15s;
    z-index: 1;
    pointer-events: none;
  }
  .ch2-tile.is-selected .ch2-tile__check { opacity: 1; }

  .ch2-tile__label {
    position: relative;
    z-index: 1;
    padding: 0.6em 0.8em;
    background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.75));
    font-size: 1.2em;
    font-weight: 500;
    text-align: center;
  }

  /* Tile images (real <img> inside .ch2-tile__img). Anchor the crop to the top
   * of the source so portrait subjects keep the face visible when the tile
   * aspect-ratio differs from the source (e.g. tall portrait → square tile). */
  .ch2-tile__img img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
  }
  .ch2-tile__img--media { overflow: hidden; }
  .ch2-tile__img--media::before { content: none; }

  /* Video tile: video autoplays behind the poster (V1 parity). Poster is the
   * first paint so we don't show a blank box while the mp4 buffers; once the
   * video is decoding the poster fades out and the looping video takes over.
   * Same top-anchored crop as still tiles so the face stays visible. */
  .ch2-tile__poster,
  .ch2-tile__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    transition: opacity 0.2s ease;
  }
  /* Opt-out for tiles with no face (e.g. the dice "Random" render): re-center
   * the crop so the subject sits in the middle of the tile instead of pinned
   * to the top edge. Apply on the .ch2-tile__img wrapper or the <img> itself. */
  .ch2-tile__img--centered img,
  .ch2-tile__poster--centered,
  .ch2-tile__video--centered {
    object-position: center;
  }
  .ch2-tile--video .ch2-tile__video { opacity: 1; pointer-events: none; }

  /* ---------- Grid ---------- */
  .ch2-grid {
    display: grid;
    gap: 1em;
    width: 100%;
    justify-content: center;
  }
  .ch2-grid--2 { grid-template-columns: repeat(2, 1fr); }
  .ch2-grid--3 { grid-template-columns: repeat(2, 1fr); } /* mobile default */
  .ch2-grid--4 { grid-template-columns: repeat(2, minmax(0, 150px)); }
  .ch2-grid--5 { grid-template-columns: repeat(3, minmax(0, 130px)); }

  @media (min-width: 768px) {
    .ch2-grid--2 { grid-template-columns: repeat(2, minmax(0, 280px)); }
    .ch2-grid--3 { grid-template-columns: repeat(3, minmax(0, 200px)); }
    .ch2-grid--4 { grid-template-columns: repeat(4, minmax(0, 150px)); gap: 2.4em; }
    .ch2-grid--5 { grid-template-columns: repeat(5, minmax(0, 130px)); gap: 1.8em; }

    .ch2-tile--tall  { aspect-ratio: 2 / 3; }
    .ch2-tile--wide  { aspect-ratio: 3 / 2; }
  }

  /* ---------- Horizontal scroll (body step, eye color, etc.) ---------- */
  .ch2-scroll {
    display: flex;
    gap: 1.6em;
    padding: 3px 2em;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -ms-overflow-style: none;
    margin-inline: -2em; /* let the fade mask reach the viewport edge */
    /* `safe center` centers when content fits, falls back to start when it
     * overflows so the first item never gets clipped off the left edge. */
    justify-content: safe center;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 3em calc(100% - 3em), transparent);
            mask-image: linear-gradient(90deg, transparent, #000 3em calc(100% - 3em), transparent);
  }
  .ch2-scroll { cursor: grab; }
  .ch2-scroll::-webkit-scrollbar { display: none; }
  /* Inside arrow wrapper, scroll fills remaining space and drops the negative margin. */
  .ch2-scroll-wrap .ch2-scroll {
    flex: 1;
    min-width: 0;
    margin-inline: 0;
  }

  /* Mobile: collapse carousels into a wrapping row so the page scrolls
   * vertically instead of horizontally. Personality (step 5) keeps its
   * horizontal carousel because the video tiles are authored for it. */
  @media (max-width: 767px) {
    [data-ch2-step]:not([data-ch2-step="5"]) .ch2-scroll {
      flex-wrap: wrap;
      overflow-x: visible;
      overflow-y: visible;
      justify-content: center;
      cursor: default;
      gap: var(--ch2-gap-l);
      padding: 3px 0;
      margin-inline: 0;
      -webkit-mask-image: none;
              mask-image: none;
    }
    [data-ch2-step]:not([data-ch2-step="5"]) .ch2-scroll > .ch2-tile--small {
      width: calc(50% - (var(--ch2-gap-l) / 2));
      max-width: none;
    }
  }

  /* Scroll wrapper with left/right arrow buttons. */
  .ch2-scroll-wrap {
    position: relative;
    display: flex;
    align-items: center;
  }

  /* Desktop: horizontal-scroll carousel. Mobile (<=767px): collapse into a
   * 2-column vertical grid so the user isn't forced to swipe inside a
   * section that already lives in a scrollable stage. */
  @media (max-width: 767px) {
    .ch2-scroll-wrap--mobile-grid .ch2-scroll-arrow { display: none; }
    /* Specificity boost: the generic `[data-ch2-step]:not(...) .ch2-scroll`
     * rule above outranks a single-class selector, so we need an attribute
     * selector here too to actually take effect. */
    [data-ch2-step] .ch2-scroll-wrap--mobile-grid .ch2-scroll {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 1em;
      overflow: visible;
      margin-inline: 0;
      padding: 3px 0;
      -webkit-mask-image: none;
              mask-image: none;
      cursor: auto;
    }
    [data-ch2-step] .ch2-scroll-wrap--mobile-grid .ch2-scroll > .ch2-tile--small {
      width: auto;
      max-width: none;
    }
  }
  .ch2-scroll-arrow {
    flex: 0 0 auto;
    width: 3.6em;
    height: 3.6em;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--ch2-white-xs);
    border: 1px solid var(--ch2-border);
    color: var(--ch2-text);
    cursor: pointer;
    transition: background-color 0.2s, opacity 0.2s;
    z-index: 2;
  }
  .ch2-scroll-arrow:hover { background: var(--ch2-white-s); }
  .ch2-scroll-arrow.is-hidden { opacity: 0; pointer-events: none; }
  /* On mobile, hide arrows — swipe is natural. */
  @media (max-width: 767px) {
    .ch2-scroll-arrow { display: none; }

    /* Step 5 (personality) keeps arrow affordances on mobile so users
     * realise the row scrolls — sliders sit just below, no room to scroll
     * through tiles by accident. Arrows overlay the carousel edges so they
     * don't steal width from the tiles. */
    .ch2-step[data-ch2-step="5"] .ch2-scroll-arrow {
      display: inline-flex;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      width: 3.2em;
      height: 3.2em;
      background: rgba(0, 0, 0, 0.55);
      backdrop-filter: blur(4px);
      -webkit-backdrop-filter: blur(4px);
      z-index: 3;
    }
    .ch2-step[data-ch2-step="5"] .ch2-scroll-arrow--left { left: 0.4em; }
    .ch2-step[data-ch2-step="5"] .ch2-scroll-arrow--right { right: 0.4em; }
  }

  /* ---------- Color swatch ---------- */
  .ch2-swatch-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8em;
    justify-content: center;
  }
  .ch2-swatch {
    width: 4em;
    height: 4em;
    border-radius: 999px;
    background: transparent;
    border: 2px solid transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.4em;
    cursor: pointer;
    transition: border-color 0.2s;
  }
  .ch2-swatch:hover { border-color: var(--ch2-white-s); }
  .ch2-swatch {
    position: relative;
  }
  .ch2-swatch.is-selected {
    border-color: transparent;
  }
  .ch2-swatch.is-selected::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 2px;
    background: var(--ch2-sel-gradient);
    -webkit-mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    pointer-events: none;
  }
  .ch2-swatch__dot {
    width: 100%;
    height: 100%;
    border-radius: 999px;
    border: 1px solid var(--ch2-border);
  }

  /* ---------- Input (text / search) ---------- */
  .ch2-input-wrap {
    position: relative;
    display: flex;
    align-items: center;
    max-width: 420px;
    margin: 0 auto;
    width: 100%;
  }
  .ch2-input-wrap__icon {
    position: absolute;
    left: 1.2em;
    top: 50%;
    transform: translateY(-50%);
    color: var(--ch2-text-muted);
    pointer-events: none;
    display: inline-flex;
  }
  .ch2-input-wrap__action {
    position: absolute;
    right: 0.6em;
    top: 50%;
    transform: translateY(-50%);
    width: 3.2em;
    height: 3.2em;
    border-radius: 999px;
    background: var(--ch2-white-xs);
    color: var(--ch2-text);
    border: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
  }
  .ch2-input-wrap__action:hover { background: var(--ch2-white-s); }

  .ch2-input {
    width: 100%;
    height: 4.4em;
    padding: 0 4.8em 0 3.6em;
    border-radius: var(--ch2-radius-xs);
    background: var(--ch2-white-xxs);
    border: 1px solid var(--ch2-border);
    color: var(--ch2-text);
    font: inherit;
    font-size: 1.4em;
    outline: none;
    transition: border-color 0.2s, background-color 0.2s;
  }
  .ch2-input::placeholder { color: var(--ch2-text-muted); }
  .ch2-input:focus {
    border-color: var(--ch2-text);
    background: var(--ch2-surface);
  }
  .ch2-input-wrap--search .ch2-input { padding-right: 1.2em; }

  /* Inline input row (age): compact input matching chip size. */
  .ch2-input-wrap--inline {
    max-width: none;
    width: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 1.2em;
    position: relative;
  }
  /* [hidden] must win over `display: flex` on the wrap. */
  .ch2-input-wrap[hidden] { display: none; }
  .ch2-input--number {
    width: 6em;
    height: auto;
    padding: 0 1em;
    text-align: center;
    font-size: 1.3em;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    min-height: 4em;
    border-radius: var(--ch2-radius-xl);
    background: var(--ch2-white-xs);
    border: 2px solid transparent;
    position: relative;
    z-index: 1;
  }
  .ch2-input--number:focus {
    outline: none;
  }
  /* Gradient ring painted by the wrapper's ::after so only the border circles
   * the input — the input's own background stays a solid surface fill. Same
   * mask-composite trick as .ch2-tile.is-selected::after. */
  .ch2-input-wrap--inline:focus-within::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: var(--ch2-radius-xl);
    padding: 2px;
    background: var(--ch2-sel-gradient);
    -webkit-mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    pointer-events: none;
    z-index: 2;
  }
  .ch2-input--number::-webkit-inner-spin-button,
  .ch2-input--number::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  .ch2-input--number { -moz-appearance: textfield; }

  /* Centered section for the step-0 random-selection link. */
  .ch2-section--center { align-items: center; text-align: center; }
  .ch2-section--custom-add { margin-top: 1.6em; }
  .ch2-section--custom-add.hidden { display: none; }

  /* Mobile: vertically center step-0 (design approach tiles + random link)
   * inside the stage so the two selection boxes sit lower on the screen
   * instead of hugging the top under the header. */
  @media (max-width: 767px) {
    .ch2-step[data-ch2-step="0"] {
      margin-top: auto;
      margin-bottom: auto;
    }
  }


  /* Plain underlined link button (step 0 "Or try a random selection"). */
  .ch2-link-btn {
    background: none;
    border: none;
    color: var(--ch2-text-muted);
    font: inherit;
    font-size: 1.3em;
    text-decoration: underline;
    cursor: pointer;
    padding: 0.6em 1em;
  }
  .ch2-link-btn:hover { color: var(--ch2-text); }

  /* "Start over" affordance shown on step 0 when a previous session was
   * restored from localStorage. Sits below the Random link. */
  .ch2-reset-wrap {
    margin-top: 0.4em;
    gap: 0.4em;
  }
  /* `.ch2-section` sets `display: flex`, which has higher specificity than
   * the UA `[hidden] { display: none }` rule, so the wrap leaks visible on
   * fresh sessions. Force it back to none whenever the `hidden` attribute
   * is present (initial paint + after clicking "Start over"). */
  .ch2-reset-wrap[hidden] { display: none; }
  .ch2-reset__hint {
    font-size: 1.2em;
    color: var(--ch2-text-muted);
    margin: 0;
  }
  .ch2-reset-btn {
    color: var(--ch2-accent);
    font-weight: 600;
  }
  .ch2-reset-btn:hover { color: var(--ch2-accent); opacity: 0.85; }

  /* ---------- Sliders ---------- */
  .ch2-sliders {
    display: flex;
    flex-direction: column;
    gap: 1.6em;
    max-width: 420px;
    margin: 0 auto;
    width: 100%;
  }
  .ch2-slider-row {
    display: grid;
    grid-template-columns: 8em 1fr 8em;
    align-items: center;
    gap: 1em;
    font-size: 1em;
    color: var(--ch2-text);
  }
  .ch2-slider-row__min { text-align: right; }
  .ch2-slider-row__max { text-align: left; }

  .ch2-slider {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 4px;
    border-radius: 2px;
    background: linear-gradient(
      to right,
      var(--ch2-text) 0%,
      var(--ch2-text) var(--ch2-slider-pct, 50%),
      var(--ch2-white-s) var(--ch2-slider-pct, 50%),
      var(--ch2-white-s) 100%
    );
    outline: none;
  }
  .ch2-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    border-radius: 4px;
    background: #f1f1f1;
    border: 4px solid #1a1a1a;
    cursor: pointer;
  }
  .ch2-slider::-moz-range-thumb {
    width: 18px;
    height: 18px;
    border-radius: 4px;
    background: #f1f1f1;
    border: 4px solid #1a1a1a;
    cursor: pointer;
  }

  /* ---------- Example preview block (chat style) ---------- */
  .ch2-example {
    border: 1px solid var(--ch2-border);
    border-radius: var(--ch2-radius-m);
    padding: 1.6em;
    display: flex;
    flex-direction: column;
    gap: 0.8em;
  }
  .ch2-example__label {
    font-size: 1.1em;
    color: var(--ch2-text-muted);
    margin: 0;
    letter-spacing: 0.04em;
  }
  .ch2-example__q,
  .ch2-example__a { margin: 0; font-size: 1.4em; line-height: 2em; }
  .ch2-example__q { color: var(--ch2-text); }
  .ch2-example__a { color: var(--ch2-text-muted); }

  /* ---------- Recap ---------- */
  .ch2-recap {
    display: flex;
    flex-direction: column;
    gap: 2em;
    align-items: center;
  }
  /* `align-items: center` would otherwise shrink-wrap child sections to their
   * intrinsic width, which breaks the horizontal-scroll layout on the gallery
   * Position picker — the scroll container needs to know its clip width to
   * decide overflow and to paint the edge fade mask. Force full width so the
   * scroll-wrap sits inside the stage's 880px max-width like every other step. */
  .ch2-recap > .ch2-section { width: 100%; }
  .ch2-recap__progress {
    font-size: 1.6em;
    font-weight: 600;
    margin: 0;
  }
  .ch2-recap__body {
    display: flex;
    flex-direction: column;
    gap: 2em;
    width: 100%;
    max-width: 560px;
  }
  @media (min-width: 768px) {
    .ch2-recap__body { flex-direction: row; align-items: stretch; }
  }
  .ch2-recap__preview {
    width: 100%;
    max-width: 240px;
    margin: 0 auto;
    /* Aspect comes from the tile variant (ch2-tile--tall = 2/3) so the recap
     * preview matches the portrait thumbs used everywhere else in the wizard. */
  }
  .ch2-recap__info {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 1.6em;
    justify-content: center;
  }
  .ch2-recap__row { display: flex; flex-direction: column; gap: 0.4em; }
  .ch2-recap__row-label {
    font-size: 1.2em;
    color: var(--ch2-text-muted);
    margin: 0;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }
  .ch2-recap__row-value {
    font-size: 1.4em;
    line-height: 2em;
    color: var(--ch2-text);
    margin: 0;
  }

  /* ---------- Footer CTA ---------- */
  .create-honey2__footer {
    flex: 0 0 auto;
    padding: 1.2em 2em 1.6em;
    display: flex;
    justify-content: center;
    background: linear-gradient(180deg, transparent, var(--ch2-bg) 40%);
    z-index: 20;
  }
  .create-honey2__footer-stack {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.8em;
    width: 100%;
    max-width: 720px;
  }
  .create-honey2__footer-actions {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1em;
    width: 100%;
  }
  /* Resume / Regenerate shortcut: only shown once the user has reached the
   * face/body review screens at least once this session. Lets them jump
   * straight back to the cached image instead of walking the wizard. */
  .create-honey2__resume {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 4.4em;
    padding: 0 3.2em;
    border-radius: var(--ch2-radius-xl);
    background: var(--ch2-accent);
    color: var(--ch2-bg);
    border: none;
    font: inherit;
    font-size: 1.5em;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 4px 20px rgba(250, 61, 114, 0.35);
    transition: transform 0.15s, box-shadow 0.15s, filter 0.15s;
  }
  .create-honey2__resume:hover {
    transform: translateY(-1px);
    box-shadow: 0 8px 28px rgba(250, 61, 114, 0.5);
    filter: brightness(1.05);
  }
  .create-honey2__resume[hidden] { display: none; }
  /* Back sits to the left of the main CTA on every viewport. The header Back
   * stays visible on desktop too, but having one in the footer keeps the
   * primary navigation (Back / Next) within thumb reach of the CTA. */
  .create-honey2__footer-back {
    display: inline-flex;
    flex: 0 0 auto;
    padding: 0 3.2em;
    min-height: 4.4em;
    border-radius: var(--ch2-radius-xl);
    align-items: center;
    justify-content: center;
    background: var(--ch2-white-xs);
    border: 1px solid var(--ch2-border);
    color: var(--ch2-text);
    font: inherit;
    font-size: 1.5em;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    min-width: 20em;
    max-width: 420px;
    transition: background-color 0.2s;
  }
  .create-honey2__footer-back:hover { background: var(--ch2-white-s); }
  .create-honey2__footer-back:disabled { opacity: 0.4; cursor: not-allowed; }
  .create-honey2__next {
    padding: 0 3.2em;
    min-height: 4.4em;
    border-radius: var(--ch2-radius-xl);
    background: var(--ch2-text);
    color: var(--ch2-bg);
    border: none;
    font: inherit;
    font-size: 1.5em;
    font-weight: 600;
    cursor: pointer;
    min-width: 20em;
    max-width: 420px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.45);
    transition: transform 0.15s, box-shadow 0.15s;
  }
  .create-honey2__next:hover {
    transform: translateY(-1px);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.55);
  }

  /* Mobile: show footer Back + shrink Next so both fit the viewport. Back and
   * Next share the row 50/50 (equal size). Hide the header Back so there's a
   * single back affordance sitting next to Next. */
  @media (max-width: 767px) {
    .create-honey2__footer-back {
      display: inline-flex;
      flex: 1 1 0;
      min-width: 0;
      padding: 0 1.6em;
      font-size: 1.5em;
    }
    .create-honey2__back { display: none; }
    .create-honey2__next {
      flex: 1 1 0;
      min-width: 0;
      padding: 0 1.6em;
      min-height: 4.4em;
      font-size: 1.5em;
    }
  }

  /* ---------- Gallery picker (step 0, path=gallery) ---------- */
  .ch2-gallery-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.8em;
    width: 100%;
  }
  @media (min-width: 768px) {
    .ch2-gallery-grid { grid-template-columns: repeat(3, minmax(0, 180px)); gap: 1.2em; justify-content: center; }
  }

  .ch2-gallery-skeleton {
    aspect-ratio: 2 / 3;
    border-radius: var(--ch2-radius-m);
    background: linear-gradient(90deg, var(--ch2-white-xxs), var(--ch2-white-s), var(--ch2-white-xxs));
    background-size: 200% 100%;
    animation: ch2-skel 1.4s ease-in-out infinite;
  }
  @keyframes ch2-skel {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
  }

  .ch2-gallery-footer {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6em;
    margin-top: 1.2em;
  }
  .ch2-chip--load {
    align-self: center;
  }
  .ch2-gallery-empty {
    color: var(--ch2-text-muted);
    font-size: 1.2em;
    margin: 0;
  }

  .ch2-recap__preview--gallery .ch2-tile__img { background: transparent; }

  /* ===========================================================================
   * Step 10 — voice picker + share toggle
   * ========================================================================= */

  .ch2-step--voice {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ch2-gap-l);
  }

  .ch2-voice-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--ch2-gap-m);
    width: 100%;
    max-width: 90rem;
    padding: 0 var(--ch2-gap-l);
  }
  @media (max-width: 768px) {
    .ch2-voice-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }
  @media (max-width: 480px) {
    .ch2-voice-grid { grid-template-columns: 1fr; }
  }

  .ch2-voice-card {
    display: flex;
    flex-direction: column;
    gap: 0.6em;
    padding: 1em 1.2em;
    background: var(--ch2-surface);
    border: 2px solid var(--ch2-border);
    border-radius: var(--ch2-radius-m);
    color: var(--ch2-text);
    cursor: pointer;
    transition: border-color 0.18s ease, background 0.18s ease;
    text-align: left;
    overflow: hidden;
    min-width: 0;
  }
  .ch2-voice-card:hover { border-color: var(--ch2-white-s); }
  .ch2-voice-card {
    position: relative;
  }
  .ch2-voice-card.is-selected {
    border-color: transparent;
  }
  .ch2-voice-card.is-selected::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 2px;
    background: var(--ch2-sel-gradient);
    -webkit-mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    pointer-events: none;
  }
  .ch2-voice-card.is-selected .ch2-voice-check {
    color: var(--ch2-accent);
    border-color: var(--ch2-accent);
  }
  .ch2-voice-card.is-playing .ch2-voice-play {
    background: var(--ch2-accent);
    color: var(--ch2-bg);
  }

  .ch2-voice-card__row {
    display: flex;
    align-items: center;
    gap: 0.6em;
    min-width: 0;
  }
  .ch2-voice-card__name {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 1.2em;
    font-weight: 500;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .ch2-voice-play {
    width: 2.2em;
    height: 2.2em;
    border-radius: 999px;
    background: var(--ch2-white-xs);
    color: var(--ch2-text);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    transition: background 0.18s ease, color 0.18s ease;
  }
  .ch2-voice-check {
    width: 1.6em;
    height: 1.6em;
    border-radius: 0.4em;
    border: 2px solid var(--ch2-border);
    color: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    margin-left: auto;
    transition: color 0.18s ease, border-color 0.18s ease;
  }

  .ch2-voice-waveform {
    display: flex;
    align-items: flex-end;
    gap: 0.2em;
    height: 1.8em;
    opacity: 0.4;
  }
  .ch2-voice-waveform__bar {
    flex: 1;
    background: var(--ch2-text-muted);
    border-radius: 999px;
    height: 30%;
  }
  .ch2-voice-card.is-playing .ch2-voice-waveform { opacity: 1; }
  .ch2-voice-card.is-playing .ch2-voice-waveform__bar {
    background: var(--ch2-accent);
    animation: ch2-voice-wave 0.9s ease-in-out infinite;
  }
  .ch2-voice-card.is-playing .ch2-voice-waveform__bar:nth-child(2n) { animation-delay: 0.1s; }
  .ch2-voice-card.is-playing .ch2-voice-waveform__bar:nth-child(3n) { animation-delay: 0.2s; }
  .ch2-voice-card.is-playing .ch2-voice-waveform__bar:nth-child(5n) { animation-delay: 0.3s; }

  @keyframes ch2-voice-wave {
    0%, 100% { height: 30%; }
    50% { height: 100%; }
  }

  .ch2-share {
    display: inline-flex;
    align-items: center;
    gap: 0.8em;
    padding: 1em 1.6em;
    border: 1px solid var(--ch2-border);
    border-radius: var(--ch2-radius-xl);
    color: var(--ch2-text);
    cursor: pointer;
    user-select: none;
    transition: border-color 0.18s ease, background 0.18s ease;
  }
  .ch2-share:hover { border-color: var(--ch2-white-s); }
  .ch2-share__input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
  }
  .ch2-share__check {
    width: 1.8em;
    height: 1.8em;
    border-radius: 0.4em;
    border: 2px solid var(--ch2-border);
    color: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
  }
  .ch2-share__input:checked ~ .ch2-share__check {
    color: var(--ch2-bg);
    background: var(--ch2-accent);
    border-color: var(--ch2-accent);
  }
  .ch2-share__label {
    font-size: 1.4em;
    font-weight: 500;
  }

  /* Locked variant — free users see this in place of the checkbox; tapping
   * navigates to /pricing/ instead of toggling. */
  .ch2-share--locked {
    text-decoration: none;
    align-items: center;
    gap: 1em;
    background: color-mix(in oklab, var(--ch2-accent) 8%, transparent);
    border-color: color-mix(in oklab, var(--ch2-accent) 35%, var(--ch2-border));
  }
  .ch2-share--locked:hover {
    border-color: var(--ch2-accent);
    background: color-mix(in oklab, var(--ch2-accent) 14%, transparent);
  }
  .ch2-share__check--locked {
    color: var(--ch2-accent);
    border-color: color-mix(in oklab, var(--ch2-accent) 60%, var(--ch2-border));
    background: transparent;
  }
  .ch2-share__copy {
    display: inline-flex;
    flex-direction: column;
    gap: 0.2em;
    line-height: 1.2;
  }
  .ch2-share__upsell {
    font-size: 1.15em;
    font-weight: 500;
    color: var(--ch2-accent);
  }

  /* ===========================================================================
   * Face / body review screens (swapped in by createBotFlow)
   * ========================================================================= */

  .ch2-step--review {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ch2-gap-l);
    padding: var(--ch2-gap-l);
  }

  .ch2-step__title {
    font-size: 2em;
    font-weight: 600;
    text-align: center;
    margin: 0;
  }
  .ch2-step__subtitle {
    color: var(--ch2-text-muted);
    text-align: center;
    margin: 0;
    font-size: 1.4em;
  }

  .ch2-review__frame {
    position: relative;
    width: 100%;
    max-width: 36em;
    aspect-ratio: 3 / 4;
    border-radius: var(--ch2-radius-m);
    overflow: hidden;
    background: var(--ch2-surface);
    border: 2px solid var(--ch2-accent);
  }
  .ch2-review__loader {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1em;
    color: var(--ch2-text);
    background: var(--ch2-bg);
  }
  .ch2-review__loader-label {
    font-size: 1.4em;
    color: var(--ch2-text);
    font-weight: 500;
  }
  .ch2-review__loader-percent {
    font-size: 2.4em;
    font-weight: 700;
    color: var(--ch2-text);
    line-height: 1;
  }
  .ch2-review__loader[hidden] { display: none; }
  .ch2-review__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
  }
  .ch2-review__img[hidden] { display: none; }
  .ch2-review__final-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.8em;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(8px);
    color: var(--ch2-text);
    z-index: 5;
  }
  .ch2-review__final-overlay[hidden] { display: none; }
  .ch2-review__spinner {
    animation: ch2-spin 1s linear infinite;
    color: var(--ch2-accent);
  }
  .ch2-review__final-label {
    font-size: 1.4em;
    font-weight: 500;
  }
  @keyframes ch2-spin { to { transform: rotate(360deg); } }

  .ch2-review__actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ch2-gap-m);
    width: 100%;
    max-width: 28em;
  }

  .ch2-btn {
    width: 100%;
    min-height: 4.4em;
    padding: 0 1.6em;
    border-radius: var(--ch2-radius-xl);
    font-size: 1.4em;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.6em;
    cursor: pointer;
    border: 1px solid transparent;
    transition: opacity 0.18s ease, background 0.18s ease, color 0.18s ease;
  }
  .ch2-btn:disabled { opacity: 0.45; cursor: not-allowed; }
  .ch2-btn--regen {
    background: transparent;
    color: var(--ch2-text);
    border-color: var(--ch2-border);
  }
  .ch2-btn--regen:hover:not(:disabled) {
    background: var(--ch2-white-xs);
  }
  .ch2-btn--primary {
    background: var(--ch2-text);
    color: var(--ch2-bg);
  }
  .ch2-btn--ghost {
    background: transparent;
    color: var(--ch2-text);
    border-color: var(--ch2-border);
  }
  .ch2-btn__badge {
    background: var(--ch2-white-xs);
    padding: 0.2em 0.6em;
    border-radius: 999px;
    font-size: 0.85em;
    font-weight: 500;
  }
  .ch2-btn__badge.is-paid {
    background: theme('colors.amber.500');
    color: var(--ch2-bg);
    display: inline-flex;
    align-items: center;
    gap: 0.25em;
  }
  .ch2-btn__badge-icon {
    width: 1.1em;
    height: 1.1em;
    flex-shrink: 0;
    display: inline-block;
    vertical-align: middle;
  }

  /* ---------- Per-phase extra-prompt edit affordance (review screens) ---- */
  /* Regenerate + Edit share the row 50/50 — same min-height, font, padding
   * inherited from `.ch2-btn`. */
  .ch2-review__actions-row {
    display: flex;
    align-items: stretch;
    gap: 0.8em;
    width: 100%;
  }
  .ch2-review__actions-row > .ch2-btn {
    flex: 1 1 0;
    width: auto;
    min-width: 0;
  }
  .ch2-btn--edit {
    background: transparent;
    color: var(--ch2-text);
    border-color: var(--ch2-border);
    position: relative;
  }
  .ch2-btn--edit:hover:not(:disabled) {
    background: var(--ch2-white-xs);
  }
  .ch2-btn--edit[hidden] { display: none; }
  /* Filled dot in the top-right corner when the user has saved a non-empty
   * extra prompt for this phase — gives a quiet visual cue that an edit is
   * active without re-opening the modal. */
  .ch2-btn--has-extra::after {
    content: '';
    position: absolute;
    top: 0.5em;
    right: 0.5em;
    width: 0.7em;
    height: 0.7em;
    border-radius: 999px;
    background: var(--ch2-accent);
    box-shadow: 0 0 0 2px var(--ch2-bg);
  }

  /* ---------- Shared edit-prompt modal (face + body review) -------------- */
  .ch2-modal {
    position: fixed;
    inset: 0;
    z-index: 300;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.6em;
  }
  .ch2-modal[hidden] { display: none; }
  .ch2-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.72);
    backdrop-filter: blur(2px);
  }
  .ch2-modal__content {
    position: relative;
    width: 90%;
    max-width: 480px;
    max-height: 80dvh;
    display: flex;
    flex-direction: column;
    background: var(--ch2-bg);
    color: var(--ch2-text);
    border: 1px solid var(--ch2-border);
    border-radius: var(--ch2-radius-xl);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55);
    overflow: hidden;
  }
  .ch2-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8em;
    padding: 1.4em 1.6em 0.8em;
    border-bottom: 1px solid var(--ch2-border);
  }
  .ch2-modal__title {
    margin: 0;
    font-size: 1.6em;
    font-weight: 600;
    line-height: 1.3;
  }
  .ch2-modal__close {
    background: transparent;
    border: none;
    color: var(--ch2-text-muted);
    cursor: pointer;
    padding: 0.4em;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    transition: background 0.18s ease, color 0.18s ease;
  }
  .ch2-modal__close:hover { background: var(--ch2-white-xs); color: var(--ch2-text); }
  .ch2-modal__body {
    padding: 1.2em 1.6em;
    overflow-y: auto;
    flex: 1 1 auto;
  }
  .ch2-modal__hint {
    margin: 0 0 0.8em;
    font-size: 1.3em;
    line-height: 1.4;
    color: var(--ch2-text-muted);
  }
  .ch2-modal__textarea {
    width: 100%;
    min-height: 6.5em;
    padding: 0.8em 1em;
    background: var(--ch2-white-xs);
    color: var(--ch2-text);
    border: 1px solid var(--ch2-border);
    border-radius: var(--ch2-radius-m);
    font: inherit;
    font-size: 1.4em;
    line-height: 1.45;
    resize: vertical;
  }
  .ch2-modal__textarea:focus {
    outline: none;
    border-color: var(--ch2-accent);
    box-shadow: 0 0 0 2px rgba(250, 61, 114, 0.25);
  }
  .ch2-modal__counter {
    margin-top: 0.4em;
    font-size: 1.2em;
    text-align: right;
    color: var(--ch2-text-muted);
    line-height: 1;
  }
  .ch2-modal__counter.is-warning { color: theme('colors.amber.500'); }
  .ch2-modal__counter.is-danger { color: theme('colors.red.500'); font-weight: 600; }
  .ch2-modal__error {
    margin-top: 0.8em;
    padding: 0.6em 0.8em;
    background: rgba(239, 68, 68, 0.12);
    border: 1px solid rgba(239, 68, 68, 0.4);
    border-radius: var(--ch2-radius-m);
    color: theme('colors.red.400');
    font-size: 1.3em;
    line-height: 1.4;
  }
  .ch2-modal__footer {
    display: flex;
    gap: 0.8em;
    padding: 1em 1.6em 1.4em;
    border-top: 1px solid var(--ch2-border);
  }
  .ch2-modal__btn {
    flex: 1 1 0;
    min-height: 4em;
    font-size: 1.4em;
  }
  /* Lock body scroll while the prompt modal is open (mobile keyboard can
   * otherwise scroll the wizard underneath). */
  body.ch2-modal-open { overflow: hidden; }

  /* ===========================================================================
   * Field error + transient toast (input protection feedback)
   * ========================================================================= */

  .ch2-char-counter {
    display: block;
    margin-top: 0.4em;
    font-size: 1.2em;
    text-align: right;
    line-height: 1;
  }
  /* The boolean `hidden` attribute must beat the component-layer `display: block`
   * above; without `!important` the component rule wins (same specificity, later
   * source order). Used by the name counter on step 6 to stay invisible until
   * the user crosses NAME_COUNTER_THRESHOLD. */
  .ch2-char-counter[hidden] { display: none !important; }
  /* Name counter sits directly under the input, right-aligned with the dice
   * shuffle button (which sits at `right: 0.6em` of the 420px input wrap). The
   * counter inherits the same 420px-max + auto margins so it shares the wrap's
   * horizontal alignment, then nudges its right edge to the dice's column. */
  [data-ch2-name-counter] {
    max-width: 420px;
    width: 100%;
    margin: 0 auto;
    text-align: right;
    padding-right: 0.6em;
  }

  .ch2-field-error {
    margin-top: 0.6em;
    color: theme('colors.red.400');
    font-size: 1.5em;
    font-weight: 600;
    line-height: 1.3;
    text-align: center;
  }
  /* Inside the inline age wrapper, place error to the right instead of below. */
  .ch2-input-wrap--inline .ch2-field-error {
    margin-top: 0;
    font-size: 1.6em;
    white-space: nowrap;
  }
  .ch2-input.is-invalid,
  input.is-invalid {
    border-color: theme('colors.red.500') !important;
    box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.25);
  }

  .ch2-toast {
    position: fixed;
    top: 2rem;
    left: 50%;
    transform: translateX(-50%) translateY(-2rem);
    padding: 1.2rem 2rem;
    min-width: 280px;
    max-width: 90vw;
    background: #2a2a2a;
    color: var(--ch2-text);
    border: 2px solid rgba(255, 255, 255, 0.2);
    border-radius: 1.2rem;
    font-size: 1.4rem;
    font-weight: 500;
    line-height: 1.4;
    text-align: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s ease, transform 0.22s ease;
    z-index: 200;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.06);
  }
  /* ---------- Advanced collapsible (step 8 background story) ---------- */
  .ch2-advanced { margin-top: 2em; }
  .ch2-advanced__toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    background: none;
    border: none;
    color: var(--ch2-text-muted);
    font: inherit;
    font-size: 1.3em;
    cursor: pointer;
    padding: 0.4em 0;
  }
  .ch2-advanced__toggle:hover { color: var(--ch2-text); }
  .ch2-advanced__chevron {
    display: inline-block;
    transition: transform 0.18s ease;
  }
  .ch2-advanced__toggle.is-open .ch2-advanced__chevron { transform: rotate(180deg); }
  .ch2-advanced__panel { margin-top: 1em; }
  .ch2-advanced__panel.hidden { display: none; }
  .ch2-label--sub {
    font-size: 1.2em;
    margin-bottom: 0.6em;
    color: var(--ch2-text-muted);
  }
  /* Textarea variant of .ch2-input — drops the single-line-input sizing
     (fixed height, icon/action padding, centered 420px wrap) so the field
     fills its panel and reads as a multi-line block. */
  .ch2-advanced__panel .ch2-input-wrap {
    max-width: none;
    margin: 0;
    display: block;
  }
  .ch2-input--textarea {
    display: block;
    width: 100%;
    height: auto;
    min-height: 8em;
    padding: 1em 1.2em;
    line-height: 1.4;
    resize: vertical;
    font-family: inherit;
  }

  /* iOS Safari auto-zooms into any focused form field whose computed font-size
   * is below 16px. The wizard's 10px-base + em-everywhere scale produces 13–14px
   * text on inputs (.ch2-input = 1.4em, --number = 1.3em, --textarea inherits),
   * which triggers the unwanted zoom on every focus. Bump inputs to a hard 16px
   * on mobile only — desktop sizing is unchanged so the visual scale stays
   * identical to design. Using `font-size` in px (not em) intentionally so the
   * 10px parent doesn't scale it back down. */
  @media (max-width: 767px) {
    .ch2-input,
    .ch2-input--number,
    .ch2-input--textarea {
      font-size: 16px;
    }

  }
  .ch2-advanced__meta {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1em;
    margin-top: 0.6em;
  }
  .ch2-advanced__notice {
    font-size: 1.1em;
    color: var(--ch2-text-muted);
    line-height: 1.35;
    margin: 0;
    flex: 1 1 auto;
  }
  .ch2-advanced__meta .ch2-char-counter {
    margin-top: 0;
    flex: 0 0 auto;
    white-space: nowrap;
  }

  .ch2-toast.is-visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }

  .ch2-toast--moderation {
    max-width: 46rem;
    padding: 1.4rem 2rem;
    border-color: rgba(250, 61, 114, 0.55);
    background: #2a1a1f;
  }

  .ch2-toast--error {
    max-width: 46rem;
    padding: 1.3rem 2rem;
    border-color: rgba(239, 68, 68, 0.55);
    background: #2a1a1a;
  }

  /* ---------- Admin debug FAB (test body generation) ------------------- */
  /* Floating action button visible only to staff/superuser. Triggers a
   * face→body generation against the v1 endpoint using the current URL
   * selections, then shows the body image in a modal for visual QA. */
  .ch2-debug-fab {
    position: fixed;
    right: 1.6rem;
    bottom: 9rem;
    z-index: 250;
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    padding: 0.9em 1.2em;
    background: theme('colors.amber.500');
    color: #1a1207;
    border: 2px solid rgba(0, 0, 0, 0.25);
    border-radius: 999px;
    font: inherit;
    font-size: 1.25em;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 6px 22px rgba(0, 0, 0, 0.45);
    transition: transform 0.12s ease, box-shadow 0.12s ease, opacity 0.12s ease;
  }
  .ch2-debug-fab:hover:not(:disabled) {
    transform: translateY(-2px);
    box-shadow: 0 8px 26px rgba(0, 0, 0, 0.55);
  }
  .ch2-debug-fab:disabled { opacity: 0.6; cursor: progress; }
  @media (max-width: 575px) {
    .ch2-debug-fab {
      bottom: 11rem;
      right: 1.2rem;
      font-size: 1.15em;
      padding: 0.7em 1em;
    }
    .ch2-debug-fab span { display: none; }
  }

  .ch2-debug-modal .ch2-modal__content { max-width: 560px; }
  .ch2-debug-modal__image-wrap {
    position: relative;
    width: 100%;
    aspect-ratio: 2 / 3;
    background: var(--ch2-white-xs);
    border-radius: 0.8em;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .ch2-debug-modal__loader {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.8em;
    color: var(--ch2-text-muted);
    font-size: 1.2em;
    text-align: center;
    padding: 1em;
  }
  .ch2-debug-modal__loader[hidden] { display: none; }
  .ch2-debug-modal__img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
  }
  .ch2-debug-modal__img[hidden] { display: none; }

}
