/* The signed-in shell. Deliberately thin: it borrows the marketing site's
   tokens and type from /style.css and adds only what a plain page needs, so
   there is one set of colours to keep at AAA rather than two. */

/* A pane that is hidden is hidden.
   `.pane.split { display: grid }` is a class selector and beats the browser's
   own `[hidden] { display: none }`, so every hidden step was still laid out and
   the page was three times taller than the one step anybody could see. */
[hidden] { display: none !important; }

body.app {
  min-height: 100vh;
  background: var(--paper);
  --apptop-h: 53px;
}

/* Every step fits one viewport, no scrolling, from a 15-inch laptop up.
   The height budget is roughly 800px of usable viewport on a 1440x900 laptop,
   minus the bar above — so about 700px for a whole step, and the primary
   button is never the thing that falls off the bottom. */
.appwrap {
  max-width: 940px;
  padding-block: var(--s6);

  /* Centred in what is left below the bar, rather than pinned to the top with a
     third of the screen empty beneath it. Every step is short by design, so
     without this they all sit high and look unfinished. */
  min-block-size: calc(100dvh - var(--apptop-h));
  display: grid;
  align-content: center;
}

/* Wide enough for two columns: the explanation on the left, the thing you came
   here to press on the right, and both above the fold. Below this width the
   grid collapses and the page may scroll, which is correct for a phone. */
@media (min-width: 900px) {
  .pane.split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--s7);
    align-items: start;
  }
  .pane.split > .said { grid-column: 1; }
  .pane.split > .done { grid-column: 2; }
}

.appmark {
  font-family: 'IBM Plex Sans Condensed', 'IBM Plex Sans', system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  font-size: 13px;
  color: var(--faint);
  margin: 0 0 var(--s7);
}

/* The marketing stylesheet rules every <section>, and a step in a flow is not
   a section of a landing page — the hairline it inherits floats under a
   centred pane with nothing beneath it. */
.pane { border: 0; }

.pane h1 { font-size: clamp(24px, 2.6vw, 30px); line-height: 1.15; margin: 0 0 var(--s3); letter-spacing: -.02em; }
.pane h2 { font-size: 17px; margin: 0 0 var(--s2); }
.pane .lede { font-size: 15.5px; line-height: 1.5; color: var(--ink-2); margin: 0 0 var(--s4); max-width: 46ch; }
.pane .quiet { color: var(--faint); max-width: 56ch; line-height: 1.55; }
.pane .small { font-size: 13px; }

/* Definition list rather than a table: three labelled values are not tabular
   data, and this reads correctly to a screen reader without any roles. */
.facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--s3) var(--s5);
  margin: 0 0 var(--s7);
  padding: var(--s5);
  background: var(--card);
  border: 1px solid var(--hair);
  border-radius: 6px;
}
.facts dt { color: var(--faint); font-size: 13px; }
.facts dd { margin: 0; font-weight: 500; overflow-wrap: anywhere; }

.next {
  border-top: 1px solid var(--rule);
  padding-top: var(--s5);
  margin-bottom: var(--s7);
}

@media (max-width: 480px) {
  .facts { grid-template-columns: 1fr; gap: var(--s1) var(--s5); }
  .facts dd { margin-bottom: var(--s3); }
}

/* ---- the plan bar and the step panes ------------------------------------ */

.apptop { border-block-end: 1px solid var(--rule); background: var(--card); }
.apptop .wrap { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); padding-block: var(--s3); }
.apptop .brand { display: flex; align-items: center; gap: var(--s2); text-decoration: none; color: var(--ink); }
.apptop .brand .name { font-weight: 600; font-size: 15px; }

.plan { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; }
.plan .pill {
  font-family: 'IBM Plex Sans Condensed', sans-serif; font-size: 12px; font-weight: 600;
  letter-spacing: .03em; text-transform: uppercase; color: var(--faint);
  border: 1px solid var(--rule); padding: 3px 9px;
}
.linkbtn {
  font: inherit; font-size: 13.5px; color: var(--ink-2); background: none; border: 0;
  padding: 0; cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}
.linkbtn:hover { color: var(--accent); }

/* The levels are buttons, not decoration: one of them is a choice being made.
 *
 * A LIST here, not the six-column grid the marketing page uses. That grid is
 * built for the full width of a landing page; dropped into the app's narrow
 * column it gives every level about ninety pixels, which wraps "UP TO $25K"
 * onto four lines and leaves an empty sixth cell. One level per row reads at
 * any width and gives the whole row as a target. */
