/* ============================================================================
   SHIPIFY — css/flow.css
   The money surfaces: signup.html + app.html. Owned by the SIGNUP+APP cell.

   House rule for this file (from the brief): on money surfaces the mechanism
   goes CALM. The label stops performing and becomes the receipt — black ink,
   flat copy, no jokes, no red totals, no stamp animation. Every label built
   here passes calm:true. What stays is the *material*: thermal stock, dotted
   leaders, perforations, a print head that sweeps once when a number changes.

   Consumes tokens.css + shared.css. Adds nothing to the :root palette.
   Namespace: .fl-  (system owns .sy-, other cells own their own prefixes)
   ========================================================================== */

/* -------------------------------------------------------------- 1. page */

.fl-page { padding-bottom: var(--sp-400); }

.fl-head { max-width: 62ch; }
.fl-head .sy-h1 { margin-top: var(--sp-150); }
.fl-head .sy-lede { margin-top: var(--sp-200); }

/* a run of small honest print under a heading */
.fl-fineprint {
  margin-top: var(--sp-200);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--ink-muted);
}

/* ------------------------------------------------------------ 2. docket
   signup.html: the ask on the left, the label being composed on the right. */

.fl-docket {
  display: grid;
  gap: clamp(var(--sp-400), 5vw, var(--sp-800));
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 940px) {
  .fl-docket { grid-template-columns: 1.02fr .98fr; }
  .fl-docket__proof { position: sticky; top: calc(var(--sy-nav-h) + var(--sp-300)); }
}

.fl-docket__ask > * + * { margin-top: var(--sp-300); }

/* ------------------------------------------------------------- 3. forms */

.fl-formcard {
  position: relative;
  background: var(--surface);
  border: 2px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-400) var(--sp-300) var(--sp-300);
  box-shadow: 0 12px 28px -22px rgb(var(--sy-shadow) / .9);
}
/* the card is taped to the page — one strip, off-axis, above the top edge */
.fl-formcard__tape {
  position: absolute;
  top: -14px;
  left: var(--sp-400);
  z-index: 2;
}

.fl-form { margin: 0; }
.fl-form fieldset { margin: 0; padding: 0; border: 0; min-width: 0; }
.fl-form legend { padding: 0; }

/* fields sit on the 8px grid; shared.css already spaces .sy-field + .sy-field */
.fl-form__row { margin-top: var(--sp-300); }
.fl-form__actions { margin-top: var(--sp-400); }

/* the required marker is a word, not a symbol a screen reader has to guess */
.fl-req {
  margin-left: var(--sp-100);
  font-size: var(--fs-xs);
  letter-spacing: .12em;
  color: var(--sy-ink-danger);
}
.fl-opt {
  margin-left: var(--sp-100);
  font-size: var(--fs-xs);
  letter-spacing: .12em;
  color: var(--ink-muted);
}

/* honeypot — off-screen, never announced, never tabbable */
.fl-hp {
  position: absolute !important;
  left: -9999px;
  top: auto;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* -------------------------------------------------------- 4. status bar
   One live region under the button. It names the field when a submit is
   blocked — the button itself is never disabled, so the ask is never hidden. */

.fl-status {
  display: none;
  margin-top: var(--sp-200);
  padding: var(--sp-150) var(--sp-200);
  border: 2px solid var(--line);
  border-left-width: 6px;
  border-radius: 0 var(--r-md) var(--r-md) 0;
  background: var(--sy-stock);
  font-size: var(--fs-sm);
  line-height: 1.5;
}
.fl-status.is-shown { display: block; }
.fl-status--error { border-left-color: var(--accent); color: var(--sy-ink-danger); font-weight: 700; }
.fl-status--wait  { border-left-color: var(--ink-muted); color: var(--ink-muted); }
.fl-status--ok    { border-left-color: var(--line); }
.fl-status a { color: inherit; }

/* the submit button reports its own work */
.fl-submit__spin {
  width: 16px; height: 16px;
  flex: 0 0 auto;
  border: 3px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: fl-spin 720ms linear infinite;
}
@keyframes fl-spin { to { transform: rotate(360deg); } }

/* --------------------------------------------------------- 5. the stub
   The label column on signup. It is a receipt, so it sits on plain stock
   with a torn top edge rather than a card shadow. */

.fl-stub { position: relative; }
/* an email is longer than a price: let the value wrap inside the leader row
   rather than run off the edge of the stock, which .sy-label would clip */
.fl-stub .sy-label__line dd,
.fl-receipt .sy-label__line dd {
  flex: 0 1 auto;
  min-width: 0;
  text-align: right;
  overflow-wrap: anywhere;
}
.fl-stub__caption {
  display: block;
  margin-bottom: var(--sp-150);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.fl-stub__note { margin-top: var(--sp-200); }

/* success: Zip turns up once, small, and says nothing */
.fl-cheer {
  display: flex;
  align-items: center;
  gap: var(--sp-200);
  margin-top: var(--sp-300);
}
.fl-cheer img { width: 64px; height: 64px; }
.fl-cheer p { margin: 0; }

/* a short list of what joining does and does not mean */
.fl-promises {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--sp-150);
}
.fl-promises li {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: var(--sp-150);
  align-items: start;
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--ink-muted);
}
.fl-promises li::before {
  content: "";
  width: 18px; height: 4px;
  margin-top: .62em;
  background: var(--accent);
}

