/* ==========================================================================
   responsive.css — shared responsive layer for the public + authenticated
   frontend (admin portal excluded).

   Loaded globally from frontend/base.html and frontend/nav.html.

   The frontend is Tailwind-based and mostly mobile-first already, so this
   file deliberately does NOT re-implement layout. It fixes the cross-cutting
   things that actually break below ~1024px:

     1. horizontal page scroll (the single most visible defect)
     2. long unbroken tokens — hashes, IPs, emails, URLs, JWTs
     3. wide data tables with no scroll container
     4. desktop-sized typography / padding / radii on small screens
     5. touch target sizes and iOS input zoom

   Breakpoints match Tailwind's so the two layers agree:
     1024px (lg)  768px (md)  640px (sm)  400px (small phones)
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Kill horizontal page scroll
   Decorative blurred orbs in base.html are absolutely positioned well outside
   the viewport; on desktop they're clipped by width, on mobile they push the
   document wider than the screen.

   Uses `overflow-x: clip`, NOT `hidden`. `hidden` forces the computed
   `overflow-y` to `auto`, and base.html sets `html, body { height: 100% }`, so
   `hidden` turned <body> into a viewport-height nested scroll container on
   every long page: the window stopped scrolling, `window.scrollY` stuck at 0,
   and scroll-anchoring/scrollIntoView inside that inner scroller fought the
   user (the blog page "scrolls back to top" bug). `clip` prevents horizontal
   scroll without establishing a scroll container and without touching
   overflow-y, so the document scrolls normally and `position: sticky` keeps
   working. (overflow: clip — Chrome 90+/Firefox 90+/Safari 16+.) */
html,
body {
    max-width: 100%;
    overflow-x: clip;
}

/* The single most common cause of sideways scroll in this codebase.

   Grid and flex items default to `min-width: auto`, which means they refuse
   to shrink below the intrinsic width of their content. One long hash, one
   nowrap badge or one unbreakable wordmark then sets the floor for the whole
   track and pushes the page wider than the screen — the container looks
   responsive, but it cannot actually shrink.

   `min-width: 0` only permits shrinking; it never forces it, so layouts that
   already fit are unaffected. Restricted to <=1024px so desktop multi-column
   grids keep their existing intrinsic sizing exactly as-is. */
@media (max-width: 1024px) {

    .grid > *,
    .flex > * {
        min-width: 0;
    }
}

/* Note: this deliberately does NOT set grid-template-columns on .grid itself.
   A bare `1fr` track has the same min-width:auto problem, but because this
   file loads last, any such rule would also override every Tailwind
   grid-cols-* utility and collapse real multi-column layouts. Relaxing the
   ITEM minimum above is enough — an auto track minimum is derived from the
   item's min-width, so min-width:0 resolves the track too. */

/* Never let a media element be the thing that overflows. */
img,
svg,
video,
canvas,
iframe {
    max-width: 100%;
}

img,
svg,
video {
    height: auto;
}


/* --------------------------------------------------------------------------
   2. Long unbroken tokens
   Threat-intel pages are full of values with no spaces to break on. Without
   this they blow out their container and drag the whole layout sideways.
   -------------------------------------------------------------------------- */
.mono,
code,
kbd,
samp,
pre {
    overflow-wrap: anywhere;
    word-break: break-word;
}

/* Scoped to the value-bearing elements rather than applied globally, so
   normal prose keeps its usual (nicer) wrapping behaviour. */
.result-hero .rh-value,
[data-copy],
a[href^="mailto:"],
a[href^="http"] {
    overflow-wrap: anywhere;
}

/* Table cells are deliberately EXCLUDED from the rule above, and opt out of
   the .mono rule here.

   Breaking inside a cell lets the table shrink to fit its container, so the
   wrapper never scrolls and the data becomes unreadable instead — an IPv6
   address wraps to one character per line and "AS15169" splits across three.
   Wide tabular data belongs in a horizontal scroller (section 3), not in a
   crushed column. */
td .mono,
th .mono,
td code,
.intel-table td,
.table-custom td {
    overflow-wrap: normal;
    word-break: normal;
}

/* <pre> blocks (API docs, JSON samples) scroll instead of stretching. */
pre {
    overflow-x: auto;
    max-width: 100%;
}


/* --------------------------------------------------------------------------
   3. Wide data tables
   Every data table in the frontend is already inside a scroll container
   (.table-wrap on hash_data, .overflow-x-auto on ip/cve/email/phone,
   .table-responsive on detcview), so the job here is NOT to add scrolling —
   it is to make those containers behave on touch and to stop the tables
   inside them being wider than they need to be.

   Deliberately no `display: block` on the tables themselves: they are the
   elements carrying .table-custom / .intel-table, and blocking them would
   break table layout and Tailwind's w-full for no gain.
   -------------------------------------------------------------------------- */
.table-wrap,
.table-responsive,
.overflow-x-auto {
    -webkit-overflow-scrolling: touch;
    /* Keep a sideways swipe on the table from turning into a browser
       back-navigation or a horizontal pan of the whole page. */
    overscroll-behavior-x: contain;
}

@media (max-width: 1024px) {

    /* .intel-table hard-codes min-width: 840px — wider than any phone and
       most tablets, forcing a long scroll to reach the last column. Bring it
       down to a width that still keeps columns legible. */
    .intel-table {
        min-width: 620px;
    }

    /* .table-custom sets no min-width, so with narrow content it collapses to
       the container and crushes columns rather than letting the surrounding
       .overflow-x-auto scroll. Give it a floor so scrolling kicks in. */
    .table-custom {
        min-width: 560px;
    }

    .table-wrap {
        max-height: 60vh;
    }
}

