/* scribbly-funnel.css
 * Modal/full-screen overlay for the embedded preview funnel.
 *
 * Two viewports:
 *   - Desktop (>= 900px): centered iframe with dim backdrop. Iframe is
 *     sized large enough to show the funnel's own desktop modal styling.
 *   - Mobile (< 900px): full-screen takeover. Backdrop hidden, iframe
 *     fills the viewport edge-to-edge.
 *
 * Z-index sits above any sticky header / chat bubble (Shopify themes
 * commonly use 100-1000); 2147483000 leaves headroom for live-chat
 * widgets that intentionally claim Number.MAX_SAFE_INTEGER-ish values.
 */

/* Hidden by default. JS toggles `.is-open`. We hide via opacity +
 * visibility (rather than display:none) so the open/close can ride a
 * smooth 200ms fade — display can't be transitioned. visibility flips
 * immediately on open and after the fade-out delay on close so the
 * invisible root never captures clicks. */
.scribbly-funnel-root {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 200ms ease, visibility 0s 200ms;
}
.scribbly-funnel-root.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 200ms ease, visibility 0s 0s;
}

/* Lock body scroll while the modal is open so the storefront page
 * underneath doesn't scroll behind the backdrop. The class is added
 * to <html> not <body> because some themes put their scroll context
 * on the html element (sticky-header tricks). */
html.scribbly-funnel-locked,
html.scribbly-funnel-locked body {
  overflow: hidden;
}

.scribbly-funnel-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
  /* No backdrop-filter blur. The funnel iframe sits inside its own
   * compositor layer, and Chrome/Safari don't propagate the parent's
   * backdrop-filter through that layer. With the bookshop's .bs-root
   * transparent (so the inner card's drop shadow lands on the parent
   * backdrop, not on a cream rectangle), enabling blur here makes the
   * storefront look crisp-but-tinted inside the iframe and blurry-and-
   * tinted outside it -- the iframe boundary reads as a phantom dark
   * rectangle. Plain tint without blur gives a uniform dim across the
   * full viewport, which is what the design wants. */
}

.scribbly-funnel-stage {
  position: relative;
  width: min(1100px, 95vw);
  height: min(800px, 90vh);
  /* Stage sizes the iframe but stays visually invisible — the funnel's
     own cream modal card provides the rounded corners and drop shadow,
     so painting another card here would just show as a frame around it. */
  background: transparent;
  /* No transition on width/height: when an in-iframe overlay opens, the
   * stage snaps from modal-sized to fullscreen instantly. Animating it
   * (which we used to do at 200ms ease) made the bookshop's inner scrim
   * visibly grow outward from the center as the iframe geometry stretched,
   * which read as "the dim is expanding from the middle" rather than
   * fading in. Snapping is invisible because the stage + iframe are both
   * background:transparent and the bookshop card inside is centered, so
   * growing the bounding box paints nothing new at the edges. The inner
   * scrim's 160ms opacity fade-in is then the only visible animation. */
}

/* When the bookshop opens an in-iframe overlay (e.g. the dedication
 * upsell), it postMessages 'scribbly:overlay' { state: 'open' } and JS
 * adds .is-overlay-active here. The stage stretches to fill the
 * browser so the iframe's own .bs-overlay scrim — which uses
 * position: fixed; inset: 0 inside the iframe — actually spans the
 * whole viewport rather than just the modal-sized iframe rectangle.
 * The bookshop card inside is max-width 960px and centered, so it
 * stays roughly where it was: only the iframe's transparent edges
 * grow outward, and the dim layer extends with them. */
.scribbly-funnel-root.is-overlay-active .scribbly-funnel-stage {
  width: 100vw;
  height: 100vh;
  height: 100dvh;
}

.scribbly-funnel-iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  background: transparent;
  /* Keep the iframe invisible until its document has loaded so the
   * customer doesn't see a white canvas before React paints the cream
   * modal card. JS adds .is-loaded on the iframe's `load` event (with a
   * 1.5s safety fallback). The backdrop fades in independently via the
   * root's opacity transition above, so the dim layer is in place before
   * the modal content cross-fades over it. */
  opacity: 0;
  transition: opacity 200ms ease;
}
.scribbly-funnel-iframe.is-loaded {
  opacity: 1;
}

