/* The homepage builder: three short steps under a live card.
   Linked from inside index.html's builder markers; flow.js drives it.

   One material from the first tap to the dashboard (Task 4b): the warm
   ground and Satoshi for the question are the homepage's, but the fields,
   buttons and lists are the dashboard's rounded, grouped surfaces, the same
   family as the card itself, which is a rounded physical thing. 54px fields
   at a 12px radius, 54px buttons at 14px, one filled button per screen.

   Phone (< 700px): a sheet. The card sits on top at about 38% of the dynamic
   viewport, the question under it, and every step fits a 375x667 screen with
   the keyboard closed. The button is in normal flow under the field, never
   fixed: iOS 26's visualViewport misreports with the keyboard up.
   Desktop: a dialog, the card large on the left, the question on the right.

   Motion is transform and opacity only, and flow.js does it (one authored
   moment: the step change, plus the strip's crossfade). */

.builder-backdrop{
  position:fixed;inset:0;z-index:100;
  background:rgba(11,13,17,.62);
  backdrop-filter:blur(22px) saturate(160%);
  -webkit-backdrop-filter:blur(22px) saturate(160%);
  display:none;opacity:0;
  transition:opacity 240ms cubic-bezier(.23,1,.32,1);
}
.builder-backdrop.is-open{display:grid;place-items:center}
.builder-backdrop.is-visible{opacity:1}

