/* The client app shell: Home, Findings, Connections, Your data
   (docs/findings.md section 5, logs/2026-09-25-findings-mock.html and its
   screenshots). Reuses web/admin.css's tokens (--hairline, --muted,
   --accent, --accent-tint, --good/--warn, --sans, --radius, ...) rather
   than inventing new ones; this file only names the shell/nav/card layout
   admin.css doesn't already cover. Class names (m-shell, m-nav, m-kpi,
   m-f, m-c) match the wireframe file's own classes 1:1 so the mock and
   the real app stay directly comparable. Kept out of admin.css itself
   (CLAUDE.md: admin.css is the admin surface's own stylesheet).

   Breakpoint: sidebar nav at >= 641px, a horizontal tab strip below 641px
   (docs/findings.md section 5's "sidebar on desktop, tab strip on phone"). */

/* U4 goal 5: one type scale for the whole client surface -- a page title,
   a section title, body text, and small/meta text -- so the shell, Home,
   Findings, Connections and sign-in stop drifting between one-off sizes
   (12/12.5/13/13.5/14/14.5/15/16/22/24px) that read as accidental rather
   than designed. Values are the sizes already most common in this file, so
   normalizing to them is not a visual redesign. */
/* This file's own --fs-page-title/section-title/body/small are now defined
   once in web/tokens.css, on the shared 13/15/16/17/24/30 scale, so this
   surface stops drifting from admin.css's scale (22/14.5/12.5 moved onto
   24/16/13 respectively; the readability-pass rationale in admin.css
   applies here too). No local :root needed. */

.m-shell {
  display: grid;
  grid-template-columns: 200px 1fr;
  min-height: 100vh;
}

.m-topbar {
  padding: 12px 32px 0;
}

.m-nav {
  border-right: 1px solid var(--hairline);
  padding: 20px 16px;
}
/* GROUPING.md: who is signed in is account housekeeping, so it sits at the
   foot of the side menu rather than above every screen. */
.m-acct {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 200px;
  padding: 16px;
  font-size: var(--fs-small);
  color: var(--muted);
}
.m-acct .who {
  margin: 0 0 4px;
  font-size: var(--fs-small);
}
.m-acct .who b {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.m-acct .who a {
  margin: 0 12px 0 0;
}
.m-nav .co {
  font-family: var(--sans);
  font-weight: 600;
  margin-bottom: 18px;
  overflow-wrap: anywhere;
}
.m-nav a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 7px 10px;
  border-radius: var(--radius-ctl);
  color: var(--text);
  text-decoration: none;
  font-size: var(--fs-body);
}
.m-nav a.on {
  background: var(--accent-tint);
}

.m-main {
  padding: 28px 32px;
  max-width: 860px;
}
.m-main h1 {
  font-family: var(--sans);
  font-weight: 600;
  font-size: var(--fs-page-title);
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin: 0 0 4px;
  /* REACH.md: a long unbroken name (a domain, say) wraps, never overflows. */
  overflow-wrap: anywhere;
}
.m-main h2 {
  font-size: var(--fs-section-title);
  margin: 26px 0 10px;
  color: var(--muted);
  font-weight: 600;
}
.m-sub {
  color: var(--muted);
  margin: 0 0 22px;
  font-size: var(--fs-body);
}
/* GROUPING.md: Home's progress counts and read date are one header, not
   two separate items. */
.m-sub:has(+ .m-sub) {
  margin-bottom: var(--sp-2);
}


