/*
 * The Reporting Desk's stylesheet, written on the shared design tokens
 * (static/tokens.css, canonical in bithive-it/bithive-website).
 *
 * The rules of the design brief, section 9: a left sidebar that becomes a menu on a
 * phone, one column of content, pages rendered on the server, and no JavaScript but the
 * report page's copy buttons (ADR-0007, amended). What moves is CSS, and a deadline is
 * always shown with its time zone.
 */

/* Inter, Latin subset, served from this application: no request leaves the page. */
@font-face {
  font-family: 'Inter Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('/static/inter-latin.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-text);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  overflow-wrap: break-word;
}

h1,
h2,
h3 {
  margin: 0;
  line-height: var(--leading-tight);
  letter-spacing: -0.01em;
}

h1 {
  font-size: var(--step-4);
}

h2 {
  font-size: var(--step-2);
}

h3 {
  font-size: var(--step-1);
}

p,
ul,
ol,
dl,
table,
figure {
  margin: 0;
}

a {
  color: var(--link);
  text-underline-offset: 0.15em;
}

a:hover {
  color: var(--link-hover);
}

:focus-visible {
  outline: var(--focus);
  outline-offset: var(--focus-offset);
  border-radius: var(--radius-sm);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: calc(-1 * var(--space-9));
  z-index: 20;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--ink-button);
  color: var(--ink-button-text);
  text-decoration: none;
}

.skip-link:focus {
  top: var(--space-4);
}

.demo-banner {
  padding: var(--space-2) var(--space-5);
  background: var(--warning-soft);
  color: var(--warning);
  font-size: var(--step--1);
  font-weight: 600;
  text-align: center;
}

/* ---------- The shell: sidebar, top bar, content ---------- */

.app {
  display: grid;
  grid-template-columns: 1fr;
  min-height: 100vh;
}

/* Without this the widest table would set the width of the whole page. */
.app > * {
  min-width: 0;
}

.app__content {
  display: flex;
  flex-direction: column;
}

@media (min-width: 60rem) {
  .app {
    grid-template-columns: 16rem 1fr;
    /* The sidebar is 100vh and sticky, so on a long page its surface would end
       halfway down; the gradient paints the column behind it. */
    background: linear-gradient(to right, var(--paper) 0 16rem, transparent 16rem);
  }
}

.sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-5) var(--space-4);
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

@media (min-width: 60rem) {
  .sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    border-right: 1px solid var(--line);
    border-bottom: 0;
  }
}

.sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--ink);
  font-weight: 600;
  font-size: var(--step-1);
  text-decoration: none;
  letter-spacing: -0.02em;
}

.sidebar__brand svg {
  height: 1.25rem;
  width: auto;
  fill: var(--ink);
}

.sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* The wide screen shows the links; the phone shows the menu that holds them. */
.sidebar__nav--wide {
  display: none;
}

.sidebar__nav a {
  display: block;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--text);
  text-decoration: none;
  font-weight: 500;
}

.sidebar__nav a:hover {
  background: var(--surface);
}

.sidebar__nav a[aria-current='page'] {
  background: var(--surface-strong);
  color: var(--ink);
}

.sidebar__section {
  margin-top: var(--space-4);
  padding: 0 var(--space-3);
  color: var(--muted);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* On a phone the navigation is a menu; the summary is the only thing shown. */
.sidebar__menu > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-weight: 500;
  list-style: none;
}

.sidebar__menu > summary::-webkit-details-marker {
  display: none;
}

.sidebar__menu[open] .sidebar__nav {
  display: flex;
}

@media (min-width: 60rem) {
  .sidebar__menu {
    display: none;
  }

  .sidebar__nav--wide {
    display: flex;
  }
}

.topbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.topbar__account {
  display: flex;
  flex-direction: column;
}

.topbar__account strong {
  font-weight: 600;
}

.topbar__account span {
  color: var(--muted);
  font-size: var(--step--1);
}

.topbar__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.topbar form {
  margin: 0;
}

main {
  min-width: 0;
  padding: var(--space-6);
}

.page {
  max-width: 64rem;
  display: grid;
  gap: var(--space-5);
}

/* A grid or flex child is as wide as its content unless it is told otherwise, and a
   table of cases is wider than a phone; the table scrolls, the page does not. */
.page > *,
.page__head > * {
  min-width: 0;
}

.page__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.page__lead {
  margin-top: var(--space-2);
  color: var(--muted);
}

