/* ==========================================================================
   Norman. component layer
   --------------------------------------------------------------------------
   Requires tokens.css.

   NO LITERAL COLOURS IN THIS FILE. Every colour comes from a token.
   `lint-tokens.sh` greps for hex, rgb() and hsl() literals and fails the build
   if it finds one. That check ships with a negative control that proves it
   fires, because a check that only reports success is worthless.

   These are not generic UI primitives. They are Norman's vocabulary: a verdict,
   a source that agrees or does not, an exception with money attached. If a new
   component does not correspond to something the product actually claims, it
   probably belongs in the page rather than in here.
   ========================================================================== */

/* --- base ---------------------------------------------------------------- */

.n-root {
  background: var(--n-paper);
  color: var(--n-ink);
  font-family: var(--n-sans);
  font-size: var(--n-text-base);
  line-height: var(--n-leading-body);
  -webkit-font-smoothing: antialiased;
}

.n-root *,
.n-root *::before,
.n-root *::after { box-sizing: border-box; }

/* Digits line up everywhere. In a product about columns agreeing, figures that
   do not align undercut the claim before anyone reads them. */
.n-figure,
.n-source__value,
.n-exception__amount,
.n-table td { font-variant-numeric: tabular-nums; }

.n-root :focus-visible {
  outline: 2px solid var(--n-focus);
  outline-offset: 2px;
  border-radius: var(--n-radius-sm);
}

@media (prefers-reduced-motion: reduce) {
  .n-root *,
  .n-root *::before,
  .n-root *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* --- typography ---------------------------------------------------------- */

.n-kicker {
  font-family: var(--n-mono);
  font-size: var(--n-text-xs);
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--n-brand);
  font-weight: 600;
  margin: 0 0 var(--n-2);
}

.n-title {
  font-size: var(--n-text-3xl);
  line-height: 1.04;
  letter-spacing: -.032em;
  font-weight: 660;
  margin: 0 0 var(--n-3);
  max-width: 17ch;
  text-wrap: balance;
}

.n-sub {
  font-size: var(--n-text-xl);
  font-weight: 630;
  letter-spacing: -.022em;
  line-height: var(--n-leading-tight);
  margin: 0 0 var(--n-3);
  max-width: 40ch;
  text-wrap: balance;
}

.n-lede {
  color: var(--n-ink-2);
  max-width: 68ch;
  margin: 0 0 var(--n-5);
}

.n-section { margin-top: var(--n-10); }

/* --- the verdict --------------------------------------------------------- */
/* Every Norman screen opens with a sentence, not a number. The sentence says
   whether anything needs the owner. This is the product thesis made visible:
   Norman already knows the answer, so it should not make the reader assemble
   it from tiles. */

.n-verdict {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--n-4);
  padding: var(--n-6) var(--n-4);
  border-bottom: 1px solid var(--n-rule);
}

.n-verdict__line {
  font-size: clamp(24px, 4.2vw, 36px);
  font-weight: 660;
  letter-spacing: -.028em;
  line-height: 1.1;
  color: var(--n-ink);
  margin: 0;
  text-wrap: balance;
}

.n-verdict__why {
  font-size: var(--n-text-base);
  color: var(--n-ink-2);
  max-width: 46ch;
  margin: 0;
}

/* --- source strip -------------------------------------------------------- */
/* The systems that must agree, and whether they currently do. */

.n-strip {
  display: grid;
  grid-template-columns: repeat(var(--n-strip-cols, 4), 1fr);
  gap: 1px;
  background: var(--n-rule);
  border-bottom: 1px solid var(--n-rule);
}

.n-source {
  background: var(--n-card);
  padding: var(--n-3) var(--n-4) var(--n-4);
}

.n-source__label {
  font-family: var(--n-mono);
  font-size: 9.5px;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--n-ink-3);
  font-weight: 600;
}

.n-source__value {
  font-size: var(--n-text-lg);
  font-weight: 640;
  letter-spacing: -.02em;
  margin-top: var(--n-2);
  color: var(--n-ink);
}

/* --- state --------------------------------------------------------------- */
/* A dot AND a word, never colour alone. Roughly one man in twelve cannot
   separate the red from the green, and this product is sold to owner-operators
   rather than to a design-aware audience. */

.n-state {
  display: inline-flex;
  align-items: center;
  gap: var(--n-1);
  font-family: var(--n-mono);
  font-size: 10px;
  letter-spacing: .09em;
  text-transform: uppercase;
  font-weight: 600;
  margin-top: var(--n-2);
}

