/* Catalog surfaces — the homepage hero and the service-card list it
   shares with /services/<category> and the 404 popular-services row.
   Loaded through {% block page_styles %} from landing.html,
   services.html and not_found.html only, so the render-blocking
   site.css no longer ships these rules to /now, /how, /privacy,
   /connect or /status/<slug>. Rules any other template can match
   (.hero-stats, .pill, .service-logo, .service-age, .legend-*, header
   and footer chrome, :root/element rules) and every @font-face block
   stay in site.css (DESIGN.md §3). */
.home-hero { position: relative; overflow: hidden; padding: 1.9rem 0 1.7rem; text-align: left; }
.hero-content { position: relative; z-index: 1; }
.home-hero .hero-content { max-width: 50rem; }
.hero-bg {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 9.5rem;
  z-index: 0;
  display: flex;
  align-items: flex-end;
  gap: 2px;
  padding: 0 0.5rem;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,0.05) 14%, rgba(0,0,0,0.30) 55%, rgba(0,0,0,0.5) 100%);
  mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,0.05) 14%, rgba(0,0,0,0.30) 55%, rgba(0,0,0,0.5) 100%);
}
.pulse-chart { display: block; width: 100%; height: 100%; }
.pulse-seg-up { fill: var(--bar-up); }
.pulse-seg-slow { fill: var(--slow); }
.pulse-seg-down { fill: var(--down); }
.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 0.7rem;
  color: var(--faint);
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
/* located eyebrow: visitor place + a small green locator dot (identity, not
   severity — mirrors the header chip dot). SPEC §2.1 owner-mandated. */
