/* chneas design system: shared by every tool page. */
:root{
  /* Tuned for long sessions rather than maximum punch.
     Near-black behind near-white measured 16.4:1, and that much contrast is
     what makes light text bloom and eyes tire, so the ground is lifted and
     warmed slightly and the ink pulled back to 14.1:1, still far above the
     4.5:1 the standard asks for. Secondary text went the other way and is now
     more readable than before (6.6:1 -> 7.4:1), and --dim finally clears AA on
     a panel at 4.9:1 where it used to fail at 3.3:1. The accent is a shade
     deeper so it stops vibrating against the background at 10.7:1. */
  --bg:#111721; --panel:#18202b; --panel2:#212a36; --line:#2c3644;
  --ink:#dde5ee; --muted:#9aa7b8; --dim:#7f8da1;
  --accent:#5fdcc6; --accent2:#4ab8ee;
  --ok:#34d399; --crit:#f87171; --high:#fb923c; --med:#fbbf24; --low:#818cf8;
  --retract:#e879f9; --radius:13px;
}
*{box-sizing:border-box} html,body{margin:0;padding:0}
body{background:var(--bg);color:var(--ink);
  font:16px/1.68 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
/* Long-form paragraphs get a measure; ~70 characters is where reading speed
   peaks and where people stop skimming. */
.lede,.note,.why p,p{max-width:74ch}
a{color:var(--accent2)}
.wrap{max-width:1080px;margin:0 auto;padding:22px 22px 80px}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}

/* nav + headings */
nav{display:flex;align-items:center;justify-content:space-between;padding:0 0 26px;gap:14px;flex-wrap:wrap}
.brand{font-size:17px;font-weight:700;letter-spacing:-.02em}
.brand span{color:var(--accent)} .brand a{color:inherit;text-decoration:none}
.navlinks{display:flex;gap:16px;font-size:13px}
.navlinks a{color:var(--muted);text-decoration:none} .navlinks a:hover{color:var(--ink)}
h1{font-size:29px;margin:0 0 8px;letter-spacing:-.03em} h1 .dot{color:var(--accent)}
.lede{color:var(--muted);margin:0 0 8px;max-width:70ch} .lede b{color:var(--ink);font-weight:600}
.srcline{font-size:12.5px;color:var(--dim);margin:0 0 18px}

/* privacy badge */
.privacy{display:inline-flex;align-items:center;gap:9px;background:rgba(52,211,153,.07);
  border:1px solid rgba(52,211,153,.26);color:#a7f3d0;border-radius:999px;padding:6px 14px;
  font-size:12.5px;margin-bottom:18px}
.pulse{width:7px;height:7px;border-radius:50%;background:var(--ok);animation:pulse 2.6s infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(52,211,153,.6)}70%{box-shadow:0 0 0 8px rgba(52,211,153,0)}
  100%{box-shadow:0 0 0 0 rgba(52,211,153,0)}}

/* inputs */
textarea,input[type=text],input[type=email],input[type=url]{
  background:var(--panel);color:var(--ink);border:1px solid var(--line);border-radius:11px;padding:12px 14px}
