/*
 * BLUEPRINT SHEET — the screen slot's content until sanitised captures from the
 * current Nexys build exist.
 *
 * Production Blueprint v1, section 08: where a sanitised screen is missing the
 * documents table carries the proof, and the slot is never filled with a
 * mock-up or a "coming soon" image. So this is not a picture of software: it is
 * the module's real document structure, set as a record on a desk-grey mat,
 * labelled STRUKTURË / СТРУКТУРА and captioned as a structure rather than a
 * screenshot. It occupies exactly the slot a real capture will occupy.
 */

.frame {
  margin: 0;
  background: var(--mat);
  padding: var(--s5);
  border: var(--hairline) solid var(--rule);
}

.sheet {
  background: var(--paper);
  border: var(--hairline) solid var(--ink);
}

.head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s3) var(--s4);
  background: var(--paper-2);
  border-bottom: var(--hairline) solid var(--ink);
  font-family: var(--font-mono);
  font-size: var(--step-label);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.title {
  font-weight: 500;
  color: var(--ink);
}

.badge {
  color: var(--muted);
  border: var(--hairline) solid var(--rule);
  padding: 2px var(--s2);
  white-space: nowrap;
}

.body {
  padding: var(--s4);
  display: grid;
  gap: var(--s4);
}

/* ---- The record itself -------------------------------------------------- */

.table {
  width: 100%;
  border-collapse: collapse;
}

.table th,
.table td {
  text-align: left;
  padding: var(--s2) var(--s3);
  border-bottom: var(--hairline) solid var(--rule);
}

.table thead th {
  font-family: var(--font-mono);
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom-color: var(--ink);
  white-space: nowrap;
}

.table td {
  font-size: var(--step-small);
}

.table td:first-child {
  font-weight: 500;
}

/* Qualified for the same specificity reason as in RecordTable. */
.table th.num,
.table td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.totalRow td {
  border-top: 2px solid var(--ink);
  border-bottom: 0;
  font-weight: 500;
  font-size: var(--step-small);
}

/* The posted value is the one green mark inside the sheet. */
.totalRow td:last-child {
  color: var(--green-ink);
}

/* ---- Function keys, exactly as they appear in the product --------------- */

.keys {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  padding-top: var(--s3);
  border-top: var(--hairline) solid var(--rule);
}

.key {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s2);
  border: var(--hairline) solid var(--rule-strong);
  background: var(--paper-2);
  padding: var(--s1) var(--s2);
  font-family: var(--font-mono);
  font-size: var(--step-label);
  letter-spacing: 0.04em;
}

.keyCode {
  font-weight: 500;
  color: var(--ink);
}

.keyLabel {
  color: var(--ink-2);
  text-transform: uppercase;
}

/* ---- Table map (Nexys Caffe) -------------------------------------------- */

.mapWrap {
  display: grid;
  gap: var(--s3);
}

