/* flow.css — the pages where a customer hands over photographs, money and trust:
   sign in, register, confirm, the account, the holding page, the gift page, and
   the order steps (who, extras, review, pay, done, progress, phone).

   Everything here leans on the tokens in site.css. Nothing invents a colour.
   The rule the whole file obeys: these pages must read as calm, legible and
   obviously safe, so the gold is spent only where a customer has to look. */

/* ---------------------------------------------------------------- 1. forms */

/* A form that takes something real is bounded, not full width: 560px is about
   as wide as a field can be before the eye loses the start of the next line. */
.flow-form { max-width: 560px; }
.flow-form .actions { margin-top: 32px; }

/* the two-column order steps: the work on the left, the aside on the right */
.flow-two { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: 56px; align-items: start; }
.flow-aside { position: sticky; top: calc(var(--header-h) + 24px); }
@media (max-width: 980px) {
  .flow-two { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .flow-aside { position: static; }
}

/* a group of fields under one quiet heading, divided from the next by a hairline */
.fieldgroup { border-top: 1px solid var(--hair-soft); padding-top: 28px; margin-top: 28px; }
.fieldgroup:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.fieldgroup > h2 { font: 600 20px/1.3 var(--sans); color: var(--champagne); margin: 0 0 6px; }
.fieldgroup > .note { margin: 0 0 22px; max-width: 52ch; }

/* the file field: the input, then what was actually chosen, shown back */
.upload .drop { border: 1px dashed var(--hair); border-radius: var(--r-pic); background: var(--night-deep); padding: 14px 16px; transition: border-color .18s ease; }
.upload .drop:hover, .upload .drop:focus-within { border-color: var(--brass-2); }
.upload input[type=file] { border: 0; background: none; padding: 0; }
.upload input[type=file]:focus-visible { outline: 2px solid rgba(220, 192, 122, .55); outline-offset: 4px; }
.upload .chosen { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-start; margin-top: 14px; }
.upload .chosen:empty { display: none; }
.upload .shot { width: 76px; }
.upload .shot .keyed { aspect-ratio: 1 / 1; }
.upload .shot .cap { display: block; margin-top: 6px; font-size: 12px; line-height: 1.3; color: var(--caption); overflow-wrap: anywhere; }
.upload .held { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--muted); }
.upload .held::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--good); flex: none; }

/* a picture already on file, shown so nobody wonders whether it arrived */
.onfile { display: flex; gap: 14px; align-items: center; margin: 0 0 14px; }
.onfile .keyed { width: 64px; aspect-ratio: 1 / 1; flex: none; }
.onfile .say { font-size: 14px; color: var(--muted); }

/* the frame picker on the extras step */
.frames { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 12px; margin-top: 10px; }
.frames .fr { display: block; position: relative; padding: 10px; border: 1px solid var(--hair); border-radius: var(--r-pic); background: var(--night-deep); cursor: pointer; transition: border-color .18s ease, transform .18s ease; }
.frames .fr:hover { border-color: var(--brass-2); transform: translateY(-2px); }
.frames .fr input { position: absolute; opacity: 0; width: 0; height: 0; }
.frames .fr:has(input:focus-visible) { outline: 2px solid rgba(220, 192, 122, .55); outline-offset: 2px; }
.frames .fr:has(input:checked) { border-color: var(--brass); box-shadow: 0 0 0 1px var(--brass), inset 0 0 0 1px rgba(243, 230, 200, .16); }
.frames .fr img { display: block; width: 100%; height: auto; border-radius: 4px; }
.frames .fr .asis { display: flex; align-items: center; justify-content: center; height: 96px; border-radius: 4px; font-size: 13px; text-align: center; padding: 0 10px; color: var(--muted);
  background: repeating-linear-gradient(45deg, rgba(192, 164, 92, .10), rgba(192, 164, 92, .10) 8px, rgba(192, 164, 92, .02) 8px, rgba(192, 164, 92, .02) 16px); }
.frames .fr b { display: block; margin-top: 10px; font: 600 14px/1.3 var(--sans); color: var(--champagne); }
.frames .fr small { display: block; margin-top: 3px; font-size: 12.5px; line-height: 1.4; color: var(--caption); }

