.dns-explorer { max-width: 100%; }
/* PIX-VIS-019: the domain field is capped at --field-w-wide instead of
   growing to fill 1fr, so it stops being a different (and wider) width
   than the quick-lookup field below on the same page. */
/* PIX-VIS-011 round 2: `align-items: end` bottom-aligns each grid item's
   whole box (label + field together) to the row's tallest column. If the
   two <div> columns ever render at even slightly different total heights
   (a native select can render a touch shorter than a text input despite
   identical CSS box values), the shorter column's LABEL shifts down with
   it -- which is exactly the "RECORD TYPE sits ~3px lower than DOMAIN
   NAME" symptom. `align-items: stretch` plus each column as its own
   flex-column (label on top, field given `flex: 1`) keeps every label on
   the same top edge regardless of field height, and the field itself
   still fills down to the row's full height so the *bottom* edges (and
   the button next to them) line up too. */
.dns-trace-form { display: grid; grid-template-columns: minmax(12rem, var(--field-w-wide)) minmax(7rem, auto) auto; gap: 12px; align-items: stretch; }
.dns-trace-form > div { display: flex; flex-direction: column; }
.dns-trace-form label { display: block; margin-bottom: 4px; }
.dns-trace-form input, .dns-trace-form select {
    width: 100%;
    max-width: none;
    box-sizing: border-box;
    flex: 1;
    /* The shared style.css field rule adds margin-bottom: 16px for stacked
       page layout; inside this grid row that margin ate into the row's own
       height budget and pushed the shorter column further, compounding the
       align-items misalignment above. The grid's own `gap` already spaces
       this form from whatever follows it. */
    margin-bottom: 0;
}
.dns-trace-form button {
    /* Direct grid child, no label row above it -- align-self: end keeps its
       bottom edge level with the input/select bottoms without needing an
       empty label placeholder (which would be new, invisible-but-still-a11y
       -relevant markup for no visible benefit). The base `button` rule's
       margin-top: 14px is a stacked-layout assumption that does not apply
       inside this grid row and was the other reason it rendered lower. */
    align-self: end;
    margin-top: 0;
}
/* Quick DNS lookup field: same field width as the trace form's domain
   field above (PIX-VIS-019), instead of the shared .input-row default
   of --field-w used by every other single-field tool. */
.dns-explorer .input-row .input-flex { max-width: var(--field-w-wide); }
/* PIX-VIS-021: a single horizontally-scrollable strip on narrow screens
   instead of wrapping onto several rows (was up to three rows at 390px). */
.dns-tabs { display: flex; flex-wrap: nowrap; gap: 8px; margin: 1.25rem 0 1rem; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.dns-tab { flex: 0 0 auto; white-space: nowrap; background: var(--surface-2); color: var(--text-dim); border: 1px solid var(--border); border-radius: var(--radius); padding: 6px 14px; cursor: pointer; font: inherit; }
.dns-tab[aria-selected="true"] { color: var(--text-bright); border-color: var(--text); box-shadow: 0 0 6px var(--glow); }
.dns-status-banner, .dns-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: .75rem 1rem; margin: 1rem 0; }
.dns-status-badge { font-weight: bold; white-space: nowrap; }
.dns-status-badge span:first-child { display: inline-block; min-width: 1.2em; }
.dns-summary { display: grid; grid-template-columns: minmax(12rem, max-content) 1fr; gap: 6px 16px; }
.dns-summary dt, .dns-card dt { color: var(--text-dim); }
.dns-summary dd, .dns-card dd { margin: 0; overflow-wrap: anywhere; }
/*
    A CSS-grid item does not shrink below its content's own min-content width
    by default (min-width: auto), no matter how narrow its track is. The
    Overview tab's "Final answer" dd holds a whole .dns-table-wrap table, and
    the "Authoritative nameservers" dd holds a comma-joined hostname list --
    both wide enough that, without this, the WHOLE PAGE was forced wider than
    the viewport (+293px at 390px) instead of the value wrapping or the
    table's own overflow-x: auto ever getting the chance to engage
    (PIX-VIS-006). Same fix as .db-side in diff.css, grid's version of it.
*/
.dns-summary dd { min-width: 0; }
.dns-table-wrap { overflow-x: auto; max-width: 100%; }
/*
    width: auto + min-width: 100% instead of width: 100%: a forced 100% makes
    the browser divide that width evenly across columns no matter how much
    content they hold, which is what squeezed "Owner" into "Owne|r" and "TTL"
    into "T|T|L" on desktop and split addresses like 198.41.0.4 into separate
    lines. With auto sizing the table only grows past its container when its
    content needs to, and .dns-table-wrap (overflow-x: auto) scrolls the rest
    (PIX-VIS-006). This used to be a max-width: 640px-only fix; the desktop
    squeeze was the same bug, just not narrow enough to trigger it before.
*/
.dns-table-wrap table { width: auto; min-width: 100%; border-collapse: collapse; margin: .5rem 0 1rem; }
.dns-table-wrap th, .dns-table-wrap td { border: 1px solid var(--border); padding: 5px 8px; text-align: left; vertical-align: top; }
.dns-table-wrap th { white-space: nowrap; }
.dns-table-wrap td { white-space: normal; overflow-wrap: break-word; min-width: 5rem; max-width: 18rem; }
/* An address is never readable across line breaks, so it does not break: the
   column widens to fit it (inside the scrollable wrapper) instead. */