/* Mobile: full-screen takeover. */
@media (max-width: 899px) {
  .scribbly-funnel-backdrop {
    display: none;
  }
  .scribbly-funnel-stage {
    width: 100vw;
    height: 100vh;
    /* Use the small/dynamic viewport units where supported so iOS
     * Safari's URL bar doesn't clip the bottom of the iframe. Falls
     * back to vh on older browsers. */
    height: 100dvh;
    border-radius: 0;
    box-shadow: none;
    /* Mobile has no backdrop, so without a stage color the iframe fade-in
     * would cross-fade from the storefront page underneath to the cream
     * modal — jarring on bright product pages. Painting the stage with the
     * funnel's own --pf-bg cream means the iframe fades cream-to-cream once
     * the storefront is covered. Desktop keeps stage transparent so the
     * inner card's drop shadow lands cleanly on the dim backdrop. */
    background: #f2f4db;
  }
}

/* ─── Resume floating card (Figma 71-14218 / 71-14247) ───
 * Persistent card painted on the storefront once a customer has stepped
 * out of their personalized preview / bookshop. Two visual variants:
 *
 *   .scribbly-resume-card--generating   "🎨 Illustrating Eamon…" + green bar
 *   .scribbly-resume-card--collection   "{Name}'s 📚Collection"
 *
 * Both share the same shell: white card, photo on the left (the kid's
 * uploaded photo from Supabase storage), content column on the right
 * (heading + optional progress + big blue Open button). A small dismiss
 * × sits in the top-right corner — not in the Figma frame but customers
 * need an escape hatch.
 *
 * Z-index sits below the funnel modal (2147483000) but above typical
 * theme elements; chat widgets that claim higher will overlap, which is
 * fine — the card is a low-priority resurfacing affordance.
 */
/* Stack: the wrapper that holds N cards. Pinned to the bottom-right of
 * the viewport, with cards flowing column-reverse so the newest kid (DOM
 * index 0) sits visually at the top of the stack. */
.scribbly-resume-stack {
  position: fixed;
  right: 16px;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 88px);
  z-index: 2147482000;
  display: flex;
  flex-direction: column-reverse;
  gap: 12px;
  /* Don't capture clicks on the empty space between/around cards — the
   * page underneath should remain interactive. Each card opts back in. */
  pointer-events: none;
}
.scribbly-resume-stack > * { pointer-events: auto; }

/* Hide the resume stack while the funnel modal is open — it would
 * otherwise sit on top of the modal's dim backdrop at z-index ~2.1B
 * (higher than the modal's own root). Lindsey QA 2026-05-12: "the
 * mini card is visible behind the modal." html.scribbly-funnel-locked
 * is added by open() and removed by close(); covers both the visible
 * fade-out and the close-then-reopen cycle. */
html.scribbly-funnel-locked .scribbly-resume-stack {
  display: none;
}

.scribbly-resume-card {
  /* Position is provided by the .scribbly-resume-stack wrapper now; cards
   * are static within the flex column. Float above any bottom-pinned UI
   * still applies (the wrapper handles bottom + safe-area). */
  display: flex;
  align-items: stretch;
  gap: 16px;
  padding: 12px 16px 12px 12px;
  width: 380px;
  max-width: calc(100vw - 32px);
  background: #ffffff;
  color: #292929;
  border-radius: 28px;
  box-shadow: 0 8px 32px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.08);
  font-family: 'Roca', 'Playfair Display', Georgia, 'Times New Roman', serif;
  font-size: 16px;
  line-height: 1.3;
  position: relative; /* anchor for the absolutely-positioned dismiss × */
}

/* Slide-in animation runs ONLY on the first paint of the session. The
 * Shopify storefront does full page reloads on every nav, so without this
 * gate the card would re-animate on every page — perceived as a flash.
 * The script adds .scribbly-resume-card--enter only when sessionStorage
 * doesn't have the 'shown' flag yet. */
.scribbly-resume-card--enter {
  animation: scribbly-resume-card-in 280ms ease-out;
}

