/* ============================================================================
 * Uptimia — Free Find IP (/find-ip) + What Is My IP (/what-is-my-ip)
 * Mechanically generated from docs/find-ip-mockup.html <style>:
 * every selector scoped under .fip (tokens live on the wrapper, not :root),
 * mockup chrome (topbar/nav/dock/foot) dropped, keyframes renamed fip-*.
 * Hand-written additions live in this header block only.
 * ==========================================================================*/

.fip .hero-error{
  max-width:640px;margin:12px auto 0;
  border:1px solid rgba(255,122,104,.45);background:rgba(255,122,104,.12);
  border-radius:10px;padding:10px 16px;font-size:14px;color:#ffc9c0;text-align:left;
}
.fip .hero-error[hidden]{display:none}

.fip *, .fip *::before, .fip *::after{box-sizing:border-box;margin:0;padding:0}
.fip a{color:inherit;text-decoration:none}
.fip button{font:inherit;cursor:pointer;background:none;border:0;color:inherit}
.fip input, .fip select{font:inherit;color:inherit}
.fip svg{display:block}
.fip .wrap{max-width:1120px;margin:0 auto;padding:0 24px}
.fip .mono{font-family:var(--mono)}
.fip .micro{font-size:11.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--soft)}
.fip .view{display:none}
.fip .view.on{display:block}
.fip .testbar{max-width:640px;margin:34px auto 0;
  display:flex;align-items:stretch;gap:0;
  background:#fff;border-radius:12px;padding:6px;
  box-shadow:0 1px 0 rgba(255,255,255,.06), 0 24px 60px -24px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.08);}
.fip .testbar .field{flex:1;display:flex;align-items:center;gap:11px;padding:0 8px 0 14px;min-width:0}
.fip .testbar .field svg{color:var(--soft);flex:none}
.fip .testbar input{flex:1;border:0;outline:0;background:none;min-width:0;font-size:16.5px;font-weight:450;color:var(--ink);height:48px}
.fip .testbar input::placeholder{color:var(--soft)}
.fip .testbar .btn-run{display:inline-flex;align-items:center;gap:8px;padding:0 22px;border-radius:8px;
  background:var(--cta);color:var(--cta-ink);font-size:15px;font-weight:650;letter-spacing:-.01em;white-space:nowrap;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22), 0 6px 18px -6px rgba(78,201,126,.55);
  transition:filter .15s,transform .1s;}
.fip .testbar .btn-run:hover{filter:brightness(1.05)}
.fip .testbar .btn-run:active{transform:scale(.99)}
.fip .adv-strip{display:inline-flex;align-items:center;flex-wrap:wrap;justify-content:center;gap:8px 16px;margin:26px auto 0;
  border:1px solid var(--dark-line-2);border-radius:10px;padding:9px 16px;
  background:rgba(255,255,255,.03);
  font-family:var(--mono);font-size:12px;color:var(--dark-muted);}
