/* Niadirect Space: the application frame and the screens inside it.
 *
 * One frame carries three different people: a promoter on a phone, a business
 * owner on whatever they have, and the Founder in the Console. They see
 * different screens and the same furniture, so nobody has to learn the platform
 * twice.
 *
 * NAVIGATION CARRIES NO ICONS. VII-1 asks what operational purpose a visual
 * decision serves; a glyph beside a word that already says "Earnings" serves
 * none, costs bytes on a 3G connection, and is the first thing that makes an
 * interface look generated. Position, weight and the accent rule do the work.
 */

.app-shell {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "topbar"
    "main";
  min-height: 100vh;
}

/* --------------------------------------------------------------------------
 * The brand block and the top bar
 * ---------------------------------------------------------------------- */

.brand {
  grid-area: brand;
  display: none;
  align-items: center;
  padding: 0 var(--s5);
  height: 4rem;
  background: var(--surface-chrome);
  border-bottom: 1px solid var(--edge);
}

.brand-mark {
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}
.brand-mark span { color: var(--accent); font-weight: 600; }

.topbar {
  grid-area: topbar;
  position: sticky;
  top: 0;
  z-index: 40;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--s4);
  height: 3.5rem;
  padding: 0 var(--gutter, 1.25rem);
  background: var(--surface-chrome);
  border-bottom: 1px solid var(--edge);
}

/* The governing figure, in the frame, on every screen. Set on the baseline of
 * the title beside it rather than in a panel of its own. */
.topbar-context {
  display: none;
  align-items: baseline;
  gap: 0.5rem;
  min-width: 0;
}
.topbar-context .t-label { margin-bottom: 0; }
.topbar-context .money { font-size: 1.0625rem; }

@media (min-width: 48rem) {
  .topbar-context { display: flex; }
}

.topbar-title {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar-narrow-brand { font-size: 0.9375rem; font-weight: 600; }

.topbar-actions {
  display: grid;
  grid-auto-flow: column;
  align-items: center;
  gap: var(--s2);
}

.who { display: none; }

@media (min-width: 56rem) {
  .app-shell {
    grid-template-columns: var(--rail-w) minmax(0, 1fr);
    grid-template-areas:
      "brand topbar"
      "rail  main";
  }
  .brand { display: flex; height: 3.5rem; padding: 0 1.0625rem; }
  .rail { max-height: calc(100vh - 3.5rem); min-height: calc(100vh - 3.5rem); }
}

/* --------------------------------------------------------------------------
 * The rail (wide) and the tab bar (narrow)
 * ---------------------------------------------------------------------- */

.rail {
  grid-area: rail;
  display: none;
  grid-template-rows: 1fr auto;
  background: var(--surface-chrome);
  border-right: 1px solid var(--edge);
  padding: var(--s3) 0.875rem var(--s4);
  position: sticky;
  top: 3.5rem;
  align-self: stretch;
  /* Full height, not the height of its contents. A navigation rail that stops
   * under its last item leaves a hard edge across the page and reads as an
   * unfinished panel rather than as the frame of the application. */
  min-height: calc(100vh - 4rem);
  max-height: calc(100vh - 4rem);
  overflow-y: auto;
}

@media (min-width: 56rem) {
  .rail { display: grid; }
}

/* Who is signed in, and the way out, at the foot of the frame rather than
 * competing with the screen title at the top of it. */
.rail-foot {
  border-top: 1px solid var(--edge);
  padding: var(--s4) 0.6875rem 0;
  margin-top: var(--s4);
}
.rail-foot strong { display: block; font-size: 0.875rem; font-weight: 600; }
.rail-foot span { display: block; font-size: 0.8125rem; color: var(--text-tertiary); }
.rail-foot button { margin-top: var(--s3); width: 100%; }

.rail-group + .rail-group { margin-top: var(--s5); }

.rail-group > .t-label {
  padding: 0 0.6875rem;
  margin-bottom: 0.25rem;
  font-size: 0.625rem;
  letter-spacing: 0.09em;
}

.rail a {
  display: grid;
  grid-template-columns: 1.125rem 1fr auto;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.6875rem;
  font-size: 0.9375rem;
  border-radius: var(--r-md);
  color: var(--text-secondary);
  font-weight: 500;
  transition: background var(--step), color var(--step);
}
.rail a + a { margin-top: 0.125rem; }
.rail a:hover { background: var(--surface-canvas); color: var(--text-primary); }

/* The current destination is stated by weight and colour, with the accent used
 * once, as a short mark rather than as a full-height bar. The rail already has
 * a vertical edge; a second one beside it was two lines doing one job. */
.rail a[aria-current="page"] {
  background: var(--surface-canvas);
  color: var(--text-primary);
  font-weight: 600;
}
.rail a[aria-current="page"] .icon { color: var(--accent); }

.icon { width: 1.125rem; height: 1.125rem; flex: none; }

.rail-count {
  float: right;
  font-variant-numeric: tabular-nums;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--accent);
}

.tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  background: var(--surface-chrome);
  border-top: 1px solid var(--edge);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

.tabbar a {
  display: grid;
  justify-items: center;
  gap: 0.1875rem;
  padding: 0.5rem var(--s1) 0.625rem;
  text-align: center;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--text-tertiary);
  border-top: 2px solid transparent;
  margin-top: -1px;
  transition: color var(--step);
}
.tabbar a[aria-current="page"] {
  color: var(--accent);
  border-top-color: var(--accent);
  font-weight: 600;
}
.tabbar .icon { width: 1.375rem; height: 1.375rem; }

@media (min-width: 56rem) {
  .tabbar { display: none; }
}

/* --------------------------------------------------------------------------
 * Main
 * ---------------------------------------------------------------------- */

/* Scoped to the shell, never to every main on the site. An earlier version of
 * this rule was a bare 'main' selector, and the public pages, which have no such
 * grid area, were given implicit tracks by the browser: the footer landed beside
 * the header and the page grew a hole down its middle. A layout rule that names
 * a grid area belongs to the grid that defines it. */
.app-shell > main {
  grid-area: main;
  min-width: 0;
  padding-bottom: 4.5rem;               /* clears the tab bar */
}

@media (min-width: 56rem) {
  .app-shell > main { padding-bottom: 0; }
}

.screen-head { margin-bottom: var(--s5); }
.screen-head p { color: var(--text-secondary); margin-top: var(--s1); max-width: 46rem; }

/* --------------------------------------------------------------------------
 * The earnings hero
 *
 * The single most important block in the product. A promoter opens this app to
 * answer one question, so that question is answered above everything else, in
 * the largest type on the platform, with the qualification attached rather than
 * hidden behind a tap.
 * ---------------------------------------------------------------------- */

.hero {
  background: var(--surface-card);
  border: 1px solid var(--edge);
  border-radius: var(--r-lg);
  box-shadow: var(--emboss);
  padding: var(--s4);
}

@media (min-width: 40rem) {
  .hero { padding: 1.5rem; }
}

.hero-action { margin-top: var(--s5); max-width: 22rem; }

@media (min-width: 40rem) {
  .hero { padding: var(--s3) 0 var(--s6); }
}

/* The figure, the line under it and the action are one block; the supporting
 * numbers below the rule are another. The space between them is deliberately
 * larger than any space inside either. */
.hero-figure { margin: var(--s2) 0 var(--s2); }

@media (min-width: 64rem) {
  .hero-top {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(16rem, 24rem);
    align-items: end;
    gap: var(--s6);
  }
  .hero-top .hero-action { margin-top: 0; max-width: none; }
}

.hero-split {
  display: grid;
  gap: var(--s4) var(--s5);
  grid-template-columns: repeat(auto-fit, minmax(min(8.5rem, 100%), 1fr));
  padding-top: var(--s5);
  margin-top: var(--s5);
  border-top: 1px solid var(--edge);
}



/* A card that happens to be a link keeps the card's colours and gains the
 * card's affordance: it lifts under the pointer rather than turning its
 * contents accent-coloured. */
a.card { color: inherit; display: block; transition: box-shadow var(--step); }
a.card:hover {
  text-decoration: none;
  box-shadow: var(--emboss), inset 0 0 0 99rem rgba(255, 255, 255, 0.035);
}

/* Small counts, four across where there is room and two where there is not.
 * The general card grid is sized for cards with sentences in them, and it left
 * a row of three with one stranded underneath. */
.tiles {
  display: grid;
  gap: var(--s4);
  grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
}

/* The money on the left, what is happening on the right. One column until
 * there is room for two, which is a decision about the reader rather than about
 * the breakpoint: below this width a second column would halve the size of the
 * figure somebody opened the app to read. */
.dash { display: grid; gap: var(--s4); align-items: start; }

@media (min-width: 64rem) {
  .dash { grid-template-columns: minmax(0, 1fr) minmax(24rem, 27rem); gap: var(--s4); }
}

@media (min-width: 100rem) {
  .dash { grid-template-columns: minmax(0, 1fr) 32rem; }
}

/* --------------------------------------------------------------------------
 * Master and detail
 *
 * Below 64rem the list is the screen and the detail replaces it. Above, they sit
 * side by side and selecting a row never loses the list.
 * ---------------------------------------------------------------------- */

.split { display: grid; gap: var(--s5); }

@media (min-width: 64rem) {
  .split { grid-template-columns: minmax(17rem, 21rem) minmax(0, 1fr); align-items: start; gap: var(--s4); }
  .split-list { position: sticky; top: 4.5rem; max-height: calc(100vh - 6rem); overflow-y: auto; }
}