textarea{width:100%;min-height:150px;font:13.5px/1.65 ui-monospace,SFMono-Regular,Menlo,monospace;resize:vertical;border-radius:var(--radius);padding:15px}
textarea:focus,input:focus{outline:none;border-color:var(--accent)}
textarea.over,.dropzone.over{border-color:var(--accent);background:#141b1c}
.dropzone{border:2px dashed var(--line);border-radius:var(--radius);padding:48px 24px;text-align:center;
  background:var(--panel);transition:.18s;cursor:pointer}
.dropzone:hover,.dropzone.over{border-color:var(--accent);background:#141b1c}
.dropzone h2{margin:0 0 6px;font-size:19px;font-weight:600}
.dropzone p{margin:0;color:var(--muted);font-size:14px}
kbd{background:var(--panel2);border:1px solid var(--line);border-bottom-width:2px;border-radius:6px;
  padding:1px 6px;font:12px ui-monospace,Menlo,monospace;color:var(--ink)}

/* buttons */
.row{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-top:12px}
.btn{appearance:none;border:1px solid var(--line);background:var(--panel2);color:var(--ink);
  padding:10px 16px;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:.15s;
  text-decoration:none;display:inline-block}
.btn:hover:not(:disabled){border-color:#3a4552;background:#222831}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#04231f}
.btn.primary:hover:not(:disabled){background:#7df0dd;border-color:#7df0dd}
.btn.ghost{background:transparent}
.btn.sm{padding:5px 11px;font-size:12px;font-weight:550;border-radius:8px}
.btn.on{background:var(--accent);border-color:var(--accent);color:#04231f}
.hint{font-size:12.5px;color:var(--dim)}

/* panels + cards */
.panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
.panel h3{margin:0;padding:13px 16px;font-size:13px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);border-bottom:1px solid var(--line);font-weight:600}
.panel .body{padding:14px 16px}
.summary{display:flex;gap:10px;flex-wrap:wrap;margin:22px 0 6px}
.card{flex:1;min-width:120px;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:12px 14px}
.card .n{font-size:25px;font-weight:700;letter-spacing:-.02em;line-height:1.1}
.card .l{font-size:12px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-top:3px;font-weight:600}
.card.ok .n{color:var(--ok)} .card.crit .n{color:var(--crit)} .card.high .n{color:var(--high)}
.card.med .n{color:var(--med)} .card.low .n{color:var(--low)} .card.dim .n{color:var(--dim)}

/* verdict banner */
.verdict{margin:22px 0 4px;padding:16px 18px;border-radius:14px;border:1px solid var(--line);background:var(--panel)}
.verdict.clean{border-color:rgba(52,211,153,.4);background:rgba(52,211,153,.06)}
.verdict.dirty{border-color:rgba(248,113,113,.45);background:rgba(248,113,113,.06)}
.verdict h2{margin:0 0 4px;font-size:20px;letter-spacing:-.02em}
.verdict.clean h2{color:#6ee7b7} .verdict.dirty h2{color:#fca5a5}
.verdict p{margin:0;font-size:13.5px;color:var(--muted)}
.chips{display:flex;gap:7px;flex-wrap:wrap;margin-top:11px}
.chip{font-size:11.5px;padding:3px 10px;border-radius:999px;border:1px solid var(--line);
  background:var(--panel2);color:var(--muted)} .chip b{color:var(--ink)}

/* finding rows */
.find{background:var(--panel);border:1px solid var(--line);border-left-width:3px;border-radius:11px;
  padding:13px 15px;margin-bottom:10px}
.find.sev-crit{border-left-color:var(--crit)} .find.sev-high{border-left-color:var(--high)}
.find.sev-med{border-left-color:var(--med)}  .find.sev-low{border-left-color:var(--low)}
.find.sev-ok{border-left-color:var(--ok)}
.find .h{display:flex;align-items:center;gap:9px;margin-bottom:6px;flex-wrap:wrap}
.find .name{font-weight:600;font-size:14.5px}
.find .where{font-size:11px;color:var(--dim);margin-left:auto}
.find .desc{font-size:13px;color:var(--muted);margin-top:2px}
.find .acts{margin-top:10px;display:flex;gap:7px;flex-wrap:wrap;align-items:center}
.find .acts .lbl{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:.06em}
.pill{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;padding:2.5px 8px;border-radius:999px}
.pill.sev-crit{background:rgba(248,113,113,.15);color:#fca5a5;border:1px solid rgba(248,113,113,.38)}
.pill.sev-high{background:rgba(251,146,60,.14);color:#fdba74;border:1px solid rgba(251,146,60,.38)}
.pill.sev-med{background:rgba(251,191,36,.13);color:#fcd34d;border:1px solid rgba(251,191,36,.35)}
.pill.sev-low{background:rgba(129,140,248,.13);color:#a5b4fc;border:1px solid rgba(129,140,248,.35)}
.pill.sev-ok{background:rgba(52,211,153,.16);color:#6ee7b7;border:1px solid rgba(52,211,153,.35)}
.pill.sev-dim{background:var(--panel2);color:var(--muted);border:1px solid var(--line)}
.payload{margin-top:10px;background:#0e1216;border:1px solid var(--line);border-radius:9px;padding:11px 13px;
  font:12.5px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;color:#fca5a5;white-space:pre-wrap;
  word-break:break-word;max-height:220px;overflow:auto}
.payload .lbl{display:block;color:var(--dim);font-size:10.5px;text-transform:uppercase;letter-spacing:.07em;
  margin-bottom:5px;font-family:inherit}
.kv{display:grid;grid-template-columns:96px 1fr;gap:3px 10px;margin-top:6px;font-size:12.5px}
.kv span:nth-child(odd){color:var(--dim);font-size:11.5px;text-transform:uppercase;letter-spacing:.05em}
.kv span:nth-child(even){color:var(--ink);word-break:break-word}

/* misc */
.bar{height:3px;background:var(--panel2);border-radius:3px;overflow:hidden;margin:14px 0}
.bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--accent),var(--accent2));transition:.25s}
.note{font-size:12.5px;color:var(--muted);line-height:1.55}
.note.warn{color:#fcd34d;background:rgba(251,191,36,.07);border:1px solid rgba(251,191,36,.25);
  padding:11px 13px;border-radius:10px}
details{margin-top:26px;border-top:1px solid var(--line);padding-top:16px}
summary{cursor:pointer;color:var(--muted);font-size:13.5px}
.hidden{display:none!important}
footer{margin-top:40px;border-top:1px solid var(--line);padding-top:16px;color:var(--dim);font-size:12.5px}

/* ─────────────────────────────────────────────────────────────
   Layout and advertising.

   The content is a centred column. Advertising sits in two narrow
   rails pinned to the left and right edges of the viewport, over
   the page rather than inside the flow, so the column stays put
   and stays centred no matter how wide the screen gets.

   The rails only appear when the viewport can hold the column and
   both rails without either one crowding the text. Below that they
   are removed rather than stacked, so a phone never scrolls past
   an advert to reach the tool. The slot below the content stays at
   every width and carries the load on small screens.
   ───────────────────────────────────────────────────────────── */
.wrap{margin:0 auto}
body.has-ads .wrap{max-width:1080px}

.adrail{display:none}
.adrail .sticky{display:flex;flex-direction:column;gap:14px}
.adlabel{font-size:10px;text-transform:uppercase;letter-spacing:.09em;color:var(--dim);
  padding-left:2px}
.adnote{font-size:11px;color:var(--dim);line-height:1.5;border-top:1px solid var(--line);padding-top:10px}
.adnote a{color:var(--muted)}

/* 1080 column + 2 x (160 rail + 28 gutter) = 1456 is the bare minimum, and at
   exactly that width the gap to the text is only 14px. 1500 is where the rails
   sit clear of the column rather than beside it, so that is where they start. */
@media (min-width:1500px){
  .adrail{display:block;position:fixed;top:50%;transform:translateY(-50%);
    width:160px;z-index:40}
  .adrail-left{left:max(16px, calc((100vw - 1080px) / 2 - 188px))}
  .adrail-right{right:max(16px, calc((100vw - 1080px) / 2 - 188px))}
}
/* Wider screens get the taller unit, since there is vertical room for it. */
@media (min-width:1500px) and (min-height:820px){
  iframe.adslot[data-size="160x600"]{height:600px}
}
@media (min-width:1500px) and (max-height:819px){
  iframe.adslot[data-size="160x600"]{height:480px}
}

.adslot .adph{color:var(--dim);font-size:12px;letter-spacing:.06em;text-transform:uppercase}

/* Below-content slot, shown at every width. On a phone this is the only one. */
.adfoot{margin:30px 0 0;min-height:90px}
@media(max-width:1499px){ .adfoot{min-height:100px} }

/* Ad slots are sandboxed iframes (opaque origin: no access to the tool page's DOM
   or canvas). Sizing has to be explicit because an iframe is a replaced element.
   The frame is transparent and empty until a network snippet is pasted into
   ad-frame.html, so reserved space reads as whitespace rather than as a broken
   box. Add `ads-live` to <body> once ads are serving and the slot chrome and the
   "Advertisement" label appear. */
iframe.adslot{border:0;width:100%;display:block;background:transparent;border-radius:var(--radius)}
body.ads-live iframe.adslot{background:var(--panel);border:1px solid var(--line)}
.adlabel,.adnote{display:none}
body.ads-live .adlabel{display:block}
body.ads-live .adnote{display:block}
iframe.adslot[data-size="160x600"]{height:600px}
iframe.adslot.adfoot{height:100px}

/* ─────────────────────────────────────────────────────────────
   Accessibility + input ergonomics
   ───────────────────────────────────────────────────────────── */

/* Keyboard focus was invisible on this dark ground: the browser default
   outline is nearly the same value as --line. Every interactive element now
   gets an unmistakable ring. */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible{
  outline:2px solid var(--accent); outline-offset:2px; border-radius:6px;
}

/* Skip link: the tool pages put five nav links before the drop zone, which is
   five stops for anyone using a keyboard or a screen reader. */
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--accent);color:#04231f;
  padding:10px 16px;border-radius:0 0 10px 0;font-weight:700;text-decoration:none}
.skip:focus{left:0}

/* Touch targets. 44px is the accessible minimum; .btn.sm was 25px tall, which
   is a coin-flip tap on a phone. Pointer-coarse only, so mouse density is kept. */
@media (pointer:coarse){
  .btn{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
  .btn.sm{min-height:38px;padding:8px 14px;font-size:13px}
  /* The tool nav is how someone moves between tools on a phone, so it gets a
     full 44px target rather than the 34px that padding alone produced. */
  .navlinks a{min-height:44px;display:inline-flex;align-items:center;padding:0 2px}
  .brand a{min-height:44px;display:inline-flex;align-items:center}
  summary{min-height:44px;display:flex;align-items:center}
  .faq summary{min-height:52px}
  /* Shade's mode selector and any bare input are primary controls too. */
  .mbtn{min-height:44px;display:inline-flex;align-items:center}
  input[type=text],input[type=email],input[type=url],input[type=search]{min-height:44px}
  .fb-launch{min-height:44px}
}

/* Respect a reduced-motion preference: the privacy pulse and card lifts are
   decoration, and vestibular sensitivity is not rare. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
  .pulse{animation:none}
}

/* Long tool nav on a narrow screen: scroll it rather than wrapping into two
   ragged rows that push the tool below the fold. */
@media (max-width:560px){
  nav{flex-wrap:nowrap;gap:10px}
  .navlinks{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;
    gap:14px;flex:1;justify-content:flex-start;padding-bottom:2px}
  .navlinks::-webkit-scrollbar{display:none}
  .navlinks a{white-space:nowrap}
}

/* iOS zooms the whole page when a font-size below 16px is focused. */
@media (max-width:640px){
  textarea,input[type=text],input[type=email],input[type=url]{font-size:16px}
}

/* Nothing should ever scroll sideways on a phone. */
html,body{overflow-x:hidden}

/* Per-tool mark beside the page heading. Sits on the text baseline so the
   name and the creature read as one lockup rather than two elements. */
h1.hasmark{display:flex;align-items:center;gap:11px}
h1.hasmark .toolmark{color:var(--accent);flex:0 0 auto}

/* Brand lockup: the mark and the wordmark are one unit, so they align on the
   optical centre rather than the text baseline. */
.brand{display:inline-flex;align-items:center;gap:8px}
.brand a{display:inline-flex;align-items:center;gap:8px}
.brand .brandmark{color:var(--accent);flex:0 0 auto}
.brand .dot{color:var(--accent)}

/* ─────────────────────────────────────────────────────────────
   Feedback widget. Deliberately quiet: it must never sit over a
   tool's controls, and on a phone it collapses to a small pill
   that clears the bottom safe area.
   ───────────────────────────────────────────────────────────── */
.fb-root{position:fixed;right:16px;bottom:calc(16px + env(safe-area-inset-bottom));z-index:80;
  display:flex;flex-direction:column;align-items:flex-end;gap:10px}
.fb-launch{border:1px solid var(--line);background:var(--panel);color:var(--muted);
  border-radius:999px;padding:9px 16px;font-size:13px;font-weight:600;cursor:pointer;
  min-height:44px;box-shadow:0 6px 20px rgba(0,0,0,.35)}
.fb-launch:hover{color:var(--ink);border-color:var(--accent)}
.fb-panel{width:min(21rem,calc(100vw - 32px));background:var(--panel);border:1px solid var(--line);
  border-radius:16px;padding:16px;box-shadow:0 18px 46px rgba(0,0,0,.5)}
.fb-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.fb-close{border:none;background:none;color:var(--dim);font-size:22px;line-height:1;cursor:pointer;
  min-width:36px;min-height:36px}
.fb-close:hover{color:var(--ink)}
.fb-text{width:100%;min-height:92px;background:var(--panel2);color:var(--ink);
  border:1px solid var(--line);border-radius:10px;padding:11px;font:inherit;font-size:16px;resize:vertical}
.fb-text:focus{outline:none;border-color:var(--accent)}
.fb-note{font-size:11.5px;color:var(--dim);line-height:1.5;margin:9px 0 11px;max-width:none}
.fb-send{width:100%}
.fb-status{font-size:12.5px;color:var(--muted);margin:9px 0 0;min-height:1.2em}
@media (max-width:560px){ .fb-root{right:12px;bottom:calc(12px + env(safe-area-inset-bottom))} }
@media print{ .fb-root{display:none} }

/* The tool name is the visual anchor; the functional line under it is what a
   search engine reads and what a first-time visitor needs. Both live inside
   the H1 so the heading is not a bare proper noun. */
h1.hasmark{align-items:flex-start}
h1.hasmark .toolmark{margin-top:.15em}
h1.hasmark .h1name{display:flex;flex-direction:column;line-height:1.05}
h1.hasmark .h1word{display:block}
h1.hasmark .h1sub{font-size:.5em;font-weight:600;letter-spacing:0;color:var(--muted);margin-top:.28em}
@media (max-width:560px){ h1.hasmark .h1sub{font-size:.56em} }

/* Launcher: icon + word on a roomy screen, icon-only circle on a phone so a
   floating control never sits on top of a tool's instructions. */
.fb-launch{display:inline-flex;align-items:center;gap:7px}
@media (max-width:560px){
  .fb-launch{width:48px;height:48px;padding:0;justify-content:center;border-radius:50%}
  .fb-launch-text{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
}

/* ═══════════════════════════════════════════════════════════════════
   Desktop layout.
   The phone layout is a single column and should stay that way. On a
   laptop the same single column left roughly a third of the content
   area permanently empty: prose sat at 705px inside a 1050px column,
   and every section stacked. These rules use the width instead.
   ═══════════════════════════════════════════════════════════════════ */

/* Use the whole screen. The capped shell meant that past about 1500px every
   extra pixel became margin; now the content spreads and only the reading
   measure inside each column is limited. The ad rail keeps its 300px. */
@media (min-width:1180px){
  .wrap{padding-left:34px;padding-right:34px}
}

/* Type scales up with the screen: 50px headings look timid at 1500px. */
@media (min-width:1180px){
  h1{font-size:34px}
  h1.hasmark .h1sub{font-size:.46em}
  .lede{font-size:17px}
}

/* Tool pages: the explanation and the evidence behind it sit side by side
   instead of stacking, which fills the row and lifts the tool itself up the
   page. Everything else still spans the full content width. */
@media (min-width:1180px){
  body.has-ads .wrap{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  body.has-ads .wrap > *:not(.adrail){grid-column:1 / span 2}
  body.has-ads .wrap > .lede,
  body.has-ads .wrap > .sub{grid-column:1;align-self:start;max-width:none;margin-top:0}
  body.has-ads .wrap > .srcline{grid-column:2;align-self:start;max-width:none;
    border-left:1px solid var(--line);padding-left:22px;margin-top:0}
}

/* Findings and results are detail rows: full width is correct for them, but
   the summary cards should spread rather than clump at one end. */
@media (min-width:1180px){
  .summary .card{min-width:0}
}