/* A shim, not a component. The four picker steps this lane does not own
   (occasion, game, style, outfit) mark their cards `.choice`, and the rule that
   drew them lived in the step indicator's old inline stylesheet. It is kept here,
   in the night's own colours, so those pages stay whole until their own lane
   restyles them to `.choice-card`. */
.choice { position: relative; cursor: pointer; }
.choice input[type=radio], .choice input[type=checkbox] { position: absolute; top: 14px; left: 14px; z-index: 2; }
.choice:hover { border-color: var(--brass-2); }
.choice:has(input:checked) { border-color: var(--brass); box-shadow: 0 0 0 1px var(--brass), inset 0 0 0 1px rgba(243, 230, 200, .14); }
.choice:has(input:focus-visible) { outline: 2px solid rgba(220, 192, 122, .55); outline-offset: 2px; }
.choice.any { border-style: dashed; }
.choice .hint { display: block; margin-top: 4px; color: var(--caption); }

/* the ending message: one radio per line of words, the last one a textarea */
.words { margin-top: 6px; }
.words .radio { padding: 11px 0; border-bottom: 1px solid var(--hair-soft); margin: 0; }
/* the lines are quoted exactly as the game letters them, so they are set small
   and tracked, as a quotation of the game's own type rather than a shouted label */
.words .radio span { font-size: 14.5px; line-height: 1.5; letter-spacing: .015em; color: var(--muted); }
.words .radio input:checked + span { color: var(--champagne); }
.words .radio:last-of-type { border-bottom: 0; }
.words textarea { margin-top: 12px; }

/* -------------------------------------------------------- 2. money on screen */

/* the itemised bill. The total row's markup is read by the tests, so its
   shape (tr.sum, three cells, td.n last) must not change. */
.bill { width: 100%; border-collapse: collapse; margin: 14px 0 4px; font-size: 15px; }
.bill td { padding: 9px 0; border-bottom: 1px solid var(--hair-soft); vertical-align: top; color: var(--text); }
.bill td.n { text-align: right; white-space: nowrap; padding-left: 16px; color: var(--muted); font-variant-numeric: lining-nums tabular-nums; }
.bill td.n b { color: var(--champagne); font-weight: 600; }
.bill tr.tier td { color: var(--champagne); }
.bill tr.sum td { border-bottom: 0; padding-top: 16px; font: 600 17px/1 var(--sans); color: var(--champagne); }
.bill tr.sum td.n { font-family: var(--display); font-size: 32px; font-weight: 600; color: var(--champagne); }

/* the invoice surface: a brass keyline, because this is the promise */
.billbox { border: 1px solid var(--brass); border-radius: var(--r-button); background: var(--night-deep); padding: 24px 26px 26px; box-shadow: inset 0 0 0 1px rgba(243, 230, 200, .10); }
.billbox > b { display: block; font: 600 17px/1.3 var(--sans); color: var(--champagne); }
.billbox .note { margin-top: 12px; }

/* the running total on the extras step */
.pricebox { position: sticky; top: calc(var(--header-h) + 24px); }
.pricebox .row { display: flex; justify-content: space-between; gap: 16px; padding: 8px 0; border-bottom: 1px solid var(--hair-soft); font-size: 15px; color: var(--text); }
.pricebox .row b { color: var(--champagne); font-weight: 600; font-variant-numeric: lining-nums tabular-nums; }
.pricebox .row.tier span { color: var(--champagne); }
.pricebox .tot { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; padding-top: 16px; font: 600 17px/1 var(--sans); color: var(--champagne); }
.pricebox .tot b { font-family: var(--display); font-size: 32px; font-weight: 600; font-variant-numeric: lining-nums tabular-nums; }
.pricebox #priceinc { margin-top: 10px; }
@media (max-width: 980px) { .pricebox { position: static; } }

