/* MyDCHub design system.
   Tokens transcribed from the handoff. Light is the authored base; dark is an
   authored palette, not an inversion, and severity hues shift lightness only. */

:root {
  --accent:#0B5CD5; --accent-hover:#084299; --accent-wash:#E7EFFC; --accent-surface:#F2F6FD; --accent-soft:#9DC0F0;
  --ink-deep:#0A1F3C; --ink-deeper:#071730; --ink-panel:#12294A; --ink-panel-line:#1E3A63;
  --text:#0F1B2D; --text-body:#33455F; --text-muted:#445674; --text-quiet:#5B6B82; --text-faint:#97A5BB;
  --surface:#FFFFFF; --surface-2:#F7F9FD; --surface-3:#F4F6FA; --surface-code:#FBFCFE;
  --border:#E4E9F2; --border-soft:#EEF2F8; --border-card:#E0E7F2; --border-input:#C6D2E6; --border-strong:#DCE4F0;

  --crit:#B3261E; --crit-tint:#FDF2F1; --crit-line:#E9BDB8; --crit-text:#8C1D18;
  --warn:#B45309; --warn-tint:#FDF7EE; --warn-line:#F2D5AC; --warn-text:#7A3C00;
  --pass:#17795E; --pass-tint:#F2FAF6; --pass-line:#B8DED1; --pass-text:#0C5E49;
  --info:#1E5AA8; --info-tint:#F4F8FD; --info-line:#C3D6EE; --info-text:#123F6E;

  --sans:"IBM Plex Sans",system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --max:1180px;
}

:root[data-theme="dark"] {
  --accent:#3D86F5; --accent-hover:#5C9BF7; --accent-wash:#16253C; --accent-surface:#101C2F; --accent-soft:#2C5A96;
  --ink-deep:#071018; --ink-deeper:#050C14; --ink-panel:#16253C; --ink-panel-line:#2F353B;
  --text:#E6ECF5; --text-body:#B6C5DD; --text-muted:#A9BBD6; --text-quiet:#8FA4C2; --text-faint:#6C7F9B;
  --surface:#101C2F; --surface-2:#16253C; --surface-3:#16253C; --surface-code:#0B1524;
  --border:#1A2942; --border-soft:#1A2942; --border-card:#1A2942; --border-input:#2F353B; --border-strong:#2F353B;

  --crit:#E4756C; --crit-tint:#241416; --crit-line:#4A2422; --crit-text:#E4756C;
  --warn:#E0A355; --warn-tint:#241D12; --warn-line:#4A3A1F; --warn-text:#E0A355;
  --pass:#47B795; --pass-tint:#0F2620; --pass-line:#1E4A3C; --pass-text:#47B795;
  --info:#7FB0FA; --info-tint:#111E33; --info-line:#223A5C; --info-text:#7FB0FA;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;font-family:var(--sans);font-size:16px;line-height:1.7;
  color:var(--text);background:var(--surface);text-wrap:pretty;
}
h1,h2,h3{text-wrap:pretty;margin:0}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
code,pre,.mono{font-family:var(--mono)}

/* Focus is never removed: a meaningful share of users are keyboard-driven. */
:focus-visible{outline:3px solid rgba(11,92,213,.35);outline-offset:2px;border-radius:4px}

.wrap{max-width:var(--max);margin:0 auto;padding:0 34px}
.eyebrow{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.11em;text-transform:uppercase;color:var(--text-quiet)}