/* The page a stranger sees: one card, centred, and nothing else to do. */
.entry {
  display: grid;
  gap: var(--space-5);
  width: 100%;
  max-width: 27.5rem;
  margin: var(--space-8) auto;
}

.entry__brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  color: var(--ink);
  font-weight: 600;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
}

.entry__brand svg {
  height: 1.25rem;
  width: auto;
  fill: var(--ink);
}

.entry__footer {
  display: grid;
  gap: var(--space-2);
  text-align: center;
}

/* ---------- Cards, lists, tables ---------- */

.card {
  padding: var(--space-5);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}

.card > * + * {
  margin-top: var(--space-3);
}

.card__title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--step-1);
}

.grid {
  display: grid;
  gap: var(--space-4);
}

@media (min-width: 48rem) {
  .grid--2 {
    grid-template-columns: repeat(2, 1fr);
  }

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

.kpi {
  display: grid;
  gap: var(--space-1);
}

.kpi__value {
  font-size: var(--step-4);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.kpi__label {
  color: var(--muted);
  font-size: var(--step--1);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step-0);
}

th {
  text-align: left;
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--muted);
}

th,
td {
  padding: var(--space-3) var(--space-3) var(--space-3) 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

tbody tr:last-child th,
tbody tr:last-child td {
  border-bottom: 0;
}

.table-scroll {
  /* position: a visually hidden label inside a wide table is positioned absolutely,
     and without a containing block here it would anchor to the page and widen it. */
  position: relative;
  overflow-x: auto;
}

.table-scroll:focus-visible {
  outline: var(--focus);
}

/* A banner for something that cannot wait: a sign, a sentence and a way in. */
.banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius);
  font-weight: 600;
}

.banner--danger {
  background: var(--danger-soft);
  color: var(--danger);
}

.banner--danger a {
  color: var(--danger);
}

/* Something worth knowing that stops nothing: a register that did not answer and will
   be asked again, a promo code that was applied. It says so in words, not in colour. */
.banner--notice {
  background: var(--accent-soft);
  color: var(--ink);
  font-weight: 500;
}

.banner__sign {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
}

/* ---------- Status pills and deadlines ---------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: 999px;
  font-size: var(--step--1);
  font-weight: 600;
  white-space: nowrap;
}

.pill--danger {
  background: var(--danger-soft);
  color: var(--danger);
}

.pill--warning {
  background: var(--warning-soft);
  color: var(--warning);
}

.pill--ok {
  background: var(--ok-soft);
  color: var(--ok);
}

.pill--quiet {
  background: var(--surface-strong);
  color: var(--muted);
}

.deadline {
  display: grid;
  gap: var(--space-1);
}

.deadline__time {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.deadline__zone {
  color: var(--muted);
  font-size: var(--step--1);
}

.coverage {
  display: grid;
  gap: var(--space-2);
}

.coverage__reasons {
  margin: 0;
  padding-left: 1.1rem;
  color: var(--muted);
  font-size: var(--step--1);
}

/* ---------- The case timeline ---------- */

.timeline {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.timeline li {
  display: grid;
  grid-template-columns: 0.75rem 1fr;
  gap: var(--space-4);
  padding-bottom: var(--space-5);
}

.timeline li:last-child {
  padding-bottom: 0;
}

/* The dot and the line that joins one step to the next. */
.timeline__mark {
  position: relative;
  width: 0.75rem;
  height: 0.75rem;
  margin-top: 0.35rem;
  border-radius: 999px;
  background: var(--line-strong);
}

.timeline li.is-done .timeline__mark {
  background: var(--ok);
}

.timeline li.is-due .timeline__mark {
  background: var(--warning);
}

.timeline li.is-overdue .timeline__mark {
  background: var(--danger);
}

.timeline li:not(:last-child) .timeline__mark::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 100%;
  width: 1px;
  height: calc(100% + var(--space-5));
  transform: translateX(-50%);
  background: var(--line);
}

.timeline__what {
  font-weight: 600;
}

.timeline__when {
  color: var(--muted);
  font-size: var(--step--1);
}

/* ---------- Empty states ---------- */

.empty {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-7) var(--space-5);
  background: var(--paper);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  text-align: left;
}

.empty h2 {
  font-size: var(--step-2);
}

.empty p {
  color: var(--muted);
  max-width: var(--measure);
}

.empty ol {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding-left: 1.25rem;
  color: var(--muted);
}

/* ---------- Forms ---------- */

form {
  margin: 0;
}

.stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
}