.eb-loc { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 0.35rem 0.45rem; border-left: 1px solid var(--line2); padding-left: 0.75rem; }
.eb-loc-label { display: inline-flex; align-items: center; gap: 0.45rem; white-space: nowrap; }
.eb-place { white-space: nowrap; }
.eb-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--good); flex: 0 0 auto; }
.home-hero h1 {
  max-width: 17ch;
  margin: 0 0 0.6rem;
  font-size: clamp(1.6rem, 4.2vw, 2.375rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
}
.hero-ok { color: var(--good); }
.hero-problem { color: var(--down); }
.home-hero .tagline {
  max-width: 50ch;
  margin: 0;
  font-size: 0.9375rem;
}
.home-hero .hero-stats {
  justify-content: flex-start;
  margin-top: 0;
  margin-left: 0;
  margin-right: 0;
}
/* DETECTDOWN-257: the operational summary leads the strip — the single
   most useful fact ("is anything down?"). It keeps the strip's no-icon /
   no-bold register; only color lifts it off the --mut siblings so it
   reads as the lead without shouting. Green when all measured services
   are up, --down when one or more carry a problem verdict. The text
   ("All 80 up" / "2 down") states the answer in full, so color is pure
   reinforcement — never the only signal (§8 accessibility). */
.hero-status { color: var(--mut); }
.hero-status .n-up { color: var(--good); font-weight: 700; font-variant-numeric: tabular-nums; }
.hero-status .n-total { color: var(--faint); font-variant-numeric: tabular-nums; }
.hero-status.is-problem .n-up { color: var(--down); }
.hero-stats .n-down { color: var(--down); font-weight: 700; font-variant-numeric: tabular-nums; }
.services-answer {
  margin: 0 0 0.4rem;
  color: var(--ink);
  font-size: 1.125rem;
  font-weight: 600;
}
.services-answer .hero-status { color: inherit; }
.services-answer .hero-status.is-problem { color: var(--down); }
.hero-caption {
  position: absolute;
  right: 1.5rem;
  bottom: 1rem;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 1rem;
  color: var(--mut);
  font-size: 0.8rem;
  /* Slightly translucent (+ blur) so the activity chart is faintly visible
     behind the legend while the text stays easily readable, both themes. */
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  border: 1px solid var(--line2);
  border-radius: var(--r-sm);
  padding: 0.45rem 0.75rem;
}
.hero-caption .nn { color: var(--ink); font-variant-numeric: tabular-nums; }
.hero-caption-link { color: var(--ink); text-decoration: underline; }
.hero-caption-link:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.lg { display: inline-flex; align-items: center; gap: 0.35rem; color: var(--faint); font-family: var(--mono); font-size: 0.625rem; letter-spacing: 0.04em; text-transform: uppercase; }
.lg + .lg { margin-left: 0.7rem; }
.lg-dot { width: 7px; height: 7px; border-radius: 1px; }
.lg-up { background: var(--bar-up); }
.lg-slow { background: var(--slow); }
.lg-down { background: var(--down); }
@media (forced-colors: active) {
  .cells .cell,
  .pill,
  .lg-dot,
  .legend-dot {
    forced-color-adjust: none;
    border: 1px solid CanvasText;
  }
}
@media print {
  .hero-bg,
  .catalog-filter[role="search"] {
    display: none;
  }
  .cells .cell,
  .pill,
  .lg-dot,
  .legend-dot {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    border: 1px solid var(--ink);
  }
}
@media (max-width: 860px) {
  .home-hero { display: flex; flex-direction: column; padding: 1.35rem 0 1.2rem; }
  .home-hero .hero-content { order: 1; }
  .hero-bg { position: static; order: 2; height: 5rem; margin-top: 0.6rem; padding: 0; }
  .hero-caption { order: 3; position: static; width: fit-content; max-width: 100%; margin: 0.55rem auto 0; }
  .catalog-list-head { margin-top: 1.5rem; }
  .catalog-categories { margin-bottom: 0.55rem; }
}
/* At the WCAG reflow reference width, keep the legend and its time window
   as two deliberate rows instead of allowing either group to split. */
@media (max-width: 350px) {
  .hero-caption { flex-direction: column; gap: 0.35rem; }
  .hero-caption > span:first-child,
  .hero-caption-window { white-space: nowrap; }
}
/* Keep the located eyebrow in deliberate phrase/place rows throughout the
   narrow mobile range; the place stays intact so its region cannot orphan. */
@media (max-width: 430px) {
  .hero-eyebrow { display: flex; }
  .hero-eyebrow .eb-lead { flex-basis: 100%; }
  .hero-eyebrow .eb-loc { border-left: 0; padding-left: 0; }
}
/* The home all-clear strip has a fourth segment ("All N up"), so it
   wraps wider than the base stats strip above. Stack only the home
   variant before that wrap point, and keep it aligned with the left edge
   of the rest of the home hero. */
@media (max-width: 530px) {
  .home-hero .hero-stats { flex-direction: column; align-items: flex-start; gap: 0.25rem; }
  .home-hero .hero-stats .sep { display: none; }
}
/* ROADMAP.md M5 "Browse by category" discovery row in the
   /services header. A single muted inline line — the categories
   are the eye-catch, the leading label is the orientation. Reuses
   --ink for the links so the row reads as the same affordance
   as every other in-product link. Categories never carry a badge
   on cards (M5 anti-pattern); these browse rows are where the
   category vocabulary surfaces to visitors. */
.services-categories {
  margin: 0.4rem 0 0;
  color: var(--mut);
  font-size: 0.92rem;
}
.services-categories-label { margin-right: 0.35rem; }
.services-categories a { color: var(--ink); text-decoration: none; }
.services-categories a:hover { text-decoration: underline; }
.services-categories a:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.services-category-current { color: var(--ink); font-weight: 600; }
.catalog-categories {
  margin: 0 0 0.85rem;
  line-height: 1.8;
}
@media (max-width: 480px) {
  nav.services-categories {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: 0.75rem;
    row-gap: 0.25rem;
    line-height: 1.35;
  }
  nav.services-categories .services-categories-label {
    grid-column: 1 / -1;
    margin-right: 0;
  }
  nav.services-categories .sep { display: none; }
  nav.services-categories a,
  nav.services-categories .services-category-current {
    display: flex;
    align-items: center;
    min-height: 24px;
  }
}
@media (max-width: 380px) {
  nav.services-categories {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.services-foot { margin: 0.5rem 0 2.5rem; text-align: center; font-size: 0.92rem; }
.services-foot a { color: var(--ink); text-decoration: none; }
.services-foot a:hover { text-decoration: underline; }
.service-group { margin: 0 0 1.25rem; }
.service-group-header {
  margin: 0 0 0.55rem;
}
.service-group-label {
  margin: 0;
  color: var(--faint);
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.service-group-note {
  margin: 0.3rem 0 0;
  color: var(--mut);
  font-size: 0.9rem;
}
.service-group-divider {
  margin: 1.5rem 0 1rem;
  border-top: 1px solid var(--line2);
}

/* DETECTDOWN-57 whole-grid empty state. Shown only when zero cards
   carry a verdict (fresh deploy, poller between recoveries) so the
   page never reads as broken. Same --surface/--line surface family
   as the cards below, strictly --mut, no status tint, no motion
   (§2.5) — it's reassurance, not an alert; the verdict pills keep
   the spotlight. Bottom margin matches the grid gap so the banner
   reads as the row above the cards, not a second hero. */
.catalog-empty-banner {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1.05rem;
  margin: 0 0 0.85rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--mut);
  font-size: 0.92rem;
}


/* Service grid — dense v3 homepage list rows. */
.service-grid {
  display: grid;
  column-gap: 2.25rem;
  grid-template-columns: 1fr 1fr;
  margin: 0;
  padding: 0;
  border-bottom: 1px solid var(--line);
  list-style: none;
}
.service-grid > li { display: contents; }
.service-grid > li[hidden] { display: none; }
.catalog-list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 2.5rem 0 0.25rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--line2);
}
.catalog-heading {
  display: flex;
  flex: 1 1 22rem;
  min-width: 0;
  flex-direction: column;
  gap: 0.35rem;
}
.catalog-list-head h2 { margin: 0; font-size: 0.9375rem; }
.catalog-filter {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0.625rem;
  flex: 0 1 440px;
  min-width: 0;
  margin: 0;
  position: relative;
}
.catalog-filter[hidden] { display: none; }
.catalog-filter label {
  color: var(--faint);
  font: 600 0.6875rem/1 var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.catalog-filter input[type=search] {
  width: 100%;
  min-width: 0;
  padding: 0.5625rem 0.75rem;
  border: 1px solid var(--line2);
  border-radius: var(--r-sm);
  background: var(--bg);
  color: var(--ink);
  font: 0.875rem/1.3 var(--sans);
}
.catalog-filter input[type=search]::-webkit-search-decoration,
.catalog-filter input[type=search]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}
.catalog-filter input[type=search]:focus {
  border-color: var(--mut);
  outline: none;
}
.catalog-filter input[type=search]:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.catalog-filter-suggestions {
  position: absolute;
  z-index: 10;
  top: calc(100% + 0.25rem);
  right: 0;
  left: 0;
  display: grid;
  overflow: hidden;
  border: 1px solid var(--line2);
  border-radius: var(--r);
  background: var(--surface);
}
.catalog-filter-suggestions[hidden] { display: none; }
.catalog-filter-suggestion {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 2.25rem;
  padding: 0.5rem 0.65rem;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font: 0.875rem/1.25 var(--sans);
  text-align: left;
  cursor: pointer;
}
.catalog-filter-suggestion:last-child { border-bottom: 0; }
.catalog-filter-suggestion:hover,
.catalog-filter-suggestion.is-active {
  background: var(--raise);
}
.catalog-filter-suggestion:focus-visible {
  position: relative;
  z-index: 1;
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}
.catalog-filter-suggestion-value {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.catalog-filter-suggestion-label {
  flex: 0 0 auto;
  color: var(--faint);
  font: 0.6875rem/1.2 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.catalog-filter-status {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.625rem;
  margin: 0.85rem 0;
}
.catalog-filter-status[hidden] { display: none; }
.catalog-filter-count {
  min-width: 0;
  margin: 0;
  color: var(--mut);
  font-size: 0.88rem;
  overflow-wrap: anywhere;
}
.catalog-filter-label { color: var(--faint); }
.catalog-filter-category-link {
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
}
.catalog-filter-category-link:hover { text-decoration: underline; }
.catalog-filter-category-link:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.catalog-filter-empty {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 0.85rem 0;
  color: var(--mut);
  font-size: 0.92rem;
}
.catalog-filter-empty[hidden] { display: none; }
.catalog-filter-empty p {
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
}
.catalog-filter-recovery-title {
  flex-basis: 100%;
  color: var(--faint);
  font: 0.75rem/1.3 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}
.catalog-filter-recovery {
  display: flex;
  flex: 1 1 100%;
  flex-wrap: wrap;
  gap: 0.4rem 0.65rem;
  margin: -0.25rem 0 0;
  padding: 0;
  list-style: none;
}
.catalog-filter-recovery[hidden] { display: none; }
.catalog-filter-paused-recovery {
  flex-basis: 100%;
}
.catalog-filter-recovery a {
  color: var(--ink);
  font-size: 0.9rem;
  text-decoration: none;
}
.catalog-filter-recovery a:hover { text-decoration: underline; }
.catalog-filter-recovery a:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.catalog-filter-clear {
  display: inline-flex;
  align-items: center;
  min-height: 2rem;
  padding: 0.375rem 0.625rem;
  border: 1px solid var(--line2);
  border-radius: var(--r-sm);
  background: var(--raise);
  color: var(--ink);
  font: 0.875rem/1.2 var(--sans);
  text-decoration: none;
  cursor: pointer;
}
.catalog-filter-clear:hover { border-color: var(--mut); }
.catalog-filter-clear[hidden] { display: none; }
.catalog-filter-clear:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.service-card {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto 12px max-content;
  align-items: center;
  gap: 0.75rem;
  min-height: 2.5625rem;
  padding: 0.5625rem 0.25rem;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  color: var(--ink);
  transition: background 0.12s ease;
}
@supports (content-visibility: auto) {
  .service-grid > li > .service-card {
    content-visibility: auto;
    contain-intrinsic-size: auto 1.375rem;
  }
}
.service-card:hover {
  background: var(--raise);
  text-decoration: none;
}
.service-card.is-stale {
  box-shadow: inset 2px 0 0 var(--line2);
}
.service-card[hidden] { display: none; }
.service-card:focus-visible {
  background: var(--raise);
  border-color: var(--ink);
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.service-name-col {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  min-width: 0;
}
.service-name {
  font-weight: 500;
  font-size: 0.875rem;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
/* Stale reading: an explicit, muted badge beside the name. Moved off the
   time column (DETECTDOWN) so the right-hand metric columns stay vertically
   aligned — the dimmed cells + this badge carry "stale", and the timestamp
   stays plain so every row's age column is one uniform width. */
.service-stale-badge {
  flex-shrink: 0;
  font-family: var(--mono);
  font-size: 0.625rem;
  line-height: 1.3;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--mut);
  border: 1px solid var(--line2);
  border-radius: var(--r-sm);
  padding: 0.05rem 0.3rem;
}
.service-cells {
  display: flex;
  justify-content: flex-end;
  min-width: 88px;
}
.service-cells.cells-stale .cell {
  filter: saturate(0.42);
  opacity: 0.58;
}
.service-not-monitored {
  color: var(--mut);
  font-size: 0.625rem;
  font-weight: 600;
  text-decoration: none;
  text-transform: uppercase;
}
.service-card-not-monitored {
  grid-column: 3 / -1;
  justify-self: end;
}

@media (max-width: 350px) {
  .service-card {
    gap: 0.375rem;
  }
  .service-card .service-cells {
    min-width: 70px;
  }
  .service-card .cells .cell {
    width: 10px;
    height: 14px;
  }
}

@media (max-width: 680px) {
  .catalog-list-head { align-items: stretch; }
  .catalog-filter {
    grid-template-columns: 1fr;
    flex-basis: 100%;
  }
  .service-grid { grid-template-columns: 1fr; }
}

/* ROADMAP M6 — homepage "currently having problems" strip (landing.html).
   Sits above the service grid and renders only when open_incidents() is
   non-empty; the template omits it entirely at zero, so there's no empty
   container in the steady state (DESIGN.md §3, §7.2). A --surface surface
   with a --down left edge — enough to pull the eye to the headline answer
   without the full-bleed alarm of a banner. Capped at the .now-list width
   so a short list doesn't stretch container-wide. Each affected service
   is a rounded chip (pill + name + honest verdict label) linking to its
   /status/<slug> evidence page; the foot link leads onward to /now. */
.incident-strip {
  margin: 1.5rem 0 0;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--down);
  border-radius: var(--r);
  overflow: hidden;
}
.incident-strip-head {
  margin: 0;
  padding: 0.75rem 0.9375rem 0.55rem;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: -0.01em;
}
.incident-strip-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--line);
}
.incident-strip-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 0.9375rem;
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  font-size: 0.88rem;
  transition: background 0.12s ease;
}
.incident-strip-item:hover,
.incident-strip-item:focus-visible {
  background: var(--raise);
  text-decoration: none;
}
.incident-strip-name { font-weight: 600; }
.incident-strip-verdict { color: var(--mut); }
.incident-strip-all {
  display: inline-block;
  padding: 0.7rem 0.9375rem 0.8rem;
  font-size: 0.88rem;
}

@media (prefers-reduced-motion: reduce) {
  .service-card,
  .incident-strip-item,
  .popular-item {
    transition: none;
  }
}
.popular-services { margin: 1.5rem 0 3rem; }
.popular-services .section-header { text-align: center; margin-top: 1.25rem; }
.popular-services .section-header h2 { font-size: 1.05rem; color: var(--mut); font-weight: 500; letter-spacing: 0.01em; }
.popular-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
}
.popular-item {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.9rem 0.5rem 0.55rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--ink);
  text-decoration: none;
  font-size: 0.95rem;
  transition: border-color 0.12s ease, background 0.12s ease, transform 0.12s ease;
}
.popular-item:hover {
  border-color: var(--ink);
  text-decoration: none;
  background: var(--raise);
  transform: translateY(-1px);
}
.popular-item:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .popular-item:hover,
  .popular-item:focus-visible {
    transform: none;
  }
}
.popular-logo {
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--raise);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  flex-shrink: 0;
  overflow: hidden;
}
.popular-logo img { width: 16px; height: 16px; object-fit: contain; }
.popular-logo .service-initial { font-size: 0.7rem; }
.popular-name { font-weight: 500; letter-spacing: -0.01em; }