/* the plans on the review page: your own order, priced three ways */
.offers { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; margin: 18px 0 0; align-items: stretch; }
.offer { display: flex; flex-direction: column; padding: 24px 24px 26px; border: 1px solid var(--hair); border-radius: var(--r-button); background: var(--night-deep); min-width: 0; }
.offer .tagline { font: 600 14px/1.3 var(--sans); color: var(--brass-2); min-height: 18px; margin-bottom: 8px; }
.offer .pname { font: 600 17px/1.3 var(--sans); color: var(--champagne); }
.offer .pp { font-family: var(--display); font-size: 42px; font-weight: 600; line-height: 1; color: var(--champagne); margin: 12px 0 4px; font-variant-numeric: lining-nums tabular-nums; }
.offer .pp small { font: 500 14px/1 var(--sans); color: var(--caption); margin-left: 8px; }
.offer .blurb { font-size: 15px; line-height: 1.5; color: var(--muted); margin: 8px 0 0; }
.offer .inc { font-size: 14px; line-height: 1.5; color: var(--muted); margin: 14px 0 0; }
.offer .ex { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hair-soft); }
.offer .ex .h { display: block; font: 500 14px/1.3 var(--sans); color: var(--caption); margin-bottom: 6px; }
.offer .ex .row { display: flex; justify-content: space-between; gap: 12px; font-size: 14px; padding: 3px 0; color: var(--text); }
.offer .ex .row b { color: var(--champagne); font-weight: 600; font-variant-numeric: lining-nums tabular-nums; }
.offer .tot { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-top: auto; padding-top: 18px; font: 600 15px/1 var(--sans); color: var(--champagne); }
.offer .tot b { font-family: var(--display); font-size: 26px; font-weight: 600; font-variant-numeric: lining-nums tabular-nums; }
.offer .no { font-size: 14px; line-height: 1.5; color: #f2b3b3; margin: 14px 0 0; }
.offer .is { font-size: 14px; color: var(--muted); margin: 14px 0 0; }
.offer .actions { margin-top: 18px; }
.offer.off { opacity: .78; }
/* the plan they are on: the second and last place the gilt is spent */
.offer.on { border-color: var(--brass); box-shadow: 0 0 0 1px var(--brass), inset 0 0 0 1px rgba(243, 230, 200, .16); }

/* ---------------------------------------------------- 3. the progress page */

/* the journey, as a real sequence: five beats on one brass rail */
.journey { list-style: none; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 16px; margin: 0 0 40px; padding: 22px 0 0; position: relative; }
.journey::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--hair); }
.journey li { position: relative; padding-top: 18px; font: 500 14px/1.4 var(--sans); color: var(--caption); min-width: 0; }
.journey li::before { content: ""; position: absolute; top: -5px; left: 0; width: 9px; height: 9px; border-radius: 50%; background: var(--night); box-shadow: 0 0 0 1px var(--hair); }
.journey li.done { color: var(--muted); }
.journey li.done::before { background: var(--brass); box-shadow: 0 0 0 1px var(--brass); }
.journey li.at { color: var(--champagne); font-weight: 600; }
.journey li.at::before { background: var(--brass-2); box-shadow: 0 0 0 1px var(--brass-2), 0 0 0 5px rgba(220, 192, 122, .22); }
@media (max-width: 860px) {
  .journey { grid-auto-flow: row; grid-auto-columns: auto; gap: 0; padding: 0 0 0 20px; }
  .journey::before { left: 4px; right: auto; top: 6px; bottom: 6px; width: 1px; height: auto; }
  .journey li { padding: 8px 0 8px 0; }
  .journey li::before { top: 13px; left: -20px; }
}

/* the bar: the worker's own number, drawn as far as it has actually got */
.prog { max-width: 720px; margin: 0 0 10px; }
.prog .bar { height: 12px; border-radius: 999px; background: var(--night-deep); box-shadow: inset 0 0 0 1px var(--hair); overflow: hidden; }
.prog .bar span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--brass-dark), var(--brass) 55%, var(--brass-2)); box-shadow: 0 0 12px rgba(220, 192, 122, .35); transition: width .8s cubic-bezier(.2, .7, .2, 1); }
.prog .pline { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; margin-top: 12px; }
.prog .pline b { font: 600 17px/1.3 var(--sans); color: var(--champagne); }
.prog .pline .pc { font-family: var(--display); font-size: 28px; font-weight: 600; color: var(--champagne); font-variant-numeric: lining-nums tabular-nums; }
/* the one thing on the site allowed to move on its own, and only while a game
   is actually being drawn: the leading edge of a bar that is genuinely working */