.n-state::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.n-state--agree { color: var(--n-agree); }
.n-state--stale { color: var(--n-stale); }
.n-state--break { color: var(--n-break); }

/* --- exception ----------------------------------------------------------- */
/* The only output of the reconciliation engine. Severity is an edge, not a
   fill, so a long queue stays readable. Every exception carries its money
   value: "14% agreement" is a statistic, "$61,400 a quarter" is a decision. */

.n-exception {
  display: grid;
  grid-template-columns: var(--n-edge) 1fr auto;
  gap: var(--n-3);
  align-items: start;
  padding: var(--n-3) var(--n-4);
  border-top: 1px solid var(--n-rule);
}

.n-exception__edge {
  align-self: stretch;
  border-radius: var(--n-radius-sm);
  background: var(--n-ink-3);
}

.n-exception--break .n-exception__edge { background: var(--n-break); }
.n-exception--stale .n-exception__edge { background: var(--n-stale); }
.n-exception--info  .n-exception__edge { background: var(--n-ink-3); }

.n-exception__title {
  font-size: var(--n-text-base);
  font-weight: 600;
  letter-spacing: -.008em;
  color: var(--n-ink);
}

.n-exception__detail {
  font-size: var(--n-text-sm);
  color: var(--n-ink-2);
  margin-top: var(--n-1);
  line-height: 1.45;
}

.n-exception__amount {
  font-family: var(--n-mono);
  font-size: var(--n-text-sm);
  font-weight: 600;
  color: var(--n-ink);
  text-align: right;
  white-space: nowrap;
}

.n-exception__amount small {
  display: block;
  font-size: 9.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--n-ink-3);
  margin-top: var(--n-1);
  font-weight: 600;
}

/* --- callout ------------------------------------------------------------- */

.n-callout {
  background: var(--n-card);
  border: 1px solid var(--n-rule);
  border-left: var(--n-edge) solid var(--n-brand);
  border-radius: var(--n-radius-sm);
  padding: var(--n-4) var(--n-5);
  margin: var(--n-5) 0;
  box-shadow: var(--n-lift);
}

.n-callout--agree { border-left-color: var(--n-agree); }
.n-callout--stale { border-left-color: var(--n-stale); }
.n-callout--break { border-left-color: var(--n-break); }

.n-callout__title {
  margin: 0 0 var(--n-2);
  font-size: var(--n-text-md);
  font-weight: 650;
  letter-spacing: -.014em;
  color: var(--n-ink);
}

.n-callout p {
  font-size: var(--n-text-base);
  color: var(--n-ink-2);
  margin: 0 0 var(--n-2);
}

.n-callout p:last-child { margin: 0; }

/* --- table --------------------------------------------------------------- */
/* Always inside .n-scroll. Wide content scrolls in its own container so the
   page body never moves sideways. */

.n-scroll {
  overflow-x: auto;
  border: 1px solid var(--n-rule);
  border-radius: var(--n-radius-sm);
  background: var(--n-card);
  box-shadow: var(--n-lift);
}

.n-table {
  border-collapse: collapse;
  width: 100%;
  font-size: var(--n-text-sm);
  min-width: 520px;
}

.n-table th,
.n-table td {
  padding: var(--n-3) var(--n-4);
  text-align: left;
  border-bottom: 1px solid var(--n-rule);
  vertical-align: top;
}

.n-table th {
  font-family: var(--n-mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--n-ink-3);
  font-weight: 600;
  background: var(--n-sunk);
  white-space: nowrap;
}

.n-table tbody tr:last-child td { border-bottom: 0; }

/* --- surfaces ------------------------------------------------------------ */

.n-panel {
  background: var(--n-card);
  border: 1px solid var(--n-rule);
  border-radius: var(--n-radius);
  box-shadow: var(--n-lift);
  overflow: hidden;
}

.n-bar {
  display: flex;
  align-items: center;
  gap: var(--n-3);
  padding: var(--n-3) var(--n-4);
  border-bottom: 1px solid var(--n-rule);
  background: var(--n-sunk);
}

.n-bar__meta {
  margin-left: auto;
  font-family: var(--n-mono);
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--n-ink-3);
}

/* --- brand marks --------------------------------------------------------- */
/* The lockup inherits `color`, so it themes automatically wherever it sits. */

.n-lockup,
.n-mark { display: block; color: var(--n-ink); }

.n-lockup { height: 18px; width: auto; }
.n-mark   { height: 22px; width: auto; }

/* --- responsive ---------------------------------------------------------- */

@media (max-width: 720px) {
  .n-strip { --n-strip-cols: 2; }
  .n-verdict { padding: var(--n-5) var(--n-4); }
}
