/* SiteRadar — cabinet, audit card and billing (docs/handoff/01-cabinet.html, T4).
 *
 * Loaded last, after tokens.css and ui.css, and only for the app shell.
 * Page classes only: the primitives (.btn .field .pill .stats .card .notice .glow)
 * live in ui.css and are never redefined here. No literal colour, radius, shadow
 * or type size — a value that is not a token does not exist (§1).
 *
 * Class dictionary: .hero* .search* .list* .audits* .empty* .props .crumbs
 * .ledger* .credits .letter .metrics .doc* .errpage*. */

/* ---- app-shell page frame -------------------------------------------------- */

/* The 1040 container of the app pages. The hero is not full-bleed: its glow
   (900 px) is narrower than the container, so at every width the picture is the
   one of the mock-up, without a 100vw break-out (a horizontal scrollbar of its
   own) and with the layout-level notices aligned to the same column. */
main {
  display: flow-root; /* the top margin of the first heading stays inside main */
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--container-pad) 64px;
}

/* A page-level notice (the "messages" partial) is the first thing in main on the
   page it belongs to, so it carries the same top offset as a heading would. */
main > .notice:first-child { margin-top: var(--page-top); }

/* Element-level defaults for the app pages that bring no heading class of their
   own (/docs/{slug}, the error page, /_ui). Any page class outranks them. */
h1 {
  margin: var(--page-top) 0 18px;
  font-size: var(--fs-h2);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-bold);
}
h2 {
  margin: 32px 0 14px;
  font-size: var(--fs-lead);
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-bold);
}

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

/* ---- hero ------------------------------------------------------------------ */

.hero {
  position: relative;   /* the glow is absolute inside it */
  overflow: hidden;     /* … and clipped by it */
  padding: 96px 0 80px; /* 56 of the hero + 24 above the metrics (mock-up) */
  text-align: center;
}
/* The glow is painted by a positioned element, so it would sit above the
   non-positioned text; every child but the glow gets a position of its own.
   :not(.glow) is deliberate — `.hero > *` would beat `.glow{position:absolute}`
   of ui.css (same specificity, later sheet) and collapse the glow to an
   empty inline. */
.hero > :not(.glow) { position: relative; }

.hero__kicker {
  margin: 0 0 12px;
  /* A page caption, not a primitive: it carries the tight line box itself
     (16.8 here, 17.0 in the mock-up). */
  line-height: var(--lh-tight);
  color: var(--accent);
  font-size: var(--fs-sm);
  font-weight: var(--fw-med);
}

.hero__title {
  max-width: 15ch;
  margin: 0 auto 18px;
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  letter-spacing: var(--ls-h1);
  font-weight: var(--fw-bold);
}

.hero__lead {
  max-width: 52ch;
  margin: 0 auto 40px;
  color: var(--text-2);
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  letter-spacing: var(--ls-lead);
}

/* The PRG flash of a just created audit, under the field it was submitted from. */
.hero__flash {
  max-width: 640px;
  margin: 22px auto 0;
  text-align: left;
}

/* ---- search field ---------------------------------------------------------- */

.search { max-width: 640px; margin: 0 auto; }

.search__pill {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 7px 7px 22px;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--r-pill);
  background: var(--bg);
  box-shadow: var(--shadow-search);
}
/* The input has no frame of its own, so the pill carries the focus ring (§6).
   :focus-within, not :focus-visible: showing it on a click too is the safe side. */