@keyframes scribbly-resume-card-in {
  from { transform: translateY(12px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}

/* Photo column — Figma puts a 162×171 photo on the left at full card
 * width 380. Scaled here so the card stays compact on storefront pages
 * without dominating the viewport. Aspect kept slightly tall (5:6) to
 * match the Figma frame. */
.scribbly-resume-card__photo {
  flex: 0 0 auto;
  width: 110px;
  height: 132px;
  border-radius: 20px;
  overflow: hidden;
  background: #f2f4db; /* cream placeholder until the photo loads */
  position: relative;
}
.scribbly-resume-card__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Placeholder state — no photo URL yet (upload still in flight). The
 * cream square + a subtle 'photo' icon hint that an image will land. */
.scribbly-resume-card__photo--placeholder::after {
  content: "🖼️";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  opacity: 0.35;
}

.scribbly-resume-card__right {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 0;
}

/* Generating heading: "🎨 Illustrating Eamon…" in italic Roca Bold,
 * left-aligned, single line. Mirrors the Figma's 16px Bold Italic. */
.scribbly-resume-card__heading {
  font-style: italic;
  font-weight: 700;
  font-size: 16px;
  line-height: 1.2;
  color: #000;
  /* Truncate long names so the layout doesn't wrap to 3 lines on
   * "Konstantinopoulos…" — show as much as fits, then ellipsis. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Mirrors .pf-progress__bar in src/preview-funnel/styles.css so the
 * resume card's bar reads as a continuation of the in-funnel one.
 * Figma uses 11px height, fully rounded, #009463 fill. */
.scribbly-resume-card__bar {
  position: relative;
  height: 11px;
  width: 100%;
  background: #fff;
  border: 1px solid #dadada;
  border-radius: 100px;
  overflow: hidden;
}

.scribbly-resume-card__bar-fill {
  height: 100%;
  width: 0;
  background: #009463;
  border-radius: 100px;
  transition: width 600ms ease;
}

/* Collection heading: "{Name}'s" / "📚 Collection" — two lines, centered,
 * 21px Roca Bold Italic per Figma frame 71-14247. */
.scribbly-resume-card__collection {
  font-style: italic;
  font-weight: 700;
  font-size: 21px;
  line-height: 1.15;
  color: #000;
  text-align: center;
}
.scribbly-resume-card__collection > div {
  /* Truncate gracefully on extreme names. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Just-flipped-to-ready variant: brief shadow pulse to catch the eye.
 * Class is added once per session-celebration (sessionStorage gate in JS)
 * so the pulse fires on the actual transition, not on every page-load.
 * If the card is also entering for the first time this session, the
 * shorthand below combines both animations; otherwise pulse alone. */
.scribbly-resume-card--just-ready {
  animation: scribbly-resume-card-ready-pulse 1200ms ease-out 1;
}
.scribbly-resume-card--enter.scribbly-resume-card--just-ready {
  animation:
    scribbly-resume-card-in 280ms ease-out,
    scribbly-resume-card-ready-pulse 1200ms ease-out 1;
}

@keyframes scribbly-resume-card-ready-pulse {
  0%   { box-shadow: 0 8px 32px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.08); }
  35%  { box-shadow: 0 8px 32px rgba(0, 148, 99, 0.55),  0 0 0 3px rgba(0, 148, 99, 0.30); }
  100% { box-shadow: 0 8px 32px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.08); }
}

/* Big blue Open button — Figma is 192×62 with 24px Roca Italic white text.
 * Width auto-fills the right column so it tracks the card's responsive
 * width without a hardcoded 192. */
.scribbly-resume-card__cta {
  flex: 0 0 auto;
  background: #3158ec;
  color: #fff;
  border: none;
  border-radius: 80px;
  padding: 14px 28px;
  width: 100%;
  font-family: inherit;
  font-style: italic;
  font-size: 22px;
  font-weight: 400;
  line-height: 1;
  cursor: pointer;
  transition: transform 100ms ease, background 100ms ease;
}
.scribbly-resume-card__cta:hover { background: #1f3fb8; transform: scale(1.02); }
.scribbly-resume-card__cta:focus-visible {
  outline: 2px solid #1f3fb8;
  outline-offset: 2px;
}

/* Dismiss × — small, top-right, intentionally low-prominence. Not in the
 * Figma frame but customers need a way to permanently close the card. */
.scribbly-resume-card__dismiss {
  position: absolute;
  top: 6px;
  right: 8px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: #9a9a9a;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 100ms ease, color 100ms ease;
}
.scribbly-resume-card__dismiss:hover { background: rgba(0, 0, 0, 0.06); color: #292929; }
.scribbly-resume-card__dismiss:focus-visible {
  outline: 2px solid #3158ec;
  outline-offset: 2px;
}

/* Mobile: span more of the viewport, shrink the photo a touch so the
 * right column has room for the headline + button. The stack itself is
 * what's pinned to the corner; cards inside fill the available width. */
@media (max-width: 599px) {
  .scribbly-resume-stack {
    left: 12px;
    right: 12px;
  }
  .scribbly-resume-card {
    width: auto;
    max-width: none;
    gap: 12px;
    padding: 10px 14px 10px 10px;
  }
  .scribbly-resume-card__photo {
    width: 96px;
    height: 116px;
    border-radius: 16px;
  }
  .scribbly-resume-card__cta {
    font-size: 20px;
    padding: 12px 22px;
  }
  .scribbly-resume-card__collection {
    font-size: 19px;
  }
}

/* Mobile anchor pill — when 2+ cards exist on a small screen, only paint
 * the topmost card by default. The script adds an extra "anchor" element
 * (.scribbly-resume-stack__more) that summarises the count of hidden
 * cards and toggles .scribbly-resume-stack--expanded on tap.
 *
 * Below 480px, even a single card eats much of the viewport — stacking
 * 3 would cover the page. The collapsed state shows just the newest kid
 * + a "+ N more" chip; tapping the chip expands the stack. */
.scribbly-resume-stack__more {
  display: none; /* hidden on desktop; the script reveals it via media query */
}
@media (max-width: 479px) {
  .scribbly-resume-stack--has-overflow .scribbly-resume-stack__more {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    align-self: flex-end;
    padding: 8px 14px;
    background: #ffffff;
    color: #1f3fb8;
    border: 1px solid rgba(31, 63, 184, 0.2);
    border-radius: 999px;
    box-shadow: 0 4px 16px rgba(15, 23, 42, 0.12);
    font-family: 'Roca', 'Playfair Display', Georgia, 'Times New Roman', serif;
    font-size: 14px;
    cursor: pointer;
  }
  /* When collapsed: hide every card except the first (newest) so the
   * customer sees only the topmost card + the "+ N more" chip. */
  .scribbly-resume-stack--has-overflow:not(.scribbly-resume-stack--expanded)
    .scribbly-resume-card:not([data-stack-position="0"]) {
    display: none;
  }
  /* When expanded: show all cards in column-reverse (newest at top), and
   * style the chip as a "Show less" affordance. */
  .scribbly-resume-stack--has-overflow.scribbly-resume-stack--expanded
    .scribbly-resume-stack__more {
    background: #1f3fb8;
    color: #ffffff;
    border-color: transparent;
  }
}

/* ─── Cap toast ───
 * Shown when the customer hits the MAX_KIDS in-flight-previews limit and
 * clicks any funnel CTA. Pinned bottom-center with high z-index so it
 * floats above the resume-card stack and any theme footers. Auto-
 * dismisses after CAP_TOAST_TIMEOUT_MS (see JS) or on the × button.
 * Styling mirrors the resume-card family — white pill, soft shadow,
 * serif body — so it feels like part of the same surface.
 */
.scribbly-cap-toast {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 32px);
  transform: translateX(-50%);
  z-index: 2147482500; /* above resume-stack (2147482000), below funnel modal (2147483000) */
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px 14px 20px;
  max-width: calc(100vw - 32px);
  width: 420px;
  background: #ffffff;
  color: #292929;
  border-radius: 28px;
  box-shadow: 0 8px 32px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.08);
  font-family: 'Roca', 'Playfair Display', Georgia, 'Times New Roman', serif;
  font-size: 15px;
  line-height: 1.35;
  animation: scribbly-cap-toast-in 240ms ease-out;
}

@keyframes scribbly-cap-toast-in {
  from { transform: translate(-50%, 12px); opacity: 0; }
  to   { transform: translate(-50%, 0);    opacity: 1; }
}

.scribbly-cap-toast__body {
  flex: 1;
}

.scribbly-cap-toast__dismiss {
  flex: 0 0 auto;
  appearance: none;
  border: none;
  background: transparent;
  color: #6b6a6a;
  font-size: 24px;
  line-height: 1;
  padding: 4px 8px;
  cursor: pointer;
  font-family: inherit;
}

.scribbly-cap-toast__dismiss:hover,
.scribbly-cap-toast__dismiss:focus-visible {
  color: #1f3fb8;
}