/* The price list, and it is what somebody is here to look at — so it gets the
 * width of the screen rather than the narrow column the wordier steps use.
 *
 * `auto-fit` with a floor rather than a fixed six columns: the marketing page's
 * grid, dropped into a narrower container, gave each level about ninety pixels
 * and wrapped "UP TO $25K" over four lines. This lays out as many across as
 * genuinely fit and stacks the rest, at any width, with no breakpoint to keep
 * in step with the number of levels. */
.applevels {
  margin-block-start: var(--s4);
  /* Five, explicitly. `auto-fit` laid out four and left a dead grey block where
     the fifth would have been — a price list with a hole in it. */
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1px; background: var(--hair);
  border: 1px solid var(--ink);
}
.applevels .tier {
  font: inherit; text-align: start; cursor: pointer; appearance: none;
  background: var(--paper); inline-size: 100%;
  display: flex; flex-direction: column; gap: var(--s2);
  padding: var(--s4) var(--s4) var(--s5);
  border: 0; border-block-start: 3px solid transparent;
  transition: background-color var(--t-colour) var(--ease);
}
.applevels .tier .upto { margin: 0; }
.applevels .tier .amt { margin: 0; font-size: clamp(22px, 2.2vw, 30px); line-height: 1; }
.applevels .tier .acc { margin: 0; }
.applevels .tier .extra {
  margin-block-start: auto;
  font-family: 'IBM Plex Sans Condensed', sans-serif; font-size: 11.5px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--accent);
}
.applevels .tier.match {
  border-block-start-color: var(--accent); background: var(--card);
}
.applevels .tier.match .amt { color: var(--accent); }

/* A step whose content is the width of the screen rather than a column of
   prose beside it. */
.pane.wide { display: block; }
.pane.wide .lede { max-inline-size: 62ch; }
/* The price list is the widest thing in the product and the one screen where
   the container should not be the constraint. */
.appwrap:has(.pane.wide:not([hidden])) { max-width: 1180px; }