.stack > * {
  width: 100%;
  max-width: 34rem;
}

label {
  display: inline-block;
  font-weight: 500;
}

input,
select,
textarea {
  width: 100%;
  padding: var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--paper);
  color: var(--text);
  font: inherit;
}

textarea {
  resize: vertical;
  min-height: 10rem;
}

textarea.copy,
input.copy {
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

/* Hidden means hidden, whatever display another rule gives the element: the report
   page's copy buttons stay hidden until the script that makes them work shows them. */
[hidden] {
  display: none !important;
}

/* The platform's form, field by field (the report page): each value beside its copy
   button, and on a phone the button under its value. */
.platform-fields {
  display: grid;
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.platform-field {
  display: grid;
  gap: var(--space-2);
}

.platform-field p {
  margin: 0;
}

.platform-field__name {
  font-weight: 600;
}

.platform-field__number {
  margin-right: var(--space-2);
  font-family: var(--font-mono);
}

.platform-field__value {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: flex-start;
}

.platform-field__value > input,
.platform-field__value > textarea {
  flex: 1 1 16rem;
  min-width: 0;
  min-height: auto;
}

input[type='checkbox'],
input[type='radio'] {
  width: auto;
  margin-right: var(--space-2);
}

fieldset {
  margin: 0;
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

legend {
  padding: 0 var(--space-1);
  font-weight: 600;
}

.states {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  gap: var(--space-1) var(--space-4);
}

.states label {
  font-weight: 400;
}

.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.row input,
.row select {
  width: auto;
  flex: 1 1 12rem;
}

/* A small form inside a table cell: its field and its button stay on one line. */
.row--cell {
  flex-wrap: nowrap;
}

.row--cell input {
  flex: 1 1 7rem;
  min-width: 7rem;
}

/* Text that must not break, such as a date and its time. */
.nowrap {
  white-space: nowrap;
}

/* Text that may break anywhere, and only where it has to: a package's name, such as
   github.com/sirupsen/logrus or a pseudo-version, has no place a line may break, and
   without this it holds its column wider than the table's room. Measured in CI, where the
   German findings table at 1280 px ran 958 px in 910. */
.breakable {
  overflow-wrap: anywhere;
}

/* Pills side by side, wrapping between pills and never inside one. */
.pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

/* Several things in one table cell, one under the other: the pills and the button that
   changes them, or a document's facts and the way to download it. */
.cell-stack {
  display: grid;
  gap: var(--space-2);
  justify-items: start;
}

/* ---------- Buttons ---------- */

/* A button says what it does on one line, in every language: a German label that breaks
   in two reads as two buttons (CTO order 33, 3a; the interface check holds it). A label
   too long for a phone is a label to shorten, not to wrap. */
button,
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: auto;
  padding: var(--space-3) var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--accent-ink);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

button:hover,
.button:hover {
  background: var(--accent-strong);
  color: var(--accent-ink);
}

button.secondary,
.button.secondary {
  border-color: var(--line-strong);
  background: transparent;
  color: var(--text);
}

button.secondary:hover,
.button.secondary:hover {
  border-color: var(--link);
  background: transparent;
  color: var(--link);
}

button.quiet {
  padding: var(--space-1) var(--space-2);
  background: transparent;
  color: var(--link);
  font-weight: 500;
}

button.danger {
  background: var(--danger);
  color: var(--paper);
}

/* ---------- Small things ---------- */

.muted {
  color: var(--muted);
}

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

.problem {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--danger-soft);
  color: var(--danger);
  font-weight: 500;
}

.secret {
  padding: var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-strong);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* ---------- Ordering ---------- */

/* The four steps of an order (ADR-0026). Steps 1 and 2 fit the stranger's column;
   the plan step puts the options beside the running total and needs more room. */
.entry--wide {
  max-width: 64rem;
}

/* The progress bar. It is a list, so that a screen reader says "3 of 4" rather than
   reading four words with no relation to each other, and the current step carries
   aria-current rather than colour alone. */
.steps {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--step--1);
  color: var(--muted);
}

.steps li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.steps__number {
  display: inline-grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  font-variant-numeric: tabular-nums;
}

.steps [aria-current='step'] {
  color: var(--ink);
  font-weight: 600;
}

.steps [aria-current='step'] .steps__number {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}

.steps__done .steps__number {
  background: var(--surface-strong);
}