.m-f {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-ctl);
  padding: 14px 16px;
  margin-bottom: var(--sp-12);
  background: var(--card);
}
.m-f h3 {
  margin: 0 0 4px;
  font-size: var(--fs-page-title);
  font-weight: 600;
}
.m-f .eyebrow {
  margin: 0 0 2px;
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.m-f .st,
.f-row .st {
  float: right;
  font-size: var(--fs-13);
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline);
}
.m-f .st.open,
.f-row .st.open {
  background: var(--warn-bg);
  border-color: var(--warn);
  color: var(--warn);
}
.m-f .st.ver,
.f-row .st.ver {
  background: var(--good-bg);
  border-color: var(--good);
  color: var(--good);
}
.m-f .st.sent,
.f-row .st.sent {
  background: var(--accent-tint);
  border-color: var(--hairline);
}
.m-f .st.fixed,
.f-row .st.fixed {
  background: var(--good-bg);
  border-color: var(--good);
  color: var(--good);
}
.m-f .st.dismissed,
.f-row .st.dismissed {
  background: var(--canvas);
  border-color: var(--hairline);
  color: var(--muted);
}
.m-f p {
  margin: 6px 0;
  font-size: var(--fs-body);
  line-height: 1.5;
}
.m-f .ev {
  color: var(--muted);
}
.m-f .ev a {
  color: inherit;
}
.m-f .acts {
  margin-top: 10px;
  display: flex;
  gap: var(--sp-8);
  flex-wrap: wrap;
  align-items: center;
}
.m-f .acts button {
  font: inherit;
  font-size: var(--fs-15);
  height: 28px;
  padding: 0 10px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-ctl);
  color: var(--text);
  background: var(--card);
  cursor: not-allowed;
}
.m-f .acts button.pri {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
  /* REACH.md: the one main action is bigger than the buttons beside it. */
  height: 36px;
  padding: 0 var(--sp-16);
}
.m-f .acts button:disabled {
  opacity: 0.55;
}
.m-f .acts button:not(:disabled) {
  cursor: pointer;
}
.m-f .status-msg {
  color: var(--muted);
  font-size: var(--fs-small);
  margin: 6px 0 0;
}
/* MOMENTUM.md, the peak moment: a verified retest reads as a result, not a
   status line, and points at the next open finding. */
.m-f .acts.verified-result {
  display: block;
  margin-top: var(--sp-16);
  padding: var(--sp-12) var(--sp-16);
  background: var(--good-bg);
  border: 1px solid var(--good);
  border-radius: var(--radius-ctl);
}
.m-f .verified-head {
  margin: 0;
  font-size: var(--fs-16);
  font-weight: 600;
  color: var(--good);
}
.m-f .verified-result .status-msg {
  color: var(--text);
}
.m-f .next-link {
  display: inline-block;
  margin-top: var(--sp-12);
  font-weight: 600;
  color: var(--text);
}
.m-f .steps {
  margin: 8px 0 0;
  padding-left: 18px;
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--text);
}
.m-f .snippet-box {
  margin-top: 10px;
}
.m-f .snippet-box summary {
  cursor: pointer;
  font-size: var(--fs-small);
  color: var(--accent);
}
.m-f .snippet {
  margin: 8px 0;
  padding: 10px 12px;
  border-radius: var(--radius-ctl);
  background: var(--canvas);
  border: 1px solid var(--hairline);
  font-family: monospace;
  font-size: var(--fs-13);
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-all;
}
.m-f .tag-check-result {
  color: var(--muted);
  font-size: var(--fs-small);
  margin: 6px 0 0;
}
/* Stripe, GA4, Google Ads and Meta's own connect box (S4b goal 3): one
   input, one primary button, one result line -- same shape as the site
   tag's .snippet-box minus the snippet itself. `.err` marks a rejected
   key or a needs_attention/400 result in the warn color; a plain or
   `pending` result stays muted so waiting never reads as failing. */
