/* ══════════════════════════════════════════════════════════════════════════
   EizTools — Responsive compatibility layer
   ──────────────────────────────────────────────────────────────────────────
   Loaded LAST on the public layouts only. Every rule is scoped
   `body:not(.admin-shell)` so the admin panel keeps its own 420→2200px
   ladder untouched.

   WHY THIS FILE EXISTS
   The public site runs five breakpoint systems that were never reconciled:

     · Bootstrap 5 grid ............ 576 / 768 / 992 / 1200 / 1400  (main.*.min.css)
     · 834 generated tool blades ... 560 only                      (tools/*.blade.php)
     · Tool shells ................. 520 / 560 / 640 / 900         (ai-*-shell.blade.php)
     · Article ..................... 400 → 1180 ladder             (premium-article.css)
     · Hand-rolled inline CSS ...... 380 → 1280                    (home/nav/footer/cat/blog)

   That is 32 distinct breakpoints, and the lowest floor on most surfaces is
   520px or 560px — so a 360px Android and a 320px iPhone SE get the exact
   same layout as a 519px phablet.

   This layer does NOT rewrite those systems. It:
     1. contains horizontal overflow properly instead of masking it
     2. kills iOS focus-zoom (the single most-felt viewport bug on the site)
     3. snaps the 560px and 640px boundaries onto Bootstrap's 576/768
     4. adds the missing ≤440 / ≤360 / ≤330 small-phone tiers
     5. fixes 100vh overshoot and short-landscape viewports

   Specificity note: inline <style> blocks in blades come later in document
   order, so every override here uses a `body:not(.admin-shell)` prefix
   (0,2,1) to beat their bare class selectors (0,1,0) without !important.
   ══════════════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════
   1 · HORIZONTAL OVERFLOW CONTAINMENT
   ───────────────────────────────────────────────────────────────────────
   custom.{ltr,rtl}.css:5 sets `body{overflow-x:hidden}`, which masks a
   sideways-poking element by clipping it — the layout bug stays, it just
   becomes invisible and the clipped content unreachable. Rather than change
   that (see the note below), this section PREVENTS the overflow instead.

   Flex and grid children default to `min-width:auto`, so a long unbreakable
   string — an API key, a URL, a generated filename — inflates its track and
   pushes the whole row wider than the screen. `min-width:0` on the
   containers that hold user/AI-generated text lets them shrink and wrap.
   ═══════════════════════════════════════════════════════════════════════ */

/* NOTE — two things deliberately NOT done here, both reverted after they
   broke the live navbar on 2026-08-17:

   1. `body { overflow-x: clip }` (replacing custom.css's `hidden`). The
      header is `position:sticky` with an absolutely-positioned mega panel
      hanging off it, and clip-vs-hidden propagation from body to the
      viewport differs subtly between engines. The semantic gain was small
      and the blast radius was the whole site chrome. custom.{ltr,rtl}.css:5
      keeps `overflow-x:hidden`; prevention below does the real work.

   2. A blanket `img { max-width:100%; height:auto }`. `height:auto` at
      (0,1,2) outranks every explicit height in the codebase — including
      `.ezhd-brand-mark img { height:32px }`, which is why the logo rendered
      at natural size. Media normalization is now scoped to content
      containers, so site chrome (logos, nav icons, footer marks) is
      untouched. Do not re-widen this to a bare element selector. */

/* Media inside CONTENT only — never the chrome. */
body:not(.admin-shell) :is(
  .pg-article, .premium-article, .pg-out-rendered, .pg-hist-rendered,
  .ao-out, .ezb-card, .ezb-card-body, .tool-card, .pg-card,
  .aitsy-cat, .ezb, .eiz-cats, .eiz-blog-grid
) :is(img, svg, video, canvas, iframe, embed, object) {
  max-width: 100%;
}
body:not(.admin-shell) :is(
  .pg-article, .premium-article, .pg-out-rendered, .pg-hist-rendered,
  .ao-out, .ezb-card-body, .tool-card
) :is(img, video) { height: auto; }

/* Let flex/grid children actually shrink. Scoped to the containers that
   carry generated text — not a blanket `* { min-width:0 }`, which would
   flatten deliberate layouts. */
