/* ============================================================================
   ip-detail.css — page-scoped styles for /ip-detail (public IP lookup).

   Scope: EVERY rule below is prefixed with `.ipd-page`. Nothing here can leak
   into another page, so this file is safe to load alongside style.css.
   Loaded via $extraStyles from ip-detail.php (same opt-in mechanism as
   auth.css / landing.css / content-page.css).

   Theme: LIGHT app system (UI_COMPONENT_LIBRARY.md §1). This page is NOT a
   Direction B (dark) page — do not introduce --ink/--surface/--bg here. Every
   colour reads a light-system token (--app-*, --brand-*, --n-*) from
   design-tokens.css, with a literal fallback so the page still renders sanely
   if that file ever fails to load.

   Replaces the ~300-line inline <style> block that used to live in
   ip-detail.php (two blocks, actually: one in $extraStyles and one mid-body
   next to the quick-search markup).
   ============================================================================ */

.ipd-page {
    --ipd-gap: 20px;
    --ipd-radius: var(--card-radius, 10px);
    --ipd-border: var(--app-border, #dfe5ef);
    --ipd-surface: var(--app-surface, #fff);
    --ipd-muted: var(--app-surface-muted, #eaeff7);
    --ipd-ink: var(--app-ink, #16202f);
    --ipd-ink-soft: var(--app-ink-soft, #667487);
    --ipd-ink-faint: var(--app-ink-faint, #95a0b5);
    --ipd-shadow: var(--card-shadow, 0 1px 2px rgba(16, 24, 40, .07), 0 1px 1px rgba(16, 24, 40, .04));
    /* Semantic trio — same hues as the canonical .status-badge / .alert
       families (UI_COMPONENT_LIBRARY.md §1), not a new palette. */
    --ipd-danger-bg: #fee2e2;
    --ipd-danger-ink: #991b1b;
    --ipd-warn-bg: #fef3c7;
    --ipd-warn-ink: #92400e;
    --ipd-ok-bg: #d1fae5;
    --ipd-ok-ink: #065f46;
    --ipd-info-bg: #dbeafe;
    --ipd-info-ink: #1e40af;

    /* No max-width/margin here on purpose. The <div> this class is on always
       also carries `container-fluid` (ip-detail.php:141,706), which already
       declares max-width:1400px; margin:0 auto; padding:0 10px (style.css).
       Both rules sit at the same specificity (0,1,0) on the SAME element, so
       whichever loads last wins the cascade — this file loads after
       style.css, so an `.ipd-page { max-width:1120px; margin:0 auto }` here
       used to silently override container-fluid's 1400px down to 1120px,
       shifting every edge 140px left of the header/footer at wide viewports
       (v1.1.2-005). Re-declaring max-width/margin here is exactly that bug —
       don't. The page now inherits container-fluid's box untouched, so it
       lines up with header/footer at every breakpoint by construction, not
       by keeping two numbers in sync by hand. min-width:0 on every flex/grid
       child below still matters independently of this: it's what keeps a
       long IPv6 string or a long ASN name from pushing the document wider
       than the (now 1400px) viewport column. */
    color: var(--ipd-ink);
}

.ipd-page *,
.ipd-page *::before,
.ipd-page *::after {
    box-sizing: border-box;
}

/* Visually hidden but announced by screen readers. `.sr-only` is NOT a global
   utility in this codebase — it is defined only in css/landing.css (not loaded
   on this page) and page-scoped in css/blog.css. Same page-scoped treatment
   here rather than adding a fourth definition to a shared stylesheet. */
.ipd-page .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ---------------------------------------------------------------- 1. Crumbs */

.ipd-page .ipd-crumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin: 14px 0 10px;
    font-size: 13px;
    color: var(--ipd-ink-soft);
    min-width: 0;
}

.ipd-page .ipd-crumbs a {
    color: var(--ipd-ink-soft);
    text-decoration: none;
}

.ipd-page .ipd-crumbs a:hover {
    color: var(--app-primary, #2158d8);
    text-decoration: underline;
}

.ipd-page .ipd-crumbs .ipd-crumb-sep {
    color: var(--ipd-ink-faint);
}

.ipd-page .ipd-crumbs .ipd-crumb-current {
    color: var(--ipd-ink);
    font-weight: 600;
    font-family: var(--num-font, "Courier New", ui-monospace, monospace);
    overflow-wrap: anywhere;
    min-width: 0;
}

/* --------------------------------------------------------- 2. Lookup (quiet)
   The old quick-search was a full-width saturated gradient band — the loudest
   thing on a page whose job is to answer a question (UX_PAGE_STANDARD.md §6:
   "chrome must not be the loudest element"). Same function, one quiet row. */

.ipd-page .ipd-lookup {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    margin-bottom: var(--ipd-gap);
    background: var(--ipd-surface);
    border: 1px solid var(--ipd-border);
    border-radius: var(--ipd-radius);
    min-width: 0;
}

.ipd-page .ipd-lookup-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ipd-ink-soft);
    white-space: nowrap;
}

.ipd-page .ipd-lookup-form {
    display: flex;
    flex: 1 1 260px;
    gap: 8px;
    min-width: 0;
}

.ipd-page .ipd-lookup-input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 9px 12px;
    font-size: 14px;
    font-family: var(--num-font, "Courier New", ui-monospace, monospace);
    color: var(--ipd-ink);
    background: var(--ipd-surface);
    border: 1px solid var(--app-border-strong, #c9d2e0);
    border-radius: 8px;
}

.ipd-page .ipd-lookup-input:focus {
    outline: none;
    border-color: var(--app-primary, #2158d8);
    box-shadow: 0 0 0 3px rgba(33, 88, 216, .12);
}

.ipd-page .ipd-lookup-btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 9px 16px;
    font-size: 14px;
    font-weight: 600;
    color: #fff;
    background: var(--brand-gradient, linear-gradient(135deg, #2158d8 0%, #0e7490 100%));
    border: none;
    border-radius: 8px;
    cursor: pointer;
    white-space: nowrap;
}

.ipd-page .ipd-lookup-btn:hover {
    filter: brightness(1.06);
}

/* ------------------------------------------------------------------ 3. Hero
   The answer. h1 names the IP (the page's unique subject); the verdict line
   states the finding in one plain sentence; the risk meter appears ONLY when
   there is something to score. */

.ipd-page .ipd-hero {
    padding: 22px var(--card-pad, 20px);
    margin-bottom: var(--ipd-gap);
    background: var(--ipd-surface);
    border: 1px solid var(--ipd-border);
    border-radius: var(--ipd-radius);
    box-shadow: var(--ipd-shadow);
    min-width: 0;
}

.ipd-page .ipd-hero-top {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 18px;
    min-width: 0;
}

.ipd-page .ipd-hero-main {
    flex: 1 1 300px;
    min-width: 0;
}

.ipd-page .ipd-h1 {
    margin: 0 0 4px;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--ipd-ink-soft);
    min-width: 0;
}

.ipd-page .ipd-h1 .ipd-ip {
    display: block;
    margin-top: 2px;
    font-size: 30px;
    font-weight: 700;
    letter-spacing: -.4px;
    color: var(--ipd-ink);
    font-family: var(--num-font, "Courier New", ui-monospace, monospace);
    /* IPv6 is 39 chars — it MUST be allowed to break, or it alone widens the
       document past a 360px viewport. */
    overflow-wrap: anywhere;
    word-break: break-word;
}

.ipd-page .ipd-verdict {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 14px 0 0;
    padding: 12px 14px;
    border-radius: 8px;
    border-left: 4px solid currentColor;
    font-size: 15px;
    font-weight: 700;
    line-height: 1.45;
    min-width: 0;
}

.ipd-page .ipd-verdict svg {
    flex: 0 0 auto;
    margin-top: 1px;
}

.ipd-page .ipd-verdict-blocked {
    background: var(--ipd-danger-bg);
    color: var(--ipd-danger-ink);
}

.ipd-page .ipd-verdict-recorded {
    background: var(--ipd-info-bg);
    color: var(--ipd-info-ink);
}

.ipd-page .ipd-verdict-none {
    background: var(--ipd-muted);
    color: var(--n-700, #3a4657);
}

.ipd-page .ipd-verdict-note {
    margin: 10px 0 0;
    font-size: 13.5px;
    line-height: 1.6;
    color: var(--ipd-ink-soft);
    max-width: 68ch;
}

/* Risk meter — replaces the bare 36px number floated to the right, which had
   no scale to read it against. */
.ipd-page .ipd-risk {
    flex: 0 0 auto;
    width: 210px;
    max-width: 100%;
    min-width: 0;
    padding: 12px 14px;
    background: var(--ipd-muted);
    border-radius: 8px;
}

.ipd-page .ipd-risk-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--ipd-ink-soft);
}

.ipd-page .ipd-risk-value {
    display: flex;
    align-items: baseline;
    gap: 4px;
    margin: 2px 0 8px;
    font-family: var(--num-font, "Courier New", ui-monospace, monospace);
    font-variant-numeric: tabular-nums;
}

.ipd-page .ipd-risk-num {
    font-size: 34px;
    font-weight: 700;
    line-height: 1;
}

.ipd-page .ipd-risk-den {
    font-size: 13px;
    color: var(--ipd-ink-faint);
}

.ipd-page .ipd-risk-track {
    height: 7px;
    border-radius: 4px;
    background: var(--app-border-strong, #c9d2e0);
    overflow: hidden;
}

.ipd-page .ipd-risk-fill {
    height: 100%;
    border-radius: 4px;
}

.ipd-page .ipd-risk-foot {
    margin-top: 7px;
    font-size: 11.5px;
    line-height: 1.4;
    color: var(--ipd-ink-soft);
}

.ipd-page .ipd-risk-high .ipd-risk-num { color: #dc2626; }
.ipd-page .ipd-risk-high .ipd-risk-fill { background: #dc2626; }
.ipd-page .ipd-risk-med .ipd-risk-num { color: #d97706; }
.ipd-page .ipd-risk-med .ipd-risk-fill { background: #d97706; }
.ipd-page .ipd-risk-low .ipd-risk-num { color: #059669; }
.ipd-page .ipd-risk-low .ipd-risk-fill { background: #059669; }

/* Block detail — key/value pairs. The old markup used
   `grid-template-columns: 150px 1fr`, a fixed track that could not shrink:
   at 360px that single rule was the page's real horizontal-overflow source. */
.ipd-page .ipd-blockinfo {
    margin-top: 14px;
    padding: 14px;
    background: var(--ipd-warn-bg);
    border-left: 4px solid #f59e0b;
    border-radius: 8px;
    min-width: 0;
}

.ipd-page .ipd-blockinfo-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
    font-size: 14px;
    font-weight: 700;
    color: var(--ipd-warn-ink);
    min-width: 0;
}

.ipd-page .ipd-kv {
    display: grid;
    grid-template-columns: minmax(0, 150px) minmax(0, 1fr);
    gap: 6px 14px;
    margin: 0;
    font-size: 13px;
    line-height: 1.55;
    color: var(--ipd-warn-ink);
    min-width: 0;
}

.ipd-page .ipd-kv dt {
    font-weight: 700;
    min-width: 0;
    overflow-wrap: anywhere;
}

.ipd-page .ipd-kv dd {
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
}

.ipd-page .ipd-kv .ipd-kv-faint {
    color: var(--ipd-ink-faint);
    font-size: 11px;
}

/* ------------------------------------------------------- 4. Section + cards */

.ipd-page .ipd-section {
    margin-bottom: var(--space-section, 24px);
    min-width: 0;
}

.ipd-page .ipd-h2 {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 4px;
    padding: 0;
    font-size: 17px;
    font-weight: 700;
    line-height: 1.35;
    color: var(--ipd-ink);
    min-width: 0;
}

.ipd-page .ipd-h2 svg {
    flex: 0 0 auto;
    color: var(--ipd-ink-soft);
}

.ipd-page .ipd-h3 {
    margin: 0 0 10px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--ipd-ink-soft);
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.ipd-page .ipd-sub {
    margin: 0 0 12px;
    font-size: 13px;
    line-height: 1.55;
    color: var(--ipd-ink-soft);
    max-width: 72ch;
}

.ipd-page .ipd-card {
    padding: var(--card-pad, 16px);
    background: var(--ipd-surface);
    border: 1px solid var(--ipd-border);
    border-radius: var(--ipd-radius);
    box-shadow: var(--ipd-shadow);
    min-width: 0;
}

/* --------------------------------------------------------- 5. Network block */

.ipd-page .ipd-net-headline {
    margin: 0 0 10px;
    font-size: 18px;
    font-weight: 700;
    line-height: 1.4;
    color: var(--ipd-ink);
    overflow-wrap: anywhere;
    min-width: 0;
}

.ipd-page .ipd-net-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
    min-width: 0;
}

.ipd-page .ipd-net-explain {
    margin: 0;
    font-size: 14px;
    line-height: 1.65;
    color: var(--n-700, #3a4657);
    max-width: 72ch;
}

/* Provenance — the trust asset. Was 11px grey fine print in a <table> that
   itself overflowed at 360px; now a wrapping definition list at a readable
   size, because "we tell you where every field came from and when" is the
   single most credible thing this page says. */
.ipd-page .ipd-prov {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--ipd-border);
    min-width: 0;
}

/* Exactly 5 provenance fields (geo, ASN, mobile, proxy, hosting) — a FIXED
   count, so the column count is declared per breakpoint rather than left to
   auto-fit. auto-fit with minmax(240px,1fr) resolved to 4 columns in the
   ~1120px container and dropped the 5th card onto a row of its own with a
   three-quarter-width void beside it: the exact lone-orphan tile
   UX_PAGE_STANDARD.md §5 forbids. 5 → 3+2 → 1 never leaves a single card
   stranded next to empty space. */
.ipd-page .ipd-prov-list {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 10px;
    margin: 0;
    min-width: 0;
}

.ipd-page .ipd-prov-item {
    padding: 9px 11px;
    background: var(--n-25, #f9fbfd);
    border: 1px solid var(--ipd-border);
    border-radius: 8px;
    min-width: 0;
}

.ipd-page .ipd-prov-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .4px;
    text-transform: uppercase;
    color: var(--ipd-ink-soft);
}

.ipd-page .ipd-prov-value {
    margin: 2px 0 4px;
    font-size: 14px;
    font-weight: 600;
    color: var(--ipd-ink);
    overflow-wrap: anywhere;
    min-width: 0;
}

.ipd-page .ipd-prov-value-danger { color: var(--ipd-danger-ink); }
.ipd-page .ipd-prov-value-warning { color: var(--ipd-warn-ink); }
.ipd-page .ipd-prov-value-no { color: var(--ipd-ok-ink); }
.ipd-page .ipd-prov-value-unknown { color: var(--ipd-ink-faint); font-weight: 500; }

.ipd-page .ipd-prov-src {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 8px;
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--ipd-ink-faint);
    min-width: 0;
}

.ipd-page .ipd-prov-src code {
    font-family: var(--num-font, "Courier New", ui-monospace, monospace);
    overflow-wrap: anywhere;
    min-width: 0;
}

.ipd-page .ipd-prov-note {
    margin: 12px 0 0;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--ipd-ink-soft);
    max-width: 72ch;
}

/* --------------------------------------------------------------- 6. Stats */

.ipd-page .ipd-stats {
    display: grid;
    /* 4 tiles → 4/2/1 columns. Never a lone orphan tile on its own row
       (UX_PAGE_STANDARD.md §5). */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
    min-width: 0;
}

.ipd-page .ipd-stats-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.ipd-page .ipd-stat {
    padding: 13px 14px;
    background: var(--n-25, #f9fbfd);
    border: 1px solid var(--ipd-border);
    border-left: 4px solid var(--app-primary, #2158d8);
    border-radius: 8px;
    min-width: 0;
}

.ipd-page .ipd-stat-danger { border-left-color: #dc2626; }
.ipd-page .ipd-stat-ok { border-left-color: #059669; }

.ipd-page .ipd-stat-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .4px;
    text-transform: uppercase;
    color: var(--ipd-ink-soft);
    line-height: 1.35;
}

.ipd-page .ipd-stat-value {
    margin-top: 4px;
    font-size: 22px;
    font-weight: 700;
    line-height: 1.2;
    color: var(--ipd-ink);
    font-family: var(--num-font, "Courier New", ui-monospace, monospace);
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
    min-width: 0;
}

.ipd-page .ipd-stat-sub {
    margin-top: 2px;
    font-size: 11.5px;
    color: var(--ipd-ink-faint);
}

/* ------------------------------------------------------- 7. Distribution bar */

.ipd-page .ipd-dist {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
    gap: 20px;
    min-width: 0;
}

.ipd-page .ipd-dist-row {
    margin-bottom: 9px;
    min-width: 0;
}

.ipd-page .ipd-dist-head {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 4px;
    font-size: 13px;
    min-width: 0;
}

.ipd-page .ipd-dist-name {
    font-weight: 600;
    overflow-wrap: anywhere;
    min-width: 0;
}

.ipd-page .ipd-dist-count {
    flex: 0 0 auto;
    color: var(--ipd-ink-soft);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.ipd-page .ipd-dist-track {
    height: 7px;
    background: var(--app-border-strong, #c9d2e0);
    border-radius: 4px;
    overflow: hidden;
}

.ipd-page .ipd-dist-fill {
    height: 100%;
    background: var(--app-primary, #2158d8);
    border-radius: 4px;
}

.ipd-page .ipd-dist-fill-b { background: var(--cyan-600, #0e7490); }
.ipd-page .ipd-dist-fill-c { background: #d97706; }

/* -------------------------------------------------------------- 8. Hour chart
   24 bars. The old version absolutely-positioned a label under every bar; at
   360px each bar is ~8px wide and the "23h" label was 3× wider than its bar,
   which is what made the chart itself overflow. Labels now live in their own
   grid row and thin out on narrow screens. */

.ipd-page .ipd-hours {
    min-width: 0;
}

.ipd-page .ipd-hours-bars {
    display: grid;
    grid-template-columns: repeat(24, minmax(0, 1fr));
    align-items: end;
    gap: 3px;
    height: 130px;
    min-width: 0;
}

.ipd-page .ipd-hour-bar {
    min-width: 0;
    min-height: 2px;
    background: var(--app-primary, #2158d8);
    border-radius: 3px 3px 0 0;
}

.ipd-page .ipd-hour-bar-peak {
    background: var(--cyan-600, #0e7490);
}

.ipd-page .ipd-hours-axis {
    display: grid;
    grid-template-columns: repeat(24, minmax(0, 1fr));
    gap: 3px;
    margin-top: 5px;
    font-size: 10px;
    color: var(--ipd-ink-faint);
    text-align: center;
    min-width: 0;
}

.ipd-page .ipd-hours-axis span {
    min-width: 0;
    overflow: hidden;
}

.ipd-page .ipd-hours-caption {
    margin: 10px 0 0;
    font-size: 12.5px;
    color: var(--ipd-ink-soft);
    text-align: center;
}

/* ------------------------------------------------------------- 9. <details> */

.ipd-page .ipd-details {
    background: var(--ipd-surface);
    border: 1px solid var(--ipd-border);
    border-radius: var(--ipd-radius);
    box-shadow: var(--ipd-shadow);
    min-width: 0;
}

.ipd-page .ipd-details > summary {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px var(--card-pad, 16px);
    cursor: pointer;
    list-style: none;
    min-width: 0;
}

.ipd-page .ipd-details > summary::-webkit-details-marker {
    display: none;
}

.ipd-page .ipd-details > summary::after {
    content: "";
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    margin-left: auto;
    border-right: 2px solid var(--ipd-ink-faint);
    border-bottom: 2px solid var(--ipd-ink-faint);
    transform: rotate(45deg) translate(-2px, -2px);
}

.ipd-page .ipd-details[open] > summary::after {
    transform: rotate(-135deg) translate(-2px, -2px);
}

.ipd-page .ipd-details > summary .ipd-h2 {
    margin: 0;
    min-width: 0;
}

.ipd-page .ipd-details-body {
    padding: 0 var(--card-pad, 16px) var(--card-pad, 16px);
    min-width: 0;
}

.ipd-page .ipd-details-note {
    margin: 0 0 14px;
    padding: 10px 12px;
    background: var(--ipd-info-bg);
    color: var(--ipd-info-ink);
    border-radius: 8px;
    font-size: 12.5px;
    line-height: 1.6;
    max-width: 78ch;
}

/* ---------------------------------------------------------- 10. Rule rows */

.ipd-page .ipd-rules {
    display: grid;
    gap: 8px;
    min-width: 0;
}

.ipd-page .ipd-rule {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 12px;
    padding: 10px 12px;
    border: 1px solid var(--ipd-border);
    border-radius: 8px;
    background: var(--n-25, #f9fbfd);
    min-width: 0;
}

.ipd-page .ipd-rule-hit {
    background: var(--ipd-danger-bg);
    border-color: #fca5a5;
}

.ipd-page .ipd-rule-main {
    flex: 1 1 200px;
    min-width: 0;
}

.ipd-page .ipd-rule-name {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--n-700, #3a4657);
    overflow-wrap: anywhere;
    min-width: 0;
}

.ipd-page .ipd-rule-hit .ipd-rule-name {
    color: var(--ipd-danger-ink);
}

.ipd-page .ipd-rule-why {
    margin-top: 3px;
    font-size: 12px;
    color: var(--ipd-ink-soft);
    overflow-wrap: anywhere;
    min-width: 0;
}

.ipd-page .ipd-rule-score {
    flex: 0 0 auto;
    text-align: right;
    font-family: var(--num-font, "Courier New", ui-monospace, monospace);
    font-variant-numeric: tabular-nums;
    font-size: 16px;
    font-weight: 700;
    color: var(--ipd-ink-faint);
}

.ipd-page .ipd-rule-hit .ipd-rule-score {
    color: var(--ipd-danger-ink);
}

.ipd-page .ipd-rule-auto {
    display: block;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .3px;
    color: var(--ipd-danger-ink);
}

/* ------------------------------------------------------------ 11. Timeline */

.ipd-page .ipd-click {
    padding: 13px 14px;
    margin-bottom: 10px;
    background: var(--n-25, #f9fbfd);
    border: 1px solid var(--ipd-border);
    border-radius: 8px;
    min-width: 0;
}

.ipd-page .ipd-click-blocked {
    background: var(--ipd-danger-bg);
    border-color: #fca5a5;
}

.ipd-page .ipd-click-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 10px;
    min-width: 0;
}

.ipd-page .ipd-click-time {
    font-weight: 700;
    font-size: 13.5px;
    min-width: 0;
}

.ipd-page .ipd-click-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    min-width: 0;
}

.ipd-page .ipd-click-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 165px), 1fr));
    gap: 9px;
    font-size: 13px;
    min-width: 0;
}

.ipd-page .ipd-click-cell {
    min-width: 0;
}

.ipd-page .ipd-click-label {
    display: block;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .3px;
    text-transform: uppercase;
    color: var(--ipd-ink-soft);
}

.ipd-page .ipd-click-val {
    display: block;
    font-weight: 500;
    color: var(--ipd-ink);
    overflow-wrap: anywhere;
    min-width: 0;
}

.ipd-page .ipd-click-ua {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--ipd-border);
    font-size: 11.5px;
    color: var(--ipd-ink-soft);
    overflow-wrap: anywhere;
    min-width: 0;
}

/* Click-log render cap notice — see CLICK_RENDER_CAP in ip-detail.php. */
.ipd-page .ipd-truncate {
    margin: 0 0 12px;
    padding: 9px 12px;
    background: var(--ipd-muted);
    border-radius: 8px;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--ipd-ink-soft);
    min-width: 0;
}

.ipd-page .ipd-truncate a {
    color: var(--app-primary, #2158d8);
    font-weight: 600;
    text-decoration: none;
}

.ipd-page .ipd-truncate a:hover {
    text-decoration: underline;
}

/* --------------------------------------------------------------- 12. Notice */

.ipd-page .ipd-notice {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 10px;
    padding: 15px 16px;
    border-radius: 8px;
    border-left: 4px solid currentColor;
    font-size: 13.5px;
    line-height: 1.6;
    min-width: 0;
}

.ipd-page .ipd-notice svg {
    flex: 0 0 auto;
    margin-top: 2px;
}

.ipd-page .ipd-notice-body {
    flex: 1 1 240px;
    min-width: 0;
}

.ipd-page .ipd-notice-info {
    background: var(--ipd-info-bg);
    color: var(--ipd-info-ink);
}

.ipd-page .ipd-notice-warn {
    background: var(--ipd-warn-bg);
    color: var(--ipd-warn-ink);
}

.ipd-page .ipd-notice-muted {
    background: var(--ipd-muted);
    color: var(--n-700, #3a4657);
}

/* ------------------------------------------------------------------ 13. CTA
   Deliberately different from the global .floating-auth-buttons bar (fixed,
   generic register/login, present on every logged-out page): this one is
   in-flow, appears once at the end of the answer, is written about the IP the
   visitor just looked up, and leads with EXPLORE (live demo) — an action the
   floating bar does not offer at all. */

.ipd-page .ipd-cta {
    padding: 24px var(--card-pad, 20px);
    background: var(--brand-gradient, linear-gradient(135deg, #2158d8 0%, #0e7490 100%));
    border-radius: var(--ipd-radius);
    color: #fff;
    min-width: 0;
}

.ipd-page .ipd-cta-title {
    margin: 0 0 8px;
    font-size: 19px;
    font-weight: 700;
    line-height: 1.35;
    color: #fff;
    min-width: 0;
}

.ipd-page .ipd-cta-text {
    margin: 0 0 16px;
    font-size: 14px;
    line-height: 1.65;
    color: rgba(255, 255, 255, .92);
    max-width: 68ch;
}

.ipd-page .ipd-cta-points {
    margin: 0 0 18px;
    padding: 0;
    list-style: none;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
    gap: 8px 18px;
    min-width: 0;
}

.ipd-page .ipd-cta-points li {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 13.5px;
    line-height: 1.55;
    color: rgba(255, 255, 255, .92);
    min-width: 0;
}

.ipd-page .ipd-cta-points svg {
    flex: 0 0 auto;
    margin-top: 2px;
}

.ipd-page .ipd-cta-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    min-width: 0;
}

.ipd-page .ipd-cta-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 11px 20px;
    border-radius: 8px;
    font-size: 14.5px;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
}

.ipd-page .ipd-cta-btn-solid {
    background: #fff;
    color: var(--brand-700, #1a45ab);
}

.ipd-page .ipd-cta-btn-solid:hover {
    background: rgba(255, 255, 255, .9);
}

.ipd-page .ipd-cta-btn-ghost {
    background: rgba(255, 255, 255, .12);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, .55);
}

.ipd-page .ipd-cta-btn-ghost:hover {
    background: rgba(255, 255, 255, .22);
}

.ipd-page .ipd-cta-fine {
    margin: 14px 0 0;
    font-size: 12px;
    line-height: 1.55;
    color: rgba(255, 255, 255, .78);
    max-width: 68ch;
}

/* ------------------------------------------------- 13b. Lookup home (state 0)
   /ip-detail with no ?ip= — the breadcrumb target the detail page links back
   to. It previously carried its own inline <style> block (white slab + a
   saturated #667eea→#764ba2 purple gradient card) that matched nothing else
   here or in the light app system. It now reuses this file's tokens and, where
   the markup is genuinely the same thing, this file's classes
   (.ipd-lookup-input / .ipd-lookup-btn / .ipd-prov-item / .ipd-cta-*). */

/* .ipd-page itself no longer caps its own width (see the comment on
   .ipd-page above) — it now spans the full 1400px container-fluid column,
   same as header/footer. That's correct for the breadcrumb/outer edge on
   both states, but the home state's content (search hero + the 3 sections
   below it: features / visitor-info / CTA) reads badly stretched across
   1400px when it's really just a search box and a couple of 4-card grids.
   So the width cap moves down one level, applied ONLY to home-state content
   via the `.ipd-home` ancestor class (ip-detail.php:141) — same 1120px this
   page always used, just scoped correctly instead of forced onto the whole
   page (which also broke alignment with header/footer — that was the bug).
   `.ipd-section` also appears in the result state (state 0's sibling, below
   line ~910) but without an `.ipd-home` ancestor there, so this selector
   does not reach it — the result state intentionally keeps the full-width
   column (more room for stat grids / tables), per the task spec. */
.ipd-page.ipd-home .ipd-hero,
.ipd-page.ipd-home .ipd-section {
    max-width: 1120px;
    margin-left: auto;
    margin-right: auto;
}

.ipd-page .ipd-home-hero {
    padding: 30px var(--card-pad, 20px);
    text-align: center;
}

.ipd-page .ipd-home-h1 {
    margin: 0 0 8px;
    font-size: 28px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--ipd-ink);
    min-width: 0;
}

.ipd-page .ipd-home-lead {
    margin: 0 auto 20px;
    max-width: 62ch;
    font-size: 14.5px;
    line-height: 1.65;
    color: var(--ipd-ink-soft);
}

.ipd-page .ipd-home-form {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    max-width: 620px;
    margin: 0 auto;
    min-width: 0;
}

.ipd-page .ipd-home-input {
    flex: 1 1 240px;
    padding: 13px 16px;
    font-size: 15px;
}

.ipd-page .ipd-home-btn {
    flex: 0 0 auto;
    padding: 13px 24px;
    font-size: 15px;
}

/* 4 tiles → 4/2/1. Never 3+1 (UX_PAGE_STANDARD.md §5). */
.ipd-page .ipd-home-features {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
    min-width: 0;
}

.ipd-page .ipd-home-feature {
    padding: 16px;
    background: var(--ipd-surface);
    border: 1px solid var(--ipd-border);
    border-radius: var(--ipd-radius);
    box-shadow: var(--ipd-shadow);
    min-width: 0;
}

.ipd-page .ipd-home-feature > svg {
    color: var(--app-primary, #2158d8);
}

.ipd-page .ipd-home-feature-title {
    margin: 8px 0 4px;
    font-size: 14.5px;
    font-weight: 700;
    line-height: 1.35;
    color: var(--ipd-ink);
    min-width: 0;
}

.ipd-page .ipd-home-feature-desc {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--ipd-ink-soft);
}

/* 4 visitor facts → 4/2/1, same rule, reusing .ipd-prov-item as the tile. */
.ipd-page .ipd-home-visitor {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    min-width: 0;
}

.ipd-page .ipd-home-visitor-ip {
    font-family: var(--num-font, "Courier New", ui-monospace, monospace);
}

@media (max-width: 767px) {
    .ipd-page .ipd-home-features,
    .ipd-page .ipd-home-visitor {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .ipd-page .ipd-home-h1 {
        font-size: 22px;
    }

    .ipd-page .ipd-home-btn {
        flex: 1 1 100%;
        justify-content: center;
    }
}

/* ------------------------------------------------------------- 14. Manage */

.ipd-page .ipd-manage-form {
    max-width: 520px;
    min-width: 0;
}

.ipd-page .ipd-field {
    margin-bottom: 14px;
    min-width: 0;
}

.ipd-page .ipd-field label {
    display: block;
    margin-bottom: 5px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ipd-ink);
}

.ipd-page .ipd-field input,
.ipd-page .ipd-field textarea {
    width: 100%;
    max-width: 100%;
    min-width: 0;
    padding: 9px 12px;
    font-size: 14px;
    font-family: inherit;
    color: var(--ipd-ink);
    border: 1px solid var(--app-border-strong, #c9d2e0);
    border-radius: 8px;
}

.ipd-page .ipd-field input[type="number"] {
    max-width: 160px;
}

.ipd-page .ipd-manage-links {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--ipd-border);
    min-width: 0;
}

/* Admin debug — the one place a wide table is legitimate. It scrolls INSIDE
   its own box so it can never widen the document. */
.ipd-page .ipd-debug {
    padding: 16px;
    background: #1f2733;
    border-radius: var(--ipd-radius);
    color: #aed581;
    font-family: var(--num-font, "Courier New", ui-monospace, monospace);
    font-size: 12.5px;
    min-width: 0;
}

.ipd-page .ipd-debug-scroll {
    max-height: 400px;
    overflow: auto;
    background: #161c25;
    border-radius: 8px;
    padding: 12px;
    min-width: 0;
}

.ipd-page .ipd-debug-scroll table {
    border-collapse: collapse;
    font-size: 12.5px;
}

.ipd-page .ipd-debug-scroll th,
.ipd-page .ipd-debug-scroll td {
    padding: 6px 8px;
    text-align: left;
    white-space: nowrap;
    border-bottom: 1px solid #37424f;
}

.ipd-page .ipd-debug-scroll thead th {
    color: #ffe082;
    background: #2b3543;
}

.ipd-page .ipd-debug pre {
    margin: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* ============================ Responsive =================================== */

@media (max-width: 1023px) {
    .ipd-page .ipd-risk {
        width: 100%;
    }

    .ipd-page .ipd-prov-list {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 767px) {
    /* container-fluid's padding:0 10px (style.css) is fine at desktop width
       where 10px is a rounding error next to 1400px of content, but at phone
       widths it reads as the page being shoved into the corner (reported
       bug: "mobile bị sát lề"). Same specificity as container-fluid's
       .container-fluid rule, but this appears later in the cascade (and only
       applies when the media query matches), so it wins here without
       touching container-fluid itself or any other page that shares it.
       15px reuses landing.css's own mobile gutter (landing.css:486,
       `50px 15px` at this same 767px breakpoint) rather than inventing a new
       number. */
    .ipd-page {
        padding: 0 15px;
    }

    .ipd-page .ipd-stats,
    .ipd-page .ipd-stats-3 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .ipd-page .ipd-h1 .ipd-ip {
        font-size: 24px;
    }

    .ipd-page .ipd-hero-top {
        gap: 14px;
    }

    .ipd-page .ipd-lookup-label {
        flex: 1 1 100%;
    }

    /* 2 columns would leave 5 cards as 2+2+1 — a lone orphan again. One
       column below 768px, which also gives a long ASN name room to breathe. */
    .ipd-page .ipd-prov-list {
        grid-template-columns: minmax(0, 1fr);
    }

    /* 24 labels cannot fit; show every 3rd. */
    .ipd-page .ipd-hours-axis span:not(.ipd-hour-tick-major) {
        visibility: hidden;
    }
}

@media (max-width: 479px) {
    /* Tighter than the 767px gutter above — 12px reuses blog.css's own
       narrow-phone floor (blog.css:80-82, the `clamp()` padding on .blogidx
       bottoms out at 12px), not a new number. */
    .ipd-page {
        padding: 0 12px;
    }

    .ipd-page .ipd-kv {
        grid-template-columns: minmax(0, 1fr);
        gap: 2px;
    }

    .ipd-page .ipd-kv dt {
        margin-top: 8px;
    }

    .ipd-page .ipd-kv dt:first-child {
        margin-top: 0;
    }

    .ipd-page .ipd-stats,
    .ipd-page .ipd-stats-3 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .ipd-page .ipd-h1 .ipd-ip {
        font-size: 20px;
    }

    .ipd-page .ipd-cta-btn {
        flex: 1 1 100%;
        justify-content: center;
    }
}