.m-f .conn-box {
  margin-top: 10px;
}
.m-f .conn-input {
  font: inherit;
  font-size: var(--fs-small);
  padding: 7px 10px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-ctl);
  width: 100%;
  max-width: 340px;
  box-sizing: border-box;
}
.m-f .conn-result {
  color: var(--muted);
  font-size: var(--fs-small);
  margin: 6px 0 0;
}
.m-f .conn-result.err {
  color: var(--warn);
}
.m-f .conn-result:empty {
  display: none;
}
.m-f .dismiss-form {
  display: none;
  margin-top: 10px;
  gap: var(--sp-8);
  align-items: center;
  flex-wrap: wrap;
}
.m-f.show-dismiss-form .dismiss-form {
  display: flex;
}
.m-f .dismiss-reason-input {
  font: inherit;
  font-size: var(--fs-13);
  padding: 5px 8px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-ctl);
  flex: 1 1 220px;
}
.m-f .dismiss-error {
  width: 100%;
  margin: 0;
  font-size: var(--fs-13);
  color: var(--warn);
}
.m-f .retest-error {
  width: 100%;
  margin: 0;
  font-size: var(--fs-13);
  color: var(--warn);
}
.m-f .retest-error:empty {
  display: none;
}
/* MOMENTUM.md: the retest wait line shares the slot but is not a warning. */
.m-f .retest-error.is-wait {
  color: var(--muted);
}
/* The finding detail page (U1 goal 3): one finding, full width, built on
   top of the .m-f card rules above for its status pill and action row. */
.m-detail {
  max-width: 640px;
}
.m-detail .back-link {
  display: inline-block;
  margin-bottom: 14px;
  font-size: var(--fs-small);
  color: var(--accent);
  text-decoration: none;
}
.m-detail .det-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: var(--sp-4);
}
.m-detail .det-head h1 {
  margin: 0;
}
.m-detail .st {
  float: none;
  flex-shrink: 0;
}
.m-detail section {
  margin-top: 18px;
}
.m-detail .det-citations {
  margin: 6px 0 0;
  padding-left: 18px;
  font-size: var(--fs-small);
}
.m-detail .det-citations a {
  color: var(--accent);
}
.m-detail .det-history {
  margin-top: 22px;
  padding-top: 14px;
  border-top: 1px solid var(--hairline);
}
.m-detail .acts {
  margin-top: var(--sp-16);
}
.m-detail .acts button:not(.pri) {
  border-color: transparent;
  background: none;
  color: var(--accent);
  padding-left: var(--sp-2);
  padding-right: var(--sp-2);
}
/* GROUPING.md: "Not relevant" hides the finding, unlike the three actions
   that help fix it, so it sits apart at the far end of the row. */
.m-detail .acts button.act-away {
  margin-left: auto;
  color: var(--muted);
}
.m-detail .acts button:not(.pri):disabled {
  color: var(--muted);
}
.m-detail .det-history ul {
  margin: 6px 0 0;
  padding-left: 18px;
  font-size: var(--fs-small);
  color: var(--muted);
  line-height: 1.6;
}

/* The Findings list: tabs, then one row per finding (U1 goal 2). Rows
   replace the old expanded m-f cards on this screen; the card styles
   above stay in use only on the finding detail page (goal 3) and Home's
   "Do these three first" (goal 4). */