body:not(.admin-shell) :is(
  .pg-out-toolbar, .pg-out-header, .pg-out-footer, .pg-kw-bar,
  .pg-hist-item-hdr, .pg-card, .pg-opt-group,
  .ao-grid, .ao-full, .ao-out, .ao-toggle-group,
  .ezb-card, .ezb-toolbar, .ezb-rail,
  .tool-card, .tb-top, .rail-left,
  .eiz-stat, .eiz-cats, .eiz-blog-grid,
  .ezft-news-in, .ezft-news-right
) > * { min-width: 0; }

/* Long unbreakable tokens wrap instead of widening the page. */
body:not(.admin-shell) :is(
  .pg-article, .premium-article, .pg-out-rendered, .pg-hist-rendered,
  .ao-out, .ezb-card-body, .tool-card
) { overflow-wrap: anywhere; }

/* Code and tables scroll inside their own box, never the page. */
body:not(.admin-shell) :is(pre, .pg-codeblock pre, .pa-codeblock pre) {
  max-width: 100%;
  overflow-x: auto;
}
body:not(.admin-shell) .pg-article > table,
body:not(.admin-shell) .premium-article > table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
}


/* ═══════════════════════════════════════════════════════════════════════
   2 · iOS FOCUS-ZOOM
   ───────────────────────────────────────────────────────────────────────
   Mobile Safari zooms the whole page when a focused control's font-size is
   below 16px, then leaves the user in a zoomed, horizontally-scrolled
   viewport with no way back except pinching. Every public control on the
   site is under that threshold:

     .ao-textarea 13.5  ·  .pg-sel 13.5  ·  .pg-input 13.5
     .pg-textarea 13.5  ·  .ezb-search 14.5  ·  .ezsx-input 15

   `.ao-textarea` alone is on all 834 tool pages, so this fires on the
   primary input of essentially every tool.

   Fixed by raising the *computed* size to 16px on coarse pointers only —
   desktop keeps the tighter 13.5px type. Guarded on `pointer:coarse` so
   this is a touch-device rule, not a global type change.
   ═══════════════════════════════════════════════════════════════════════ */

@media (pointer: coarse) {
  body:not(.admin-shell) :is(
    input[type="text"], input[type="search"], input[type="email"],
    input[type="url"], input[type="tel"], input[type="number"],
    input[type="password"], input[type="date"], input[type="time"],
    textarea, select
  ),
  body:not(.admin-shell) :is(
    .ao-textarea, .pg-sel, .pg-input, .pg-textarea,
    .ezb-search, .ezb-filter select, .ezsx-input,
    .ezft-news-form input, .tb-search
  ) {
    font-size: 16px;
  }
}

/* Touch targets: the WCAG 2.2 (2.5.8) floor is 24px, Apple/Google guidance
   is 44/48. Bring the smallest icon buttons up to 44px on touch without
   changing their painted size on desktop. */
@media (pointer: coarse) {
  body:not(.admin-shell) :is(
    .pg-tb-btn, .pg-dl-btn, .pg-copy-btn, .ezhd-ann-x,
    .ezsx-close, .ezb-tag, .pg-hi-chev
  ) {
    min-width: 44px;
    min-height: 44px;
  }
}


/* ═══════════════════════════════════════════════════════════════════════
   3 · BOUNDARY RECONCILIATION — 560px → 575.98px
   ───────────────────────────────────────────────────────────────────────
   The 834 tool blades, both tool shells, category-styles and blog-styles
   all collapse their grids at 560px. Bootstrap's `sm` tier — which governs
   the containers those grids sit inside — fires at 576px. In the 16px band
   between them the two systems disagree: Bootstrap has already stacked the
   outer column while the inner grid is still two-up, squeezing each option
   into ~250px.

   Re-collapsing at Bootstrap's own 575.98px boundary removes the band.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 575.98px) {
  body:not(.admin-shell) :is(
    .ao-grid,          /* generated tool template — all 834 pages */
    .pg-opts-grid,     /* ai-tool-shell + ai-writers-shell        */
    .tool-grid,        /* category listing                        */
    .ezb-card,         /* blog cards                              */
    .eiz-cats,         /* home category grid                      */
    .eiz-blog-grid     /* home blog grid                          */
  ) {
    grid-template-columns: 1fr;
  }

  body:not(.admin-shell) :is(.tb-top, .rail-left, .ezb-toolbar, .ezb-rail, .hero-main) {
    flex-direction: column;
    align-items: stretch;
  }
  body:not(.admin-shell) :is(.tb-right, .tb-sort) { width: 100%; }
  body:not(.admin-shell) .ezb-filter { min-width: 0; }
}