/* ===================================================== 6. app.html shell */

/* persistent, unmissable, and above every label on the page */
.fl-demobar {
  position: sticky;
  top: calc(var(--sy-nav-h) + 2px);
  z-index: 40;
  background: var(--line);
  color: var(--bg);
  border-bottom: 2px solid var(--line);
}
.fl-demobar__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-100) var(--sp-200);
  padding-block: var(--sp-100);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  line-height: 1.4;
}
/* Reversed on the dark bar: this tag is the whole reason the bar exists, so it
   is solid red stock with white ink (5.11:1) rather than thin red-on-near-black
   (--accent-bright on --line measured 3.58:1). */
.fl-demobar__tag {
  padding: 2px var(--sp-100);
  border: 2px solid var(--accent);
  border-radius: var(--r-sm);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  white-space: nowrap;
}
.fl-demobar__text { color: var(--kraft); }
.fl-demobar a { color: var(--bg); }

/* ---------------------------------------------------------- 7. step rail
   Four labels on a backing strip, torn apart by perforations. */

.fl-rail {
  --fl-rail-line: rgb(var(--sy-shadow) / .3);
  list-style: none;
  margin: 0 0 var(--sp-400);
  padding: 0;
  display: grid;
  gap: 0;
  grid-template-columns: 1fr;
  border: 2px solid var(--line);
  border-radius: var(--r-md);
  background: var(--sy-stock);
  overflow: hidden;
  /* clears the sticky nav AND the sticky demo bar when a step scrolls into view */
  scroll-margin-top: calc(var(--sy-nav-h) + 56px);
}
@media (min-width: 720px) { .fl-rail { grid-template-columns: repeat(4, 1fr); } }

.fl-rail__step { position: relative; display: flex; }
/* the perforation between steps */
.fl-rail__step + .fl-rail__step::before {
  content: "";
  position: absolute;
  z-index: 2;
  left: 0; right: 0; top: -1px;
  height: 2px;
  background-image: radial-gradient(circle at 50% 50%, var(--fl-rail-line) 0 1.5px, transparent 1.6px);
  background-size: 10px 2px;
  background-repeat: repeat-x;
}
@media (min-width: 720px) {
  .fl-rail__step + .fl-rail__step::before {
    left: -1px; right: auto; top: 0; bottom: 0;
    width: 2px; height: auto;
    background-size: 2px 10px;
    background-repeat: repeat-y;
  }
}

.fl-rail__btn {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: var(--sp-150);
  min-height: 56px;
  padding: var(--sp-150) var(--sp-200);
  background: transparent;
  border: 0;
  border-radius: 0;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  text-align: left;
  color: var(--ink-muted);
  cursor: default;
}
.fl-rail__btn[data-reachable="yes"] { cursor: pointer; }
.fl-rail__btn[data-reachable="yes"]:hover { background: var(--bg); color: var(--ink); }
.fl-rail__btn:focus-visible { outline-offset: -4px; }