@media (max-width: 900px) {
  .applevels { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .applevels { grid-template-columns: 1fr; }
}
.applevels .tier:hover { background: var(--card); }
.applevels .tier:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.applevels .tier.current { background: var(--card); }
.applevels .tier.current .extra { color: var(--accent); }

.talkto { font-size: 14.5px; color: var(--ink-2); margin-block-start: var(--s5); max-width: 60ch; }
.actions { display: flex; gap: var(--s3); flex-wrap: wrap; margin-block-start: var(--s6); }
.pane .err { color: var(--accent); font-size: 14px; margin-block-start: var(--s3); }
.pane .err:empty { display: none; }
.pane .formnote { font-size: 13.5px; color: var(--faint); margin-block-start: var(--s4); max-width: 60ch; }
.pane .permissions { margin-block-start: var(--s5); }

.wsswitch select {
  font: inherit; font-size: 13px; color: var(--ink); background: var(--paper);
  border: 1px solid var(--rule); padding: 4px 6px; border-radius: 0; max-inline-size: 15rem;
}
.wsswitch select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Present for a screen reader, absent for everyone else. */
.vh {
  position: absolute; inline-size: 1px; block-size: 1px;
  margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ---- choosing accounts -------------------------------------------------- */

.pickcap { margin-block: var(--s6) var(--s3); }
.accounts { border-block-start: 1px solid var(--ink); }

.acctrow {
  display: flex; gap: var(--s4); align-items: baseline;
  padding-block: var(--s3); border-block-end: 1px solid var(--hair);
  cursor: pointer;
}
.acctrow:hover { background: var(--card); }
.acctrow input { flex: none; margin: 0; accent-color: var(--accent); }
.acctrow b { font-weight: 500; display: block; }
.acctrow .acctmeta { display: block; font-size: 12.5px; color: var(--faint); margin-block-start: 2px; }
.acctrow.on b::after { content: " · connected"; color: var(--accent); font-weight: 400; font-size: 12.5px; }


/* ---- height budget ------------------------------------------------------ */
/* Each of these was measured against the step it appears in rather than chosen
   for looks. The connect step is the tightest: four permission rows, a note and
   a button all have to sit under the fold with the heading. */

.pane .permissions > div { padding-block: 9px; font-size: 14px; line-height: 1.45; }
.pane .formnote { margin-block-start: var(--s3); font-size: 13px; }
.pane .actions { margin-block-start: var(--s4); }
.pane .quiet { line-height: 1.5; }

.facts { padding: var(--s4); gap: var(--s2) var(--s5); margin-block-end: var(--s5); }
.next { padding-top: var(--s4); margin-bottom: var(--s5); }

.applevels { margin-block-start: var(--s4); }
.applevels .tier { padding-block: var(--s3); }
.bandpick { margin-block-start: var(--s4); }

.accounts { max-block-size: 42vh; overflow-y: auto; }
.acctrow { padding-block: 8px; }
.pickcap { margin-block: var(--s4) var(--s2); }

/* ---- the scan, while it is happening ------------------------------------ */
/* Determinate where we know the numbers, and moving where we do not. A bar
   that fills on a timer while nothing is happening is a lie told smoothly. */

.progress {
  block-size: 6px;
  background: var(--hair);
  overflow: hidden;
  margin-block-end: var(--s4);
}
.progress .bar {
  block-size: 100%;
  inline-size: 0;
  background: var(--accent);
  transition: inline-size var(--t-move) var(--ease);
}

/* Before the first account is read there is no proportion to show, so it says
   so by moving rather than by sitting at zero looking broken. */
.progress.waiting .bar {
  inline-size: 30%;
  animation: scanwait 1.4s var(--ease) infinite;
}
@keyframes scanwait {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(333%); }
}
@media (prefers-reduced-motion: reduce) {
  .progress.waiting .bar { animation: none; inline-size: 100%; opacity: .35; }
}

.scanstate { font-size: 15px; color: var(--ink); font-weight: 500; margin: 0 0 var(--s2); }

/* ---- what the scan found ------------------------------------------------ */

.findstats { display: grid; gap: var(--s3); margin-block: var(--s5) var(--s4); }
.findstats > div { display: flex; gap: var(--s3); align-items: baseline; }
.findstats b { font-size: 22px; font-weight: 600; letter-spacing: -.02em; color: var(--ink); min-inline-size: 3.5rem; }
.findstats span { font-size: 14px; color: var(--faint); }

.findings { border-block-start: 1px solid var(--ink); max-block-size: 52vh; overflow-y: auto; }
.finding { padding-block: var(--s3); border-block-end: 1px solid var(--hair); }
.finding b { display: block; font-weight: 500; font-size: 14.5px; }
.finding span { display: block; font-size: 13.5px; color: var(--ink-2); margin-block-start: 2px; }
.findhead { margin-block: var(--s4) var(--s2); color: var(--faint); }

/* Something happening, while it happens. */
.loadblock {
  display: flex; align-items: center; gap: var(--s3);
  font-size: 14.5px; color: var(--muted);
  padding-block: var(--s4);
}
.pulse {
  flex: none; inline-size: 9px; block-size: 9px; border-radius: 50%;
  background: var(--accent); animation: pulsing 1.1s var(--ease) infinite;
}
@keyframes pulsing {
  0%, 100% { opacity: .25; transform: scale(.8); }
  50%      { opacity: 1;   transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) { .pulse { animation: none; opacity: .8; } }

/* Waiting for something, said properly.
 *
 * Both of these were a line of grey text against the top left corner of an
 * otherwise empty page, which reads as a page that failed rather than one that
 * is working. Centred in what is left of the screen, with the mark drawing
 * itself — the brand is a single stroke, so it can be the thing that moves
 * instead of a spinner borrowed from somewhere else.
 */
.waiting {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--s4); text-align: center;
  min-block-size: min(60dvh, 26rem);
  color: var(--muted);
}
.waiting p { margin: 0; font-size: 15px; }
.wmark { color: var(--ink); opacity: .9; }
.wmark path { stroke-dasharray: 44; stroke-dashoffset: 44; animation: draw 1.8s var(--ease) infinite; }
@keyframes draw {
  0%   { stroke-dashoffset: 44; opacity: .25; }
  45%  { stroke-dashoffset: 0;  opacity: 1; }
  75%  { stroke-dashoffset: 0;  opacity: 1; }
  100% { stroke-dashoffset: -44; opacity: .25; }
}
@media (prefers-reduced-motion: reduce) {
  .wmark path { animation: none; stroke-dashoffset: 0; }
}

/* What the level buys that the one below it does not. The levels used to
   differ only by account count, which is not something a customer chooses —
   it is a fact about them — so the ladder had no reason to be climbed. */
.applevels .buys {
  margin-block-start: var(--s2); padding-block-start: var(--s2);
  border-block-start: 1px solid var(--hair);
  font-size: 12px; line-height: 1.35; color: var(--faint);
}
.applevels .tier.match .buys, .applevels .tier.current .buys { color: var(--ink-2); }

/* A level smaller than these accounts spend. */
.applevels .tier.under { opacity: .42; cursor: not-allowed; }

/* More accounts ticked than the level covers. Said while somebody is choosing,
   not after they have finished and pressed the button. */
.overcap { color: var(--accent); }