/* ═══════════════════════════════════════════════════════════════════════
   4 · BOUNDARY RECONCILIATION — 640px → 767.98px
   ───────────────────────────────────────────────────────────────────────
   The same article body gets two different mobile paddings depending on
   which page renders it: `.pg-article` (tool pages) re-pads at 640px,
   `.premium-article` (blog posts) re-pads at 767.98px. Between those two
   numbers a tool article sits at desktop padding while an identical blog
   article has already gone to mobile padding.

   Snap the tool-shell article to Bootstrap's `md` boundary so both agree.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 767.98px) {
  body:not(.admin-shell) .pg-article    { padding: 6px 18px 22px; }
  body:not(.admin-shell) .pg-out-header { padding: 18px 18px 12px; }
  body:not(.admin-shell) .pg-out-footer { padding: 12px 18px; }
  body:not(.admin-shell) .pg-kw-bar     { padding: 0 18px 12px; }
  body:not(.admin-shell) .pg-out-divider{ margin: 14px 18px; }
  body:not(.admin-shell) .pg-hist-rendered { padding: 16px; }
}


/* ═══════════════════════════════════════════════════════════════════════
   5 · SMALL-PHONE TIER — ≤ 440px
   ───────────────────────────────────────────────────────────────────────
   New. Below 520px (tool shells, home) and 560px (category, blog) there
   was previously nothing at all. This tier covers 360 / 375 / 390 / 412 —
   between them the overwhelming majority of phones in use.

   The theme here is reclaiming horizontal space: side padding comes in,
   nowrap comes off, and anything that was sitting in a row gets to stack.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 440px) {

  /* ── Tool shell ─────────────────────────────────────────────────── */
  body:not(.admin-shell) .pg-article    { padding: 6px 14px 20px; }
  body:not(.admin-shell) .pg-out-header { padding: 16px 14px 10px; }
  body:not(.admin-shell) .pg-out-footer { padding: 12px 14px; }
  body:not(.admin-shell) .pg-kw-bar     { padding: 0 14px 12px; }
  body:not(.admin-shell) .pg-out-divider{ margin: 14px 14px; }
  body:not(.admin-shell) .pg-out-prompt { font-size: 18px; line-height: 1.35; }
  body:not(.admin-shell) .pg-out-edit   { width: calc(100% - 28px); margin: 0 14px 14px; }
  body:not(.admin-shell) .pg-save-btn   { margin: 0 14px 14px; }

  /* Badges and pills stop forcing a single line. */
  body:not(.admin-shell) :is(.pg-foot-badge, .pg-kw-label, .pg-kw-pill) {
    white-space: normal;
    letter-spacing: .2px;
  }
  body:not(.admin-shell) .pg-foot-badge { font-size: 11px; padding: 5px 10px; }

  /* Action buttons go full width rather than crowding two-up. */
  body:not(.admin-shell) :is(.pg-tg-btn, .pg-coffee-btn, .pg-cta-btn, .pg-dl-btn) {
    width: 100%;
    justify-content: center;
  }
  body:not(.admin-shell) .pg-out-toolbar .tb-actions > * { flex: 1 1 auto; }

  /* Dropdowns were anchored right and could hang off-screen. */
  body:not(.admin-shell) :is(.pg-dl-menu, .pg-model-dropdown) {
    right: 0;
    left: auto;
    max-width: calc(100vw - 28px);
  }

  /* ── Generated tool template (all 834 pages) ────────────────────── */
  body:not(.admin-shell) .ao-toggle-group { flex-wrap: wrap; }
  body:not(.admin-shell) .ao-toggle-group > * { flex: 1 1 auto; }
  body:not(.admin-shell) .ao-range-label  { flex-wrap: wrap; gap: 4px; }
  body:not(.admin-shell) .ao-textarea     { min-height: 88px; }

  /* ── Home ───────────────────────────────────────────────────────── */
  body:not(.admin-shell) .eiz-stats { padding: 14px 10px; gap: 8px; }
  body:not(.admin-shell) .eiz-chip  { padding: 5px 9px; font-size: 11.5px; }

  /* ── Category ───────────────────────────────────────────────────── */
  body:not(.admin-shell) .aitsy-cat        { padding: 14px 12px 0; }
  body:not(.admin-shell) .seo-breadcrumbs  { padding-inline: 12px; }
  body:not(.admin-shell) .hero-text h1 { font-size: 23px; line-height: 1.22; }
  body:not(.admin-shell) .aitsy-explore{ padding: 26px 16px; }
  body:not(.admin-shell) .ex-tx h2     { font-size: 19px; }

  /* ── Blog ───────────────────────────────────────────────────────── */
  body:not(.admin-shell) .ezb       { padding: 14px 12px 40px; }
  body:not(.admin-shell) .ezb-hero  { padding: 22px 16px; border-radius: 16px; }

  /* ── Footer ─────────────────────────────────────────────────────── */
  /* Gutter only — the `padding` shorthand also zeroed padding-block, which
     killed .ezft-main's 44px top and .ezft-bottom-in's 26/32px on every
     phone (both are .ezft-wrap too). Never use the shorthand here. */
  body:not(.admin-shell) .ezft-wrap { padding-inline: 12px; }   /* aligned with .container */
  body:not(.admin-shell) .ezft-news { padding: 20px 14px; }
  body:not(.admin-shell) .ezft-news-copy { flex-direction: column; align-items: flex-start; gap: 12px; }

  /* ── Article ────────────────────────────────────────────────────── */
  body:not(.admin-shell) .premium-article :is(h2, h3) { overflow-wrap: anywhere; }
  body:not(.admin-shell) .pa-figure { margin-inline: -2px; }
}