@media (max-width: 640px) {

    .intel-table {
        min-width: 520px;
        font-size: 0.82rem;
    }

    .intel-table thead th,
    .intel-table td,
    .table-custom th,
    .table-custom td {
        padding: 0.55rem 0.6rem;
    }

    /* Sticky headers inside a short scroll box cost more than they give. */
    .table-wrap {
        max-height: 70vh;
    }
}


/* --------------------------------------------------------------------------
   4. Shared result hero (detail pages)
   Defined in base.html at desktop proportions: a 52px icon, 1.22rem mono
   value and a horizontal action row. Below 640px the actions need to own a
   full row and the value needs to come down a step.
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {

    .result-hero {
        padding: 0.9rem 0.95rem;
        border-radius: 16px;
        gap: 0.75rem;
    }

    .result-hero .rh-ico {
        width: 42px;
        height: 42px;
        border-radius: 12px;
        font-size: 1.05rem;
    }

    .result-hero .rh-main {
        flex: 1 1 100%;
    }

    .result-hero .rh-value {
        font-size: 0.98rem;
    }

    .result-hero .rh-actions {
        flex: 1 1 100%;
        gap: 0.45rem;
    }

    /* Actions share the row evenly instead of wrapping one-per-line. */
    .result-hero .rh-actions .rh-btn {
        flex: 1 1 auto;
        justify-content: center;
        padding: 0.55rem 0.7rem;
        font-size: 0.8rem;
    }
}


/* --------------------------------------------------------------------------
   5. Navigation
   The brand wordmark is a fixed 2rem, which collides with the account button
   on narrow screens. The mobile menu itself already works.
   -------------------------------------------------------------------------- */
/* The desktop link row switches on at xl (1280px). Below that the hamburger is
   used, so the wordmark is the only wide element left and can be scaled down to
   sit comfortably beside the account button. */
@media (max-width: 1280px) {

    .navbar-brand,
    .brand-logo-text {
        font-size: 1.4rem;
    }

    /* The brand must never be the element that shrinks: it cannot wrap, so
       min-width:0 above would let it be clipped mid-word instead. */
    .navbar-brand {
        flex: 0 0 auto;
        white-space: nowrap;
    }

    /* nowrap: "About Us" / "Contact Us" / "Why Us" otherwise break onto a
       second line once the row gets tight, doubling the navbar height. */
    .navbar .nav-link {
        font-size: 0.92rem;
        white-space: nowrap;
    }

    .container-navbar > div:nth-child(2) {
        gap: 1.15rem;
    }
}

@media (max-width: 768px) {

    .navbar {
        padding: 0.6rem 0;
    }

    .container-navbar {
        gap: 0.5rem;
    }

    .user-dropdown-btn {
        padding: 0.4rem 0.6rem;
    }

    /* Anchored to the right edge it can hang off-screen; pin it inside. */
    .dropdown-menu {
        right: 0;
        min-width: 180px;
        max-width: calc(100vw - 2rem);
    }
}

@media (max-width: 400px) {

    .navbar-brand,
    .brand-logo-text {
        font-size: 1.15rem;
    }
}


/* --------------------------------------------------------------------------
   6. Typography and spacing
   Headings are set for desktop; at phone widths the largest steps overflow
   or eat the whole first screen. Scale the top of the ramp only — body text
   is already fine and must not shrink.
   -------------------------------------------------------------------------- */
@media (max-width: 768px) {

    h1,
    .h1 {
        font-size: clamp(1.7rem, 6.5vw, 2.4rem);
        line-height: 1.18;
    }

    h2,
    .h2 {
        font-size: clamp(1.35rem, 5.2vw, 1.9rem);
        line-height: 1.22;
    }

    h3,
    .h3 {
        font-size: clamp(1.12rem, 4.4vw, 1.5rem);
        line-height: 1.28;
    }

    /* Long headings with tight desktop tracking wrap badly when small. */
    h1,
    h2,
    h3 {
        letter-spacing: -0.01em;
        overflow-wrap: break-word;
    }
}

@media (max-width: 640px) {

    /* Deep desktop section padding wastes most of a phone screen. */
    section {
        padding-top: 2.25rem;
        padding-bottom: 2.25rem;
    }

    /* Big card radii read as bloat once cards span the full width. */
    .glass,
    .glass-soft,
    .gcard::before {
        border-radius: 18px;
    }
}


/* --------------------------------------------------------------------------
   7. Forms, buttons and touch targets
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {

    /* iOS zooms the page when a focused input is under 16px. */
    input,
    select,
    textarea {
        font-size: 16px;
    }

    /* Comfortable minimum hit area (WCAG 2.5.8 target size). */
    button,
    [role="button"],
    .btn-primary,
    .btn-ghost,
    .rh-btn,
    .dropdown-item {
        min-height: 44px;
    }

    /* Search / submit pairs stack rather than squeezing to unusable widths. */
    form .btn-primary,
    form button[type="submit"] {
        width: 100%;
    }
}


/* --------------------------------------------------------------------------
   8. Modals
   base.html's shared reCAPTCHA modal is fixed at 400px; the widget itself is
   304px wide and cannot shrink, so keep padding small and let it scroll.
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {

    #tfaCaptchaModal > div,
    .modal-backdrop > div {
        max-width: calc(100vw - 1.5rem);
        padding: 1.1rem;
        max-height: 90vh;
        overflow-y: auto;
    }
}


/* --------------------------------------------------------------------------
   9. Motion
   The decorative background orbs are large blurred layers. On mobile GPUs
   they cost real frames for something barely visible at that size.
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {

    .bg-grid {
        background-size: 24px 24px;
    }
}