/* The honeypot. It is off-screen rather than display:none, because the simplest
   scripts skip what is not displayed and fill what is, which is the whole point. It
   is hidden from assistive technology and cannot be reached by keyboard, so nobody
   who reads the page ever meets it. */
.trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* The plan step: options on the left, the total on the right, one column on a phone. */
.order {
  display: grid;
  gap: var(--space-5);
  align-items: start;
}

@media (min-width: 60rem) {
  .order {
    grid-template-columns: minmax(0, 1fr) 20rem;
  }

  .order__summary {
    position: sticky;
    top: var(--space-5);
  }
}

/* A plan is a radio with a card around it, so the whole card is the label and the
   click target, and the choice still works without a stylesheet. */
.choices {
  display: grid;
  gap: var(--space-3);
}

@media (min-width: 48rem) {
  .choices--plans {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .choices--period {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.choice {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-2) var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--paper);
  cursor: pointer;
}

.choice:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.choice:has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.choice__name {
  font-weight: 600;
}

.choice__note {
  grid-column: 2;
  margin: 0;
  color: var(--muted);
  font-size: var(--step--1);
}

/* The running total. Lines are a description list: the label and the amount belong
   to each other, and a reader that ignores the layout still hears the pair. */
.total {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-2) var(--space-4);
  margin: 0;
}

.total dt {
  color: var(--muted);
}

.total dd {
  margin: 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.total__sum {
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
  font-weight: 600;
}

.total__sum + .total__sum {
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
  color: var(--ink);
}

/* ---------- On a phone ---------- */

/* Below a tablet a table is unreadable however it scrolls, so every row becomes a
   card of label and value. The labels come from the column headers (data-label). */
@media (max-width: 47.99rem) {
  .table-scroll {
    overflow-x: visible;
  }

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

  thead {
    display: none;
  }

  tbody tr {
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--line);
  }

  tbody tr:last-child {
    border-bottom: 0;
  }

  tbody th {
    display: block;
    padding: 0 0 var(--space-1);
    border: 0;
    color: var(--text);
    font-size: var(--step-0);
  }

  td {
    display: grid;
    /* minmax(0, 1fr): a grid track is as wide as its content unless it is told
       otherwise, and an address or a token is wider than a phone. The label's track is
       never narrower than its longest word: "Produktversion" broke after its twelfth
       letter. */
    grid-template-columns: minmax(min-content, 38%) minmax(0, 1fr);
    gap: var(--space-3);
    padding: var(--space-1) 0;
    border: 0;
    overflow-wrap: anywhere;
  }

  /* An address or a token may break anywhere; a label, a button or a pill only between
     words. */
  td::before,
  td button,
  td .button,
  td .pill {
    overflow-wrap: normal;
  }

  /* A cell of actions takes the card's whole width: its label would say nothing its
     buttons do not, and the buttons need the room. */
  td.cell--wide {
    grid-template-columns: minmax(0, 1fr);
  }

  td.cell--wide::before {
    display: none;
  }

  /* A field and its button share a line where they fit, and the button goes under the
     field where they do not. */
  .row--cell {
    flex-wrap: wrap;
  }

  /* A value column on a phone is some 140 pixels wide: a button in it keeps its label on
     one line with less padding, and a date and its time may take two lines, between the
     two and never inside either. */
  td button,
  td .button {
    padding-inline: var(--space-3);
  }

  td .nowrap {
    white-space: normal;
  }

  td > * {
    min-width: 0;
  }

  /* A pill is as wide as its words; a form still fills the column. */
  td > .pill {
    justify-self: start;
  }

  td::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: var(--step--1);
    font-weight: 600;
  }

  /* A cell with nothing in it says nothing on a phone either. */
  td:empty {
    display: none;
  }

  /* A field inside a row takes the width it is given, not a basis of its own. */
  /* min-width: a field will not shrink below the width its size attribute implies
     unless it is told it may, and a label above a field makes that field a grid item
     of its own, which needs telling too. */
  .row input,
  .row select,
  .row > div {
    flex-basis: 100%;
    min-width: 0;
  }

  .row > div > input,
  .row > div > select {
    width: 100%;
    min-width: 0;
  }

  /* A pill wraps rather than being cut off: "read, not yet matched" is a sentence. */
  .pill {
    white-space: normal;
  }
}

/* ---------- Reporting obligations ---------- */

/* One obligation in its section: what it is, and how the account or the case stands. */
.obligation {
  display: grid;
  gap: var(--space-2);
}

.obligation h3 {
  font-size: var(--step-0);
}

.obligation + .obligation {
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}