/* ═══════════════════════════════════════════════════════════════════════
   6 · COMPACT-PHONE TIER — ≤ 360px
   ───────────────────────────────────────────────────────────────────────
   360px is the single most common viewport width in the world (Galaxy A
   series and most budget Android). It previously fell through to the 520px
   rules with no tuning of its own.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 360px) {
  body:not(.admin-shell) .pg-article    { padding: 6px 12px 18px; }
  body:not(.admin-shell) .pg-out-header { padding: 14px 12px 10px; }
  body:not(.admin-shell) .pg-out-footer { padding: 10px 12px; }
  body:not(.admin-shell) .pg-kw-bar     { padding: 0 12px 10px; }
  body:not(.admin-shell) .pg-out-divider{ margin: 12px 12px; }
  body:not(.admin-shell) .pg-out-prompt { font-size: 17px; }
  body:not(.admin-shell) .pg-out-edit   { width: calc(100% - 24px); margin: 0 12px 12px; }
  body:not(.admin-shell) .pg-save-btn   { margin: 0 12px 12px; }
  body:not(.admin-shell) .pg-card       { border-radius: 12px; }

  /* Stats drop to a single column — two 160px tiles were clipping labels. */
  body:not(.admin-shell) .eiz-stats { grid-template-columns: 1fr; }
  body:not(.admin-shell) .eiz-popular-label { font-size: 11.5px; }

  body:not(.admin-shell) .aitsy-cat        { padding: 12px 10px 0; }
  body:not(.admin-shell) .seo-breadcrumbs  { padding-inline: 10px; }
  body:not(.admin-shell) .hero-text h1 { font-size: 21px; }
  body:not(.admin-shell) .ex-tx h2     { font-size: 18px; }

  body:not(.admin-shell) .ezb          { padding: 12px 10px 36px; }
  body:not(.admin-shell) .ezb-hero     { padding: 18px 14px; }

  body:not(.admin-shell) .ezft-wrap    { padding-inline: 12px; }
  body:not(.admin-shell) .ezft-strip   { grid-template-columns: 1fr; }

  /* Trust strip and toggle groups stop trying to sit side by side. */
  body:not(.admin-shell) .pg-trust-strip  { grid-template-columns: 1fr; padding: 14px 2px; }
  body:not(.admin-shell) .ao-toggle-group > * { flex: 1 1 100%; }
}