.fip .adv-strip .lbl{font-size:10.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--dark-soft)}
.fip .adv-strip b{color:#fff;font-weight:600}
.fip .adv-strip a{color:var(--accent-bright);font-weight:600}
.fip .sec{padding:72px 0 0}
.fip .sec:last-child{padding-bottom:72px}
.fip .sec-head{max-width:640px;margin:0 0 34px}
.fip .sec-head.center{margin:0 auto 38px;text-align:center}
.fip .sec-head .micro{display:block;margin-bottom:12px;color:var(--accent)}
.fip .sec-head h2{font-size:31px;line-height:1.15;font-weight:700;letter-spacing:-.022em;color:var(--ink)}
.fip .sec-head p{margin-top:12px;font-size:15.5px;color:var(--muted)}
.fip .note-mono{font-family:var(--mono);font-size:12px;color:var(--soft)}
.fip .duo{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start}
.fip .duo-side h3{font-size:22px;line-height:1.2;font-weight:700;letter-spacing:-.018em;margin-bottom:10px}
.fip .duo-side p{font-size:14.5px;line-height:1.65;color:var(--muted);margin-bottom:12px}
.fip .duo-side ul{list-style:none;display:grid;gap:8px;margin:16px 0 20px}
.fip .duo-side li{display:flex;gap:9px;font-size:13.5px;color:var(--muted)}
.fip .duo-side li svg{color:var(--accent);flex:none;margin-top:3px}
.fip .port-row{display:flex;align-items:center;gap:12px;padding:11px 0;border-bottom:1px solid var(--bg-3)}
.fip .port-row:last-child{border-bottom:0}
.fip .port-row .pt{flex:none;min-width:170px;font-family:var(--mono);font-size:12px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fip .port-row .pd{flex:1;font-size:12.5px;color:var(--muted)}
.fip .cheat{max-width:860px;margin:0 auto;display:grid;gap:8px}
.fip .ch-row{display:flex;align-items:center;gap:14px;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-sm);padding:12px 16px;flex-wrap:wrap}
.fip .ch-row b{flex:1;font-size:13.5px;font-weight:600;letter-spacing:-.01em;color:var(--ink-2);min-width:190px}
.fip .cmd{display:inline-flex;align-items:center;gap:8px;max-width:100%;
  font-family:var(--mono);font-size:11.5px;color:var(--ink-3);
  background:var(--bg-3);border:1px solid var(--line-2);border-radius:7px;padding:5px 10px;}
.fip .cmd .c{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fip .cmd button{color:var(--accent);font-weight:600;font-size:11px;flex:none}
.fip .faq{max-width:760px;margin:0 auto}
.fip .faq-item{border-bottom:1px solid var(--line)}
.fip .faq-item:first-child{border-top:1px solid var(--line)}
.fip .faq-q{width:100%;display:flex;align-items:center;justify-content:space-between;gap:16px;padding:18px 2px;text-align:left;font-size:15.5px;font-weight:600;letter-spacing:-.01em;color:var(--ink-2)}
.fip .faq-q .pm{flex:none;width:22px;height:22px;border-radius:50%;border:1px solid var(--line-2);display:flex;align-items:center;justify-content:center;color:var(--soft);font-size:14px;transition:transform .18s var(--ease)}
.fip .faq-item.open .pm{transform:rotate(45deg);color:var(--accent);border-color:var(--accent-line);background:var(--accent-soft)}
/* Do NOT reintroduce a fixed cap here. max-height:460px clipped the last answer
   by 36px at 320px wide (five of the seven at 300px) — the 2026-07-29 sweep only
   measured 360 and 1280, so nothing caught it. grid-template-rows 0fr -> 1fr
   animates to the content's own height, whatever that turns out to be. */
.fip .faq-a{display:grid;grid-template-rows:0fr;overflow:hidden;transition:grid-template-rows .25s var(--ease)}
.fip .faq-a p{min-height:0;overflow:hidden;padding:0 40px 0 2px;font-size:14.5px;line-height:1.65;color:var(--muted)}
.fip .faq-a p::after{content:"";display:block;height:18px}
.fip .faq-item.open .faq-a{grid-template-rows:1fr}
.fip .tools-row{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.fip .tool-link{display:flex;flex-direction:column;gap:5px;padding:17px 18px 15px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--surface);transition:border-color .15s, box-shadow .15s}
.fip .tool-link:hover{border-color:var(--accent-line);box-shadow:0 8px 24px -14px rgba(15,23,42,.18)}
.fip .tool-link b{font-size:14px;font-weight:600;letter-spacing:-.01em;color:var(--ink-2);display:flex;align-items:center;gap:7px}
.fip .tool-link b svg{color:var(--accent)}
.fip .tool-link span{font-size:12.5px;color:var(--soft)}
.fip .tool-link.featured{border-color:var(--accent-line);background:linear-gradient(180deg,#fff,var(--accent-soft))}
.fip .band{margin-top:80px;background:var(--dark);color:var(--dark-ink);position:relative;overflow:hidden}
.fip .band::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 640px 320px at 82% 130%, rgba(78,201,126,.14), transparent 60%);pointer-events:none}
.fip .band-in{max-width:1120px;margin:0 auto;padding:58px 24px;display:grid;grid-template-columns:1.05fr .95fr;gap:48px;align-items:center;position:relative}
.fip .band h2{font-size:30px;line-height:1.14;font-weight:700;letter-spacing:-.022em;color:#fff}
.fip .band p{margin-top:12px;font-size:15px;line-height:1.6;color:var(--dark-muted);max-width:46ch}
.fip .band-form{display:flex;gap:8px;background:#fff;border-radius:12px;padding:6px;box-shadow:0 20px 50px -22px rgba(0,0,0,.5)}
.fip .band-form input{flex:1;border:0;outline:0;background:none;padding:0 14px;height:44px;font-size:14.5px;color:var(--ink);min-width:0}
.fip .band-form input::placeholder{color:var(--soft)}
.fip .band-form .btn-run{display:inline-flex;align-items:center;padding:0 18px;border-radius:8px;background:var(--cta);color:var(--cta-ink);font-size:14px;font-weight:650;white-space:nowrap;box-shadow:inset 0 1px 0 rgba(255,255,255,.22)}
.fip .band-trust{display:flex;gap:20px;margin-top:14px;font-family:var(--mono);font-size:11.5px;color:var(--dark-soft)}
.fip .band-trust span{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.fip .band-trust svg{color:var(--accent-bright)}
.fip .runhead{background:var(--dark);color:var(--dark-ink);position:relative;overflow:hidden}
.fip .runhead::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 700px 300px at 50% 130%, rgba(78,201,126,.10), transparent 60%);pointer-events:none}
.fip .runhead-in{max-width:1120px;margin:0 auto;padding:30px 24px 26px;position:relative}
.fip .runrow{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.fip .urlchip{display:inline-flex;align-items:center;gap:10px;background:rgba(255,255,255,.05);border:1px solid var(--dark-line-2);border-radius:10px;padding:9px 14px;font-family:var(--mono);font-size:14px;color:#fff}
.fip .urlchip .fav{width:18px;height:18px;border-radius:5px;background:linear-gradient(135deg,#7ea4e8,#4f6ab8);display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;color:#fff;font-family:var(--sans)}
/* Real favicon of the checked site (loaded into the .fav box; falls back to the initial). */
.fip .urlchip .fav img{width:16px;height:16px;object-fit:contain;border-radius:3px;display:block}
.fip .urlchip .fav[data-favicon]{background:#fff}
.fip .urlchip .rt{color:var(--accent-bright);font-size:12px;font-weight:600}
.fip .runrow .spacer{flex:1}
.fip .run-status{display:inline-flex;align-items:center;gap:9px;font-size:13.5px;color:var(--dark-muted)}
.fip .run-status .hit{color:var(--amber-bright);font-weight:600}
.fip .budget{display:flex;gap:5px}
.fip .lad-labels{display:flex;gap:5px;margin-top:7px;font-family:var(--mono);font-size:10.5px;color:var(--dark-soft)}
.fip .lad-labels span{flex:1;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fip .lad-labels span.on{color:#fff;font-weight:600}
.fip .check-banner{margin-top:18px;display:none;align-items:center;gap:10px;
  border:1px solid rgba(240,205,109,.38);background:rgba(240,205,109,.10);
  border-radius:var(--radius-sm);padding:11px 16px;font-size:14px;color:#f4e3b2;}
.fip .check-banner svg{color:var(--amber-bright);flex:none}
.fip .check-banner.good{border-color:rgba(78,201,126,.35);background:rgba(78,201,126,.08);color:#c4e8d2}
.fip .check-banner.good svg{color:var(--accent-bright)}
.fip .live-zone{padding:34px 0 0}
.fip .term{background:var(--dark);border:1px solid var(--dark-line-2);border-radius:var(--radius);overflow:hidden;box-shadow:0 20px 50px -28px rgba(0,0,0,.55)}
.fip .spf-raw{font-family:var(--mono);font-size:12.5px;line-height:2.15;word-break:break-word}
.fip .tok{display:inline-block;border-radius:6px;padding:1px 7px;margin:0 3px 3px 0;border:1px solid var(--line-2);background:var(--bg-3);color:var(--ink-3);white-space:nowrap}
.fip .tok.ver{color:var(--soft);background:var(--bg-2);border-style:dashed}
.fip .tok.lk{border-color:#d8dcea;background:#f2f4fa;color:#40518f}
.fip .tok.ip{border-color:var(--accent-line);background:var(--accent-soft);color:var(--accent-2)}
.fip .tok.goodk{border-color:var(--accent-line);background:var(--accent-soft);color:var(--accent);font-weight:600}
.fip .tok.warnk{border-color:var(--warn-line);background:var(--warn-soft);color:var(--warn);font-weight:600}
.fip .tok.badk{border-color:var(--bad-line);background:var(--bad-soft);color:var(--bad);font-weight:600}
.fip .tok.dep{border-color:var(--warn-line);background:var(--warn-soft);color:var(--warn);text-decoration:underline wavy rgba(182,120,0,.5)}
.fip .rec-note{margin-top:10px;font-size:12.5px;color:var(--muted)}
.fip .rec-note b{color:var(--ink-2)}
.fip .tree-foot{margin-top:12px;font-size:13px;color:var(--muted)}
.fip .tree-foot b{color:var(--ink-2)}
.fip .auth-rec{font-family:var(--mono);font-size:11.5px;color:var(--ink-3);
  background:var(--bg-3);border:1px dashed var(--line-2);border-radius:8px;
  padding:9px 12px;margin-top:8px;word-break:break-all;line-height:1.7;}
.fip .auth-rec b{color:var(--accent-2);font-weight:600}
/* ORDER GUARD (step 9): .auth-rec renders INSIDE .opp (see the oppsCardHTML
   builders in public/website/js/), so its <b> matches both rules at 0-2-1.
   The shared .tool .opp b now lives in tools-page.css, which loads BEFORE this
   file, so .auth-rec b would newly win. It did not before. Restating the two
   overlapping declarations after it keeps today's rendering exactly. */
.fip .opp b{font-weight:650;color:var(--ink-2)}
.fip .auth-rec.missing{border-color:var(--bad-line);background:var(--bad-soft);color:var(--bad)}
.fip .auth-rec.missing b{color:var(--bad)}
.fip .opp:last-child{border-bottom:0}
.fip .sev.ok{background:var(--accent)}
.fip .opp p b{display:inline;font-size:inherit;color:var(--ink-2)}
.fip .opp p .mono{font-size:11.5px;color:var(--ink-3)}
.fip .opp .act{display:inline-block;margin-top:8px;font-family:var(--mono);font-size:11px;font-weight:600;color:var(--accent);background:var(--accent-soft);border:1px solid var(--accent-line);border-radius:6px;padding:2px 8px;white-space:nowrap}
.fip .opp .act.warn{color:var(--warn);background:var(--warn-soft);border-color:var(--warn-line)}
.fip .opp .act.bad{color:var(--bad);background:var(--bad-soft);border-color:var(--bad-line)}
.fip .capture.warn{border-color:var(--warn-line);background:linear-gradient(180deg,#fff,var(--warn-soft));box-shadow:0 1px 2px rgba(15,23,42,.04), 0 16px 40px -22px rgba(182,120,0,.22)}
.fip .capture.bad{border-color:var(--bad-line);background:linear-gradient(180deg,#fff,var(--bad-soft));box-shadow:0 1px 2px rgba(15,23,42,.04), 0 16px 40px -22px rgba(192,56,43,.22)}
.fip .capture h3 em{font-family:var(--serif);font-style:italic;font-weight:500;color:var(--warn)}
.fip .capture.bad h3 em{color:var(--bad)}
.fip .cap-form .btn-warn{display:inline-flex;align-items:center;gap:7px;padding:0 16px;border-radius:8px;
  background:var(--warn);color:#fff;font-size:13.5px;font-weight:650;white-space:nowrap;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.15);transition:filter .15s;}
.fip .cap-form .btn-warn:hover{filter:brightness(1.08)}
.fip .cap-form .btn-bad{display:inline-flex;align-items:center;gap:7px;padding:0 16px;border-radius:8px;
  background:var(--bad);color:#fff;font-size:13.5px;font-weight:650;white-space:nowrap;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.15);transition:filter .15s;}
.fip .cap-form .btn-bad:hover{filter:brightness(1.08)}
.fip .owner-line{margin-top:14px;padding-top:14px;border-top:1px dashed var(--warn-line);font-size:13px;color:var(--muted)}
.fip .owner-line b{color:var(--ink-2)}
.fip .owner-line a{color:var(--accent);font-weight:600}
.fip .kv .v.warn{color:var(--warn);font-weight:550}
.fip .kv .v.good{color:var(--accent);font-weight:550}
.fip .deep-link{display:flex;align-items:center;gap:14px;padding:16px 18px;
  border:1px solid var(--accent-line);border-radius:var(--radius-sm);
  background:linear-gradient(180deg,#fff,var(--accent-soft));transition:box-shadow .15s;}
.fip .deep-link:hover{box-shadow:0 10px 26px -16px rgba(0,126,66,.35)}
.fip .deep-link .glyph{flex:none;width:36px;height:36px;border-radius:9px;background:var(--accent-soft);border:1px solid var(--accent-line);color:var(--accent);display:flex;align-items:center;justify-content:center}
.fip .deep-link b{display:block;font-size:13.5px;font-weight:650;color:var(--ink-2)}
.fip .deep-link span{font-size:12px;color:var(--muted)}
.fip .deep-link svg.arr{margin-left:auto;color:var(--accent);flex:none}
@media (max-width:960px){
.fip .duo, .fip .res-grid{grid-template-columns:1fr}
.fip .quad{grid-template-columns:1fr 1fr}
.fip .err-grid{grid-template-columns:1fr 1fr}
.fip .tools-row{grid-template-columns:1fr 1fr}
.fip .band-in{grid-template-columns:1fr;gap:28px}
}
@media (max-width:620px){
.fip .testbar{flex-direction:column;gap:6px}
.fip .testbar .btn-run{height:46px;justify-content:center}
.fip .quad, .fip .err-grid, .fip .tools-row{grid-template-columns:1fr}
}
.fip .ip-row{display:flex;gap:12px;align-items:flex-start;padding:11px 0}
.fip .ip-row + .ip-row{border-top:1px solid var(--bg-3)}
.fip .fam{flex:none;font-family:var(--mono);font-size:10px;font-weight:700;letter-spacing:.06em;border-radius:6px;padding:3px 8px;margin-top:2px;background:var(--accent-soft);color:var(--accent);border:1px solid var(--accent-line)}
.fip .fam.v6{background:#eef4fb;color:#3d6fa8;border-color:#d5e3f2}
.fip .ip-main{flex:1;min-width:0}
.fip .ip-mono{font-family:var(--mono);font-size:13.5px;font-weight:600;color:var(--ink);word-break:break-all}
.fip .ip-meta{font-size:12px;color:var(--muted);margin-top:3px;line-height:1.55}
.fip .ip-meta .okk{color:var(--accent);font-weight:600}
.fip .ip-meta .wrn{color:var(--warn);font-weight:600}
.fip .conf-row{display:flex;align-items:center;gap:10px;padding:7px 0}
.fip .conf-row + .conf-row{border-top:1px solid var(--bg-3)}
.fip .conf-row .cn{flex:none;width:88px;font-size:12px;font-weight:600;color:var(--ink-2)}
.fip .conf-row .cb{flex:1;height:7px;border-radius:4px;background:var(--bg-3);border:1px solid var(--line-2);overflow:hidden}
.fip .conf-row .cb i{display:block;height:100%;border-radius:4px;background:var(--accent)}
.fip .conf-row.w .cb i{background:var(--amber)}
.fip .conf-row.b .cb i{background:var(--bad)}
.fip .conf-row .cl{flex:none;width:168px;text-align:right;font-family:var(--mono);font-size:10.5px;color:var(--ink-3)}
/* .cn 88px + .cl 168px + two 10px gaps needs 276px of row before the card's own
   padding, which overflowed the viewport at 320px (page scrollWidth 323). Below
   that, let the caption drop to its own line instead of widening the page. */
@media (max-width:430px){
	.fip .conf-row{flex-wrap:wrap;row-gap:2px}
	.fip .conf-row .cb{min-width:60px}
	.fip .conf-row .cl{flex:1 1 100%;width:auto;text-align:left;padding-left:98px}
}
.fip .myip-ip{display:flex;align-items:center;gap:16px;flex-wrap:wrap;font-family:var(--mono);font-weight:600;letter-spacing:-.01em;font-size:clamp(34px,6vw,56px);color:#fff;margin:18px 0 4px}
.fip .myip-ip button{font-family:var(--mono);font-size:12px;font-weight:600;padding:8px 14px;border-radius:8px;border:1px solid rgba(255,255,255,.25);background:rgba(255,255,255,.07);color:#fff;cursor:pointer}
.fip .myip-ip button:hover{background:rgba(255,255,255,.14)}
.fip .myip-sub{font-family:var(--mono);font-size:12px;color:var(--dark-muted);margin-bottom:14px}

/* ---- 360px containment (2026-07-29 review) --------------------------------
   The terminal cheatsheet is the exact shape that clipped /port-checker,
   /mx-checker and /subnet-calculator: flex children default to min-width:auto,
   so the nowrap shell command (.cmd .c, ellipsis that could never engage) and
   the min-width:190px label dictated the row's minimum and .ch-row grew to
   442px inside a 360px viewport. min-width:0 lets the ellipsis actually work.
   .port-row .pt ships the same ellipsis+flex:none pattern — flex:0 1 auto so
   its ellipsis can engage too instead of propagating min-content upward. */
.fip .cheat > *{min-width:0}
.fip .ch-row > *{min-width:0}
.fip .cmd .c{min-width:0}
.fip .port-row .pt{flex:0 1 auto}
.fip .res-grid > *{min-width:0}

/* Narrow viewports: .pt's min-width:170px would leave the row's text a
   ~110px strip (worst on /what-is-my-ip's long quick-answer labels) —
   stack the label above the text instead. */
@media (max-width:480px){
	.fip .port-row{flex-wrap:wrap;gap:4px 12px}
	.fip .port-row .pt{flex:0 0 100%;min-width:0;white-space:normal}
}

/* ---- Result-view containment (2026-08-05 review) ---------------------------
   The 2026-07-29 pass measured the SSR landing and what-is-my-ip at 360 and
   1280 and stopped there. The RESULT view — where every visitor actually ends
   up — was still leaking: an .opp row is a flex container whose text column is
   emitted as <div style="flex:1"> (find-ip.js oppsCardHTML), so it inherits
   min-width:auto and a single unbreakable token sets the row's minimum. A real
   PTR name does exactly that: "ns31711641.ip-145-239-146.eu" pushed the row to
   315px inside a ~294px column and the whole page to scrollWidth 381 at 360.
   break-word (never `anywhere` — that mangles min-content elsewhere in this
   family) lets prose break only when the word itself cannot fit. */
.fip .opp > div{min-width:0}
.fip .opp p,.fip .opp p .mono{overflow-wrap:break-word}

/* The share badge is one nowrap pill: host + status label + "Uptimia". With a
   long owner string ("AS13335 · Cloudflare, Inc.") it outgrew a 360px viewport
   on its own. Same containment the blacklist/bimi siblings already carry. */
@media (max-width:520px){
	/* .act is white-space:nowrap, so a long action label ("renaming is a support
	   ticket") is itself an unbreakable box ~290px wide. Let it wrap down here. */
	.fip .opp .act{white-space:normal}
	.fip .upt-badge{max-width:100%;flex-wrap:wrap;height:auto;min-height:30px;row-gap:2px;white-space:normal}
	.fip .badge-demo{flex-wrap:wrap}
	.fip .badge-code{min-width:0;overflow-wrap:anywhere}
}

/* ---- The page could not display an IPv6 address (2026-08-06 review) --------
   Every prior sweep of /what-is-my-ip ran over IPv4, so nothing caught this:
   with a real IPv6 client the hero address was CUT MID-DIGIT at every width
   including 1280 (scrollWidth 1289 in a 792px box), running under the side
   chips, and the summary card ellipsised it too ("2a02:8109:8c40:1234:5678…").
   The visitor could not read the one number the page exists to show.

   Cause: `.myip-ip` is a flex row and the address was a bare text node, i.e.
   an ANONYMOUS flex item with min-width:auto — and an IPv6 literal has no
   break opportunity, so its min-content IS the whole 39-character string. The
   address now sits in its own `.ipv` span (targetable), and a `.v6` class
   drops the type scale for the longer family. */
.fip .myip-h1{font-size:13px;font-weight:600;letter-spacing:.01em;color:var(--dark-muted);margin:16px 0 0}
.fip .myip-ip{margin-top:6px}
.fip .myip-ip .ipv{min-width:0;overflow-wrap:anywhere}
.fip .myip-ip.v6{font-size:clamp(19px,3.1vw,31px);gap:14px}

/* `.tool .kv .v` is nowrap + text-overflow:ellipsis over a fixed 150px label
   column, so realistic values were silently truncated — an IPv6 address and
   "Berlin (Bezirk Tempelhof-Schöneberg), DE" both at 1280, and EVERY value at
   320 (a 66px value column). A shortened fact reads as a fact, so wrap instead
   of clipping, and give the label column the whole row on narrow screens. */
.fip .kv .v{white-space:normal;text-overflow:clip;overflow-wrap:anywhere}
@media (max-width:520px){
	.fip .kv{grid-template-columns:1fr;gap:0}
	.fip .kv .k{padding-bottom:0;border-bottom:0}
	.fip .kv .v{padding-top:1px}
}

/* Same containment the bimi/dkim/dmarc/mta-sts/tls-rpt siblings all carry and
   this stylesheet was missing: chip values are org names and PTR labels. */
.fip .v-chip .micro,.fip .v-chip .val,.fip .v-chip .sub{overflow-wrap:anywhere}

/* The "what this page can see" rows put the raw address inside a <b>; at 300px
   that single token pushed the row 11px past the viewport. */
.fip .port-row .pd{overflow-wrap:break-word}
.fip .port-row .pd b,.fip .port-row .pd .mono{overflow-wrap:anywhere}

/* The quick-answers card reuses .port-row, whose .pt is a nowrap, ellipsised
   mono label — fine for "reverse name", wrong for a full question. The 07-30
   pass let the row wrap below 480px and verified 360 + 1280; at 1024 the
   two-column grid narrows this column to ~440px and the questions were cut off
   with an ellipsis again ("Why does this page show only my IPv4 or only…").
   A question/answer pair reads better stacked at every width anyway. */
.fip .qa .port-row{flex-wrap:wrap;gap:3px 12px}
.fip .qa .port-row .pt{flex:0 0 100%;min-width:0;white-space:normal;overflow:visible;text-overflow:clip;font-size:12.5px;color:var(--ink-2);font-weight:600}