/* ---------- utility bar ---------- */
.util{background:var(--ink-deep);color:#C9D6EA;font-size:12.5px;min-height:38px;display:flex;align-items:center}
.util .wrap{display:flex;gap:16px;align-items:center;justify-content:space-between;flex-wrap:wrap;padding-block:7px}
.util a{color:#C9D6EA}
.util-r{display:flex;gap:16px;align-items:center}
.dot-ok{width:7px;height:7px;border-radius:999px;background:#47B795;display:inline-block;margin-right:6px}

/* ---------- header ---------- */
.hdr{background:var(--surface);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:50}
.hdr .wrap{display:flex;align-items:center;gap:20px;min-height:72px;padding-inline:26px}
.brand{display:flex;align-items:center;gap:11px;color:var(--text)}
.brand:hover{text-decoration:none}
.brand b{font-weight:700;font-size:19px;letter-spacing:-.03em}
.nav{display:flex;gap:20px;margin-left:8px;flex-wrap:wrap}
.nav a{font-size:14.5px;font-weight:500;color:var(--text-muted);white-space:nowrap;padding:6px 0;border-bottom:2px solid transparent}
.nav a:hover{color:var(--accent);text-decoration:none}
.nav a[aria-current="page"]{color:var(--accent);border-bottom-color:var(--accent)}
.hdr-r{margin-left:auto;display:flex;gap:10px;align-items:center}

/* ---------- buttons and inputs ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:var(--sans);
  font-size:15px;font-weight:600;border-radius:9px;padding:12px 22px;border:1.5px solid transparent;
  cursor:pointer;transition:background 140ms,border-color 140ms,box-shadow 140ms;min-height:44px}
.btn-primary{background:var(--accent);color:#fff}
.btn-primary:hover{background:var(--accent-hover);text-decoration:none}
.btn-secondary{background:var(--surface);color:#22334D;border-color:var(--border-input);font-weight:500}
.btn-secondary:hover{background:var(--surface-3);text-decoration:none}
:root[data-theme="dark"] .btn-secondary{color:var(--text)}
.btn-quiet{background:transparent;color:var(--accent);font-weight:500}
.btn-quiet:hover{background:var(--accent-surface);text-decoration:none}

.field{display:flex;gap:10px;flex-wrap:wrap}
.field input{flex:1;min-width:min(100%,260px);font-family:var(--mono);font-size:17px;
  padding:14px 18px;border:1.5px solid var(--border-input);border-radius:10px;
  background:var(--surface);color:var(--text);min-height:44px}
.field input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(11,92,213,.18)}

/* ---------- hero ---------- */
.hero{background:linear-gradient(180deg,var(--accent-surface) 0%,var(--surface) 100%);
  border-bottom:1px solid var(--border)}
.hero-home{padding:62px 0 56px;text-align:center}
.hero-home .inner{max-width:660px;margin:0 auto}
.pill{display:inline-block;background:var(--accent-wash);color:var(--accent);
  font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;padding:6px 14px;border-radius:999px}
h1.hero-h1{font-size:46px;font-weight:700;letter-spacing:-.03em;line-height:1.1;margin:18px auto 12px;max-width:22ch}
.subhead{font-size:18px;color:var(--text-muted);max-width:60ch;margin:0 auto 26px}
.reassure{display:flex;gap:20px;justify-content:center;flex-wrap:wrap;margin-top:16px;
  font-size:13.5px;color:var(--text-quiet)}
.reassure span::before{content:"✓";color:var(--pass);font-weight:700;margin-right:6px}

/* ---------- cards / tool grid ---------- */
.band{padding:58px 0 62px}
.band-2{background:var(--surface-2);border-block:1px solid var(--border)}
h2.band-h2{font-size:30px;font-weight:700;letter-spacing:-.02em;text-align:center;margin-bottom:8px}
.band .lede{text-align:center;color:var(--text-muted);max-width:60ch;margin:0 auto 34px}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.card{border:1px solid var(--border-card);border-radius:12px;padding:22px;background:var(--surface);
  transition:border-color 140ms,box-shadow 140ms;display:block;color:inherit}
.card:hover{border-color:var(--accent);box-shadow:0 8px 22px rgba(15,27,45,.08);text-decoration:none}
.card .tile{width:38px;height:38px;border-radius:9px;background:var(--accent-wash);color:var(--accent);
  display:flex;align-items:center;justify-content:center;font-family:var(--mono);font-size:11.5px;font-weight:500;margin-bottom:14px}
.card h3{font-size:17px;font-weight:600;margin-bottom:6px}
.card p{font-size:14px;line-height:1.6;color:var(--text-muted);margin:0}

/* ---------- dark credibility band ---------- */
.credit{background:var(--ink-deep);color:#BCCBE2;padding:48px 0 52px}
.credit .cols{display:grid;grid-template-columns:1fr 1.1fr;gap:44px;align-items:start}
.credit h2{color:#fff;font-size:30px;font-weight:700;letter-spacing:-.02em;margin:10px 0 14px}
.credit .eyebrow{color:#7FB0FA}
.stats{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.stat{background:var(--ink-panel);border:1px solid var(--ink-panel-line);border-radius:11px;padding:18px}
.stat b{display:block;color:#fff;font-size:22px;font-weight:700;letter-spacing:-.02em}
.stat span{font-size:13px;color:#9DB2D0}

/* ---------- report ---------- */
.verdict{background:linear-gradient(180deg,var(--accent-surface) 0%,var(--surface) 100%);
  border-bottom:1px solid var(--border);padding:30px 0}
.verdict .cols{display:grid;grid-template-columns:1fr 232px;gap:40px;align-items:start}
h1.domain{font-size:38px;font-weight:700;letter-spacing:-.03em;line-height:1.12;word-break:break-word;margin:10px 0 12px}
.verdict-line{font-size:20px;line-height:1.5;color:var(--text-body);margin-bottom:16px}
.counts{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:18px}
.count{display:inline-flex;align-items:center;gap:7px;border-radius:999px;padding:6px 12px;
  font-size:13.5px;background:var(--surface);border:1px solid var(--border-card)}
.count i{width:16px;height:16px;border-radius:999px;display:inline-flex;align-items:center;
  justify-content:center;font-style:normal;font-size:10px;color:#fff;font-weight:700}
.count.zero{background:var(--surface-3);color:var(--text-faint)}
.count.zero i{background:var(--border-input)}
.c-critical i{background:var(--crit)} .c-warning i{background:var(--warn)}
.c-pass i{background:var(--pass)} .c-info i{background:var(--info)}

.permalink{display:flex;align-items:stretch;max-width:600px;border:1px solid var(--border-strong);
  border-radius:10px;overflow:hidden;background:var(--surface)}
.permalink code{flex:1;padding:11px 14px;font-size:13px;color:var(--text-muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.caption{font-size:13px;color:var(--text-quiet);margin-top:10px;max-width:66ch}

.score{background:var(--surface);border:1px solid var(--border-strong);border-radius:12px;padding:18px;
  box-shadow:0 6px 18px rgba(15,27,45,.06)}
.score .grade{font-size:40px;font-weight:700;line-height:1;margin:8px 0 4px}
.score .out{font-family:var(--mono);font-size:17px}
.score .out span{color:var(--text-faint)}
.bar{height:6px;border-radius:999px;background:#EAEEF6;margin:12px 0 10px;overflow:hidden}
:root[data-theme="dark"] .bar{background:#1A2942}
.bar i{display:block;height:100%;border-radius:999px}
.score p{font-size:12.5px;color:var(--text-quiet);line-height:1.5;margin:0 0 14px}
.score .btn{width:100%;margin-bottom:8px;font-size:14px;padding:10px 14px}

.report-body{display:grid;grid-template-columns:228px 1fr;gap:36px;padding:34px 0 44px}
.rail{position:sticky;top:92px;align-self:start}
.rail ol{list-style:none;margin:10px 0 0;padding:0;border:1px solid var(--border-card);border-radius:10px;overflow:hidden}
.rail li a{display:flex;justify-content:space-between;gap:10px;padding:10px 14px;font-size:14px;
  color:var(--text-muted);border-bottom:1px solid var(--border-soft);border-left:3px solid transparent}
.rail li:last-child a{border-bottom:0}
.rail li a:hover{background:var(--accent-surface);color:var(--accent);text-decoration:none}
.rail .note{margin-top:14px;background:var(--surface-2);border:1px solid var(--border-card);
  border-radius:10px;padding:14px;font-size:13px;color:var(--text-quiet);line-height:1.55}

.group{margin-bottom:34px}
.group-head{display:flex;justify-content:space-between;align-items:baseline;gap:16px;
  padding-bottom:10px;border-bottom:1px solid var(--border);margin-bottom:18px}
.group-head h2{font-size:20px;font-weight:700;letter-spacing:-.015em}

/* ---------- the finding card, the core component ---------- */
.finding{border-radius:12px;border:1px solid var(--border-card);background:var(--surface);
  margin-bottom:16px;overflow:hidden}
.finding-head{display:flex;align-items:center;gap:12px;padding:12px 20px;border-bottom:1px solid;flex-wrap:wrap}
.chip{display:inline-flex;align-items:center;gap:6px;border-radius:6px;padding:4px 10px;color:#fff;
  font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.09em;text-transform:uppercase}
.chip b{font-weight:700}
.rec{font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase}
.restate{margin-left:auto;font-size:13px}
.finding-body{padding:20px;display:flex;flex-direction:column;gap:14px}
.finding-body h3{font-size:22px;font-weight:700;letter-spacing:-.02em;line-height:1.3}
.finding-body .explain{font-size:16px;line-height:1.7;color:var(--text-body);max-width:72ch;margin:0}

.f-critical{border-color:var(--crit-line)} .f-critical .finding-head{background:var(--crit-tint);border-bottom-color:var(--crit-line);color:var(--crit-text)}
.f-critical .chip{background:var(--crit)}
.f-warning{border-color:var(--warn-line)} .f-warning .finding-head{background:var(--warn-tint);border-bottom-color:var(--warn-line);color:var(--warn-text)}
.f-warning .chip{background:var(--warn)}
.f-pass{border-color:var(--pass-line)} .f-pass .finding-head{background:var(--pass-tint);border-bottom-color:var(--pass-line);color:var(--pass-text)}
.f-pass .chip{background:var(--pass)}
.f-info{border-color:var(--info-line)} .f-info .finding-head{background:var(--info-tint);border-bottom-color:var(--info-line);color:var(--info-text)}
.f-info .chip{background:var(--info)}
:root[data-theme="dark"] .chip{color:#071018}

.fix{border:1px solid var(--border-strong);border-radius:10px;background:var(--surface-2);
  padding:16px 18px;max-width:72ch;display:flex;gap:16px;align-items:flex-start}
.fix .lbl{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.09em;color:var(--accent);flex:none;padding-top:2px}
.fix p{margin:0;font-size:15.5px;line-height:1.65;color:var(--text-body)}

/* ---------- monospace record block ---------- */
.record{display:flex;align-items:stretch;border:1px solid var(--border);border-radius:9px;
  background:var(--surface-code);overflow:hidden}
/*
   A DNS record is the thing people came to read, so it wraps rather than
   becoming a box you drag sideways. Scrolling hid the end of the record
   behind the COPY button, and the tail of an SPF record is exactly where
   the interesting part lives -- ~all against -all is the last token.

   pre-wrap keeps the line breaks in a multi-line MX block. anywhere rather
   than break-word because a DKIM key has no spaces to break at. min-width:0
   matters as much: the pre is a flex child with flex:1, so its automatic
   minimum is its content width, and without it the COPY button is pushed
   off the edge instead of the text wrapping.
*/
.record pre{margin:0;flex:1;min-width:0;padding:11px 14px;font-size:13px;line-height:1.55;
  white-space:pre-wrap;overflow-wrap:anywhere;color:var(--text-body)}
.copy{flex:none;align-self:flex-start;background:var(--surface-3);border:0;border-left:1px solid var(--border);
  color:var(--accent);font-family:var(--mono);font-size:11px;letter-spacing:.07em;
  padding:0 14px;cursor:pointer;min-width:64px;min-height:44px}
.copy:hover{background:var(--accent-wash)}

/* ---------- lookup budget ---------- */
.budget{border:1px solid var(--border);border-radius:10px;overflow:hidden;max-width:72ch}
.budget-h{display:flex;justify-content:space-between;padding:9px 14px;background:var(--surface-2);
  border-bottom:1px solid var(--border);font-family:var(--mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--text-quiet)}
.budget-r{display:grid;grid-template-columns:1fr 70px;gap:10px;padding:8px 14px;
  font-family:var(--mono);font-size:12.5px;border-bottom:1px solid var(--border-soft);color:var(--text-body)}
.budget-r:last-child{border-bottom:0}
.budget-r.bad{color:var(--crit);font-weight:500}

/* ---------- raw records table ---------- */
.raw{border:1px solid var(--border);border-radius:12px;overflow:hidden}
.raw .h{display:grid;grid-template-columns:96px 1fr auto;gap:12px;padding:10px 14px;
  background:var(--surface-2);border-bottom:1px solid var(--border);
  font-family:var(--mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--text-quiet)}
.raw .r{display:grid;grid-template-columns:96px 1fr auto;gap:12px;align-items:start;
  padding:9px 14px;border-bottom:1px solid var(--border-soft)}
.raw .r:last-child{border-bottom:0}
.raw .t{font-family:var(--mono);font-size:12.5px;color:var(--accent)}
/*
   No ellipsis. This table is captioned AS PUBLISHED, so a clipped value is
   not what was published: somebody comparing our output against their zone
   file would have been reading a record we cut off without saying so. COPY
   always put the whole thing on the clipboard, which made the truncation
   worse rather than safer -- the two disagreed and only one was visible.
*/
.raw .v{font-family:var(--mono);font-size:13px;color:var(--text-body);white-space:pre-wrap;overflow-wrap:anywhere}
.raw .copy{border:1px solid var(--border-input);border-radius:6px;min-height:32px;padding:0 10px;background:var(--surface)}

/* ---------- all clear ---------- */
.allclear{border:1px solid var(--pass-line);background:var(--pass-tint);color:var(--pass-text);
  border-radius:12px;padding:16px 20px;margin-bottom:18px}
.allclear b{display:block;font-size:17px;margin-bottom:4px}
.allclear span{font-size:14px}

/* ---------- footer ---------- */
.foot{background:var(--ink-deeper);color:#B9C8DE;padding:48px 0 26px;font-size:14px}
.foot .cols{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:36px}
.foot h4{font-family:var(--mono);font-size:11px;letter-spacing:.11em;text-transform:uppercase;
  color:#8FA4C2;margin:0 0 12px;font-weight:500}
.foot a{color:#B9C8DE;display:block;padding:4px 0}
/* The footer's column links are display:block so they stack. The legal line at
   the bottom is a sentence, not a column: without this its links became blocks
   too, stacking one per line and leaving the separator stranded between them. */
/*
   No max-width here.
   
   It used to be 46ch, which wrapped the attribution onto two lines at every
   width including a desktop one with room to spare. Google's terms ask for the
   attribution to be shown; breaking it across lines for no reason made it read
   like an afterthought. It still wraps on a phone, because the alternative at
   360px is a line that runs off the side.
*/
.foot .bar2 .attrib{display:block;font-size:11.5px;color:#7E93B4}
.foot .bar2 .attrib a{color:#7E93B4}

.foot .bar2 a{display:inline;padding:0;text-decoration:underline;text-underline-offset:2px;
  text-decoration-color:#3C577F}
.foot .bar2 a:hover{color:#fff;text-decoration-color:#fff}
/*
   Two rows.
   
   The first pins the copyright to the left margin and the legal links to the
   right, which is the pairing people expect at the bottom of a page. The
   second carries Google's attribution under them, against the right margin,
   on one line.
   
   On a phone the first row wraps to two lines rather than squeezing: at 360px
   there is not room for both ends of it, and a squeezed line reads worse than
   a wrapped one.
*/
.foot .bar2{border-top:1px solid #14284A;margin-top:34px;padding-top:18px;
  display:flex;flex-direction:column;align-items:stretch;gap:8px;
  font-size:13px;color:#8FA4C2}
.foot .bar2-row{display:flex;justify-content:space-between;align-items:baseline;
  gap:16px;flex-wrap:wrap}
.foot .bar2 .attrib{text-align:right}

/*
   Room under the small print for the chat bubble.
   
   The bubble is position:fixed in the bottom-right corner, so at the very
   bottom of a page it sits on top of whatever is there -- which on a phone was
   the Privacy link. Padding the footer rather than moving the bubble, because
   the bubble's corner is where people look for it and the footer has room to
   give.
*/
@media (max-width:640px){ .foot .bar2{padding-bottom:64px} }

/* ---------- faq ---------- */
.faq{max-width:860px;margin:0 auto}
.faq details{border:1px solid var(--border-card);border-radius:11px;padding:18px 20px;margin-bottom:10px;background:var(--surface)}
.faq summary{font-size:16.5px;font-weight:600;cursor:pointer;list-style:none;display:flex;justify-content:space-between;gap:16px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";color:var(--accent);font-weight:700;font-size:20px;line-height:1}
.faq details[open] summary::after{content:"–"}
.faq p{font-size:15px;line-height:1.7;color:var(--text-muted);max-width:74ch;margin:12px 0 0}

/* ---------- notices ---------- */
.err{border:1px solid var(--crit-line);background:var(--crit-tint);color:var(--crit-text);
  border-radius:10px;padding:12px 16px;font-size:14px;margin-top:14px}
.err::before{content:"✕";font-weight:700;margin-right:8px}

/* ---------- responsive ----------

   Three things caused every mobile problem on this site, and they are worth
   naming because none of them is a breakpoint being missing:

   1. Inline grid-template-columns in five templates. An inline style beats a
      stylesheet rule at any breakpoint, so those layouts could not respond at
      all. They are classes now, defined just below.

   2. Grid and flex children default to min-width:auto, which means one long
      unbroken string -- a DNS record, a base64 DKIM key -- makes its track as
      wide as the string. That is why the report page was 3342px wide on a
      390px phone: not a broken breakpoint, a single SPF record.

   3. The nav was display:none below 1000px with nothing put in its place, so
      every phone and most tablets got a header containing no navigation.
*/

/* Layout defaults the media queries below override. */
.plans{display:grid;grid-template-columns:repeat(5,1fr);gap:14px;align-items:start}
.report-body.rail-right{grid-template-columns:1fr 288px}
.raw .probe-row{grid-template-columns:200px 1fr auto}
.raw .domain-row{grid-template-columns:1fr 200px 170px auto;align-items:center}

/* (2) above. Without this, overflow-x:auto on a child cannot clip, because the
   track has already grown to fit it. */
.report-body>*,.verdict .cols>*,.credit .cols>*,.raw .r>*,.raw .h>*{min-width:0}

/* Long mono values wrap instead of pushing the page sideways. anywhere rather
   than break-word because a DKIM key has no spaces to break at. */
.raw .v,.record pre,.permalink code,.copy code{overflow-wrap:anywhere}

/* Nothing may be wider than the screen, whatever it is. */
img,svg,video,table,pre{max-width:100%}

@media (max-width:1180px){
  .plans{grid-template-columns:repeat(3,1fr)}
}

/*
   The mobile navigation drawer.

   The nav used to become a horizontally scrolling strip below 1000px. Measured
   at 386px it was 471px of content in a 354px box, so it was cut off mid-word
   -- "Site preview" and "Pricing" were simply off the right edge, reachable
   only by a sideways scrub most people never think to try on a header.

   WHY THE HIDING IS GATED ON .js
   ------------------------------
   The drawer needs script to open. If the nav were hidden by default in CSS,
   a script that failed to load or threw would leave a phone with no navigation
   at all -- worse than the strip it replaced. The script adds `js` to <html>
   as its first act, so the rules that hide the nav only apply once something
   is definitely there to open it again.
*/
/*
   No margin-left:auto here. .hdr-r already has one, and whichever flex item
   carries it first consumes the free space -- so the toggle took it and parked
   itself midway between the brand and the button, which is not where anybody
   has ever looked for a menu. The right-hand group keeps the auto margin and
   the toggle sits at the end of it.
*/
/*
   Google's reCAPTCHA badge is position:fixed and sits over the bottom-right of
   every page that loads it. On a phone that is on top of real content -- it was
   covering the slowest-files list on the speed report.

   Hiding it is allowed only if the attribution it carries appears somewhere the
   visitor can see, which is why the footer now says it in words. Removing the
   badge without that would be taking Google's service on terms we had not met.
*/
.grecaptcha-badge{visibility:hidden}

/*
   Drawer-only entries. Hidden by default because at desktop width the header
   carries these two as buttons; shown only where the header does not.
*/
.nav-only{display:none}

.navtoggle{display:none;align-items:center;justify-content:center;width:42px;height:42px;
  border:1px solid var(--border-card);border-radius:9px;background:#fff;
  color:var(--text);cursor:pointer;flex:none}
.navtoggle:hover{border-color:var(--accent);color:var(--accent)}

@media (max-width:1000px){
  .hdr .wrap{flex-wrap:wrap;min-height:0;padding-block:12px;gap:12px}
  .hdr-r{gap:8px;order:2;margin-left:auto}
  .navtoggle{display:flex;order:3}

  .nav{display:flex;order:4;width:100%;margin-left:0;
    flex-direction:column;align-items:stretch;gap:0}
  .nav a{padding:12px 2px;min-height:44px;display:flex;align-items:center;
    border-bottom:1px solid var(--border-card)}
  .nav a[aria-current="page"]{border-bottom-color:var(--accent)}

  /* Each tool group is a plain disclosure inside the drawer. */
  .nav .menu{width:100%;border-bottom:1px solid var(--border-card)}
  .nav .menu>summary{padding:12px 2px;min-height:44px;display:flex;align-items:center;
    justify-content:space-between}
  .nav .menu-panel{position:static;width:100%;box-shadow:none;border:0;
    padding:2px 0 10px;background:transparent}
  .nav .menu-panel a{border-bottom:0;padding:9px 10px}

  /* Only hidden once the script that opens it is running. */
  html.js .nav{display:none}
  html.js .nav.open{display:flex}
}

@media (max-width:900px){
  .wrap{padding:0 18px}
  .hdr .wrap{padding-inline:18px}
  .verdict .cols,.report-body,.report-body.rail-right,.credit .cols{grid-template-columns:1fr;gap:22px}
  .rail{position:static}
  .grid3{grid-template-columns:1fr}
  .foot .cols{grid-template-columns:1fr 1fr}
  h1.hero-h1{font-size:32px}
  h1.domain{font-size:27px}
  .verdict-line{font-size:17px}
  .finding-body h3{font-size:19px}
  .finding-body .explain{font-size:15px;line-height:1.65}
  .stats{grid-template-columns:1fr}
  .plans{grid-template-columns:repeat(2,1fr)}

  /* The rail is a table of contents above the content, not a sidebar. */
  .rail ol{margin-top:8px}
  .rail .note{display:none}
}

@media (max-width:720px){
  /*
   * The strapline goes.
   *
   * On a phone it wrapped to two lines and pushed the status and Docs on
   * to a third, turning the top of every page into a dark three-line
   * block of marketing before any content. It says nothing the footer
   * does not, and the bar is tidy as a single line without it.
   */
  .util-l{display:none}
  .util{min-height:0;font-size:12px}

  /*
   * No vertical padding on the bar itself.
   *
   * The Docs link inside it carries the 44px touch target set above, so
   * padding here is added to 44 rather than absorbed by it -- which is how
   * a one-line bar ended up 58px tall. The link supplies the height; the
   * bar just holds it.
   */
  .util .wrap{justify-content:center;flex-wrap:nowrap;padding-block:0;gap:14px}

  /*
   * Stacked rows. A four-column row cannot be read at this width, and the
   * columns carry no meaning once the header row is gone, so each cell gets
   * its own line and the header row is dropped rather than squashed.
   */
  .raw .h{display:none}
  .raw .r,.raw .probe-row,.raw .domain-row{grid-template-columns:1fr;gap:6px;padding:14px}
  .raw .r .t{font-size:13.5px}
  .raw .domain-row>span:last-child{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}
  .budget-r{grid-template-columns:1fr auto}
}

@media (max-width:640px){
  .plans{grid-template-columns:1fr}
  .wrap{padding:0 16px}
  .hdr .wrap{padding-inline:16px}

  /*
   * No buttons in the header on a phone. Brand, and a menu.
   *
   * Hiding only the quiet one left "Check a domain" sitting at the top of every
   * page, where it is both the largest thing in the header and, on the home
   * page, a link to the page you are already on. Both actions moved into the
   * drawer, which is where somebody on a phone looks for a destination.
   */
  .hdr-r{display:none}
  .nav .nav-only{display:flex}

  /*
   * The auto margin has to move with them.
   *
   * .hdr-r carried it, and a flex item that is display:none carries nothing --
   * so the toggle would fall in beside the brand, which is precisely the
   * "menu button in the middle of the header" this drawer was built to fix.
   */
  .navtoggle{margin-left:auto}

  h1.hero-h1{font-size:27px}
  h1.domain{font-size:23px}
  .score .grade{font-size:34px}

  /* Forms: full width, and never smaller than 16px or iOS zooms on focus. */
  .field{flex-direction:column;align-items:stretch}
  .field input,.field .btn{width:100%}
  .field input{font-size:16px;min-width:0}
  .field .btn{justify-content:center}

  .counts{gap:6px}
  .util .wrap{gap:8px}
  .util-r{gap:12px}
}

@media (max-width:560px){
  .foot .cols{grid-template-columns:1fr}
}

/*
   Touch targets.

   Keyed on width rather than on (hover:none), which was the first thing tried
   and is wrong twice over: it never matches a desktop browser being resized,
   so the rule cannot be verified without a physical phone, and a 21px link is
   hard to hit on a narrow screen whether or not the device reports a mouse.
   Width is the thing that actually predicts a thumb.
*/
@media (max-width:900px){
  .util a,.nav a,.rail li a,.foot a,.faq summary,.tools-list a{
    min-height:44px;display:flex;align-items:center}

  /* Links that sit inside a line of text keep their flow, so they get the
     hit area as padding instead of as a height. A domain name in a table
     row was 18px tall, which is a coin-flip to tap. */
  .raw a,.subhead a{display:inline-flex;align-items:center;min-height:44px}
  .faq summary{padding-block:11px}
  .btn{min-height:44px}
  .brand{min-height:44px}

  /* .raw .copy sets min-height:32px explicitly, so it needs naming here
     rather than relying on the .btn rule above. */
  .raw .copy,.copy{min-height:44px}

  /*
     A DNS record is the thing people came to read, so on a phone it wraps
     instead of becoming a box you drag sideways. An SPF record has spaces
     to break at; a DKIM key does not, hence anywhere rather than
     break-word.

     min-width:0 matters as much as the wrapping: the pre is a flex child
     with flex:1, so its automatic minimum is its content width and it
     would otherwise push the COPY button off the screen.
  */
  .record{align-items:flex-start}
  .record .copy{align-self:stretch}
}

/* Bengali needs its own leading; it is not a Latin face at a different size. */
:lang(bn){font-family:"Noto Sans Bengali",var(--sans);font-size:15.5px;line-height:2.0}

/* ---------- speed test: the three locations side by side ---------- */

/*
   Four columns, and the location gets the flexible one because "Dhaka ·
   Colocation" is long and a timing is never more than a few characters.
*/
.raw .vantage-row{grid-template-columns:1fr 88px 88px 168px;gap:12px;align-items:baseline}
.raw .vantage-row .v{font-size:12.5px}

/* A location that produced nothing says so across the whole row rather than
   leaving three cells blank, which would read as three zeroes. */
.raw .vantage-row .miss{grid-column:2 / -1;color:var(--text-quiet)}

@media (max-width:720px){
  /*
     Stacked, with the location as its own line. The header row goes: without
     columns to head, it is three words floating above unrelated numbers.
  */
  .raw .vantage-row{grid-template-columns:1fr;gap:4px;padding:14px}
  .raw .h.vantage-row{display:none}
  .raw .vantage-row .miss{grid-column:1}
}

/* ---------- speed test: where the bytes went ---------- */

/*
   A label beside a sentence.

   Distinct from .split-row, which is a label plus three narrow numeric columns
   and is right for the speed and certificate tables. Used with only two
   children it drops the value into the 64px column, where a sentence overflows
   and is drawn straight over the label. That is what happened on /privacy.
*/
.raw .pair{grid-template-columns:minmax(130px,26%) 1fr;gap:14px;align-items:start}
.raw .pair .t{white-space:normal}
.raw .pair .v{font-family:var(--sans);font-size:14px;line-height:1.6;white-space:normal;color:var(--text-body)}

.raw .split-row{grid-template-columns:1fr 64px 84px 64px;gap:12px;align-items:baseline}
.raw .split-row .v{font-size:12.5px;text-align:right}
.raw .h.split-row span:not(:first-child){text-align:right}

/*
   Per-file timings. The bar is a length, not a position: files are fetched
   several at a time, so a start offset would imply an order that does not
   exist. Only the width carries meaning.
*/
.raw .bar-row{grid-template-columns:minmax(0,1fr) 200px 74px;gap:12px;align-items:center}
.bar-name{font-family:var(--mono);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bar-track{display:block;height:12px;background:var(--surface-3);border-radius:3px;overflow:hidden}
/* Transfer: the lighter half of the bar. Kept distinct from the wait by
   colour rather than opacity alone, because when the wait is the whole
   duration -- which is most files on a fast server -- an opacity difference
   with nothing beside it just reads as one solid block. */
.bar{display:block;height:100%;background:var(--accent-soft, #9dc0f0);border-radius:3px}

/* The wait before the first byte, drawn solid inside the total. */
.bar-wait{display:block;height:100%;background:var(--accent);border-radius:3px 0 0 3px}
.bar-time{font-size:12.5px;text-align:right;white-space:nowrap}

@media (max-width:720px){
  /* One column: 130px of label beside a sentence is not a layout on a phone. */
  .raw .pair{grid-template-columns:1fr;gap:2px}
  .raw .pair .t{font-size:12px;letter-spacing:.04em}

  .raw .split-row{grid-template-columns:1fr auto;gap:4px 12px}
  .raw .split-row .v{text-align:left}
  .raw .h.split-row{display:none}

  /* The bar is the least useful part on a narrow screen; the name and the
     number are the point, so the track goes rather than being squeezed. */
  .raw .bar-row{grid-template-columns:minmax(0,1fr) auto}
  .raw .bar-row .bar-track{display:none}
  .bar-name{white-space:normal;overflow-wrap:anywhere}
}

/* ---------- SSL: the chain, as the server sent it ---------- */

.cert{border:1px solid var(--border);border-radius:10px;margin-bottom:10px;overflow:hidden}
.cert-h{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 14px;
  background:var(--surface-2);border-bottom:1px solid var(--border)}
.cert-h b{font-size:14.5px;font-weight:600;overflow-wrap:anywhere}

/*
   Label and value, not a table: the values are wildly uneven -- a SAN list
   runs to several lines while a key type is three words -- and a column grid
   would leave most of the row empty to accommodate the longest one.
*/
.cert-b{display:grid;grid-template-columns:120px minmax(0,1fr);gap:5px 14px;padding:12px 14px}
.cert-b .k{font-family:var(--mono);font-size:11px;letter-spacing:.07em;text-transform:uppercase;
  color:var(--text-quiet);padding-top:2px}
.cert-b .v{font-size:13.5px;color:var(--text-body);overflow-wrap:anywhere}
.cert-b .v.mono{font-family:var(--mono);font-size:12.5px}

@media (max-width:720px){
  /* The label above its value; 120px of label beside a serial number leaves
     the serial wrapping in a sliver. */
  .cert-b{grid-template-columns:1fr;gap:2px}
  .cert-b .k{margin-top:8px}
}

/*
   The severity chip is white text on a severity colour. A certificate's role
   is not a severity, so it inherited the white text with no coloured ground
   behind it and came out near-invisible. It gets its own quiet treatment:
   this is a label, not a verdict.
*/
.cert-h .chip{background:var(--surface-3);color:var(--text-muted);
  border:1px solid var(--border);font-weight:600}

/* ---------- the tool menu ---------- */

/*
   Built on <details>, so it opens by click, tap and keyboard with no
   JavaScript at all. Hover-to-open is added on top for pointer devices,
   because a menu that only opens on click feels stiff on a desktop -- but it
   is an enhancement, never the mechanism.
*/
.nav .menu{position:relative}
.nav .menu>summary{display:inline-flex;align-items:center;gap:5px;cursor:pointer;
  font-size:14.5px;font-weight:500;color:var(--text-muted);padding:6px 0;
  border-bottom:2px solid transparent;white-space:nowrap;list-style:none}
.nav .menu>summary::-webkit-details-marker{display:none}
.nav .menu>summary:hover{color:var(--text)}
.nav .menu[open]>summary{color:var(--text)}
.nav .menu>summary[aria-current]{color:var(--accent);border-bottom-color:var(--accent)}
.caret{transition:transform .15s ease;flex:none}
.nav .menu[open] .caret{transform:rotate(180deg)}

/* An absolutely positioned grid shrinks to fit its containing block, which
   here is a narrow nav item, so the columns collapsed to a few characters.
   The width is stated. */
.menu-panel{position:absolute;top:calc(100% + 10px);left:-14px;z-index:60;
  width:min(560px,calc(100vw - 32px));
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2px;
  padding:8px;background:var(--surface);border:1px solid var(--border);
  border-radius:12px;box-shadow:0 12px 34px rgba(16,28,47,.13)}
/* The nav's own links are nowrap so they never break mid-label; inside the
   panel that is wrong -- these are sentences, and nowrap made every blurb run
   off the edge and get cut mid-word. */
.menu-panel a{display:block;padding:9px 11px;border-radius:8px;text-decoration:none;
  white-space:normal}
.menu-panel a:hover,.menu-panel a:focus-visible{background:var(--surface-2)}
.menu-panel b{display:block;font-size:14px;font-weight:600;color:var(--text);margin-bottom:2px}

/* Two lines of blurb, clamped: the taglines are written for a page heading
   and some run long, and a panel with rows of wildly different heights is
   harder to scan than one with a ragged last line. */
.menu-panel span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;font-size:12.5px;line-height:1.45;color:var(--text-muted)}

@media (max-width:860px){
  /*
     The header nav is a horizontal scroller on narrow screens, and an
     absolutely positioned panel inside a scroller is clipped by it. So the
     panel becomes an ordinary block that pushes the page down -- which is
     also the behaviour people expect from a menu on a phone.
  */
  .menu-panel{position:static;width:auto;grid-template-columns:1fr;box-shadow:none;
    border:0;padding:4px 0 8px;min-width:250px}
  .nav .menu[open]{background:var(--surface-2);border-radius:10px;padding:0 10px}
}

/*
   The chain, drawn as a chain.
   
   The arrow points from a certificate to the one that signed it, which is the
   single relationship the whole panel exists to show. Read as a list, three
   certificates look like three unrelated facts; read as a chain, it is
   obvious which one vouches for which and where the chain stops.
   
   aria-hidden on the connector: "signed by" is already stated in each card's
   Issued by row, so a screen reader would otherwise hear it twice.
*/
.chain-link{display:flex;align-items:center;gap:8px;padding:2px 0 2px 18px;
  color:var(--text-quiet)}
.chain-link span{font-family:var(--mono);font-size:11px;letter-spacing:.07em;text-transform:uppercase}
.cert{margin-bottom:0}
.chain>.cert+.chain-link{margin-top:2px}

/*
   The certificate offer. Deliberately quieter than the primary rail card:
   it appears only when something is actually broken, and a diagnostic that
   shouts an advert at the moment it delivers bad news reads as having been
   looking for a sale rather than for a fault.
*/
.offer{border:1px solid var(--warn-line);background:var(--warn-tint);
  border-radius:12px;padding:18px;margin-bottom:18px}
.offer h3{font-size:15.5px;margin:8px 0 6px;color:var(--text)}
.offer p{font-size:14px;line-height:1.6;color:var(--text-muted);margin:0 0 14px}
.offer .btn{width:100%}

/*
   An upgrade offer follows no finding, so it must not wear the warning
   colours a fault does. Same shape, neutral surface: it reads as information
   beside the result rather than as another thing wrong with the site.
*/
.offer-quiet{border-color:var(--border-strong);background:var(--accent-surface)}
.offer .caption{margin:10px 0 0;font-size:12px}

/* ---------- blocklists: every list we asked ---------- */

.raw .rbl-row{grid-template-columns:82px minmax(0,1fr) minmax(0,200px) 150px;gap:12px;align-items:baseline}
.rbl-s{font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;font-weight:600;color:var(--pass-text)}
.rbl-listed .rbl-s{color:var(--crit)}
.rbl-timeout .rbl-s{color:var(--warn-text)}
.rbl-refused .rbl-s{color:var(--warn-text)}
.rbl-via{font-style:normal;font-size:9.5px;letter-spacing:.06em;font-weight:600;
  color:var(--text-quiet);border:1px solid var(--line);border-radius:3px;padding:1px 4px;margin-left:6px}

/* A whitelist hit is good news wearing the word LISTED, so it is coloured as
   a pass however the row is generated. */
.rbl-good .rbl-s{color:var(--pass-text)}
.raw .rbl-row .t em{font-style:normal;font-family:var(--mono);font-size:10.5px;
  color:var(--text-quiet);letter-spacing:.05em}
.rbl-ms{color:var(--text-quiet);font-size:11.5px}

/* The list's own explanation, indented under the row it belongs to. */
.raw .rbl-why{display:block;padding:0 14px 10px 96px;font-size:12.5px;
  color:var(--text-muted);border-bottom:1px solid var(--border-soft);overflow-wrap:anywhere}

@media (max-width:860px){
  /*
     The status moves alongside the name instead of holding a column of its own.

     With a 74px status column and everything else stacked in column two, the
     first column was empty for every line after the first -- a fifth of a phone
     screen of nothing, on a table that is forty-five rows long. Explicit
     placement, because the status comes first in the markup and needs to sit to
     the right of the name that follows it.
  */
  .raw .rbl-row{grid-template-columns:minmax(0,1fr) auto;gap:2px 10px}
  .raw .rbl-row .rbl-s{grid-column:2;grid-row:1;text-align:right}
  .raw .rbl-row .t{grid-column:1;grid-row:1}
  .raw .rbl-row .v{grid-column:1/-1}
  .raw .h.rbl-row{display:none}
  .raw .rbl-why{padding-left:14px}
}

/* ---------- the full file list, on request ---------- */

/*
   Behind a disclosure because sixty rows is the answer to "which file", not
   to "is my site slow". The summary above answers the second; this answers
   the first, for the person who has decided they need it.
*/
.everyfile{margin:-6px 0 20px}
.everyfile>summary{cursor:pointer;font-size:13.5px;color:var(--accent);
  padding:6px 0;list-style:none;display:inline-flex;align-items:center;gap:6px}
.everyfile>summary::-webkit-details-marker{display:none}
.everyfile>summary::before{content:"▸";font-size:11px}
.everyfile[open]>summary::before{content:"▾"}
.everyfile>.raw{margin-top:8px}

.raw .file-row{grid-template-columns:minmax(0,1fr) 110px 72px 72px 72px;gap:10px;align-items:baseline}

/* Full addresses, wrapped. They are long by nature -- a cache filename is a
   32-character hash -- and the whole point of showing them is that somebody
   can read or copy one. */
.file-url{font-family:var(--mono);font-size:11.5px;overflow-wrap:anywhere;line-height:1.5}
.raw .file-row .v{font-size:12px;text-align:right}
.raw .h.file-row span:not(:first-child){text-align:right}

@media (max-width:860px){
  .raw .file-row{grid-template-columns:1fr auto;gap:2px 10px}
  .raw .file-row .v{text-align:left}
  .raw .h.file-row{display:none}
}

/* The legend, so a two-tone bar is readable without guessing. */
.legend{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);
  font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--text-quiet)}
.legend i{width:10px;height:10px;border-radius:2px;display:inline-block;margin-left:8px}
.legend i:first-child{margin-left:0}
.sw-wait{background:var(--accent)}
.sw-xfer{background:var(--accent-soft, #9dc0f0)}

/* The expiry reminder offer, quieter than a finding: it is an option, not a
   verdict, and it appears on every certificate result including healthy ones. */
.remind{border:1px solid var(--border);background:var(--surface-2);
  border-radius:12px;padding:16px 18px;margin-bottom:18px}
.remind p{font-size:14px;line-height:1.6;color:var(--text-muted);margin:8px 0 12px}
.remind .btn{width:100%}
.remind .caption{margin:10px 0 0;font-size:12px}

/* ---------- mail check ---------- */

.sendto{max-width:620px}
.waiting{border:1px dashed var(--border-strong);border-radius:12px;padding:22px 24px;
  background:var(--surface-2)}
.waiting p{font-size:14.5px;line-height:1.65;color:var(--text-muted);margin:8px 0 0}

/* Headers keep their arrival order, so the name column is fixed and the value
   wraps: a Received line is long by nature and is the one worth reading. */
.raw .hdr-row{grid-template-columns:190px minmax(0,1fr);gap:12px;align-items:baseline}
.raw .hdr-row .t{font-family:var(--mono);font-size:11.5px;color:var(--accent);overflow-wrap:anywhere}
.raw .hdr-row .v{font-family:var(--mono);font-size:11.5px;white-space:pre-wrap;overflow-wrap:anywhere}

@media (max-width:720px){
  .raw .hdr-row{grid-template-columns:1fr;gap:2px}
}

/* The DKIM key lookup, set apart from the signature tags above it: one is
   what the message claims, the other is what DNS actually holds. */
.keylookup{border-top:1px solid var(--border-soft);padding:12px 14px 14px;background:var(--surface-2)}

/* A quiet pulse beside "waiting", so the page reads as watching rather than
   stuck. Motion is dropped for anyone who has asked for less of it. */
.pulse{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--accent);
  margin-right:6px;vertical-align:middle;animation:pulse 1.8s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:.25}50%{opacity:1}}
@media (prefers-reduced-motion:reduce){.pulse{animation:none;opacity:.7}}