.search__pill:focus-within {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.search__pill.has-error { border-color: var(--warn-text); }

.search__input {
  flex: 1;
  min-width: 0;
  min-height: var(--tap);   /* §6; on >=768 the padding already gives 48 */
  padding: 14px 0;
  border: 0;
  background: transparent;
  color: var(--text);
  font-size: var(--fs-search);
}
.search__input:focus { outline: none; }

.search .btn { flex: none; padding: 14px 26px; }

/* --text-2, not the --text-3 of a caption: the line carries the price of a run
   and the way out of an empty balance — meaning, so 4.5:1 (§6, R1 MED-4). */
.search__hint {
  margin: 14px 0 0;
  line-height: var(--lh-tight);
  color: var(--text-2);
  font-size: var(--fs-cap);
}
.search__hint a { color: var(--text-2); text-decoration: underline; }
.search__hint a:hover { color: var(--accent-hover); }
/* A1: the caption of a run in progress carries the only ring of the page. Only
   this variant is a flex line — the zero-balance caption holds a link inside a
   sentence, and a flex row would tear the sentence into two items. */
.search__hint--active {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.search__error { margin: 10px 0 0; text-align: center; }

/* ---- metrics --------------------------------------------------------------- */

/* No line-height here any more: .stat__num (--lh-num) and .stat__label
   (--lh-tight) carry their own line box in ui.css, so the card is the 116.8 of
   the mock-up (117.0) without the block override this used to need.

   .stats (ui.css) fits three 220px cards into a 768px window on its own; §5 asks
   for two in a row below 1040, so the cabinet's grid says it explicitly. */
@media (min-width: 768px) and (max-width: 1039.98px) {
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- audits list ----------------------------------------------------------- */

/* 36 + the 64 of main = the 100 px tail of the mock-up before the footer. */
.list { padding: 56px 0 36px; }

.list__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 18px;
  padding: 0 4px;
  /* .list__count and the 26px title are page classes, not ui.css primitives, so
     the tight line box of the mock-up is set here (30.0 in 01-cabinet.html). */
  line-height: var(--lh-tight);
}
.list__title {
  margin: 0;
  font-size: var(--fs-h2);
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-bold);
}
.list__count { color: var(--text-2); font-size: var(--fs-cap-2); }

.audits {
  /* Positioned for one reason only: the 2px .progress of a running row pins
     itself to the top edge of its positioned ancestor, and that ancestor is the
     row (.audits__row--active). A browser that still refuses `position` on a
     table row then puts the bar on the top edge of the list — the row it belongs
     to is the first one — instead of letting it escape to the viewport. */
  position: relative;
  width: 100%;
  table-layout: fixed;       /* the colgroup below owns the widths */
  border-collapse: collapse; /* so that a border on <tr> is painted */
  /* Line box of the mock-up's rows (75 px). The cell text (.audits__link/__url/
     __date/__meta) is page markup, not a ui.css primitive, so the table sets the
     tight role once for all of it. */
  line-height: var(--lh-tight);
}
.audits td,
.audits th {
  padding: 18px 10px;        /* 10 + 10 = the 20 px column gap of the mock-up */
  text-align: left;
  vertical-align: middle;
}
.audits tr > :first-child { padding-left: 24px; }
.audits tr > :last-child { padding-right: 24px; }

/* Track widths of the mock-up (130 / 170 / 150) plus the cell padding around them. */
.audits__col--date { width: 150px; }
.audits__col--status { width: 190px; }
.audits__col--report { width: 184px; }

.audits tbody tr { border-bottom: 1px solid var(--divider); }
.audits tbody tr:last-child { border-bottom: 0; }
.audits tbody tr:hover { background: var(--bg-subtle); }

/* A2. A row that is waiting for its report — queued or running: the same subtle
   fill as a hover, and the containing block of the progress bar (see .audits
   above). Only a running row carries that bar; a queued one keeps the fill, the
   pill, its position in the queue and «Отменить» (приёмка L5). The class is what
   the live module of app.js adds and removes — the [data-status] attribute stays
   the machine-readable half. */
.audits__row--active { position: relative; background: var(--bg-subtle); }

.audits__site { min-width: 0; }
.audits__link {
  color: var(--text);
  font-size: var(--fs-body);
  font-weight: var(--fw-med);
  letter-spacing: var(--ls-row);
}
.audits__link:hover { color: var(--text); }
.audits__url {
  display: block;
  margin: 3px 0 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* The address is the row's own data (the link above it shows the domain only),
     so it reads at 4.7:1 instead of the 2.6:1 of --text-4 (§6, задача D5). */
  color: var(--text-2);
  font-size: var(--fs-cap);
}

/* The words of the run (A2: «Проверено 18 страниц»), in place of the address of
   the row for as long as they exist. Same line box as .audits__url. */
.audits__progress {
  display: block;
  margin: 3px 0 0;
  color: var(--text-2);
  font-size: var(--fs-cap);
}

.audits__date { color: var(--text-2); font-size: var(--fs-cap-2); white-space: nowrap; }

/* Queue position and the dedup note: meaning, not decoration (§6, R1 MED-4). */
.audits__meta {
  display: block;
  margin: 5px 0 0;
  color: var(--text-2);
  font-size: var(--fs-cap);
}

/* The column of the mock-up is justify-self: end — the download button, the
   «Отменить»/ETA pair and the refund note all sit on the right edge of the card.
   `td.` is needed: the `.audits td { text-align: left }` above is a class plus a
   type, so a bare class would lose to it. */
.audits td.audits__report { text-align: right; }
/* The mock-up's compact download button; on touch it grows to the 44px target (§6). */
.audits__btn {
  min-height: 0;
  padding: 8px 16px;
  font-size: var(--fs-cap-2);
}
@media (pointer: coarse) { .audits__btn { min-height: var(--tap); } }

/* "ожидает" / "кредит возвращён" — the state of the report column, so --text-2. */
.audits__wait { color: var(--text-2); font-size: var(--fs-cap); }

/* The report column of a waiting row (A2) and of a failed one (A5): a text
   action on top, the estimate or the refund note under it. Both forms are plain
   blocks — .audits__report already aligns their text to the right edge, and a
   flex container on a <td> would drop it out of the table layout. */
.audits__cancel-form,
.audits__retry { margin: 0; }
.audits__cancel,
.audits__retry .link { font-size: var(--fs-cap-2); font-weight: var(--fw-med); }
/* «Отменить» is a way out, not the call to action of the row: --text-2 of the
   mock-up, accent only on hover. «Повторить» keeps the accent of .link. */
.audits__cancel { color: var(--text-2); }
.audits__cancel:hover { color: var(--accent-hover); }

.audits__eta {
  display: block;
  margin: 2px 0 0;
  color: var(--text-2);   /* the mock-up's --text-4 is 2.6:1 (§6, задача D5) */
  font-size: var(--fs-fine);
}
.audits__retry + .audits__wait { display: block; margin: 2px 0 0; }

.empty {
  padding: 48px 26px;
  border-radius: var(--r-card);
  background: var(--surface-2);
  text-align: center;
}
.empty__title { margin: 0; font-size: var(--fs-body); font-weight: var(--fw-med); }
.empty__hint { margin: 8px 0 0; color: var(--text-2); font-size: var(--fs-sm); }

/* ---- request-credits block (the "credits" partial of layout.html) ----------- */

.credits { margin: 24px 0 0; }
.credits h2 { margin: 0 0 10px; }
.credits p { margin: 0 0 14px; color: var(--text-2); }
.credits p:last-child { margin-bottom: 0; }
.credits details { color: var(--text-2); font-size: var(--fs-cap-2); }
.credits summary { cursor: pointer; }

.letter {
  margin: 12px 0 0;
  padding: 16px 18px;
  overflow-x: auto;
  border-radius: var(--r-input);
  background: var(--surface-2);
  color: var(--text-2);
  font-family: inherit;
  font-size: var(--fs-cap);
  line-height: var(--lh-cap);
  white-space: pre-wrap;
}

/* ---- audit card ------------------------------------------------------------ */

.crumbs { margin: var(--page-top) 0 14px; font-size: var(--fs-cap-2); }
.crumbs a { color: var(--text-2); }
.crumbs a:hover { color: var(--accent-hover); }

/* Every app-shell page without a hero starts at the same --page-top under the
   header (приёмка оркестратора): the h1 rule above, .doc, .errpage — and this
   title, unless the audit card's breadcrumb already carries the offset. */
.page__title { margin: var(--page-top) 0 18px; }
.crumbs + .page__title { margin-top: 0; }

.props {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr);
  gap: 12px 24px;
  margin: 0;
  align-items: baseline;
}
.props dt { color: var(--text-2); font-size: var(--fs-cap); }
.props dd { margin: 0; font-size: var(--fs-body); overflow-wrap: anywhere; }