.fl-rail__n {
  display: grid;
  place-items: center;
  width: 28px; height: 28px;
  flex: 0 0 auto;
  border: 2px solid currentColor;
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: 700;
  line-height: 1;
}
.fl-rail__name { font-family: var(--font-display); font-size: var(--fs-base); font-weight: 500; }

.fl-rail__step[data-state="done"] .fl-rail__btn { color: var(--ink); }
.fl-rail__step[data-state="done"] .fl-rail__n { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.fl-rail__step[data-state="current"] { background: var(--surface); }
.fl-rail__step[data-state="current"] .fl-rail__btn { color: var(--ink); }
.fl-rail__step[data-state="current"] .fl-rail__name { font-weight: 700; }
.fl-rail__step[data-state="current"] .fl-rail__n {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* ------------------------------------------------------------ 8. panels */

.fl-panel { display: none; }
.fl-panel.is-active { display: block; }
.fl-panel:focus { outline: none; }
.fl-panel:focus-visible { outline: 3px solid var(--ink); outline-offset: 6px; border-radius: var(--r-md); }

.fl-panel__head { margin-bottom: var(--sp-300); }
.fl-panel__head .sy-h2 { margin-top: var(--sp-100); }
.fl-panel__head p { margin-top: var(--sp-150); max-width: 60ch; color: var(--ink-muted); }

.fl-panel__body {
  display: grid;
  gap: clamp(var(--sp-400), 4vw, var(--sp-600));
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 940px) {
  .fl-panel__body--split { grid-template-columns: 1.05fr .95fr; }
}

.fl-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-200);
  margin-top: var(--sp-400);
  padding-top: var(--sp-300);
  border-top: 2px solid var(--line);
}
.fl-actions__spacer { flex: 1 1 auto; }
.fl-actions .sy-note { flex: 1 1 100%; margin: 0; }

/* ------------------------------------------------- 9. selectable options
   Each carrier option is a real label you can pick. The radio stays a radio. */

.fl-options {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--sp-300);
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
}

.fl-option { position: relative; display: block; }
.fl-option__input {
  position: absolute;
  top: var(--sp-200);
  left: var(--sp-200);
  z-index: 3;
  width: 24px; height: 24px;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.fl-option__box {
  display: block;
  padding: var(--sp-150);
  border: 2px dashed rgb(var(--sy-shadow) / .35);
  border-radius: var(--r-md);
  background: transparent;
  cursor: pointer;
  transition: border-color var(--dur-quick) linear, background-color var(--dur-quick) linear;
}
.fl-option__box:hover { border-color: var(--ink-muted); background: var(--surface); }
/* general sibling, not adjacent: a visually hidden <label> sits between the
   radio and the box so the radio keeps a real, price-bearing accessible name */
.fl-option__input:focus-visible ~ .fl-option__box {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
}
.fl-option__input:checked ~ .fl-option__box {
  border-style: solid;
  border-color: var(--accent);
  background: var(--surface);
}
/* the selected option carries a picked chit */
.fl-option__input:checked ~ .fl-option__box .fl-option__pick { display: inline-flex; }
.fl-option__pick {
  display: none;
  position: absolute;
  z-index: 3;
  top: var(--sp-100);
  right: var(--sp-100);
  padding: 2px var(--sp-100);
  background: var(--accent);
  border: 2px solid var(--accent);
  border-radius: var(--r-sm);
  color: var(--accent-ink);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
}
/* the label inside an option must clear the radio in its corner */
.fl-option__box .sy-label__head { padding-left: 56px; }

.fl-option__foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-100) var(--sp-150);
  align-items: center;
  margin-top: var(--sp-150);
  padding-inline: var(--sp-050);
  font-size: var(--fs-sm);
}
.fl-option__flag {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--sy-ink-danger);
}

/* ------------------------------------------------------- 10. summary bar
   The total is always above the button it belongs to. Never the other way. */