@media (prefers-reduced-motion: no-preference) {
  .prog.live .bar span { position: relative; }
  .prog.live .bar span::after { content: ""; position: absolute; inset: 0 0 0 auto; width: 34px; border-radius: 999px; background: linear-gradient(90deg, rgba(243, 230, 200, 0), rgba(243, 230, 200, .55)); animation: breathe 2.4s ease-in-out infinite; }
  @keyframes breathe { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
}

/* the three attempts: a gallery of framed prints, not a form */
.attempts { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 28px; margin: 8px 0 0; align-items: start; }
.attempts.one { grid-template-columns: minmax(0, 560px); }
.attempt { margin: 0; }
.attempt .keyed { aspect-ratio: 4 / 5; }
.attempt .keyed > img { object-fit: contain; background: var(--champagne); }
.attempt .under { display: flex; flex-wrap: wrap; gap: 12px 18px; align-items: center; justify-content: space-between; margin-top: 16px; }
.attempt .under .who { font-size: 14px; color: var(--caption); }
.attempt form { margin: 0; }
.again { display: flex; gap: 24px; align-items: center; flex-wrap: wrap; margin: 36px 0 0; }
.again .note { max-width: 46ch; margin: 0; }

/* the game in every format */
.cover-play { display: block; position: relative; max-width: 720px; }
.cover-play .keyed { aspect-ratio: 5 / 3; }
.cover-play .go { position: absolute; left: 18px; bottom: 18px; display: inline-flex; align-items: center; gap: 9px; height: 44px; padding: 0 20px; border-radius: var(--r-button); background: linear-gradient(160deg, var(--brass-2), #b8994f); color: var(--ink); font: 600 15px/1 var(--sans); box-shadow: 0 10px 24px -12px rgba(4, 7, 26, .9); }
.cover-play:hover .go { filter: brightness(1.06); }
.cover-play .go svg { width: 12px; height: 12px; fill: currentColor; }
.formats { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 18px; }
.formats a { display: inline-flex; align-items: center; gap: 10px; height: 46px; padding: 0 18px; border: 1px solid var(--hair); border-radius: var(--r-pic); background: transparent; color: var(--champagne); text-decoration: none; font: 600 15px/1 var(--sans); transition: border-color .18s ease, transform .18s ease; }
.formats a:hover { border-color: var(--brass-2); transform: translateY(-1px); }
.formats a.off { opacity: .4; pointer-events: none; }
.formats svg { width: 20px; height: 20px; flex: none; }

/* one game on the account page */
.mygame { padding: 26px 28px 28px; }
.mygame .head { display: flex; flex-wrap: wrap; gap: 12px 16px; align-items: baseline; }
.mygame .head b { font: 600 20px/1.3 var(--sans); color: var(--champagne); }
.mygame .meta { margin-top: 8px; font-size: 15px; line-height: 1.6; color: var(--muted); }
.mygame .meta span { color: var(--caption); }
.mygame .thin { max-width: 420px; margin-top: 16px; }
.mygame .thin .bar { height: 8px; border-radius: 999px; background: var(--night); box-shadow: inset 0 0 0 1px var(--hair); overflow: hidden; }
.mygame .thin .bar span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--brass-dark), var(--brass-2)); }
.mygame .thin .note { margin-top: 8px; }

/* --------------------------------------------------- 4. small set pieces */

/* the gift a recipient opens */
.gift { max-width: 720px; }
.gift .from { font: 500 15px/1.4 var(--sans); color: var(--brass-2); margin: 0 0 10px; }
.gift .msg { margin: 0 0 32px; padding: 20px 24px; border-left: 2px solid var(--brass); background: var(--night-deep); border-radius: 0 var(--r-pic) var(--r-pic) 0; font-size: 19px; line-height: 1.6; color: var(--champagne); }
.gift .msg p { margin: 0 0 .4em; }

/* the gift card a recipient opens (9 Sep 2026): one brass keyline, the amount
   in the display face, the code large and plain so it can be read out loud */
.gcard { border: 1px solid var(--brass); border-radius: var(--r-button); background: var(--night-deep); padding: 26px 28px 24px; margin: 0 0 28px; box-shadow: inset 0 0 0 1px rgba(243, 230, 200, .10); }
.gcard-head { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; flex-wrap: wrap; }
.gcard-head .kind { font: 600 17px/1.3 var(--sans); color: var(--champagne); }
.gcard-head .amount { font-family: var(--display); font-weight: 600; font-size: 42px; line-height: 1; color: var(--champagne); font-variant-numeric: lining-nums tabular-nums; }
.gcard-code { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--hair-soft); display: flex; align-items: center; gap: 16px 20px; flex-wrap: wrap; }
.gcard-code .label { flex-basis: 100%; font: 500 14px/1.4 var(--sans); color: var(--caption); }
.gcard-code code { font-size: 26px; line-height: 1.3; letter-spacing: .06em; color: var(--champagne); word-break: break-all; user-select: all; }
.gcard .use { margin: 18px 0 0; font-size: 15px; color: var(--muted); }
/* the claim link (10 Sep 2026): the one place it can be pressed rather than
   read out, so the button leads and the address itself sits under it small,
   for a reader who would rather copy it than trust a button */
