/* A Scan's pages (sites/scans), one family: .scan-*. Its glyphs are
   icons.css's (.scan-glyph), with the other status glyphs.

   Every Scan permalink opens with the same header, the Url detail page's own
   shape so that someone arriving from there meets what they just left: the
   Scan's name, address and date, with the pager and the kebab beside them,
   and Share too when the Scan has a list to hand on. The list of a Site's
   Scans (sites/scans/index) draws the header's title and pager. A Scan that
   failed shows the verdict band under the header, whatever its Scanner, and
   every Scan can end in the technical details' raw results (.scan-json).

   The URL and Form Scans (sites/scans/_url, _form) then draw the verdict band
   and one card holding the queue of what was found and, beside it, the focus
   pane on the one picked: its evidence, the decision it asks for, and the
   finds there is nothing to decide about. A broken-links Scan draws the Site
   page's rows and drawers instead (broken_links.css), and takes only a
   link's evidence (its raw response included), its steps, the open buttons
   and the address type from here.

   The header and the card were folded in from the Scan#show UI prototype
   (2026-09-13, .claude/skills/prototype/UI.md), which won out over three
   alternatives, including a Scan-as-a-diff-against-the-previous-one that
   was built and rejected (don't rebuild it); the full set stays on the
   throwaway branch prototype/scan-show-broken-links, and the reasoning is in
   .scratch/scanner-broken-links/map.md under "Redesigned: the Scan
   permalink".

   THIS FILENAME IS A CASCADE DECISION. Propshaft serves one <link> per
   stylesheet in alphabetical order and there is no @layer, so this sorts
   after application.css, broken_links.css and the rest up to rows.css, and a
   rule here beats one in those files that ties it on specificity. These
   rules moved here from application.css (2026-10-29), where button.css's
   .button had been beating .scan-off's cursor and hover border; that is the
   only computed style the move changed. */

/* .resource-header's box, rule included. align-items: flex-start is what puts the
   pager level with the h1 rather than with the bottom of the meta line; the
   identity block's flex-basis of 0 (not auto) is what stops it claiming its
   text's full width and wrapping the controls away. */
.scan-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--color-border);
}

.scan-head-identity {
  flex: 1 1 0;
  min-width: 0;
}

.scan-head-identity h1 {
  margin: 0;
  overflow-wrap: anywhere;
}

.scan-head-address {
  margin: 0.2rem 0;
  font-size: 0.95rem;
  overflow-wrap: anywhere;
}

.scan-head-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.4rem 0;
  color: var(--color-text-muted);
  font-size: 0.85rem;
}

.scan-head-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.scan-pager {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Each end of the pager is a span, not a [disabled] button: the end of a list
   is not a control that happens to be switched off. Dimmed rather than
   removed so the header does not change width as you walk it. */
.scan-off {
  opacity: 0.4;
  cursor: default;
}

.scan-off:hover {
  border-color: var(--color-border);
}

/* With Share beside the pager there is one control too many for a phone's
   row: the title takes the row and the buttons wrap under it, which keeps
   the kebab on screen (.scratch/broken-links-handoff/issues/04 point 1). */
@media (max-width: 40rem) {
  .scan-head--shareable {
    .scan-head-identity {
      flex-basis: 100%;
    }

    .scan-head-actions {
      flex-wrap: wrap;
      flex-shrink: 1;
    }
  }
}

/* --- The verdict band --- */

/* Same shape as .action-card: one tinted surface, a thick tone edge, the
   verdict reading as the band's own sentence rather than a banner dropped on
   top of it. */
.scan-verdict {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 1.25rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--tone);
  border-left: 8px solid var(--tone);
  border-radius: var(--card-radius);
  background: var(--tone-bg);
}

/* A flex item keeps its min-content width unless told otherwise, and a
   verdict can name the Site's address: the last resort for one part wider
   than the line, as everywhere an address wraps at its punctuation. */
.scan-verdict-text {
  min-width: 0;
  overflow-wrap: anywhere;
}

.scan-verdict h2 {
  margin: 0;
  font-size: 1.3rem;
  color: var(--color-text);
}