.fl-due {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-100) var(--sp-300);
  margin-top: var(--sp-300);
  padding: var(--sp-200) var(--sp-300);
  background: var(--ink);
  color: var(--bg);
  border-radius: var(--r-md);
}
.fl-due__k {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--kraft);
}
.fl-due__v {
  font-family: var(--font-mono);
  font-size: var(--fs-2xl);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.fl-due__note { flex: 1 1 100%; margin: 0; font-size: var(--fs-sm); color: var(--kraft); }

/* ============================================ 11. the 4x6 thermal label ==
   The artifact at the end of the flow. Real proportions (4in x 6in), real
   postal furniture, entirely CSS + the shared Code 39 renderer. */

.fl-sheetwrap {
  container-type: inline-size;
  container-name: sheet;
  width: 100%;
  max-width: 420px;
  margin-inline: auto;
}

.fl-sheet {
  position: relative;
  aspect-ratio: 4 / 6;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--sy-stock);
  color: var(--ink);
  border: 2px solid var(--line);
  border-radius: var(--r-sm);
  box-shadow: 0 1px 0 var(--line), 0 26px 44px -30px rgb(var(--sy-shadow) / .95);
  font-family: var(--font-mono);
  line-height: 1.2;
  /* one type scale drives the whole sheet; overridden per container width */
  --u: 13px;
}
/* thermal stock grain, and a hint of the roll's curl at the top */
.fl-sheet::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background-image:
    linear-gradient(180deg, rgb(var(--sy-shadow) / .10), transparent 26px),
    repeating-linear-gradient(0deg, rgb(var(--sy-shadow) / .045) 0 1px, transparent 1px 3px);
}

@supports (container-type: inline-size) {
  @container sheet (min-width: 0px) {
    .fl-sheet { --u: 3.1cqi; }
  }
}

.fl-sheet__band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-100);
  padding: calc(var(--u) * .62) calc(var(--u) * .72);
  background: var(--line);
  color: var(--bg);
}
.fl-sheet__service {
  font-family: var(--font-display);
  font-size: calc(var(--u) * 1.24);
  font-weight: 600;
  letter-spacing: .01em;
  text-transform: uppercase;
  line-height: 1.05;
}
.fl-sheet__weight {
  font-size: calc(var(--u) * .82);
  font-weight: 600;
  letter-spacing: .1em;
  white-space: nowrap;
}

.fl-sheet__upper {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: calc(var(--u) * .6);
  padding: calc(var(--u) * .72);
  border-bottom: 2px solid var(--line);
}

.fl-sheet__from {
  font-size: calc(var(--u) * .78);
  line-height: 1.35;
  text-transform: uppercase;
  letter-spacing: .02em;
}
.fl-sheet__cap {
  display: block;
  margin-bottom: calc(var(--u) * .2);
  font-size: calc(var(--u) * .62);
  font-weight: 700;
  letter-spacing: .22em;
  color: var(--ink-muted);
}

.fl-sheet__indicia {
  flex: 0 0 auto;
  padding: calc(var(--u) * .3) calc(var(--u) * .45);
  border: 2px solid var(--line);
  text-align: center;
  font-size: calc(var(--u) * .6);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  line-height: 1.45;
}
.fl-sheet__indicia b { display: block; font-size: calc(var(--u) * .74); letter-spacing: .06em; }
.fl-sheet__indicia i { display: block; font-style: normal; color: var(--ink-muted); letter-spacing: .06em; }

.fl-sheet__to {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: calc(var(--u) * .1);
  padding: calc(var(--u) * .9) calc(var(--u) * .72);
  font-size: calc(var(--u) * 1.14);
  font-weight: 600;
  line-height: 1.28;
  text-transform: uppercase;
  letter-spacing: .01em;
  word-break: break-word;
}
.fl-sheet__to .fl-sheet__cap { font-size: calc(var(--u) * .62); }
.fl-sheet__zoneline {
  margin-top: calc(var(--u) * .35);
  font-size: calc(var(--u) * .72);
  font-weight: 700;
  letter-spacing: .16em;
  color: var(--ink-muted);
}

.fl-sheet__meta {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--u) * .2) calc(var(--u) * .8);
  padding: calc(var(--u) * .5) calc(var(--u) * .72);
  border-top: 2px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-size: calc(var(--u) * .66);
  letter-spacing: .08em;
  text-transform: uppercase;
}
.fl-sheet__meta span { white-space: nowrap; }
.fl-sheet__meta b { font-weight: 700; }
.fl-sheet__meta em { font-style: normal; color: var(--ink-muted); }