.card__actions { margin: 22px 0 0; }
.card__note { margin: 22px 0 0; color: var(--text-2); font-size: var(--fs-cap-2); }

/* ---- billing --------------------------------------------------------------- */

/* One card only: a single auto-fit column would stretch it across the container. */
.metrics--one { grid-template-columns: repeat(auto-fit, minmax(220px, 320px)); }

.billing__note { margin: 24px 0 0; }
.billing__note p { margin: 0; }

.ledger {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  line-height: var(--lh-tight); /* same as .audits: page cell text, not primitives */
}
.ledger td,
.ledger th { padding: 14px 10px; text-align: left; vertical-align: middle; }
.ledger tr > :first-child { padding-left: 24px; }
.ledger tr > :last-child { padding-right: 24px; }
.ledger thead th { color: var(--text-2); font-size: var(--fs-cap); font-weight: var(--fw-med); }
.ledger tbody tr { border-bottom: 1px solid var(--divider); }
.ledger tbody tr:last-child { border-bottom: 0; }
.ledger tbody tr:hover { background: var(--bg-subtle); }

.ledger__col--date { width: 170px; }
.ledger__col--sum { width: 130px; }
.ledger__col--audit { width: 130px; }

.ledger__date { color: var(--text-2); font-size: var(--fs-cap-2); white-space: nowrap; }
/* `td.` for the same reason as .audits td.audits__report: `.ledger td { text-align:
   left }` above is a class plus a type, so a bare class would lose to it and the two
   right-hand columns of the mock-up would stay left (приёмка L5, пункт 3). */