/* ═══════════════════════════════════════════════════════════════════════
   7 · EXTRA-COMPACT TIER — ≤ 330px
   ───────────────────────────────────────────────────────────────────────
   iPhone SE (1st gen) and iPhone 5/5s are 320px. Nothing on the site went
   below 380px, so these devices had zero tuning. Last-resort compaction:
   drop to the tightest gutters and let everything that can wrap, wrap.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 330px) {
  body:not(.admin-shell) :is(
    .pg-article, .pg-out-header, .pg-out-footer, .pg-kw-bar
  ) { padding-inline: 10px; }

  body:not(.admin-shell) .pg-out-prompt { font-size: 16px; }
  body:not(.admin-shell) .pg-out-edit   { width: calc(100% - 20px); margin-inline: 10px; }
  body:not(.admin-shell) .pg-save-btn   { margin-inline: 10px; }

  body:not(.admin-shell) :is(.aitsy-cat, .ezb, .seo-breadcrumbs) { padding-inline: 8px; }
  body:not(.admin-shell) .ezft-wrap { padding-inline: 10px; }
  body:not(.admin-shell) .hero-text h1 { font-size: 19px; }

  /* Anything still on one line gets to break. */
  body:not(.admin-shell) :is(
    .pg-foot-badge, .pg-kw-label, .pg-kw-pill, .pg-hi-title,
    .ezft-bottom-links a, .eiz-chip, .ezb-tag
  ) { white-space: normal; }

  /* Table cells stop being nowrap — the wrapper still scrolls if needed. */
  body:not(.admin-shell) .pg-article th { white-space: normal; }
}


/* ═══════════════════════════════════════════════════════════════════════
   8 · VIEWPORT UNITS & SHORT LANDSCAPE
   ───────────────────────────────────────────────────────────────────────
   `100vh` on mobile means the viewport with the URL bar *retracted*, so a
   full-height element is taller than what is actually visible and its
   bottom edge sits behind the browser chrome. The search overlay
   (search-overlay.blade.php:523) is the one place this happens — its
   footer was being cut off on iOS and Chrome Android.

   `dvh` tracks the live visible height. Declared after the vh rule so
   engines without dvh keep the old value.

   Then: a phone in landscape is ~380px tall. Overlays sized for portrait
   have no room for their own padding there, so they get a scrollable body.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 640px) {
  body:not(.admin-shell) .ezsx-shell {
    width: 100%;
    max-height: 100dvh;
  }
}

@media (max-height: 480px) and (orientation: landscape) {
  body:not(.admin-shell) .ezsx-shell { max-height: 100dvh; }
  body:not(.admin-shell) .ezsx-body  { max-height: 46dvh; overflow-y: auto; }
  body:not(.admin-shell) .ezsx-head  { padding-block: 8px; }
  body:not(.admin-shell) .ezsx-tabs  { padding-block: 6px; }

  /* Sticky sidebars have nowhere to stick on a 380px-tall screen. */
  body:not(.admin-shell) :is(.sidebars .sticky-top, .pa-toc--sticky) {
    position: static;
  }
}


/* ═══════════════════════════════════════════════════════════════════════
   9 · SAFE-AREA INSETS (notched devices)
   ───────────────────────────────────────────────────────────────────────
   The layout meta tag is `width=device-width, initial-scale=1` with no
   `viewport-fit=cover`, so the page already avoids the notch and no inset
   padding is required for normal content. Fixed-position overlays are the
   exception — they are positioned against the visual viewport and can land
   under the home indicator on iOS.
   ═══════════════════════════════════════════════════════════════════════ */

@supports (padding: env(safe-area-inset-bottom)) {
  body:not(.admin-shell) :is(.ez-float, .ez-vid, .ezsx-foot) {
    padding-bottom: calc(12px + env(safe-area-inset-bottom));
  }
}


/* ═══════════════════════════════════════════════════════════════════════
   10 · PRINT
   ───────────────────────────────────────────────────────────────────────
   Printing a tool result or article should not carry the site chrome.
   ═══════════════════════════════════════════════════════════════════════ */

@media print {
  body:not(.admin-shell) :is(
    .ezhd-ann, .ezhd-bar, .ezft, .ezsx, .ez-float, .ez-vid,
    .pg-out-toolbar, .pg-out-footer, .pg-cta-login
  ) { display: none !important; }

  body:not(.admin-shell) :is(.pg-article, .premium-article) {
    padding: 0;
    max-width: 100%;
  }
}