.fl-sheet__routing {
  padding: calc(var(--u) * .4) calc(var(--u) * .72) 0;
}
.fl-sheet__routing .sy-barcode { height: calc(var(--u) * 1.5); color: var(--ink); }

.fl-sheet__code {
  padding: calc(var(--u) * .55) calc(var(--u) * .72) calc(var(--u) * .8);
  border-top: 2px solid var(--line);
  margin-top: calc(var(--u) * .4);
}
.fl-sheet__code .sy-barcode { height: calc(var(--u) * 3.1); color: var(--ink); }
.fl-sheet__human {
  padding-top: calc(var(--u) * .34);
  text-align: center;
  font-size: calc(var(--u) * .68);
  font-weight: 700;
  letter-spacing: .2em;
  text-indent: .2em;
}

/* the sheet's own DEMO stamp — bigger than the card stamp, still calm */
.fl-sheet__stamp {
  position: absolute;
  z-index: 3;
  right: calc(var(--u) * .6);
  bottom: calc(var(--u) * 5.4);
  padding: calc(var(--u) * .16) calc(var(--u) * .5);
  border: 3px solid var(--accent);
  border-radius: 8px 5px 9px 4px;
  box-shadow: inset 0 0 0 1px var(--sy-accent-bleed);
  color: var(--accent);
  font-family: var(--font-display);
  font-size: calc(var(--u) * 1.2);
  font-weight: 600;   /* footprint unchanged; the legibility comes from the ink */
  letter-spacing: .14em;
  text-transform: uppercase;
  transform: rotate(-8deg);
  pointer-events: none;
  mix-blend-mode: multiply;
}

/* the print head crossing the sheet once, when it is first produced */
.fl-sheet__head {
  position: absolute;
  z-index: 5;
  left: -2px; right: -2px;
  top: 0;
  height: 4px;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--accent-bright) 12%, var(--sy-stock) 50%, var(--accent-bright) 88%, transparent);
  box-shadow: 0 0 16px 4px var(--sy-glow-hot);
}
.fl-sheet.is-printing .fl-sheet__head { animation: sy-printhead 900ms var(--ease-print) both; }
.fl-sheet.is-printing { animation: fl-sheet-print 900ms var(--ease-print) both; }
@keyframes fl-sheet-print {
  0%   { clip-path: inset(0 0 100% 0); filter: contrast(1.4) saturate(.5); }
  100% { clip-path: inset(0 0 0 0);    filter: none; }
}

/* the caption under the sheet */
.fl-sheetnote { margin-top: var(--sp-200); text-align: center; }

/* --------------------------------------------------- 12. receipt column */

.fl-receipt > * + * { margin-top: var(--sp-300); }

.fl-locked {
  display: grid;
  gap: var(--sp-150);
  padding: var(--sp-300);
  border: 2px dashed rgb(var(--sy-shadow) / .4);
  border-radius: var(--r-md);
  background: var(--surface);
}
.fl-locked__title {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.fl-locked p { margin: 0; font-size: var(--fs-sm); color: var(--ink-muted); }

/* an empty/error state that still looks like it belongs on a workbench */
.fl-empty {
  padding: var(--sp-400) var(--sp-300);
  border: 2px dashed rgb(var(--sy-shadow) / .4);
  border-radius: var(--r-md);
  background: var(--surface);
  text-align: center;
}
.fl-empty p { max-width: 44ch; margin-inline: auto; color: var(--ink-muted); }
.fl-empty .sy-btn { margin-top: var(--sp-200); }

/* --------------------------------------------------- 13. reduced motion */

@media (prefers-reduced-motion: reduce) {
  .fl-submit__spin { animation: none; border-top-color: currentColor; opacity: .5; }
  .fl-sheet.is-printing,
  .fl-sheet.is-printing .fl-sheet__head { animation: none; }
  .fl-sheet__head { display: none; }
}

/* ------------------------------------------------------------ 14. print */

@media print {
  .fl-demobar, .fl-rail, .fl-actions, .fl-form, .fl-status, .fl-due { display: none !important; }
  .fl-panel { display: block !important; }
  .fl-sheet { box-shadow: none; break-inside: avoid; }
  .fl-sheet__stamp { opacity: 1; }
}
