/*
 * The /try flow.
 *
 * Every colour here is one of the page's tokens, read through var() with a
 * literal fallback: the theme's main.css defines them on :root, and the
 * fallback is what keeps this readable if the plugin is ever used under a
 * different theme. There are no new hues - the palette is one blue at
 * different depths, and a second one introduced here would be visible
 * immediately.
 *
 * Mobile first, because most uploads will be phone camera photos. The one
 * breakpoint matches the landing page's (900px).
 */

/* Changed 2026-08-17: dropped the "100vh minus header" calc. It required
   staying in sync with --header-h (published by the theme's app.js) and,
   underneath it, the page's own fixed paddings (main.memorink-page-body's
   8px+40px from page.php, .memorink-page's 112px bottom padding from
   header.php - there to clear the *landing page's* sticky CTA, which this
   page never has). Getting any one of those wrong added real extra scroll on
   top of a normal page rather than just mis-centering something.
   Simpler: .memorink-page - the site's own page container - becomes the one
   flex column, sized to at least the viewport. The sticky header takes its
   natural height and main takes whatever is left (flex: 1), so the flow
   centers inside that leftover space instead of a number anyone has to
   compute. A screen taller than the available height still grows past it and
   scrolls rather than clipping - flex items don't shrink below their
   content's natural height by default. Safe unscoped because this stylesheet
   only loads on the page that has the shortcode (see
   memorink_preview_enqueue()). */