.ledger td.ledger__sum { text-align: right; font-variant-numeric: tabular-nums; }
.ledger td.ledger__audit { text-align: right; font-size: var(--fs-cap-2); }

/* ---- document page (/docs/{slug}, shell "app") ----------------------------- */

.doc {
  max-width: 720px;
  margin: var(--page-top) auto 0;
}

.doc__title {
  margin: 0 0 18px;
  font-size: var(--fs-h2);
  line-height: var(--lh-h1-auth);
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-bold);
}

.doc__text { margin: 18px 0 0; color: var(--text-2); }
/* Same as .auth__note a: an in-sentence link is underlined, not only blue. */
.doc__text a { text-decoration: underline; }

/* Revision line under the title ("Редакция от …"). */
.doc__meta { margin: -8px 0 28px; font-size: var(--fs-cap-2); color: var(--text-2); }

/* Body of a published document: prose role (16.5/25), numbered sections, a small
   table for the cookie list. Links inside sentences are underlined (see .doc__text a). */
.doc__body { font-size: var(--fs-body); line-height: var(--lh-body); }
.doc__body p { margin: 0 0 14px; }
.doc__body h2 {
  margin: 30px 0 10px;
  font-size: var(--fs-lead);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-bold);
}
.doc__body ol,
.doc__body ul { margin: 0 0 14px; padding-left: 26px; }
.doc__body li { margin: 0 0 8px; padding-left: 4px; }
.doc__body li::marker { color: var(--text-2); }
.doc__body a { text-decoration: underline; }
.doc__body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.92em;
  padding: 1px 6px;
  border-radius: 6px;
  background: var(--surface-2);
}
.doc__table {
  width: 100%;
  margin: 6px 0 16px;
  border-collapse: collapse;
  font-size: var(--fs-sm);
  line-height: var(--lh-cap-2);
}
.doc__table th,
.doc__table td {
  padding: 10px 12px 10px 0;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--divider);
}
.doc__table th { color: var(--text-2); font-weight: var(--fw-med); }
.doc__table td:last-child,
.doc__table th:last-child { padding-right: 0; }

