/* Layout knobs the breakpoints at the bottom of this file adjust. The summary
   grid's track sizing lives here (not as an inline style in status.js) so media
   queries can reach it — inline styles would win over them. */
:root {
  --summary-col-min: 7rem;
  --summary-col-gap: 1.25rem;
}

/* Fluid: the page fills the window. The cap only guards ultrawide/5K, where
   spreading the summary columns further apart would hurt row/column association.
   Nothing on this page is prose, so extra width helps every component. */
body { font-family: system-ui, sans-serif; margin: 2rem auto; max-width: 2560px; padding: 0 1.5rem; }

.summary-panel { margin: 1rem 0 .25rem; border: 1px solid #e5e7eb; border-radius: .5rem; padding: .75rem 1rem 1rem; overflow-x: auto; }
.summary-title { font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; color: #666; margin: 0 0 .6rem; }
/* --summary-columns is set by status.js (the service count); the track sizing
   stays here so breakpoints can shrink the minimum on narrow screens. */
.summary-grid {
  display: grid;
  grid-template-columns: auto repeat(var(--summary-columns, 1), minmax(var(--summary-col-min), 1fr));
  gap: .35rem var(--summary-col-gap);
  align-items: baseline;
}
/* align-self overrides the grid's `align-items: baseline` for the header cells
   only. Names now break after the dot, so most take two lines while a dotless
   one ("tef") takes one; under baseline alignment that short name kept its
   FIRST line level with everyone else's and floated a line above its own
   number. Bottom-aligning sits every name just above the column it labels,
   whatever its line count. The numbers below stay on the baseline. */
.summary-service { font-size: .85rem; font-weight: 600; color: inherit; text-decoration: none; text-align: center; overflow-wrap: anywhere; align-self: end; }
.summary-service:hover { text-decoration: underline; }
.summary-row-label { font-size: .65rem; text-transform: uppercase; letter-spacing: .04em; color: #999; white-space: nowrap; }
.summary-num { font-size: 1.35rem; font-weight: 700; text-align: center; font-variant-numeric: tabular-nums; }
.summary-num.ok { color: #15803d; }
.summary-num.bmp_error { color: #b91c1c; }
.summary-num.client_error { color: #b45309; }
.summary-num.zero { color: #d1d5db; font-weight: 400; }
header { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: .5rem 1rem; }
.header-actions { display: flex; align-items: baseline; gap: .75rem; }
.app-version { font-size: .75rem; color: #888; font-variant-numeric: tabular-nums; }

.legend { display: flex; flex-wrap: wrap; gap: .75rem 1.25rem; margin: .5rem 0 1rem; font-size: .8rem; color: #555; }
.chip { display: inline-flex; align-items: center; gap: .35rem; }
.swatch { width: 12px; height: 12px; border-radius: 2px; display: inline-block; }

.service-row { margin: 1.5rem 0; }
.row-header { display: flex; gap: .35rem 1rem; align-items: baseline; margin-bottom: .35rem; flex-wrap: wrap; }
.state { font-size: .9rem; }
.state-ok .state { color: #15803d; }
.state-bmp_error .state { color: #b91c1c; }
.state-client_error .state { color: #b45309; }
.badge { font-size: .75rem; border: 1px solid #999; border-radius: .5rem; padding: 0 .4rem; color: #666; }
.counts { margin-left: auto; font-size: .8rem; color: #666; }
.probe-btn { font-size: .75rem; border: 1px solid #888; border-radius: .5rem; padding: .1rem .6rem; background: #fff; color: #333; cursor: pointer; }
.probe-btn:hover:not(:disabled) { background: #f3f4f6; }
.probe-btn:disabled { cursor: default; opacity: .8; }

.bar-days { display: flex; gap: 8px; align-items: flex-end; overflow-x: auto; padding-bottom: .25rem; }
/* Right-align the history strip so the NEWEST call is always at the right edge,
   and every service row lines its "now" up on the same vertical — otherwise a
   row with one bar (pix.return) starts far left while a full row ends far right,
   and the two cannot be read against each other.

   `margin-left: auto` on the first child, NOT `justify-content: flex-end`:
   flex-end puts the overflow on the LEADING side, which several browsers refuse
   to scroll back to, making the oldest bars unreachable. An auto margin only
   consumes FREE space, so it collapses to 0 once the row overflows and normal
   scrolling still reaches every bar. */
.bar-days > :first-child { margin-left: auto; }
.day-group { display: flex; flex-direction: column; gap: 2px; }
.day-group .segs { display: flex; gap: 1px; height: 28px; }
.day-label { font-size: .65rem; color: #888; text-align: center; white-space: nowrap; }
.gap-block .day-label { color: #aaa; font-style: italic; }

.seg { border-radius: 1px; flex: none; }
.seg.ok, .swatch.ok { background: #22c55e; }
.seg.bmp_error, .swatch.bmp_error { background: #dc2626; }
.seg.client_error, .swatch.client_error { background: #f59e0b; }
.seg.probe, .swatch.probe { background-image: repeating-linear-gradient(45deg, transparent 0 2px, rgba(255,255,255,.65) 2px 4px); }
.seg.gap, .swatch.gap { background: #e5e7eb; border: 1px dashed #9ca3af; width: 14px; }
/* MAKO-764: a failure on a PRE-LAUNCH service. Magenta because it must not read
   as either verdict colour above -- a pre-launch failure is a lead to
   prioritise, not a production outage. Two classes, and declared after the
   single-class rules, so it wins over both .seg.bmp_error and .seg.client_error
   while the outcome class stays on the element for the tooltip. The probe
   stripe must keep layering on top, so this sets background-COLOR only: the
   `background` shorthand would reset the background-image .seg.probe adds
   above it and erase the stripe (caught in the headless render). */
.seg.prelaunch_error, .swatch.prelaunch_error { background-color: hsl(280, 100%, 30%); }

/* MAKO-766: failures grouped by message. Counts reuse the outcome colours from
   .seg above so one hue keeps meaning one thing across the page -- including
   MAKO-764's pre-launch magenta, which applies to the page's own rows. */
.failures { margin: 1.5rem 0; }
.failures-title { font-size: .95rem; margin: 0 0 .5rem; }
.failure-group { border: 1px solid #e5e7eb; border-radius: .4rem; margin-bottom: .4rem; padding: .4rem .6rem; }
.failure-group > summary { cursor: pointer; display: flex; gap: .6rem; align-items: baseline; flex-wrap: wrap; }
.failure-count { font-variant-numeric: tabular-nums; font-weight: 600; min-width: 2.5rem; }
.failure-count.bmp_error { color: #b91c1c; }
.failure-count.client_error { color: #b45309; }
.failure-message { flex: 1; min-width: 12rem; }
.failure-when, .failure-caller, .failure-status { color: #6b7280; font-size: .78rem; white-space: nowrap; }
.failure-event { display: flex; gap: .6rem; align-items: baseline; flex-wrap: wrap; padding: .25rem 0 .25rem 1.2rem; }
.failure-payload { flex-basis: 100%; padding-left: 1.2rem; }
.failure-payload > summary { cursor: pointer; color: #2563eb; font-size: .78rem; }
.failure-truncated { color: #b45309; font-size: .72rem; margin-left: .4rem; }
.payload-copy { font-size: .72rem; margin: .3rem 0; }
/* Wraps rather than scrolls: an EMV payload is one 300-character token, and
   a <pre> that wide pushes a horizontal scrollbar onto the whole PAGE (seen in
   the headless render), which then affects every section above and below it. */
/* MAKO-788 — the human triage label. Its own band, never the outcome colour:
   the bar's colour answers "is it up?" and this answers "what did we conclude?",
   and painting them the same would blur the one distinction the page sells. */
.failure-label-chip { font-size: .68rem; font-weight: 600; letter-spacing: .02em; color: #3730a3; background: #eef2ff; border: 1px solid #c7d2fe; border-radius: .25rem; padding: .05rem .35rem; }
.failure-label { display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline; margin: .35rem 0; padding: .35rem .5rem; background: #f8fafc; border-left: 3px solid #6366f1; border-radius: .2rem; }
.failure-label-name { font-weight: 600; font-size: .75rem; color: #3730a3; }
.failure-label-meaning, .failure-label-author, .failure-label-since, .failure-label-locked { font-size: .72rem; color: #6b7280; }
.failure-label-since { color: #b45309; }
.failure-label-note { flex-basis: 100%; margin: .2rem 0 0; font-size: .75rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.failure-label-form { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin: .35rem 0 .5rem; }
.failure-label-form input[type="text"] { flex: 1; min-width: 12rem; font-size: .75rem; padding: .2rem .35rem; }
.failure-label-form select, .failure-label-form button { font-size: .72rem; padding: .2rem .4rem; }

.payload-block { background: #f9fafb; border: 1px solid #e5e7eb; border-radius: .3rem; padding: .5rem; font-size: .72rem; max-width: 100%; white-space: pre-wrap; overflow-wrap: anywhere; }

.error-banner { color: #b91c1c; border: 1px solid #b91c1c; border-radius: .5rem; padding: .75rem 1rem; margin: 1rem 0; }

/* Breakpoints. The defaults above target >=1400px, where 10 services need
   ~87.5rem (~1400px) and a 1920px window offers ~1872px. Below that the column
   minimum shrinks so the totals keep fitting instead of scrolling. */

@media (max-width: 1400px) {
  :root { --summary-col-min: 6rem; }   /* 10 services -> ~77.5rem (~1240px), fits a 1366px laptop */
}

@media (max-width: 900px) {
  :root { --summary-col-min: 4.5rem; --summary-col-gap: .75rem; }
  body { margin: 1rem auto; padding: 0 .75rem; }
  .summary-num { font-size: 1.1rem; }
  /* Dense table on a phone: horizontal scroll inside the panel is the right
     answer here, so .summary-panel keeps its own overflow-x. */
  .counts { margin-left: 0; flex-basis: 100%; }
}

/* Duration sparkline (MAKO-420). All layout sizing lives here, never inline. */
.sparks { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.spark-line { display: flex; align-items: flex-end; gap: 6px; }
.spark-label { font-size: .7rem; color: #6b7280; min-width: 9rem; text-align: right; }
.spark { display: flex; align-items: flex-end; gap: 1px; height: 28px; flex: 1; overflow-x: auto; }
.spark-bar { flex: none; width: 6px; background: #64748b; border-radius: 1px; }
.spark-bar:hover { background: #0f172a; }
.spark-peak { font-size: .7rem; color: #6b7280; min-width: 4rem; }
.spark-empty { font-size: .75rem; color: #6b7280; }

/* Latency breakdown page (MAKO-429). Every layout dimension lives here; the
   only inline styles are the bar widths, which are data-driven magnitudes. */
.row-service { font-weight: 700; color: inherit; text-decoration: none; }
.row-service:hover { text-decoration: underline; }

.detail-section { margin: 1.5rem 0; }
.detail-header { display: flex; gap: .35rem 1rem; align-items: baseline; flex-wrap: wrap; margin-bottom: .4rem; }
.detail-headline { font-size: .85rem; color: #b45309; }
.detail-peak { font-size: .75rem; color: #6b7280; margin-left: auto; }
.detail-row { display: flex; align-items: center; gap: .6rem; font-size: .8rem; padding: 2px 0; }
.detail-count { min-width: 2.5rem; color: #6b7280; font-variant-numeric: tabular-nums; }
.detail-track { flex: 1; min-width: 8rem; }
.detail-bar { display: flex; height: 14px; border-radius: 2px; overflow: hidden; }
.detail-bmp, .swatch.detail-bmp { background: #64748b; }
.detail-ours, .swatch.detail-ours { background: #f59e0b; }
/* MAKO-509: neutral grey says "this time was spent inside BMP"; it must not
   also be what a BMP FAILURE looks like. Reuses #dc2626 from .seg.bmp_error so
   one hue means one thing across the whole page. Two classes beat the
   single-class rule above on specificity.
   client_error is deliberately NOT coloured here: its verdict colour (#f59e0b)
   is already .detail-ours, so tinting the BMP segment with it would make the
   two-tone bar uniformly amber and erase the split the bar exists to show. */
.detail-bmp.bmp_error, .swatch.detail-bmp.bmp_error { background: #dc2626; }
.detail-total { min-width: 4rem; text-align: right; font-variant-numeric: tabular-nums; }
.detail-label { min-width: 14rem; color: #6b7280; }
.detail-when { color: #9ca3af; white-space: nowrap; }
.detail-untimed, .detail-empty, .detail-note { font-size: .75rem; color: #6b7280; }

@media (max-width: 900px) {
  .detail-label { min-width: 0; flex-basis: 100%; }
  .detail-track { min-width: 5rem; }
}

/* Daily availability strip on the service detail page (MAKO-704). New
   uptime- prefixed classes only: .bar-days/.day-group/.day-label/.seg
   belong to the call-history strip above and mean call OUTCOMES (ok /
   bmp_error / client_error), not incident IMPACT -- reusing them would put
   two different vocabularies on one row. Severity colours are new here too,
   not borrowed from .impact-*/.severity-* (those reuse #9ca3af grey for
   "operational", which on a bar strip would read as just another shade of
   the no-data grey right next to it) or from .seg (whose green/red/amber
   already mean something else on this same page). no-data follows
   .seg.gap's precedent exactly -- #e5e7eb plus a dashed border -- so
   absence reads as absence, never as neutral-good. */
.uptime-block { margin: .5rem 0 1rem; }
/* MAKO-717: centre the strip + caption in the row on desktop (>=900px, i.e.
   above the mobile breakpoint further down). `width: fit-content` + `margin:
   0 auto` centres the strip itself without stretching it to the row's full
   width -- a plain `justify-content: center` on a flex container that also
   needs `overflow-x: auto` would fight the scroll behaviour, so the strip
   stays a fit-content flex box instead. Bars keep their 7px width; nothing
   else in the row (name, state, counts) moves. */
.uptime-strip { display: flex; gap: 2px; align-items: center; overflow-x: auto; padding-bottom: .15rem; width: fit-content; margin: 0 auto; }
.uptime-bar { width: 7px; height: 18px; border-radius: 1px; flex: none; }
.uptime-operational { background: #16a34a; }
.uptime-degraded { background: #d99200; }
.uptime-partial_outage { background: #e06c00; }
.uptime-major_outage { background: #b3261e; }
.uptime-no-data { background: #e5e7eb; border: 1px dashed #9ca3af; }
.uptime-caption { font-size: .75rem; color: #6b7280; margin: .3rem 0 0; text-align: center; }
.uptime-caption.prelaunch { color: #b45309; }

/* "Como ler esta página" (MAKO-576). The page is read by suporte/atendimento,
   not only engineers, so the vocabulary is explained before the data. All
   sizing lives here, never inline. */
.howto { border: 1px solid #e5e7eb; border-radius: .5rem; padding: .75rem 1rem; margin: 1rem 0 .5rem; }
/* Collapsible via native <details> (MAKO-578): the legend is only useful the
   first few visits, and 9 items push the data below the fold on every other
   one. <summary> already carries the keyboard + a11y semantics, so the only
   work here is hiding the default marker and drawing our own chevron. */
.howto-summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: .4rem; }
.howto-summary::-webkit-details-marker { display: none; }
.howto-summary::before { content: "\25B6"; font-size: .6rem; color: #9ca3af; transition: transform .15s ease; }
.howto[open] > .howto-summary::before { transform: rotate(90deg); }
.howto[open] > .howto-summary { margin-bottom: .5rem; }
.howto-summary:focus-visible { outline: 2px solid #2563eb; outline-offset: 3px; border-radius: .25rem; }
.howto-title { font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; color: #666; margin: 0; font-weight: 600; }
.howto-list { margin: 0; padding-left: 1.1rem; font-size: .82rem; color: #374151; }
.howto-list li { margin: .2rem 0; }
.howto-ok { color: #15803d; }
.howto-bmp { color: #b91c1c; }
.howto-client { color: #b45309; }
/* The plain-language line under each service name (MAKO-576). Sits BELOW the
   name rather than beside it: inline it competes with the state text and the
   right-aligned counts, which `margin-left:auto` then shoves around on a
   narrow window. */
.row-brief { font-size: .8rem; color: #6b7280; margin: -.15rem 0 .35rem; }

/* Incidents (MAKO-399) */
.incident-banner {
  margin: 0 0 12px;
  padding: 10px 14px;
  border-left: 4px solid #b3261e;
  background: #fdecea;
  color: #3b1f1d;
}
.incident-banner a { color: #8c1d18; }
.incident-banner-title { margin: 0 0 6px; font-size: 14px; }
.incident-banner-list, .incident-list, .incident-affected { list-style: none; margin: 0; padding: 0; }
/* border-left starts transparent so the impact-* modifiers below (which only
   set border-left-color) actually render a border, not merely change the
   colour of one that never existed. */
.incident-banner-item, .incident-list-item {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 4px 0 4px 8px;
  border-left: 4px solid transparent;
}
.incident-link { margin: 0 0 12px; font-size: 13px; }
.incident-section { margin: 0 0 18px; padding: 10px 14px; }
.incident-form { display: flex; flex-direction: column; gap: 8px; max-width: 640px; }
.incident-services { display: flex; flex-direction: column; gap: 4px; border: 1px solid #444; padding: 8px; }
.incident-service-row { display: flex; justify-content: space-between; gap: 12px; }
.incident-timeline { margin: 0; padding-left: 18px; }
.incident-timeline li { margin-bottom: 10px; }
.incident-status { font-weight: 600; }
.incident-when, .incident-author, .incident-source { opacity: 0.75; font-size: 12px; }
.incident-empty { opacity: 0.7; font-size: 13px; }
/* Neutral on purpose: an incident affecting nothing (an empty `affected` list
   derives `operational`) must not fall back to the red major-outage border --
   that would read as a major outage for a non-event. */
.impact-operational { border-left-color: #9ca3af; }
.impact-degraded { border-left-color: #d99200; }
.impact-partial_outage { border-left-color: #e06c00; }
.impact-major_outage { border-left-color: #b3261e; }
.incident-list-item.resolved { opacity: 0.7; }

/* Per-service severity on the detail page (templates/incident_detail.html).
   Distinct from impact-*: this colours the LIST ITEM text/marker for one
   affected service, not a banner/list-row border. */
.severity-operational { color: #6b7280; }
.severity-degraded { color: #d99200; }
.severity-partial_outage { color: #e06c00; }
.severity-major_outage { color: #b3261e; font-weight: 600; }

/* Login page (MAKO-425/MAKO-717). Was styled entirely inline (`<main style=…>`,
   the sign-in `<a style=…>`, the version `<p style=…>`) -- moved here so
   layout sizing lives in one place and the mobile breakpoint below can reach
   it. Desktop values match what was inline before. */
.login-main { font-family: system-ui, sans-serif; max-width: 24rem; margin: 20vh auto; text-align: center; padding: 0 1.5rem; }
.login-error { color: #b91c1c; }
.login-button { display: inline-block; padding: .75rem 1.5rem; border: 1px solid #ccc; border-radius: .5rem; text-decoration: none; }
.login-version { margin-top: 2rem; font-size: .75rem; color: #888; }

/* Pre-launch marker (MAKO-703). #b45309 is ~5.02:1 on the page's white ground,
   above AA. The incident banner shipped unreadable in MAKO-399 because nobody
   rendered the page -- check this one on screen, not only in the stylesheet. */
.prelaunch, .prelaunch-tag { color: #b45309; }
.prelaunch-tag { font-size: 12px; }
.prelaunch-form { display: flex; align-items: center; gap: .5rem; font-size: .8rem; margin: .5rem 0 1rem; }

/* MAKO-717: phone layout. Measured on a Samsung Galaxy A13 (1080x2408,
   Chrome 152, CSS viewport ~384px) -- WITHOUT the viewport meta this page
   added in the same change, mobile Chrome laid the whole desktop CSS out at
   its default ~980px and shrank it, rendering body text at an effective
   ~8px. The viewport meta fixes the scale; this block fixes the sizes so the
   page is actually usable at that width, not merely legible under a loupe. */
@media (max-width: 600px) {
  body { font-size: 16px; }
  h1 { font-size: 1.4rem; }

  .row-brief, .uptime-caption, .day-label { font-size: 14px; }

  .summary-num { font-size: 20px; }

  .row-service { font-size: 18px; }
  /* .row-header already wraps (flex-wrap: wrap); forcing .state onto its own
     line keeps a long service name from being squeezed against the verdict
     text on a narrow screen. */
  .state { flex-basis: 100%; }

  .day-group .segs { height: 24px; }

  /* Fill the row with no page-level horizontal scroll: 60 bars at flex:1
     share the available width instead of a fixed 7px each (which overflowed
     to ~540px on a ~384px screen). The desktop centring above
     (width: fit-content; margin: 0 auto) is undone here on purpose -- a
     flex:1 child needs a stretchable container, not a fit-content one. */
  .uptime-strip { width: 100%; margin: 0; overflow-x: visible; }
  .uptime-bar { flex: 1 1 0; min-width: 0; width: auto; height: 24px; }

  .probe-btn { min-height: 44px; padding: .5rem 1rem; font-size: 1rem; }

  .legend { font-size: 14px; }

  /* Sparklines: the bar's own height is a data-driven percentage of this
     container (status.js), so a taller container makes every bar taller in
     lockstep -- this does not guarantee any single bar hits 16px (the
     shortest in a series can still be near the 2% floor), but it moves the
     typical bar well clear of the ~8px the unscaled page rendered before.
     Verify the tallest few bars per series look tappable on the device. */
  .spark { height: 32px; }

  /* Login page (MAKO-717). */
  .login-main h1 { font-size: 24px; }
  .login-button { display: block; width: 100%; min-height: 48px; font-size: 1.1rem; line-height: 48px; box-sizing: border-box; }

  /* Latency breakdown page (MAKO-429/MAKO-717). Fix-round: at 384px the
     .detail-label text ("1.2s in BMP") was wrapping mid-phrase into "1.2s
     in" / "BMP" -- the 900px block already put it on its own flex line
     (flex-basis: 100%) but never stopped it SHRINKING below its own text
     width, so the browser wrapped the words instead. `white-space: nowrap`
     fixes that; `.detail-track` (the bar -- decorative, not text) keeps
     being the flexible column that yields width first, with a lower floor
     than the 900px breakpoint's 5rem. `.detail-row` gains `flex-wrap: wrap`
     so that if a row still can't fit everything on one line, the LAST item
     (`.detail-when`, the timestamp -- already `white-space: nowrap` in the
     base rule) is what wraps to its own line, never the label mid-word. */
  .detail-row { flex-wrap: wrap; }
  .detail-track { min-width: 3rem; }
  .detail-label { white-space: nowrap; }
}

/* MAKO-719: centre the caller sparklines under the availability strip on
   desktop (>=900px, mirroring the >=900px threshold MAKO-717 used for the
   strip itself). `.spark { flex: 1 }` stretches the bar strip to fill the
   row, which pins label+bars left and the peak far right -- once MAKO-717
   centred `.uptime-strip` above it, that left/right pinning reads as
   misaligned against the now-centred strip. `justify-content: center` on
   `.spark-line` plus letting `.spark` size to its own bars (flex: 0 1 auto,
   capped at max-width: 100% so a long series still scrolls instead of
   overflowing the row) turns label+bars+peak into one group centred on the
   same axis as the strip. `.spark-label` keeps its own right alignment and
   min-width so labels stay aligned to each other across rows. Below 900px
   this block does not apply; the phone block above (max-width: 600px)
   already sets `.spark { height: 32px }` and is unaffected here. */
@media (min-width: 900px) {
  .spark-line { justify-content: center; }
  .spark { flex: 0 1 auto; max-width: 100%; }
}