.gcard-link { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--hair-soft); display: flex; align-items: center; gap: 12px 16px; flex-wrap: wrap; }
.gcard-link .label { flex-basis: 100%; font: 500 14px/1.4 var(--sans); color: var(--caption); }
.gcard-link code { flex-basis: 100%; font-size: 13px; line-height: 1.5; color: var(--muted); word-break: break-all; user-select: all; }
.giftcard-link { margin-top: 8px; }
.giftcard-link summary { cursor: pointer; color: var(--brass-2); font-size: 14px; }
.giftcard-link code { display: inline-block; margin-top: 8px; font-size: 14px; color: var(--champagne); word-break: break-all; user-select: all; }
.giftcard-row { font-size: 15px; line-height: 1.55; color: var(--text); }
.giftcard-row .note { display: block; margin-top: 4px; }
.giftcard-code { margin-top: 8px; }
.giftcard-code summary { cursor: pointer; color: var(--brass-2); font-size: 14px; }
.giftcard-code code { display: inline-block; margin-top: 8px; font-size: 20px; letter-spacing: .06em; color: var(--champagne); user-select: all; }

/* the gift card fields on the extras step */
.gcfields[hidden] { display: none; }
.gcfields .two { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 12px; }

/* the holding page: its own document, so it carries its own centring */
.closed-page { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 40px 20px; }
.closed { max-width: 620px; width: 100%; }
.closed .tile { display: block; width: 52px; height: 52px; border-radius: 12px; background: var(--tile); overflow: hidden; box-shadow: 0 0 0 1px var(--hair); margin-bottom: 28px; }
.closed h1 { font-size: 42px; }
.closed .demos { display: flex; gap: 16px 28px; flex-wrap: wrap; align-items: center; margin: 32px 0 0; }
.closed .foot { border-top: 1px solid var(--hair); margin-top: 40px; padding-top: 20px; font-size: 14px; line-height: 1.7; color: var(--caption); }
.closed .foot a { color: var(--muted); }

/* the phone instructions */
.howto { counter-reset: step; list-style: none; margin: 16px 0 0; padding: 0; }
.howto li { position: relative; padding: 0 0 18px 40px; font-size: 16px; line-height: 1.6; color: var(--text); }
.howto li::before { counter-increment: step; content: counter(step); position: absolute; left: 0; top: 0; width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--hair); color: var(--brass-2); font: 600 14px/24px var(--sans); text-align: center; }
.howto li:last-child { padding-bottom: 0; }

/* a plain list of what happens next, on the review page */
.next { list-style: none; margin: 14px 0 0; padding: 0; }
.next li { position: relative; padding: 0 0 14px 22px; font-size: 15px; line-height: 1.55; color: var(--muted); }
.next li::before { content: ""; position: absolute; left: 0; top: 9px; width: 6px; height: 6px; border-radius: 50%; background: var(--brass); }
.next li:last-child { padding-bottom: 0; }

/* the summary of an order, read back before it is placed */
.recap dt { font: 500 14px/1.4 var(--sans); color: var(--caption); }
.recap dd { margin: 4px 0 18px; font-size: 16px; line-height: 1.5; color: var(--text); }
.recap dd b { color: var(--champagne); }
.recap dd:last-child { margin-bottom: 0; }

/* an admin's log, kept out of the way */
pre.log { font-size: 12.5px; line-height: 1.6; max-height: 340px; }
.upload-status[hidden] { display: none; }
.upload-status { margin-top: 24px; }
.upload-status progress { width: 100%; height: 14px; accent-color: var(--brass-2); }
.upload .shot button { margin-top: 6px; min-height: 32px; font-size: 12px; }
.upload > .btn { margin-top: 12px; }