.mapLabel {
  font-family: var(--font-mono);
  font-size: var(--step-label);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.map {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--s2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.cell {
  border: var(--hairline) solid var(--rule);
  background: var(--paper-2);
  padding: var(--s2);
  min-height: 52px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--step-mono);
}

.cellNumber {
  font-weight: 500;
}

.cellState {
  font-size: var(--step-label);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.open {
  border-left: 3px solid var(--green-ink);
  background: var(--paper);
}

.open .cellState {
  color: var(--green-ink);
}

.bill {
  border-left: 3px solid var(--ink);
  background: var(--paper);
}

.bill .cellState {
  color: var(--ink);
}

/* ---- Caption ------------------------------------------------------------ */

.caption {
  margin-top: var(--s4);
  display: grid;
  gap: var(--s1);
  font-family: var(--font-mono);
  font-size: var(--step-mono);
  color: var(--ink-2);
}

.note {
  font-size: var(--step-label);
  letter-spacing: 0.02em;
  color: var(--muted);
  max-width: 72ch;
}

/* ---- Responsive --------------------------------------------------------- */

@media (max-width: 1023px) {
  .map {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (max-width: 767px) {
  .frame {
    padding: var(--s3);
  }

  .body {
    padding: var(--s3);
  }

  .map {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  /*
   * The record line, at phone width.
   *
   * The first build stacked the trailing columns as a mono run under a bold
   * row number, which put the least useful cell of a ledger line — "01" — in
   * the largest type and the document description in 11 px grey beside the
   * figures. It read as a wall of mono rather than a record.
   *
   * So a row becomes two lines: the subject in reading type, then the figures
   * under it as LABEL/value pairs that wrap. Which cell is the subject depends
   * on the sheet: a ledger leads with its number and its description together,
   * every other sheet leads with the thing being counted.
   */
  .table thead {
    display: none;
  }

  .table,
  .table tbody {
    display: block;
    width: 100%;
  }

  .table tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: var(--s3);
    row-gap: 3px;
    padding-block: var(--s3);
    border-bottom: var(--hairline) solid var(--rule);
  }

  .table td {
    display: block;
    padding: 0;
    border-bottom: 0;
    text-align: left;
  }

  /* The subject takes the whole first line. */
  .table td:first-child {
    flex: 1 0 100%;
    font-size: var(--step-body);
    font-weight: 500;
    color: var(--ink);
  }

  /* The trailing cells: one wrapped mono line of label/value pairs. */
  .table td:nth-child(n + 2) {
    flex: 0 0 auto;
    font-family: var(--font-mono);
    font-size: var(--step-label);
    font-weight: 400;
    color: var(--ink-2);
  }

  .table td[data-label]:nth-child(n + 2)::before {
    content: attr(data-label) " ";
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }

  /* A ledger numbers its lines, so the number leads the description. */
  .table[data-kind="ledger"] td:first-child {
    flex: 0 0 auto;
    font-family: var(--font-mono);
    font-size: var(--step-mono);
    font-weight: 400;
    color: var(--muted);
  }

  .table[data-kind="ledger"] td:nth-child(2) {
    flex: 1 0 calc(100% - 5ch);
    font-family: var(--font-body);
    font-size: var(--step-body);
    font-weight: 500;
    color: var(--ink);
  }

  .table[data-kind="ledger"] td:nth-child(2)::before {
    content: none;
  }

  /*
   * A stacked cell with no value must not print its label on its own, or the
   * totals row reads as "QUANTITY PRICE VALUE 580,00". This has to sit after
   * the rules above, which set `display` at a lower specificity.
   */
  .table td:empty {
    display: none;
  }

  .totalRow {
    border-top: 2px solid var(--ink);
  }

  .totalRow td {
    border-top: 0;
  }
}

/* ======================================================================== */
/* THE WORLD — V4: the document as the product page's first chapter          */
/* ======================================================================== */

/*
 * Unframed, full width, in the document voice. No mat, no border, no badge
 * saying STRUKTURË: the document is simply set on the page the way the
 * program would print it, and the demonstration-data line is the only label.
 */

.world {
  margin: 0;
}

.world .sheet {
  border: 0;
  background: transparent;
}

.world .head {
  padding: 0 0 var(--s3);
  background: transparent;
  border-bottom: 2px solid var(--ink);
  align-items: flex-end;
  flex-wrap: wrap;
}

.world .title {
  overflow-wrap: anywhere;
}

.world .badge {
  white-space: normal;
}

.world .title {
  font-size: clamp(1rem, 2vw, 1.5rem);
  letter-spacing: 0.04em;
  line-height: 1.1;
}

.world .badge {
  font-size: var(--step-label);
}

.world .body {
  padding: var(--s4) 0 0;
  gap: var(--s5);
}

.world .table th,
.world .table td {
  padding: var(--s3) var(--s3);
}

.world .table thead th {
  border-bottom-color: var(--rule-strong);
}

.world .table td {
  font-size: 1.0625rem;
}

.world .table td:first-child {
  font-weight: 600;
}

/* Figures in the document voice. */
.world .figure {
  font-family: var(--font-mono);
  font-size: 1.0625rem;
  letter-spacing: 0.01em;
}

/* The double rule under the total: the one place two rules meet. */
.world .totalRow td {
  border-top: 3px double var(--ink);
  font-size: 1.125rem;
  font-weight: 600;
}

.world .totalRow td.num {
  font-family: var(--font-mono);
  font-size: 1.125rem;
}

.world .foot {
  height: 0;
}

/* The period's closing rule, for the payslip. */
.world[data-kind="table"] .foot {
  height: 2px;
  background: var(--ink);
  transform-origin: left center;
}

.world .keys {
  border-top: 0;
  padding-top: 0;
}

/* Caffe: the key row is the most Nexys thing on the site. Set large. */
.world[data-kind="tables"] .key {
  font-size: var(--step-small);
  padding: var(--s2) var(--s3);
  gap: var(--s3);
}

.world[data-kind="tables"] .keyCode {
  font-size: var(--step-body);
}

.world[data-kind="tables"] .cell {
  min-height: 72px;
  font-size: var(--step-body);
  padding: var(--s3);
}

.world[data-kind="tables"] .cellState {
  font-size: var(--step-mono);
}

.world .caption {
  margin-top: var(--s5);
}

/* ---- Navy tone: the system's surface ----------------------------------- */

.world[data-tone="navy"] {
  color: #fff;
}

.world[data-tone="navy"] .head {
  border-bottom-color: #fff;
}

.world[data-tone="navy"] .title {
  color: #fff;
}

.world[data-tone="navy"] .badge {
  color: var(--muted-2);
  border-color: var(--rule-navy);
}

.world[data-tone="navy"] .table thead th {
  color: var(--muted-2);
  border-bottom-color: var(--blue-2);
}

.world[data-tone="navy"] .table td {
  color: #fff;
  border-bottom-color: var(--rule-navy);
}

.world[data-tone="navy"] .totalRow td {
  border-top-color: #fff;
}

.world[data-tone="navy"] .totalRow td:last-child {
  color: var(--green);
}

.world[data-tone="navy"] .mapLabel {
  color: var(--muted-2);
}

.world[data-tone="navy"] .cell {
  border-color: var(--rule-navy);
  background: var(--navy-2);
  color: var(--mat);
}

.world[data-tone="navy"] .cellState {
  color: var(--muted-2);
}

.world[data-tone="navy"] .open {
  border-left-color: var(--green);
  background: var(--navy);
}

.world[data-tone="navy"] .open .cellState {
  color: var(--green);
}

.world[data-tone="navy"] .bill {
  border-left-color: #fff;
  background: var(--navy);
}

.world[data-tone="navy"] .bill .cellState {
  color: #fff;
}

.world[data-tone="navy"] .key {
  border-color: var(--rule-navy);
  background: var(--navy-2);
}

.world[data-tone="navy"] .keyCode {
  color: #fff;
}

.world[data-tone="navy"] .keyLabel {
  color: var(--mat);
}

.world[data-tone="navy"] .caption {
  color: var(--mat);
}

.world[data-tone="navy"] .note {
  color: var(--muted-2);
}

@media (max-width: 767px) {
  .world[data-tone="navy"] .table tr {
    border-bottom-color: var(--rule-navy);
  }

  .world[data-tone="navy"] .table td:first-child {
    color: #fff;
  }

  .world[data-tone="navy"] .table td:nth-child(n + 2) {
    color: var(--mat);
  }

  .world[data-tone="navy"] .table td[data-label]:nth-child(n + 2)::before {
    color: var(--muted-2);
  }

  .world[data-tone="navy"] .totalRow {
    border-top-color: #fff;
  }
}

/* ---- Tempo: four products, four ways of posting ------------------------ */

/*
 * The world is the first chapter, above the fold, so it plays from the first
 * paint rather than waiting for a scroll, the way the masthead does. Every
 * keyframe below starts from the finished state and only withholds it for
 * the length of its delay; with reduced motion the block does not apply and
 * the document is simply there.
 */
@media (prefers-reduced-motion: no-preference) {
  /* Finance: still, precise. Rows post one by one; the double rule last. */
  .world[data-kind="ledger"] tbody tr {
    animation: sheet-post 1ms linear calc(240ms + var(--i, 0) * 110ms) both;
  }

  .world[data-kind="ledger"] .totalRow {
    animation-delay: calc(240ms + var(--i, 0) * 110ms + 160ms);
  }

  /* MAT: physical. Rows post, then the quantities cut up into their cells. */
  .world[data-kind="pos"] tbody tr {
    animation: sheet-post 1ms linear calc(200ms + var(--i, 0) * 80ms) both;
  }

  .world[data-kind="pos"] tbody tr .figure {
    display: inline-block;
    animation: qty-cut 220ms var(--ease) calc(560ms + var(--i, 0) * 80ms) both;
  }

  /* Budget: periodic. Everything is there; the month closes with one rule. */
  .world[data-kind="table"] .foot {
    animation: sheet-draw 320ms var(--ease) 420ms both;
  }

  /* Caffe: live. The places change state one after another; the order ticks in. */
  .world[data-kind="tables"] .cell {
    animation: sheet-post 1ms linear calc(160ms + var(--i, 0) * 70ms) both;
  }

  .world[data-kind="tables"] tbody tr {
    animation: sheet-post 1ms linear calc(1120ms + var(--i, 0) * 90ms) both;
  }

  .world[data-kind="tables"] .key {
    animation: sheet-post 1ms linear 1620ms both;
  }

  @keyframes sheet-post {
    from {
      visibility: hidden;
    }
    to {
      visibility: visible;
    }
  }

  @keyframes qty-cut {
    from {
      clip-path: inset(100% 0 0 0);
      transform: translateY(0.4em);
    }
    to {
      clip-path: inset(-10% 0 -10% 0);
      transform: none;
    }
  }

  @keyframes sheet-draw {
    from {
      transform: scaleX(0);
    }
    to {
      transform: scaleX(1);
    }
  }
}