.f-tabs {
  display: flex;
  gap: var(--sp-4);
  border-bottom: 1px solid var(--hairline);
  margin-bottom: var(--sp-6);
}
.f-tab {
  font: inherit;
  font-size: var(--fs-body);
  padding: 8px 12px;
  border: none;
  background: none;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.f-tab.on {
  color: var(--text);
  border-bottom-color: var(--accent);
  font-weight: 600;
}
.f-tab-count {
  color: var(--muted);
  font-size: var(--fs-13);
}
.f-tab.on .f-tab-count {
  color: inherit;
}
.f-panel[hidden] {
  display: none;
}
.f-empty {
  color: var(--muted);
  font-size: var(--fs-body);
  padding: 14px 0;
}
.f-row {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  padding: 12px 4px;
  border-bottom: 1px solid var(--hairline);
  text-decoration: none;
  color: inherit;
}
.f-row:hover {
  background: var(--canvas);
}
.f-row-main {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: var(--sp-8);
  flex-wrap: wrap;
}
.f-title {
  font-size: var(--fs-body);
  color: var(--text);
}
.f-cat {
  font-size: var(--fs-small);
  color: var(--muted);
}
.f-do-first {
  font-size: var(--fs-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--accent);
}
.f-row .st {
  float: none;
  flex-shrink: 0;
}
/* Group headings inside a list (decision-load pass): the Open tab's
   "Do these first" and its areas, and Connections' "Not available yet".
   Same eyebrow as .f-do-first; muted except the first group. */
.f-group {
  font-size: var(--fs-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
  margin: var(--sp-16) 0 0;
  padding: 0 4px var(--sp-4);
  border-bottom: 1px solid var(--hairline);
}
.f-group-first {
  color: var(--accent);
  margin-top: var(--sp-12);
}
.f-date {
  font-size: var(--fs-small);
  color: var(--muted);
  flex-shrink: 0;
}
.f-row.static {
  cursor: default;
}
.f-row.static:hover {
  background: none;
}
.c-connect {
  font-size: var(--fs-small);
  color: var(--accent);
  flex-shrink: 0;
}
.c-soon {
  font-size: var(--fs-small);
  color: var(--muted);
  flex-shrink: 0;
}
.f-unknowns {
  margin-top: 14px;
  font-size: var(--fs-small);
}
.f-unknowns a {
  color: var(--accent);
}
.m-hist {
  font-size: var(--fs-small);
  color: var(--muted);
  margin-top: var(--sp-8);
}

/* Your data screen (S5a): the list of rows uses .f-row/.f-row-main/
   .f-title/.f-cat above, same as Connections. This is just the one
   primary action underneath it and its quiet result line. */
.data-download {
  margin-top: var(--sp-16);
}
.data-download-result {
  font-size: var(--fs-small);
  color: var(--muted);
  margin: 8px 0 0;
}
.data-download-result.err {
  color: var(--warn);
}
.data-download-result:empty {
  display: none;
}

.m-c {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-ctl);
  padding: 14px 16px;
  margin-bottom: var(--sp-12);
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-8);
  background: var(--card);
}
.m-c small {
  color: var(--muted);
  display: block;
  font-size: var(--fs-small);
}

@media (max-width: 640px) {
  .m-shell {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }
  .m-topbar {
    padding: 10px 16px 0;
  }
  .m-acct {
    position: static;
    width: auto;
    padding: 0 16px 24px;
  }
  .m-nav {
    border-right: 0;
    border-bottom: 1px solid var(--hairline);
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    padding: 10px 16px;
    /* Wrap rather than scroll: a scrolled strip hid "Your data" off the
       right edge at 390px with nothing to say it was there. */
    flex-wrap: wrap;
  }
  .m-nav a {
    padding: 6px 10px;
    white-space: nowrap;
  }
  .m-nav .co {
    margin: 0 12px 0 0;
    white-space: nowrap;
    /* REACH.md: a long company name ends in "…" instead of widening the
       page past the screen. */
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .m-main {
    padding: 20px 16px;
  }
  .m-c {
    grid-template-columns: 1fr;
  }
}

/* POLISH.md: the screen heading takes focus after navigation so screen
   readers announce it; it is not a control, so it gets no ring. */
#screen h1[tabindex="-1"]:focus { outline: none; }

/* In preview every action is off. Make that visible without a hover. */
body.viewas-active button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Responsive slice 2: 44px tap targets on phones and tablets. The action
   buttons are 28px tall at desktop width, which is fine with a mouse. */
@media (max-width: 900px) {
  .m-f .acts button,
  .m-f .acts a.btn-link.pri {
    height: auto;
    min-height: 44px;
  }
  /* REACH.md: 16px text in a box stops iPhone Safari zooming the page when
     the owner taps it to paste an ID. */
  .m-f .conn-input,
  .m-f .dismiss-reason-input {
    font-size: var(--fs-16);
    min-height: 44px;
  }
  .m-acct .who a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .f-tab {
    min-height: 44px;
  }
}

/* MOMENTUM.md, the last moment: the one next step when nothing is open,
   drawn like the .pri buttons above but as a link (it opens email). */
.m-f .acts a.btn-link.pri {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 var(--sp-16);
  border-radius: var(--radius-ctl);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--fs-15);
  text-decoration: none;
}
.m-f.all-handled p {
  margin: 0 0 var(--sp-8);
}