.scan-verdict p {
  margin: 0.2rem 0;
  color: var(--color-text-muted);
}

/* --- The card ---
   Wears `card`; the queue and the focus run to its edges on a white surface. */

.scan-work {
  margin-top: 1.25rem;
  padding: 0;
  overflow: hidden;
}

/* The queue is fixed-width and the focus takes the rest: a column that grew
   with the longest address in it would move every time you clicked, and again
   every time you switched grouping. */
.scan-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 19rem;
  border-top: 1px solid var(--card-border);
}

@media (max-width: 60rem) {
  .scan-body {
    grid-template-columns: minmax(0, 1fr);
  }

  .scan-queue {
    border-left: 0;
    border-top: 1px solid var(--card-border);
  }
}

/* --- The focus pane --- */

.scan-focus {
  padding: 1.5rem;
  min-width: 0;
}

.scan-kicker {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
}

.scan-focus-url {
  margin: 0.6rem 0 0;
  font-size: 1.25rem;
  line-height: 1.3;
}

.scan-focus-reason {
  margin: 0.3rem 0;
  font-size: 1rem;
  color: var(--color-text-muted);
}

/* An address is the one thing on this page that must be readable character by
   character -- a trailing slash, or a 2024 in a filename, can be the whole
   finding. Monospace everywhere one appears, at every size. The single
   exception is the header's own address, which is identity rather than
   evidence and is set as prose, exactly as the Url page sets it. The size is
   in em, not a step, so "at every size" holds: it follows the text the
   address sits in. It wraps between its parts, at the <wbr>s
   ApplicationHelper#address_breaks puts in, and inside one only when that
   part is wider than its line. */
.scan-url {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.92em;
  overflow-wrap: anywhere;
}

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

.scan-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  background: var(--color-bg);
  color: var(--color-text-muted);
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}

/* The evidence block gets the page's only inset surface. It is a different
   KIND of content from everything around it -- not what we found, but how
   much you should believe it -- and the inset is what says so without a
   second heading level. Every grouping draws one. */
.scan-evidence {
  margin-top: 1.25rem;
  padding: 1rem 1.25rem 1.25rem;
  border-radius: var(--radius);
  background: var(--color-bg);
}

.scan-evidence h3 {
  margin: 0 0 0.7rem;
  font-size: 1rem;
}

.scan-evidence dl {
  margin: 0;
  display: grid;
  gap: 0.8rem;
}

.scan-evidence dd {
  margin: 0.2rem 0;
  line-height: 1.55;
  max-width: 42rem;
}

.scan-evidence code {
  padding: 0.1rem 0.4rem;
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  /* em, not a step: inline code is sized against the sentence around it. */
  font-size: 0.85em;
}

.scan-evidence-actions {
  margin-top: 0.5rem;
}

/* These buttons carry a whole address, which can be wider than the pane. It
   wraps as .scan-url does. */