/* --------------------------------------------------------------------------
 * The caption block
 *
 * What the promoter actually posts. Shown in full, in the exact characters that
 * will be pasted, with the disclosure line visible rather than promised.
 * ---------------------------------------------------------------------- */

.caption {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--surface-chrome);
  border: 1px solid var(--edge);
  border-radius: var(--r-md);
  padding: var(--s4);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--text-primary);
}

.caption-link { color: var(--accent); }

/* Set below the work, above a rule, so a destructive action is found when it is
 * wanted and not met when it is not. */
.quiet-actions {
  padding-top: var(--s3);
  margin-top: var(--s2);
  border-top: 1px solid var(--edge);
}

/* --------------------------------------------------------------------------
 * Console rule rows
 * ---------------------------------------------------------------------- */

.rule-row {
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--edge);
}
.rule-row:last-child { border-bottom: 0; }

.rule-grid {
  display: grid;
  gap: var(--s3);
  grid-template-columns: 1fr;
}

@media (min-width: 48rem) {
  .rule-grid { grid-template-columns: minmax(0, 1fr) 12rem auto; align-items: start; }
}

.rule-locked {
  display: inline-block;
  padding: var(--s2) var(--s3);
  border-radius: var(--r-md);
  background: var(--surface-chrome);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* --------------------------------------------------------------------------
 * Sign-in and the public pages
 * ---------------------------------------------------------------------- */

.public {
  min-height: 100vh;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

.public-bar {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--s3);
  padding: var(--s4) var(--s4);
  background: var(--surface-chrome);
  border-bottom: 1px solid var(--edge);
}

.public-main { width: 100%; max-width: 64rem; margin: 0 auto; padding: var(--s6) var(--s4) var(--s7); }

.public-foot {
  padding: var(--s5) var(--s4);
  background: var(--surface-chrome);
  border-top: 1px solid var(--edge);
  color: var(--text-tertiary);
  font-size: 0.8125rem;
}
.public-foot a { color: var(--text-secondary); }

.auth-card { max-width: 26rem; margin: 0 auto; }

.doors { display: grid; gap: var(--s3); grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr)); }

.door {
  display: block;
  width: 100%;
  padding: var(--s4);
  text-align: left;
  background: var(--surface-interactive);
  border: 1px solid var(--edge);
  border-radius: var(--r-md);
  color: var(--text-primary);
  cursor: pointer;
  transition: box-shadow var(--step);
}
.door:hover { box-shadow: inset 0 0 0 99rem rgba(255, 255, 255, 0.07); text-decoration: none; }
.door[aria-pressed="true"] { box-shadow: inset 0 0 0 2px var(--accent); }
.door strong { display: block; font-weight: 600; }
.door span { display: block; margin-top: var(--s1); font-size: 0.8125rem; color: var(--text-secondary); }

/* The six-digit code. Wide tracking so a person can check what they typed
 * against what they were sent, one digit at a time. */
.code-input {
  font-variant-numeric: slashed-zero tabular-nums;
  font-feature-settings: "zero" 1;
  font-weight: 600;
  font-size: 1.75rem;
  letter-spacing: 0.4em;
  text-align: center;
  padding-left: 0.4em;
  min-height: 3.25rem;
}

/* --------------------------------------------------------------------------
 * Legal documents
 *
 * Long-form reading, set at a comfortable measure. A privacy policy nobody can
 * read is a privacy policy that does not do its job (Gate 15a).
 * ---------------------------------------------------------------------- */

.doc { max-width: 44rem; }
.doc h2 { margin-top: var(--s6); margin-bottom: var(--s3); }
.doc h3 { margin-top: var(--s5); margin-bottom: var(--s2); }
.doc p, .doc li { color: var(--text-secondary); }
.doc p + p { margin-top: var(--s3); }
.doc ul { margin: var(--s3) 0 0; padding-left: var(--s5); list-style: disc; }
.doc li + li { margin-top: var(--s2); }
.doc dl { margin-top: var(--s3); }
.doc dt { font-weight: 600; color: var(--text-primary); margin-top: var(--s3); }
.doc dd { margin: var(--s1) 0 0; color: var(--text-secondary); }

/* --------------------------------------------------------------------------
 * Loading
 *
 * A skeleton that occupies the space its content will occupy, so the screen
 * does not jump when the answer arrives. VII-4: motion explains what changed.
 * ---------------------------------------------------------------------- */

.skeleton {
  border-radius: var(--r-md);
  background: var(--surface-card);
  animation: pulse 1.4s ease-in-out infinite;
}
.skeleton-line { height: 0.875rem; margin-bottom: var(--s2); }
@keyframes pulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 0.85; } }

/* A comfortable line length for a paragraph somebody reads once and acts on.
 * A class rather than a style attribute: the content policy is closed to inline
 * styles, so an attribute here would be silently dropped by the browser and the
 * line would run the full width of a desk monitor. */
.measure { max-width: 38rem; }