.dns-table-wrap td li { white-space: nowrap; }
.dns-timeline { list-style: none; margin: 1rem 0; padding: 0 0 0 1.5rem; border-left: 2px solid var(--border); }
.dns-timeline > li { position: relative; padding: 0 0 1rem 1rem; }
.dns-timeline > li::before { content: ''; position: absolute; left: -1.93rem; top: .4rem; width: .7rem; height: .7rem; border: 2px solid var(--text-bright); border-radius: 50%; background: var(--surface); }
.dns-graph-scroll { overflow-x: auto; width: 100%; }
.dns-graph { display: block; min-width: 760px; width: 900px; height: auto; }
.dns-graph rect { fill: var(--surface-2); stroke: var(--border); }
.dns-graph text { fill: var(--text-bright); text-anchor: middle; dominant-baseline: middle; }
.dns-graph line { stroke: var(--text-dim); stroke-width: 2; }
.dns-graph-arrowhead { fill: var(--text-dim); }
.dns-graph-edge { stroke: var(--text-dim); stroke-width: 2; fill: none; }
.dns-graph-edge-branch { stroke: var(--border); }
.dns-graph-edge-dnssec { stroke: var(--text-bright); stroke-dasharray: 4 3; }
/*
    ".dns-graph .dns-graph-edge-label" (two classes) beats ".dns-graph text"
    (one class + one type) on specificity, so this text-anchor: start wins
    over the text-anchor: middle set above for every other label in the
    graph. DS/DNSKEY are the only labelled edges, and their lines run mostly
    vertical, so centring the label on the line (the default) put the text
    on top of the dashed line itself; starting the text to the right of the
    line's own midpoint (dns-graph.blade.php offsets labelX by +8) clears it
    regardless of the line's angle (PIX-VIS-007).
*/
.dns-graph .dns-graph-edge-label { fill: var(--text-bright); text-anchor: start; }
.dns-copy { margin: .5rem .5rem .5rem 0; }
.dns-copy-status { min-height: 1.4em; }
.dns-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; }
.dns-trace-form input:focus-visible, .dns-trace-form select:focus-visible, .dns-explorer button:focus-visible, .dns-tab:focus-visible, .dns-explorer summary:focus-visible, .dns-copy:focus-visible { outline: 2px solid var(--text-bright); outline-offset: 2px; }
/*
    The wrapper must scroll, the way .dns-graph-scroll does, at any width, not
    only a narrow one: with width:100% and overflow-wrap:anywhere the table
    shrank to fit its container even on a 1440px desktop, and every cell
    collapsed towards one character per line -- a nameserver address printed
    vertically, and headers split mid-word ("Quer y st atus" / "T|T|L").
    Giving the table its natural width with a floor per cell (declared with
    .dns-table-wrap table/th/td above) keeps the columns readable at every
    viewport and hands the overflow to .dns-table-wrap, which already has
    overflow-x: auto. This used to be scoped to max-width: 640px only, which
    is why the desktop squeeze (PIX-VIS-006) survived the first pass.

    The list items need their own rule. An address column that only holds a
    <ul> still collapses to the 5rem floor, and 108.162.193.64 then breaks
    into "10 / 8.1 / 62. / 19 / 3.6 / 4" -- the same defect one column further
    along. An address is never readable across line breaks, so it does not
    break: the column widens to fit it and the wrapper scrolls, which is what
    it is for.
*/
@media (max-width: 640px) { .dns-trace-form { grid-template-columns: 1fr; } .dns-trace-form button, .dns-copy { width: 100%; } .dns-summary { grid-template-columns: 1fr; } }
.dns-wire-data { max-width: 100%; overflow-x: auto; }
.dns-wire-data pre { max-width: 100%; overflow-x: auto; overflow-wrap: anywhere; white-space: pre-wrap; }
.dns-table-wrap td ul { margin: 0; padding-left: 1.25rem; }