.scan-evidence-actions .scan-open {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* "Open it yourself" -- the most important control on the page, because it is
   the only one that can actually settle whether a finding is real. Styled as
   a link-button so it never looks like the primary action of a form. */
.scan-open {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.scan-open:hover {
  border-color: var(--color-accent);
  color: var(--color-accent-dark);
}

.scan-open--primary {
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.scan-open--primary:hover {
  background: var(--color-accent-dark);
  color: var(--color-on-accent);
}

.scan-steps {
  margin: 0.4rem 0;
  padding-left: 1.25rem;
  max-width: 44rem;
}

.scan-steps li {
  margin: 0.4rem 0;
  line-height: 1.55;
}

.scan-steps-heading {
  margin: 1.25rem 0 0;
  font-size: 1rem;
}

.scan-raw {
  margin-top: 1.25rem;
}

.scan-raw summary {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  cursor: pointer;
}

.scan-raw pre {
  margin: 0.5rem 0;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  font-size: 0.8rem;
  white-space: pre-wrap;
}

/* --- The queue --- */

.scan-queue {
  border-left: 1px solid var(--card-border);
  padding: 1.25rem 0 1.5rem;
  background: var(--color-surface);
}

.scan-queue-heading {
  margin: 0 1rem 0.8rem;
}

.scan-queue-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.scan-queue-item {
  display: block;
  padding: 0.5rem 1rem;
  border-left: 3px solid transparent;
  color: var(--color-text);
  text-decoration: none;
}

.scan-queue-item:hover {
  background: var(--tone-bg);
}

/* The open row is drawn exactly as hover draws it, plus the tone edge:
   pointing at a row promises what clicking does, and the open row has already
   kept that promise. */
.scan-queue-item[aria-current="true"] {
  background: var(--tone-bg);
  border-left-color: var(--tone);
}

.scan-queue-text {
  display: block;
  min-width: 0;
}

.scan-queue-title {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
}

.scan-queue-meta {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

/* --- Bodies that rule on finds rather than on defects (ADR 0033) ---

   The crawl's body reads a list of problems; the url and form bodies read a
   list of things to say yes or no to. They reuse the whole skeleton above --
   the verdict band, the focus pane, the queue -- and add only what a decision
   needs: somewhere to put the buttons, a table of a form's fields, and a
   quieter block below the queue for what nobody has to rule on. */

/* The decision itself. Directly under the evidence that justifies it, because
   pressing Confirm is meant to be the end of reading rather than a thing you
   hunt for afterwards. */
.scan-decide-blurb {
  margin: 0.4rem 0 0.9rem;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

.scan-decide-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.8rem;
}

/* Found, and nothing to decide about: numbers that are not numbers, forms
   that are search boxes. BELOW the card rather than inside it, and visibly
   quieter, so the queue stays a work list -- but present, because a page
   showing four phone numbers over a Scan listing three reads as a Scan
   that lost one. */
.scan-aside {
  margin-top: 1.25rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--card-border);
  border-radius: var(--card-radius);
  background: var(--color-bg);
}

.scan-aside h3 {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
}

.scan-aside-blurb {
  margin: 0.3rem 0 0.8rem;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

/* Its rows, and a form's hidden fields: a value and why it is set aside, on a
   hairline in the card's border colour rather than the plain one, the two
   running on as one line of text. */
:is(.scan-aside, .scan-raw) {
  .row {
    border-top-color: var(--card-border);
  }

  .row-top {
    padding-block: 0.4rem;
    font-size: 0.9rem;
  }

  .row-text {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
  }

  .row-name {
    font-weight: 400;
  }

  .row-what {
    margin: 0;
  }
}

/* A form's fields. Its own scroll container, so a form with long labels
   scrolls inside the pane instead of widening the page. */
.scan-table-scroll {
  overflow-x: auto;
  margin-top: 0.5rem;
}

.scan-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.scan-table th {
  padding: 0.4rem 0.8rem 0.4rem 0;
  border-bottom: 1px solid var(--card-border);
  text-align: left;
}

.scan-table td {
  padding: 0.5rem 0.8rem 0.5rem 0;
  border-bottom: 1px solid var(--card-border);
  vertical-align: top;
}

.scan-table td .scan-url {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.8rem;
}

/* The Scanner Variant's business facts, in the same definition-list shape the
   evidence block uses -- they are read the same way, a label and a value, and
   a second layout for the same reading would be a second thing to learn. */
.scan-facts {
  margin: 0.5rem 0;
  display: grid;
  gap: 0.5rem;
}

.scan-facts > div {
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
  gap: 0.8rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--card-border);
}

.scan-facts dt {
  color: var(--color-text-muted);
  font-size: 0.85rem;
}

.scan-facts dd {
  margin: 0;
  font-size: 0.9rem;
}

@media (max-width: 40rem) {
  .scan-facts > div {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.2rem;
  }
}

/* Everything the Scanner sent, verbatim, at the foot of every Scan page. Same
   disclosure treatment a Url's Checks get -- it answers "what exactly did you
   pick up?" and must never be what a non-technical owner has to read. */
.scan-json {
  margin: 0.5rem 0 0;
  padding: 0.8rem;
  border-radius: var(--card-radius);
  background: var(--color-bg);
  overflow-x: auto;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 0.8rem;
  line-height: 1.5;
  white-space: pre;
}