.memorink-page {
  padding-bottom: 0 !important;
  /* 100vh is the *largest* possible viewport on mobile Chrome/Safari - the
     height with the address bar collapsed - not what's on screen on first
     paint. Sizing to it means the page is taller than the visible area until
     the visitor scrolls and the bar hides, which reads as empty scroll space
     for no reason. 100svh (the *smallest* possible viewport, i.e. bar always
     assumed visible) fixes that on first paint - it never overreports.
     100dvh was tried first and reverted: it's meant to track the bar live,
     but mobile Safari has a known bug where dvh reports the *large* size
     until the first scroll/resize event fires, so on load it behaves exactly
     like plain vh and still overflows. The landing page's hero
     (section-hero.php) already uses svh for the same reason - match it here
     rather than re-introducing the dvh bug. The 100vh line stays only as the
     fallback for browsers with neither unit. */
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

/* WordPress's own admin toolbar - visible only to a logged-in visitor who
   hasn't turned it off, never to a real customer - injects
   `html { margin-top: 32px !important }` (46px under 782px, its own
   breakpoint) ahead of everything else on the page. That sits *above* this
   flex column, so a page already sized to exactly one viewport becomes one
   viewport plus the toolbar's height - the extra sliver of scroll a logged-in
   admin sees and a visitor never does. WP publishes the toolbar's current
   height as --wp-admin--admin-bar--height (it flips 32px/46px at 782px on
   its own), so reading it back here tracks both sizes without a second
   breakpoint of our own. Scoped to body.admin-bar, the class WP only adds
   when the toolbar is actually showing. */
body.admin-bar .memorink-page {
  min-height: calc(100vh - var(--wp-admin--admin-bar--height, 0px));
  min-height: calc(100svh - var(--wp-admin--admin-bar--height, 0px));
}

main.memorink-page-body {
  padding: 0 !important;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.mrp {
  max-width: 430px;
  width: 100%;
  margin: 0 auto;
  padding: 8px 24px 10px;
  box-sizing: border-box;
  font-family: 'Noto Sans', sans-serif;
  color: var(--ink-soft, #33405a);
  line-height: 1.5;
  /* Fills main's height exactly (flex:1, one child) rather than adding to
     it - .mrp-screen below does the same one level down, so everything
     inside just fills whatever main was given. */
  flex: 1;
  display: flex;
  flex-direction: column;
  /* Each step scrolls the flow back to the top, and the site header is sticky -
     so without this the heading of whichever screen just appeared lands
     underneath it. --header-h is published by the theme's app.js; the fallback
     is the header's rendered height, used before that runs. */
  scroll-margin-top: calc(var(--header-h, 53px) + 14px);
}

.mrp *,
.mrp *::before,
.mrp *::after { box-sizing: border-box; }

/* Several classes below set an explicit `display`, which beats the UA's
   [hidden] rule. The flow hides things by setting the attribute, so this has to
   win - without it, hiding a screen or a form field silently does nothing. */
.mrp [hidden] { display: none !important; }

.mrp-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* -------------------------------- screens ------------------------------- */

/*
 * The flow is centred, and the frame is the axis. Type is centred over it and
 * the controls sit under it in one column, so the whole screen reads as one
 * object with things above and below it - which is the point the copy is
 * making. Forms are the exception and opt back out below: a centred label over
 * a full-width input has nothing to align to.
 */
.mrp-screen[hidden] { display: none; }

/* Changed 2026-08-17, fixed same day: every screen fills the viewport rather
   than just the space its own content needs - "100vh" here is the whole
   screen's worth including the sticky header. The actual 100vh math lives on
   main.memorink-page-body above now, not here: flex: 1 just makes this
   screen fill whatever height .mrp (itself filling main) has, so there is
   only one place computing "100vh minus header" instead of three stacking
   their own slices on top of it (that was the original bug - see the note
   above main.memorink-page-body). A screen taller than the available height
   (the finish screen on a short phone) still grows past it and scrolls
   rather than clipping - flex items don't shrink below their content's
   natural height by default, so "grow, never clip" still holds. */
.mrp-screen:not([hidden]) {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.mrp-h1 {
  font-size: 27px;
  line-height: 1.2;
  font-weight: 700;
  color: var(--ink, #16233a);
  margin: 0 0 10px;
  letter-spacing: -0.015em;
  text-align: center;
}

.mrp-h2 {
  font-size: 25px;
  line-height: 1.22;
  font-weight: 700;
  color: var(--ink, #16233a);
  margin: 0 0 18px;
  letter-spacing: -0.015em;
  text-align: center;
}

.mrp-sub {
  font-size: 15px;
  color: var(--ink-soft, #33405a);
  margin: 0 auto 22px;
  max-width: 38ch;   /* Two lines at the column's width, not three. */
  text-align: center;
}

/* Only used on the finish screen, under the mockup - tightened 2026-08-17
   along with the mockup and throbber above it, so that whole group reads as
   one compact block above the finish picker rather than a screen's worth of
   space on its own. Shrunk and pulled closer to the mockup 2026-08-18 (was
   16px, sitting 10px below it): "Pick the finish." was cut from the copy
   (the swatch row right under it already says that) and the line reads as
   a caption on the frame now, not a second subhead the size of the page's
   other .mrp-sub text. */
.mrp-sub--tight { margin: 6px auto 10px; font-size: 13.5px; line-height: 1.4; }

.mrp-fineprint,
.mrp-note {
  font-size: 13px;
  color: var(--muted, #59697f);
  margin: 10px 0 0;
}

/* The reassurance under Skip. Deliberately the quietest type on the screen -
   it is there to be found by someone who is hesitating, not to be read first. */
.mrp-frame-note {
  margin: 6px auto 0;
  max-width: 30ch;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--muted-2, #7b8aa3);
  text-align: center;
}

.mrp-noscript {
  border: 1px solid var(--accent-quiet, #cfdcec);
  border-radius: 16px;
  padding: 18px;
  margin-bottom: 20px;
}

.mrp-devbadge {
  margin: 28px 0 0;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--tint-indigo, #ecedfa);
  color: var(--muted, #59697f);
  font-size: 12px;
}

/* -------------------------------- buttons ------------------------------- */

.mrp-btn {
  display: block;
  width: 100%;
  /* The primary button follows whatever the screen ended on - a consent line, a
     zoom slider, a swatch row - so the gap belongs to the button rather than to
     each of them. Without it the consent copy wraps straight into it. */
  margin-top: 22px;
  border: 0;
  border-radius: 999px;
  padding: 16px 20px;
  font: inherit;
  font-size: 17px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  transition: background 0.2s ease, opacity 0.2s ease;
}

/* The page's one gradient. Its lightest stop is 5.14:1 on white, so white
   text on it passes at any size - keep any new stop inside that range. */
.mrp-btn--primary {
  background: var(--grad-cta, linear-gradient(100deg, #2e6fb8 0%, #1d4e93 100%));
  color: #fff;
  box-shadow: 0 8px 20px rgba(16, 35, 63, 0.18);
}

.mrp-btn--primary:hover:not(:disabled) { background: var(--grad-cta-hover, linear-gradient(100deg, #27619f 0%, #183f79 100%)); }
.mrp-btn:disabled { opacity: 0.4; cursor: not-allowed; box-shadow: none; }

.mrp-btn--quiet {
  background: var(--field, #f4f8fd);
  color: var(--accent-strong, #1d4573);
  border: 1px solid var(--accent-quiet, #cfdcec);
  font-size: 15px;
  padding: 13px 16px;
}

.mrp-btn--quiet:hover:not(:disabled) { background: var(--blue-100, #e3eaf4); }

.mrp-textlink {
  display: block;
  width: 100%;
  margin: 14px 0 0;
  padding: 8px;
  background: none;
  border: 0;
  font: inherit;
  font-size: 15px;
  color: var(--accent, #2e6fb8);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-align: center;
  cursor: pointer;
}

/* Skip carries the underline, not the accent: it is a real way through, but it
   is not the action the screen is asking for. Per the palette's rule, the
   affordance is the underline rather than the colour. */
.mrp-textlink--skip { color: var(--muted, #59697f); }
.mrp-textlink--skip:hover { color: var(--ink-soft, #33405a); }

.mrp-btn:focus-visible,
.mrp-textlink:focus-visible,
.mrp-swatch:focus-visible,
.mrp-choice:focus-visible,
.mrp-frame-btn:focus-within {
  outline: 3px solid var(--accent-mid, #3d82cc);
  outline-offset: 2px;
}

/* ------------------------------ onboarding ------------------------------ */

/* WHO and NAME used to read as short, cramped screens when they only took the
   space their content needed - now every screen is vertically centred in the
   viewport by default (see .mrp-screen above), so that space comes for free
   and these two just need their own looser internal gap. */
.mrp-screen--onboarding .mrp-sub {
  margin-bottom: 36px;
}

/* WHO: two peer options, not a form field - so they read as a choice list
   rather than radio buttons standing in for one. */
.mrp-choice-list {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-top: 8px;
}

.mrp-choice {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 20px 20px;
  background: #fff;
  border: 1px solid var(--accent-quiet, #cfdcec);
  border-radius: 18px;
  box-shadow: 0 6px 16px rgba(16, 35, 63, 0.06);
  font: inherit;
  cursor: pointer;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.mrp-choice:hover { border-color: var(--accent, #2e6fb8); }

.mrp-choice-icon {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: var(--tint-indigo, #ecedfa);
  color: var(--accent, #2e6fb8);
}

.mrp-choice-body { flex: 1; min-width: 0; }
.mrp-choice-title { display: block; font-size: 16px; font-weight: 700; color: var(--ink, #16233a); }
.mrp-choice-sub { display: block; margin-top: 3px; font-size: 13.5px; color: var(--muted, #59697f); }
.mrp-choice-chevron { flex: 0 0 auto; color: var(--muted-2, #7b8aa3); }

/* NAME: same field styling as the email form, and the same reason it opts out
   of the screen's centred type - a full-width input has nothing to align to. */
.mrp-nameform {
  margin-top: 36px;
  text-align: left;
}

.mrp-nameform .mrp-field { margin-bottom: 16px; }
.mrp-nameform .mrp-field input { padding: 16px 16px; }

/* --------------------------------- choose ------------------------------- */

/* Changed 2026-08-18: the button sits over a real front-on product photo
   (a straight-on shot of the frame, screen blank) instead of the flat
   bezel-and-mat card that stood in for it. The source PNG's background is
   cut out (alpha, not solid white), so it drops onto the page ground with
   no card edge of its own - there is nothing to preview or confirm here
   (picking a file still jumps straight to the finish screen), so the photo
   just needs to read as "this is what arrives, empty". `.mrp-upload-mat` is
   now only a centering box for the button, not a styled surface.
   Fixed 2026-08-18 (overflow): mobile Safari was rendering the box at
   ~518px wide (the image's own pixel width) and letting it run off the
   right edge of the screen, on phones where the heading above it stayed
   correctly inside the column - confirmed from a real device screenshot.
   That was a flex-stretch/aspect-ratio gap in WebKit (a flex item's
   stretched width isn't always treated as "definite" for resolving
   `aspect-ratio`) - width:100% fixed the box's own sizing.
   Rebuilt 2026-08-18 (off-centre button): fixing the overflow didn't fix a
   second, separate Safari bug - on some phones (confirmed on iPhone via a
   real screenshot; Chromium at the same viewport measured the box and
   button as exactly concentric) Safari was painting the `background-size:
   contain` image using a different reference height than the box's own
   `aspect-ratio`-computed height, so the *photo* rendered shifted inside a
   *correctly-centred* box - the button never actually moved, the picture
   under it did. Background-image + aspect-ratio is exactly the pairing
   with the most WebKit history here, so the fix is to stop combining them:
   the photo is a real `<img>` now (`.mrp-upload-photo` in template-flow.php)
   sized by its own natural width/height like any other image, and
   `.mrp-upload-mat` overlays it with `position: absolute; inset: 0`
   instead of depending on the frame's height matching a CSS-computed
   aspect-ratio at all. */
.mrp-upload-frame {
  position: relative;
  margin: 0 0 10px;
}

.mrp-upload-photo {
  display: block;
  width: 100%;
  height: auto;
}

.mrp-upload-frame.is-over { box-shadow: inset 0 0 0 3px var(--accent, #2e6fb8); border-radius: 22px; }

.mrp-upload-mat {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mrp-frame-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 14px 26px;
  border-radius: 999px;
  background: var(--grad-cta, linear-gradient(100deg, #2e6fb8 0%, #1d4e93 100%));
  color: #fff;
  font-size: 16px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(16, 35, 63, 0.26);
  transition: background 0.2s ease, opacity 0.2s ease;
}

.mrp-frame-btn:hover { background: var(--grad-cta-hover, linear-gradient(100deg, #27619f 0%, #183f79 100%)); }
.mrp-plus { flex: 0 0 auto; }

.mrp-turnstile { display: flex; justify-content: center; }
.mrp-error { margin: 14px 0 0; font-size: 14px; color: #b32d2e; text-align: center; }
.mrp-error[hidden] { display: none; }

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

/* The screens are centred; anything with a field in it is not - except the
   email-notify row below, which is centred like the rest of the reserve
   copy it sits under (a single pill reads fine centred; a labelled field
   would not). */
.mrp-emailform { margin-top: 14px; text-align: center; }

.mrp-update {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink, #16233a);
  max-width: 300px;
  margin: 0 auto;
  line-height: 1.45;
}

/* One pill - email and its own button inline - rather than a labelled field
   with a text-link below, matching the reserve-screen reference. The button
   is flush against the pill's right edge with no padding of its own between
   them (.mrp-mail's right padding is 0) and stretches the full height of
   the row (align-self: stretch) rather than sitting centred with margin
   above and below it, so field and button read as one control at one size
   rather than a small button floating inside a bigger one. */
.mrp-mail {
  display: flex;
  align-items: stretch;
  gap: 8px;
  width: 100%;
  height: 58px;
  margin-top: 10px;
  padding: 0 0 0 20px;
  background: #fff;
  border: 1.5px solid var(--on-band-line, #cfdcec);
  border-radius: 16px;
  box-shadow: 0 10px 24px -18px rgba(20, 30, 60, 0.3);
}

.mrp-mail input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: none;
  font: inherit;
  font-size: 17px;                /* 16px or iOS zooms the page on focus. */
  font-weight: 500;
  color: var(--ink-soft, #33405a);
}

.mrp-mail input::placeholder { color: var(--muted-2, #7b8aa3); }
.mrp-mail input:focus { outline: 2px solid var(--accent-mid, #3d82cc); outline-offset: 1px; border-radius: 4px; }

.mrp-mail button {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  border: 0;
  cursor: pointer;
  font: inherit;
  background: var(--accent, #2e6fb8);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  padding: 0 22px;
  border-radius: 0 14px 14px 0;
}

.mrp-mail button:hover { background: var(--accent-strong, #1d4573); }

.mrp-field { display: block; margin-bottom: 12px; }
.mrp-field span { display: block; font-size: 13px; color: var(--muted, #59697f); margin-bottom: 5px; }

.mrp-field input {
  width: 100%;
  padding: 13px 14px;
  font: inherit;
  font-size: 16px;               /* 16px or iOS zooms the page on focus. */
  color: var(--ink-soft, #33405a);
  background: #fff;
  border: 1px solid var(--on-band-line, #cfdcec);
  border-radius: 12px;
}

.mrp-field input:focus { outline: 2px solid var(--accent-mid, #3d82cc); outline-offset: 1px; }

/* --------------------------------- finish -------------------------------- */

/* One canvas for the whole screen: the frame holding the greyscale
   placeholder while the model works, then the drawing once it lands, then
   whatever finish the visitor picks - never a swap between two elements.
   Changed 2026-08-18: back up from 70% to 75% width - the drawing is the
   nicest feature on this page and the point of the screen, so it should
   read as the main event rather than a compact header. That's paid for by
   removing the throbber row and status line that used to sit under it (the
   throbber is now an overlay badge on the frame itself, .mrp-throbber
   below) and by removing Regenerate.
   Same day, later: the margin/line-height trims that had gone with the
   above (tuned to fit one 100svh iPhone-SE viewport with zero scroll) read
   as cramped, and were given back - see .mrp-sub--tight, .mrp-finish,
   .mrp-price, .mrp-deposit, .mrp-emailform and .mrp-mail below, sized up.
   That overshot on the *largest* phones, not the smallest: .mrp caps at
   430px wide, so a Pro-Max-class screen (>=430px, e.g. 430-442px) renders
   the frame and every margin at their maximum, and that full-size stack
   didn't fit even a tall 100svh there - a narrower phone never hits this
   because its whole column (frame included) scales down with the viewport
   width, needing less height to begin with. Re-trimmed the same handful of
   margins/line-heights a second time, this time measuring against the
   430px cap itself rather than a specific device, and left type sizes and
   the mail pill's height alone since those were what was asked to be
   bigger. Still no guarantee below that on short + narrow phones (iPhone
   SE) - grows past 100svh and scrolls there, same as every other screen in
   this flow (see the "no step rail" comment up in template-flow.php). */
/* Sized up from 75% to 88%, per explicit request - the frame is the point
   of this screen, so bigger reads as more confident rather than cramped.
   Left the vertical rhythm (margins/line-heights above, tuned to the 430px
   cap) alone: a taller frame eats into that same one-viewport budget on
   short phones, but nothing here was re-measured against a specific device
   - if it overflows on something like an iPhone SE, this is the value to
   shrink back down before touching anything else. */
.mrp-mockup {
  position: relative;
  width: 88%;
  margin: 0 auto 12px;
}

.mrp-mockup canvas {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 14px 26px rgba(16, 35, 63, 0.16));
}

/* The wait indicator, now a small overlay badge centred on the frame rather
   than a row below it with a changing status line - the photo stays at full
   strength underneath, and "working" needs only a spinner, not prose.
   Toggled via [hidden] by refreshFinishUI() in preview.js. Added 2026-08-18:
   a one-word "Initialising" label under the spin badge, still on top of the
   photo and still toggled by the same [hidden]. */
.mrp-throbber {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.mrp-throbber-spin {
  position: relative;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(15, 23, 42, 0.38);
}

.mrp-throbber-spin::after {
  content: '';
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.45);
  border-top-color: #fff;
  animation: mrp-spin 0.9s linear infinite;
}

.mrp-throbber-label {
  font-size: 12px;
  font-weight: 500;
  color: #fff;
  background: rgba(15, 23, 42, 0.38);
  padding: 3px 9px;
  border-radius: 10px;
  white-space: nowrap;
}

.mrp-swatches { display: flex; gap: 16px; justify-content: center; margin: 0 0 8px; }

.mrp-swatch {
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: 50%;
  border: none;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
}

.mrp-swatch span:first-child {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(11, 26, 46, 0.18);
}

/* The selected state is a halo ring, aria-checked and the label below - never
   the swatch colour on its own, which is a sample of the product rather than
   UI. The white layer first is what keeps the ring reading as a gap around
   the swatch rather than a thick blue outline touching it. */
.mrp-swatch.is-on span:first-child {
  box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--accent, #2e6fb8);
}

.mrp-finish {
  text-align: center;
  margin: 6px 0 12px;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink, #16233a);
}

.mrp-price {
  text-align: center;
  margin: 0;
  font-size: 34px;
  line-height: 1.05;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--ink, #16233a);
}

.mrp-deposit {
  text-align: center;
  margin: 6px auto 0;
  max-width: 300px;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--muted, #59697f);
}

.mrp-deposit strong { color: var(--ink, #16233a); font-weight: 700; }

/* .mrp-btn's default 22px top margin is sized for a screen that ends on one
   line of copy above it - the finish screen ends on the deposit paragraph,
   which already carries its own margin, so the button needs less on top of
   that. Scoped rather than lowering the shared default, which the other
   screens (onboarding, upload) are tuned against. Part of fitting the whole
   screen in 100svh - see .mrp-mockup's comment above. */
[data-screen="finish"] .mrp-btn { margin-top: 14px; padding-top: 14px; padding-bottom: 14px; }

.mrp-screen--stop { text-align: center; }

/* -------------------------------- desktop ------------------------------- */

@media (min-width: 900px) {
  .mrp { max-width: 560px; padding-top: 24px; }
  .mrp-h1 { font-size: 36px; }
  .mrp-h2 { font-size: 32px; }
  .mrp-sub { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .mrp-btn { transition: none; }
  .mrp-throbber-spin::after { animation: none; }
}