.builder-shell{
  --ob-ink:var(--ink,#0B0D11);
  --ob-ground:var(--ground,#F5F2EC);
  --ob-stage:#EAE4D9;
  --ob-ok:#07683F;
  --ob-no:#A9301F;
  --ob-ease:cubic-bezier(.22,1,.36,1);
  position:relative;
  width:min(960px,calc(100vw - 48px));
  /* 680 holds the save step, its "Show this email on my card" included,
     with Apple and Google above the fold (the HIG) */
  height:min(680px,calc(100vh - 48px));
  background:var(--ob-ground);
  color:var(--ob-ink);
  font-family:var(--body);
  display:grid;
  grid-template-columns:minmax(0,1fr) 400px;
  grid-template-rows:auto minmax(0,1fr);
  grid-template-areas:"stage bar" "stage pane";
  overflow:hidden;
  box-shadow:0 40px 90px -30px rgba(4,12,32,.6),0 2px 10px -4px rgba(4,12,32,.3);
  transform:translateY(14px) scale(.985);
  transition:transform 280ms var(--ob-ease);
  caret-color:var(--blue);
}
@media (min-width:900px){.builder-shell{grid-template-columns:minmax(0,1fr) 440px}}
.builder-backdrop.is-visible .builder-shell{transform:none}
.builder-shell ::selection{background:rgba(2,95,253,.2)}

/* ── the bar: back, the dialog's name, close ── */
.ob-bar{grid-area:bar;display:flex;align-items:center;justify-content:space-between;gap:4px;padding:14px 14px 0 26px;min-width:0}
/* the dialog's name sits over the card, top left, so the question in the
   pane lines up with nothing above it but the back button */
/* the dialog's name is for a screen reader: the question in the pane already
   says where you are */
.ob-title{position:absolute;width:1px;height:1px;margin:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.ob-icon{
  flex:none;width:44px;height:44px;display:grid;place-items:center;
  border:0;background:none;color:var(--ob-ink);cursor:pointer;border-radius:999px;
  -webkit-tap-highlight-color:transparent;
}
.ob-icon::before{content:"";grid-area:1/1;width:36px;height:36px;border-radius:999px;
  background:rgba(11,13,17,.06);transition:transform 160ms cubic-bezier(.23,1,.32,1),opacity 160ms}
.ob-icon svg{grid-area:1/1;position:relative}
@media (hover:hover) and (pointer:fine){.ob-icon:hover::before{transform:scale(1.08)}}
.ob-icon:active::before{transform:scale(.97)}
.ob-icon:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
/* hidden on the first step, but it keeps its place, so close stays put */
.ob-back[hidden]{display:grid;visibility:hidden}

/* ── the pane: the steps ── */
.builder-form-pane{grid-area:pane;min-width:0;overflow-y:auto;overscroll-behavior:contain}
.builder-form-inner{padding:28px 40px 40px}
.builder-offer{margin:0 0 14px;font-size:14px;font-weight:600;color:var(--blue)}
.ob-form{display:block;margin:0}
.ob-steps{display:grid}
.ob-step{grid-area:1/1;min-width:0;margin:0;padding:0;border:0}
.ob-step[hidden]{display:none}
.ob-q{float:left;width:100%;padding:0;margin:0 0 20px;
  font-family:var(--disp);font-weight:700;font-size:32px;line-height:1.08;
  letter-spacing:-.04em;color:var(--ob-ink);text-wrap:balance}
.ob-q+*{clear:both}

/* ── fields: the hero's claim field, as a form ── */
.b-field{display:block}
.b-field+.b-field{margin-top:16px}
.b-field-label{display:block;font-size:14px;font-weight:500;line-height:1.3;color:var(--fg2)}
/* The field: white, a hairline, a 12px radius. Focus and error swap at once
   (box-shadow is a state here, not a motion). */
.b-field-input{
  display:block;width:100%;margin-top:8px;height:54px;padding:0 16px;box-sizing:border-box;
  font:500 17px/1.2 var(--body);letter-spacing:-.012em;color:var(--ob-ink);
  background:#fff;border:1px solid rgba(11,13,17,.16);border-radius:12px;outline:none;
  box-shadow:none;
  -webkit-appearance:none;appearance:none;
}
.b-field-input::placeholder{color:var(--fg3);font-weight:400;opacity:1}
@media (hover:hover) and (pointer:fine){.b-field-input:hover{border-color:rgba(11,13,17,.28)}}
.b-field-input:focus{border-color:#025FFD;box-shadow:0 0 0 4px rgba(2,95,253,.16)}
.b-field-input.is-invalid{border-color:var(--ob-no);box-shadow:0 0 0 4px rgba(169,48,31,.14)}
.b-field-label.is-invalid{color:var(--ob-no)}
.ob-err{margin:8px 0 0;font-size:14px;line-height:1.4;color:var(--ob-no)}
.ob-err[hidden]{display:none}

/* Who do you meet (P-AUDIENCE): three pills in the field's own language,
   the chosen one in the brand blue. */
.ob-meet{min-width:0;margin:16px 0 0;padding:0;border:0}
.ob-meet legend{padding:0}
/* Its own question, not a field label: it stays when a cramped step hides
   those, since three pills without it say nothing. */
.ob-meet-q{display:block;font-size:14px;font-weight:500;line-height:1.3;color:var(--fg2)}
/* Each pill as wide as its words, the row shared out between them, so
   "Business contacts" never breaks inside its pill; a phone too narrow for
   one row wraps whole pills. */
.ob-meet-opts{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.ob-meet-opt{position:relative;display:flex;flex:1 1 auto}
.ob-meet-opt input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.ob-meet-opt > span{display:flex;flex:1;align-items:center;justify-content:center;min-height:48px;padding:6px 14px;box-sizing:border-box;white-space:nowrap;
  font:500 15px/1.2 var(--body);letter-spacing:-.01em;color:var(--ob-ink);text-align:center;
  background:#fff;border:1px solid rgba(11,13,17,.16);border-radius:12px;transition:transform 160ms cubic-bezier(.23,1,.32,1)}
@media (hover:hover) and (pointer:fine){.ob-meet-opt input:hover + span{border-color:rgba(11,13,17,.28)}}
/* The chosen one in the accent at the same weight, so a tap never moves
   the others; the inset ring doubles the border without changing size. */
.ob-meet-opt input:checked + span{border-color:#025FFD;background:rgba(2,95,253,.09);color:var(--blue-dk,#0140AE);box-shadow:inset 0 0 0 1px #025FFD}
.ob-meet-opt input:checked:focus-visible + span{box-shadow:inset 0 0 0 1px #025FFD,0 0 0 4px rgba(2,95,253,.16)}
.ob-meet-opt input:focus-visible + span{border-color:#025FFD;box-shadow:0 0 0 4px rgba(2,95,253,.16)}
.ob-meet-opt input:active + span{transform:scale(.97)}
.ob-meet-note{margin:8px 0 0;font-size:13px;line-height:1.4;color:var(--fg2)}
/* The smallest phones (under 360px) fold "Business contacts" to "Business",
   as You does: the question above says who, and all three stay on one row. */
@media (max-width:359px){.ob-meet-wide{display:none}.ob-meet-opt > span{padding:6px 10px}}
@media (prefers-reduced-motion:reduce){.ob-meet-opt > span{transition:none}}

/* "Alex Morgan?": a name read out of the handle, offered and never typed in */
.ob-chip{
  display:inline-flex;align-items:center;gap:8px;min-height:44px;margin-top:10px;padding:0 14px 0 12px;
  border:0;border-radius:12px;background:rgba(2,95,253,.09);color:var(--blue-dk,#0140AE);
  font:600 15px var(--body);letter-spacing:-.01em;cursor:pointer;
  transition:transform 160ms cubic-bezier(.23,1,.32,1);
  -webkit-tap-highlight-color:transparent;
}
.ob-chip[hidden]{display:none}
.ob-chip svg{flex:none}
@media (hover:hover) and (pointer:fine){.ob-chip:hover{background:rgba(2,95,253,.15)}}
.ob-chip:active{transform:scale(.97)}
.ob-chip:focus-visible{outline:2px solid var(--blue);outline-offset:2px}

/* text buttons: Skip, Not you?, Use a different email. A link's weight, a button's target. */
.ob-link{
  flex:none;display:inline-flex;align-items:center;justify-content:center;min-height:44px;min-width:44px;padding:0 6px;
  border:0;background:none;cursor:pointer;
  font:600 15px var(--body);letter-spacing:-.01em;color:var(--blue);
  text-decoration:underline;text-decoration-color:transparent;text-underline-offset:3px;
  transition:opacity 140ms;
  -webkit-tap-highlight-color:transparent;
}
.ob-link[hidden]{display:none}
@media (hover:hover) and (pointer:fine){.ob-link:hover{text-decoration-color:currentColor}}
.ob-link:active{opacity:.6}
.ob-link:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
.ob-skip{display:flex;margin:6px auto 0;color:var(--fg2)}

/* the step's one button, in flow under the field: 54px, a 14px radius, one
   press feel (scale .97 in 160ms) for every pressable thing in the sheet */
.builder-shell .ob-primary.btn{display:flex;width:100%;margin-top:22px;padding:0 24px;min-height:54px;
  border-radius:14px;background:#025FFD;color:#fff;font:600 17px/1.15 var(--body);letter-spacing:-.012em;
  transition:transform 160ms cubic-bezier(.23,1,.32,1);will-change:auto}
@media (hover:hover) and (pointer:fine){.builder-shell .ob-primary.btn:hover{background:#0259EE}}
.builder-shell .ob-primary.btn:active{transform:scale(.97)}
.builder-shell .ob-primary.btn:disabled,.builder-shell [aria-busy="true"] .ob-primary.btn[type=submit]{opacity:.6;cursor:default;transform:none}

/* ── signing in instead ──
   Step one's quiet row: "or continue with  Apple · Google", then "Already
   have a Cardr? Sign in". A link's weight, a button's target, so it catches
   a returning visitor without competing with Continue. */
.ob-sprite{position:absolute;width:0;height:0;overflow:hidden}
.ob-social{margin-top:10px}
.ob-quiet{margin:0;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;column-gap:2px;
  min-height:44px;font-size:14.5px;line-height:1.3;color:var(--fg2);text-align:center}
.ob-quiet[hidden]{display:none}
.ob-quiet>span:first-child{margin-right:4px}
.ob-qlink{display:inline-flex;align-items:center;gap:6px;min-height:44px;min-width:44px;padding:0 6px;
  font-weight:600;color:var(--ob-ink);text-decoration:underline;text-decoration-color:transparent;
  text-underline-offset:3px;-webkit-tap-highlight-color:transparent;transition:opacity 140ms}
.ob-qlink[hidden],.ob-dot[hidden]{display:none}
.ob-qlink-blue{color:var(--blue)}
@media (hover:hover) and (pointer:fine){.ob-qlink:hover{text-decoration-color:currentColor}}
.ob-qlink:active{opacity:.6}
.ob-qlink:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
.ob-dot{color:var(--fg3)}
.ob-mark{flex:none;width:16px;height:16px}
.ob-mark-apple{width:14px;height:17px;margin-top:-2px;color:currentColor;fill:currentColor}
.ob-returning{margin-top:-6px}

/* The save step's and the existing-account screen's Apple and Google: the
   same size as the primary button (Apple's HIG), never smaller. Outlined in
   ink like the fields, white like Apple's "white outline" style, so the one
   filled button on the screen stays the blue one. The system face, which is
   San Francisco on Apple's devices, as the HIG asks of a custom button. */
.ob-providers{display:grid;gap:12px;margin-top:10px}
.ob-providers[hidden]{display:none}
.ob-or{display:flex;align-items:center;gap:12px;margin:4px 0;font-size:13px;line-height:1;color:var(--fg3)}
.ob-or::before,.ob-or::after{content:"";flex:1;height:1px;background:rgba(11,13,17,.14)}
/* With Apple and Google above it, "or with email" is the field's visible
   label, the same distance above the field as below Google; "Email" again
   under it goes to the screen reader only. */
.ob-providers:not([hidden])+.ob-email .b-field-label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.ob-providers:not([hidden])+.ob-email .b-field-input{margin-top:16px}
.ob-provider{
  display:flex;align-items:center;justify-content:center;gap:10px;min-height:54px;padding:0 20px;box-sizing:border-box;
  background:#fff;color:var(--ob-ink);border:1px solid rgba(11,13,17,.24);border-radius:14px;
  font:600 17px/1.1 -apple-system,BlinkMacSystemFont,system-ui,"Segoe UI",Roboto,sans-serif;letter-spacing:-.01em;
  text-decoration:none;-webkit-tap-highlight-color:transparent;
  transition:transform 160ms cubic-bezier(.23,1,.32,1);
}
.ob-provider[hidden]{display:none}
.ob-provider .ob-mark{width:19px;height:19px}
.ob-provider .ob-mark-apple{width:17px;height:21px;margin-top:-4px}
@media (hover:hover) and (pointer:fine){.ob-provider:hover{background:#FBFAF7}}
.ob-provider:active{transform:scale(.97)}
.ob-provider:focus-visible{outline:2.5px solid var(--blue);outline-offset:3px}

/* ── the save step ── */
/* signed in (back from Apple, Google or a code): the address is said, not
   asked; the field stays in the form, read-only, and is what is sent */
.is-signed-in .ob-email{display:none}
.ob-who[hidden]{display:none}
/* the field's own shape, quieter: a hairline, not the ink outline, because
   there is nothing to type */
.ob-who-row{display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin:8px 0 0;padding:4px 4px 4px 16px;min-height:54px;background:rgba(255,255,255,.5);
  border:1px solid rgba(11,13,17,.12);border-radius:12px}
.ob-who-row b{min-width:0;overflow-wrap:break-word;font:500 17px/1.25 var(--body);letter-spacing:-.012em;color:var(--ob-ink)}
.ob-who-row .ob-link{font-size:14.5px}
/* "Use name@gmail.com": the 422's fix, under the field it fixes; the field's
   red edge says what is wrong */
.ob-suggest{display:flex;flex-wrap:wrap;align-items:center;gap:4px 10px;margin:8px 0 0;font-size:14px;font-weight:600;color:var(--ob-no)}
.ob-sr{position:absolute;width:1px;height:1px;margin:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.ob-suggest[hidden]{display:none}
.ob-suggest .ob-chip{margin:0;max-width:100%;overflow-wrap:anywhere;text-align:left}
.ob-plan{margin:0 0 14px;font-size:14px;line-height:1.45;color:var(--fg2);text-wrap:pretty}
.ob-plan[hidden]{display:none}
.b-consent{margin-top:4px}
.b-consent-line{margin:0;font-size:14px;line-height:1.45;color:var(--fg2);text-wrap:pretty}
/* fine print, not two more questions: 15px rows, a 24px box, a 44px target */
.b-consent-checks{display:flex;flex-wrap:wrap;column-gap:20px}
.b-consent-check{display:inline-flex;align-items:center;gap:10px;min-height:44px;font-size:15px;color:var(--fg2);cursor:pointer;-webkit-tap-highlight-color:transparent}
.b-consent-check input{width:24px;height:24px;margin:0;flex:none;accent-color:var(--blue);cursor:pointer;transition:transform 160ms cubic-bezier(.23,1,.32,1)}
@media (hover:hover) and (pointer:fine){.b-consent-check:hover input{transform:scale(1.08)}}
.b-consent-check:active input{transform:scale(.97)}
.b-consent-check input:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.ob-step[data-step="save"] .ob-primary.btn{margin-top:14px}
.ob-step .ob-lede.ob-save-lede{margin:-8px 0 18px;font-size:15px;line-height:1.4}
.b-legal{margin:6px 0 0;font-size:13px;line-height:1.5;color:var(--fg2)}
.b-legal a{color:var(--blue);text-decoration:underline;text-underline-offset:2px;border-radius:2px}
.b-legal a:hover{text-decoration-thickness:2px}
.b-legal a:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.b-legal a:active{opacity:.7}
.b-code{margin-top:4px}
.b-code-sum{cursor:pointer;font-size:14px;font-weight:600;color:var(--fg2);min-height:44px;display:inline-flex;align-items:center;list-style:none;transition:opacity .12s}
.b-code-sum::-webkit-details-marker{display:none}
@media (hover:hover) and (pointer:fine){.b-code-sum:hover{opacity:.75}}
.b-code-sum:active{opacity:.55}
.b-code-sum:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.b-code .b-field{margin-top:4px}
.b-code-status{margin:6px 0 0;font-size:13px;color:var(--fg2);min-height:1.4em}
.b-code [aria-invalid="true"]{box-shadow:0 0 0 2px var(--ob-no) inset}

/* ── "You already have a Cardr" (a 409) ── */
.ob-taken .ob-q{float:none;outline:none}
.ob-lede{margin:-6px 0 0;font-size:16px;line-height:1.45;color:var(--fg2);overflow-wrap:anywhere;clear:both}
.ob-lede b{color:var(--ob-ink);font-weight:600}
/* step 2's one line: both fields are optional, and the card shows them as typed */
.ob-role-lede{margin:-6px 0 14px;font-size:15px;line-height:1.4;color:var(--fg2)}
.builder-shell.is-cramped .ob-role-lede{display:none}
/* the save step's heading takes focus on arrival (flow.js focusFirst): no ring
   for a focus nobody asked for, the ring for a keyboard user */
.ob-step[data-step="save"] .ob-q:focus{outline:none}
.ob-step[data-step="save"] .ob-q:focus-visible{outline:2px solid var(--blue);outline-offset:4px;border-radius:6px}
.ob-taken .ob-primary.btn{margin-top:18px}
.ob-alt{display:flex;flex-wrap:wrap;justify-content:space-between;gap:4px;margin-top:6px}
.ob-alt .ob-link{padding:0 2px;font-size:16px;font-weight:600}

/* ── the stage: the real Oxford pass front ── */
.builder-preview-pane{
  grid-area:stage;position:relative;min-width:0;overflow:hidden;
  display:grid;place-items:center;
  background:
    radial-gradient(60% 50% at 50% 46%,rgba(255,255,255,.62),rgba(255,255,255,0) 70%),
    var(--ob-stage);
  box-shadow:-1px 0 0 rgba(11,13,17,.08) inset;
}
.ob-card.passcard{
  --pw:min(360px,calc((min(640px,100vh - 48px) - 112px) / 1.27));
  box-shadow:0 30px 60px -28px rgba(4,22,64,.55),0 2px 8px -3px rgba(4,22,64,.28);
}
/* The card itself, its anatomy, artwork, photo and rows, is the live card's
   one stylesheet (./live-card.css, linked beside this one). Here: where it
   sits in the builder, and what the builder's steps do to it. */

/* the card is made: no step to go back to, and an empty row is not a
   placeholder any more */
.builder-shell.is-done .ob-back,
.builder-shell.is-done .ob-title,
.builder-shell.is-done .ob-card .rows b.is-empty,
.builder-shell.is-done .ob-card .rows div:has(>b.is-empty){visibility:hidden}
.builder-shell.is-done .ob-card .ob-logo-text.is-empty{visibility:hidden}

/* ── phone: the sheet ── */
@media (max-width:699px){
  .builder-backdrop.is-open{place-items:end stretch}
  .builder-shell{
    width:100%;
    height:calc(100svh - 10px);
    height:calc(100dvh - 10px);
    grid-template-columns:minmax(0,1fr);
    grid-template-rows:auto auto;
    grid-template-areas:"stage" "pane";
    align-content:start;
    border-radius:16px 16px 0 0;
    overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch;
    transform:translateY(100%);
  }
  .builder-backdrop.is-visible .builder-shell{transform:none}
  /* back and close float in the stage's top corners, beside the card */
  .ob-bar{position:absolute;top:0;left:0;right:0;z-index:3;padding:6px 6px 0;pointer-events:none}
  .ob-bar>*{pointer-events:auto}
  .ob-icon::before{background:rgba(255,255,255,.72);box-shadow:0 0 0 1px rgba(11,13,17,.08)}
  .ob-title{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
  .builder-shell{--sh:clamp(212px,38dvh,380px)}
  .builder-preview-pane{
    height:var(--sh);padding:14px 0;
    box-shadow:0 -1px 0 rgba(11,13,17,.08) inset;
  }
  .ob-card.passcard{--pw:calc((var(--sh) - 28px) / 1.27)}
  .builder-form-pane{overflow:visible}
  .ob-q{font-size:26px;margin-bottom:16px}
  .builder-drag-handle{position:absolute;top:6px;left:50%;width:36px;height:5px;margin-left:-18px;border-radius:3px;background:rgba(11,13,17,.2);z-index:2;pointer-events:none}
}
@media (min-width:700px){.builder-drag-handle{display:none}}
/* A short phone (an SE, or any phone with the browser's bars showing): the
   card gives up a little height and the steps a little air, so the save step
   still fits one screen with the keyboard down. */
@media (max-width:699px) and (max-height:720px){
  .builder-shell{--sh:clamp(200px,36dvh,380px)}
  .ob-q{font-size:24px;margin-bottom:12px}
  .b-field-input{margin-top:6px}
  .ob-primary.btn{margin-top:18px}
  .ob-step[data-step="save"] .ob-primary.btn{margin-top:8px}
  /* the step's three buttons stay one size (Apple's HIG), a little shorter */
  .ob-primary.btn,.ob-provider{min-height:52px}
  .b-consent{margin-top:4px}
  .b-legal{margin-top:8px}
  /* the Pro note gives back a little, so Pro's save step keeps Apple above
     the fold too */
  .ob-plan{margin-bottom:8px;font-size:13px;line-height:1.4}
  /* and the save step's own rhythm a notch tighter: Pro's note is three
     lines, and Apple and Google stay above the fold under it (the HIG) */
  .ob-step[data-step="save"] .ob-q{font-size:22px;margin-bottom:10px}
  .ob-step[data-step="save"] .b-field-input{height:50px}
  .ob-step[data-step="save"] .ob-primary.btn,.ob-step[data-step="save"] .ob-provider{min-height:52px}
  .ob-step[data-step="save"] .ob-providers{gap:8px;margin-top:8px}
  .ob-step[data-step="save"] .ob-or{margin:2px 0}
  .ob-providers:not([hidden])+.ob-email .b-field-input{margin-top:10px}
  .ob-step[data-step="save"] .b-legal{margin-top:6px}
}

/* The tuck (flow.js tuck()): on a phone where the save step or the
   existing-account screen does not fit under the whole card, the sheet's
   surface slides up over the card's QR and foot by exactly what is missing,
   leaving its strip and rows in view. The motion is transform only, so it is
   interruptible at any point; the negative margin (not animated) takes back
   the blank the transform would leave at the end of the scroll. */
@media (max-width:699px){
  /* the iOS drawer curve: 240ms rising, 200ms on release; a transition, so
     a tap mid-way turns it round from where it is */
  .builder-form-pane{position:relative;z-index:1;background:var(--ob-ground);
    transition:transform 200ms cubic-bezier(.32,.72,0,1)}
  .builder-form-pane::before{content:"";position:absolute;left:0;right:0;top:0;height:18px;transform:translateY(-100%);
    background:linear-gradient(to top,rgba(4,12,32,.14),rgba(4,12,32,0));opacity:0;pointer-events:none;
    transition:opacity 200ms cubic-bezier(.32,.72,0,1)}
  .builder-shell.is-tucked .builder-form-pane{transform:translateY(calc(-1 * var(--tuck,0px)));margin-bottom:calc(-1 * var(--tuck,0px));transition-duration:240ms}
  .builder-shell.is-tucked .builder-form-pane::before{transition-duration:240ms}
  /* keyboard up and still short on the name step: the sign-in row steps
     aside until the field lets go */
  .builder-shell.is-cramped .ob-social{display:none}
  .builder-shell.is-cramped .ob-primary.btn{margin-top:12px}
  .builder-shell.is-cramped .ob-q{margin-bottom:10px}
  .builder-shell.is-cramped .ob-meet-note{display:none}
  .builder-shell.is-cramped .ob-step:not([data-step="save"]) .b-field-label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  .builder-shell.is-cramped .ob-step:not([data-step="save"]) .b-field-input{margin-top:0}
  .builder-shell.is-cramped .b-field+.b-field{margin-top:10px}
  .builder-shell.is-cramped .ob-chip{margin-top:8px}
  /* the save step with the keyboard up (the email typed, so Apple and Google
     are passed): what the person agrees to, Create and the Terms all above
     it. The lede, the Pro note and the providers step aside until the field
     lets go; the question and the Email label go to the screen reader (the
     field's placeholder says it), and the consent rows close up. */
  .builder-shell.is-cramped .ob-step[data-step="save"] .ob-save-lede,
  .builder-shell.is-cramped .ob-step[data-step="save"] .ob-plan,
  .builder-shell.is-cramped .ob-step[data-step="save"] .ob-providers{display:none}
  .builder-shell.is-cramped .ob-step[data-step="save"] .ob-q{position:absolute;width:1px;height:1px;margin:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  .builder-shell.is-cramped .ob-step[data-step="save"] .ob-email .b-field-label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  .builder-shell.is-cramped .ob-step[data-step="save"] .ob-email .b-field-input{margin-top:0}
  .builder-shell.is-cramped .ob-step[data-step="save"] .b-consent{margin-top:4px}
  /* a 360x640 phone: the Terms' second line clears the keyboard too */
  .builder-shell.is-cramped .builder-form-inner{padding-top:12px}
  .builder-shell.is-cramped .ob-step[data-step="save"] .b-consent-line{line-height:1.35}
  .builder-shell.is-cramped .ob-step[data-step="save"] .b-legal{margin-top:4px;line-height:1.4}
  .builder-shell.is-cramped .ob-step[data-step="save"] .ob-primary.btn{margin-top:6px}
  .builder-shell.is-tucked .builder-form-pane::before{opacity:1}
  /* the QR is a promise of the finished card; tucked, it would show as a
     white sliver at the sheet's edge */
  .ob-card .qr,.ob-card .qcap{transition:opacity 240ms ease-out}
  .builder-shell.is-tucked-qr .ob-card .qr,.builder-shell.is-tucked-qr .ob-card .qcap{opacity:0}
  .builder-shell.is-done .builder-form-pane{transform:none}
}

@media (prefers-reduced-motion:reduce){
  .builder-shell{transition:none}
  .ob-icon::before,.ob-chip,.b-consent-check input,.ob-provider,.ob-qlink{transition:none}
  .builder-form-pane,.builder-form-pane::before{transition:none}
}
.builder-shell .builder-form-inner{padding-bottom:calc(24px + env(safe-area-inset-bottom))}
@media (min-width:700px){.builder-shell .builder-form-inner{padding-bottom:40px}}
/* an image appears once it has loaded: a slow one is a blank, never a broken box */
img.ob-wait{opacity:0}



/* ── the card is live ──
   One moment: the card, the device's one action, the link, the email switch,
   and the dashboard bar pinned under them (conversion v2 §2). */
.builder-shell .builder-success{text-align:left}
/* the view's own heading only: the Wallet block's titles keep their 17px */
.builder-shell .builder-success>h3{font-family:var(--disp);font-weight:700;font-size:26px;letter-spacing:-.035em;margin:0;color:var(--ob-ink);text-wrap:balance;outline:none}
.builder-shell .ob-done-main{margin-top:16px}
/* its rows never grow to the address's full length: it ellipsizes */
.ob-done-main>*{min-width:0}
.builder-shell #builderDownload.ob-primary.btn{margin-top:0}
/* the address, live: one quiet line. Open it, Copy, Share. */
.builder-shell .builder-success .ob-done-addr{display:flex;align-items:center;flex-wrap:nowrap;gap:2px;min-width:0;margin:10px 0 0;
  font-size:15px;line-height:1.3;color:var(--fg2)}
.ob-done-addr .ob-addr-live{flex:0 1 auto;min-width:0;display:flex;align-items:center;min-height:44px;
  color:var(--fg2);text-decoration:none;-webkit-tap-highlight-color:transparent}
.ob-done-addr .ob-addr-live code{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:500 15px/1.3 var(--body);letter-spacing:-.005em}
@media (hover:hover) and (pointer:fine){.ob-done-addr .ob-addr-live:hover code{text-decoration:underline;text-underline-offset:3px}}
.ob-done-addr .ob-addr-live:active{opacity:.6}
.ob-done-addr .ob-link{flex:none;padding:0 8px;min-width:44px;color:#025FFD}
.ob-done-addr .ob-sep{flex:none;color:var(--fg3)}
.ob-done-addr .ob-sep[hidden],.ob-done-addr .ob-link[hidden]{display:none}
/* the line's 44px tap row already pads its text: on any touch screen (phone,
   tablet or hybrid, at any width) the gap from the Wallet block above reads
   as about 24px, not 48; a real pointer gets 32px rows and the 14px below */
.ob-done-link{margin-top:14px}
@media (hover:none),(pointer:coarse){
  .ob-done-link{margin-top:0}
  .builder-shell .builder-success .ob-done-addr{margin-top:0}
}
/* scoped to the view: index.html's inline .builder-success p would beat a bare class */
.builder-shell .builder-success .ob-done-change{margin:0;font-size:13.5px;line-height:1.4;color:var(--fg2)}
/* Email on your card · On / Off: the whole row is the switch's label */
.ob-email-switch{position:relative;display:flex;align-items:center;gap:12px;min-height:52px;margin-top:12px;padding:0 2px;
  border-top:1px solid rgba(11,13,17,.08);cursor:pointer;-webkit-tap-highlight-color:transparent}
.ob-email-switch[hidden]{display:none}
.ob-email-switch-t{flex:1;font-size:16px;font-weight:500;color:var(--fg)}
.ob-email-switch-v{font-size:15px;color:var(--fg2);font-variant-numeric:tabular-nums}
.ob-email-switch input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.ob-switch{position:relative;flex:none;width:51px;height:31px;border-radius:999px;background:rgba(120,120,128,.18);pointer-events:none;
  transition:transform 160ms cubic-bezier(.23,1,.32,1)}
.ob-switch::before{content:"";position:absolute;inset:0;border-radius:inherit;background:#025FFD;opacity:0;transition:opacity 200ms ease-out}
.ob-switch i{position:absolute;top:2px;left:2px;width:27px;height:27px;border-radius:50%;background:#fff;
  box-shadow:0 3px 8px rgba(0,0,0,.15),0 1px 1px rgba(0,0,0,.16);transition:transform 220ms cubic-bezier(.23,1,.32,1)}
.ob-email-switch input:checked+.ob-switch::before{opacity:1}
.ob-email-switch input:checked+.ob-switch i{transform:translateX(20px)}
.ob-email-switch input:focus-visible+.ob-switch{outline:2px solid #025FFD;outline-offset:2px}
.ob-email-switch input:active+.ob-switch{transform:scale(.96)}
.ob-email-switch input:disabled+.ob-switch{opacity:.5}
@media (hover:hover) and (pointer:fine){.ob-email-switch:hover .ob-email-switch-t{color:#000}}
.builder-shell .builder-success .ob-email-switch-err{margin:4px 0 0;font-size:14px;line-height:1.4;color:#b00020}
.ob-email-switch-err[hidden]{display:none}
/* a card with no email (a Sign in with Apple relay sign-up): the switch's
   row, saying so, with the way to add one */
.builder-shell .builder-success .ob-email-add{display:flex;align-items:center;flex-wrap:wrap;gap:0 2px;min-height:52px;margin:12px 0 0;padding:0 2px;
  border-top:1px solid rgba(11,13,17,.08);font-size:16px;line-height:1.35;color:var(--fg)}
.builder-shell .builder-success .ob-email-add[hidden]{display:none}
.ob-email-add-t{font-weight:500}
.ob-email-add .ob-sep{color:var(--fg3)}
.ob-email-add .ob-link{padding:0 8px;color:#025FFD}
/* the dashboard bar: pinned to the pane's foot, quiet until Wallet is tapped.
   The view fills the pane, so on a tall screen the bar sits at the foot rather
   than under the last row; on a short one it is sticky and the rows scroll
   under its fade (the pane's own ground, so the fade has no edge). Its top
   padding is the gap above it, which margin-top:auto cannot promise. */
.builder-shell .builder-success:not([hidden]){display:flex;flex-direction:column;min-height:100%}
.ob-dashbar{position:sticky;bottom:0;z-index:2;margin:auto -20px calc(-20px - env(safe-area-inset-bottom));
  padding:24px 20px calc(12px + env(safe-area-inset-bottom));
  background:linear-gradient(to top,var(--ob-ground) 72%,transparent);
  /* the fade is not a target: only the button takes a tap */
  pointer-events:none}
.ob-dashbar-go{pointer-events:auto}
@media (min-width:700px){
  .ob-dashbar{margin:auto -40px -40px;padding:16px 40px 24px}
  /* the pane sits under the close button's row: the heading needs no more air */
  .builder-shell .builder-success:not([hidden]){padding-top:6px}
}
@media (min-width:700px) and (hover:hover) and (pointer:fine){
  /* a real pointer: the address line's targets at 32px, as the hand-off's */
  .ob-done-addr .ob-addr-live,.builder-shell .builder-success .ob-done-addr .ob-link{min-height:32px}
  .builder-shell .builder-success .ob-done-addr{margin-top:6px}
  .ob-email-switch{min-height:48px}
}
.ob-dashbar-go{position:relative;isolation:isolate;display:flex;align-items:center;justify-content:center;gap:8px;min-height:52px;
  border-radius:14px;color:#0147c2;font:600 17px/1.2 var(--body);letter-spacing:-.01em;text-decoration:none;
  -webkit-tap-highlight-color:transparent;transition:transform 160ms cubic-bezier(.23,1,.32,1)}
.ob-dashbar-go::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;background:rgba(2,95,253,.09)}
.ob-dashbar-go::after{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;background:#025FFD;
  box-shadow:0 8px 18px -10px rgba(2,95,253,.8);opacity:0;transition:opacity 240ms ease-out}
.ob-dashbar-go[data-primary="true"]{color:#fff}
.ob-dashbar-go[data-primary="true"]::after{opacity:1}
@media (hover:hover) and (pointer:fine){
  .ob-dashbar-go:hover::before{background:rgba(2,95,253,.14)}
  .ob-dashbar-go[data-primary="true"]:hover::after{opacity:.9}
  .ob-dashbar-go:hover svg{transform:translateX(2px)}
}
.ob-dashbar-go:active{transform:scale(.97)}
.ob-dashbar-go:focus-visible{outline:2px solid #025FFD;outline-offset:3px}
.ob-dashbar-go svg{width:18px;height:18px;transition:transform 160ms cubic-bezier(.23,1,.32,1)}
@media (prefers-reduced-motion:reduce){
  .ob-dashbar-go,.ob-dashbar-go svg,.ob-switch,.ob-switch i{transition:none}
  .ob-dashbar-go:active,.ob-email-switch input:active+.ob-switch{transform:none}
  .ob-dashbar-go::after,.ob-switch::before{transition:opacity 200ms ease}
}
/* a Pro checkout that could not start once the card was made */
.ob-trouble{margin-top:16px}
.ob-trouble[hidden]{display:none}
.ob-trouble .builder-error{margin-top:0}
.ob-retry[hidden]{display:none}

/* the secondary button (Retry checkout): 44px, a 12px radius, tinted, no
   outline, so the one filled button stays the one that matters on the screen */
.ob-retry{
  display:flex;align-items:center;justify-content:center;gap:8px;width:100%;min-height:44px;margin-top:12px;padding:0 20px;
  border:0;border-radius:12px;background:rgba(2,95,253,.08);color:#0147c2;box-shadow:none;
  font:600 16px/1.2 var(--body);letter-spacing:-.01em;text-decoration:none;cursor:pointer;
  -webkit-tap-highlight-color:transparent;transition:transform 160ms cubic-bezier(.23,1,.32,1)}
@media (hover:hover) and (pointer:fine){.ob-retry:hover{background:rgba(2,95,253,.14)}}
.ob-retry:active{transform:scale(.97)}
.ob-retry:disabled{opacity:.6;cursor:default;transform:none}

/* ── phone: the card stays in view beside the success view ──
   The sheet stops scrolling as a whole: the card sits at the top, larger
   than on the steps. For a beat after it settles the whole card shows, its
   real QR included (flow.js POCKET_HOLD); then the sheet rises over the QR
   and the foot (transform only, on the iOS drawer curve), leaving the header
   and the strip (flow.js measures --pocket and --pocket-tuck). The success
   view scrolls under it. */
@media (max-width:699px){
  .builder-shell.is-done{overflow:hidden;grid-template-rows:auto minmax(0,1fr);align-content:stretch}
  .builder-shell.is-done .builder-preview-pane{display:block;height:var(--pocket,calc(min(100vw - 112px,330px) * 1.27 + 30px));
    padding:14px 0 0;overflow:hidden}
  .builder-shell.is-done .ob-card.passcard{--pw:min(calc(100vw - 112px),330px);margin:0 auto}
  .builder-shell.is-done .builder-form-pane{overflow-y:auto;overscroll-behavior:contain;min-height:0;-webkit-overflow-scrolling:touch;margin-bottom:0;
    transition:transform 320ms cubic-bezier(.32,.72,0,1)}
  .builder-shell.is-done.is-pocketed .builder-form-pane{transform:translateY(calc(-1 * var(--pocket-tuck,0px)));margin-bottom:calc(-1 * var(--pocket-tuck,0px))}
  .builder-shell.is-done .builder-form-pane::before{display:block;opacity:0}
  .builder-shell.is-done.is-pocketed .builder-form-pane::before{opacity:1;transition-duration:320ms}
  /* the QR is for someone else's camera, and the sheet's edge would cut it */
  .builder-shell.is-done.is-pocketed .ob-card .qr,.builder-shell.is-done.is-pocketed .ob-card .qcap{opacity:0}
}

@media (prefers-reduced-motion:reduce){
  .ob-retry{transition:none}
}

/* ── one focus ring, everywhere in the sheet: 2px accent, 3px out ── */
.builder-shell :is(a,button,summary,label,[tabindex]:not([tabindex="-1"])):focus-visible{outline:2px solid #025FFD;outline-offset:3px}
.builder-shell .ob-icon:focus-visible{outline-offset:-1px}

/* ── the existing-account screen: the draft steps back, since it will not
   be made (flow.js .is-taken) ── */
.builder-shell .ob-card.passcard{transition:opacity 240ms ease-out,transform 240ms cubic-bezier(.23,1,.32,1)}
.builder-shell.is-taken .ob-card.passcard{opacity:.35;transform:scale(.96)}

/* ── desktop: the Wallet hand-off's QR is the one to scan; the card's own
   steps back while it is on screen (flow.js handoff()) ── */
.ob-card .qr{transition:opacity 180ms ease-out}
.builder-shell.is-handoff .ob-card .qr{opacity:.25}

@media (prefers-reduced-motion:reduce){
  .builder-shell .ob-primary.btn,.builder-shell .ob-card.passcard,.ob-card .qr{transition:none}
  .builder-shell .ob-primary.btn:active,.ob-provider:active,.ob-retry:active{transform:none}
  .builder-shell.is-taken .ob-card.passcard{transform:none}
  .builder-shell.is-done .builder-form-pane{transition:none}
}
@media (max-width:699px) and (max-height:720px){
  .ob-step .ob-lede.ob-save-lede{margin:-6px 0 12px;font-size:14.5px}
}