.doc__more {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin-top: 36px;
  padding-top: 22px;
  border-top: 1px solid var(--divider);
  font-size: var(--fs-cap);
}
.doc__more-title { margin-bottom: 2px; color: var(--text); font-weight: var(--fw-med); }
.doc__more a { color: var(--text-2); }
.doc__more a:hover { color: var(--accent-hover); }

/* ---- error page (404 / 403 / 429 / 500, shell "app") ----------------------- */

.errpage {
  max-width: 520px;
  margin: var(--page-top) auto 0;
  text-align: center;
}

.errpage__title {
  margin: 0 0 10px;
  font-size: var(--fs-h2);
  line-height: var(--lh-h1-auth);
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-bold);
}

.errpage__text { margin: 0 0 20px; color: var(--text-2); }
.errpage__actions { margin: 0; }

/* ---- touch targets (§6) ---------------------------------------------------- */

/* The page-level counterpart of the ui.css block: navigation and controls grow to
   the 44px minimum on a touch pointer. An in-sentence link keeps its line box
   (.search__hint a, .doc__text a) — see the note there. */
@media (pointer: coarse) {
  .crumbs a,
  .doc__more a,
  .ledger__audit a,
  .audits__cancel,
  .audits__retry .link {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
  }
  .doc__more { gap: 0; }
  .credits summary { min-height: var(--tap); line-height: var(--tap); }
}

/* In the card layout the site name is the card's own action, not a word inside a
   sentence, so there it becomes a 44px target as well. */
@media (max-width: 767.98px) and (pointer: coarse) {
  .audits__link { display: inline-flex; align-items: center; min-height: var(--tap); }
}

/* ---- responsive (§5) ------------------------------------------------------- */

@media (max-width: 767.98px) {
  .hero { padding: 56px 0 56px; }
  .hero__lead { margin-bottom: 32px; }

  /* The button moves under the input and takes the whole width. */
  .search__pill {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    padding: 10px;
    border-radius: var(--r-card);
  }
  .search__input { padding: 10px 12px; }
  .search .btn { width: 100%; }

  .list { padding: 40px 0 20px; }

  /* The table becomes a list of cards; the roles in the markup keep it a table
     for assistive technology (решение №11). */
  .audits,
  .audits tbody,
  .audits tr,
  .audits td {
    display: block;
    width: auto;
  }
  /* Only the colgroup goes: `display: none` on the thead would take the column
     headers out of the accessibility tree as well (R1 MED-3). The header row is
     already .sr-only in the markup, so it is invisible either way. */
  .audits colgroup { display: none; }
  .audits tr { padding: 18px 20px; }
  .audits td,
  .audits tr > :first-child,
  .audits tr > :last-child { padding: 0; }
  .audits td + td { margin-top: 10px; }
  .audits td.audits__report { text-align: left; }
  .audits__btn { width: 100%; min-height: var(--tap); font-size: var(--fs-md); }

  .props { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .props dt { margin-top: 12px; }
  .props dt:first-child { margin-top: 0; }

  .ledger,
  .ledger tbody,
  .ledger tr,
  .ledger td {
    display: block;
    width: auto;
  }
  /* Same as .audits: the header row is hidden the .sr-only way — visually gone,
     still a <th scope="col"> for a screen reader (R1 MED-3). */
  .ledger colgroup { display: none; }
  .ledger thead {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .ledger tr { padding: 14px 20px; }
  .ledger td,
  .ledger tr > :first-child,
  .ledger tr > :last-child { padding: 0; }
  .ledger td + td { margin-top: 6px; }
  .ledger td.ledger__sum,
  .ledger td.ledger__audit { text-align: left; }
}
