/**
 * =============================================================================
 *  Project:        Enterramon
 *  Filename:       assets/css/build-compat.css
 *  Location:       /var/www/enterramon.com/public_html/new/assets/css/build-compat.css
 *  Description:    Behaviour the live site implemented in JavaScript, expressed
 *                  as CSS. Nothing here is a new visual design.
 *  Version:        1.0
 *  Copyright :     (c) 2026 InlineBlack. All rights reserved.
 * =============================================================================
 *
 *  WHY THIS EXISTS
 *  ---------------
 *  The live theme's footer.php ran this on every page load and every resize:
 *
 *      function handleResponsiveLayout() {
 *          const isMobile = window.innerWidth < 768;
 *          if (isMobile) {
 *              $('.desktop, .table').css('display', 'none');
 *              $('.mobile').css('display', 'flex');
 *          } else {
 *              $('.mobile').css('display', 'none');
 *              $('.desktop, .table').css('display', 'flex');
 *          }
 *      }
 *
 *  Those classes have NO rules in style.css - their display is set entirely by
 *  that jQuery code. The markup ships them with the `hidden` class, so with
 *  JavaScript disabled or failing the domain input never appears at all.
 *
 *  This file does the same job in CSS: works without JavaScript, no resize
 *  listener, no layout thrash, and the swap happens before first paint instead
 *  of after it.
 *
 *  BREAKPOINT NOTE
 *  ---------------
 *  768px is carried over deliberately from the jQuery above, even though the
 *  live icon nav switches via .mb-only/.dk-only at 1300px (see style.css).
 *  That inconsistency is the live site's, and is preserved rather than
 *  quietly changed. Worth revisiting: a single breakpoint would be cleaner.
 *
 *  `.table` is included because the live selector was '.desktop, .table'.
 */

.desktop,
.tablet,
.table,
.mobile {
    display: none;
}

@media (min-width: 768px) {
    .desktop,
    .tablet,
    .table {
        display: flex;
    }
}

@media (max-width: 767px) {
    .mobile {
        display: flex;
    }
}

/*
    The homepage carried a duplicate question-mark link inside the mobile
    block purely to sit beside the input. It is aria-hidden in the markup
    because the same link exists in the desktop group; hiding it here keeps
    one focusable "how to run a test" link per breakpoint.
*/
@media (max-width: 767px) {
    .input-group.mobile .enterra-doc-hide-main {
        display: none;
    }
}

/* =============================================================================
   HEADING LEVEL WITHOUT THE SIZE CHANGE

   The live theme uses <h4> for card titles that sit under an <h2>:
       <h2>What the Website Audit Checks</h2>   ... <h4 class="tool-card-title">
   and again in the Pro band:
       <h2>Scheduled Monitoring &amp; Reporting</h2> ... <h4>Full Detail Reports</h4>
   That skips a heading level, which is an accessibility and outline defect.

   Swapping those to <h3> fixes the outline but changes the rendered size,
   because GeneratePress sizes headings: h3 is 29px/1.2em, h4 is 24px with an
   inherited 1.5 line-height. Measured on the live page:

       live h4  ->  24px / 800 / line-height 36px
       plain h3 ->  29px / 200 / line-height 35px

   `.h4-metrics` reproduces h4's exact metrics on a differently-tagged element,
   so the document outline can be correct with zero visual difference.
   ============================================================================= */

.h4-metrics {
    font-size: 24px;
    line-height: 1.5;
}

/* -----------------------------------------------------------------------------
   .h5-metrics - the same idea as .h4-metrics, for the stat-card captions.

   The live homepage captions "across 3,136 domains..." with an <h5>, purely to
   get the styling that style.css applies to h5. An h5 there is a heading-level
   defect: it is supporting text, not a heading, and it sits under an <h1> with
   no h2/h3/h4 before it.

   These are the exact declarations style.css gives h5, so a <p class="h5-metrics">
   renders identically (24px band height -> 43px caption, measured):

       live <h5>  14.4px / 400 / 21.6px line-height / rgb(155,157,158)
       <p> alone  16px   / 300 / 24px   line-height / rgb(89,92,93)
   ----------------------------------------------------------------------------- */

.h5-metrics {
    /* Was var(--color-on-surface-inverse) = #9b9d9e, matching live's h5 exactly
       - and matching live's accessibility defect. #9b9d9e on the card surface
       (#fcfcfd) is 2.66:1; axe needs 4.5:1. This keeps the same muted grey
       character at 4.72:1. The token itself is NOT changed: it is still correct
       for the dark surfaces it was named for. */
    color: #6b7280;
    font-weight: 400;
    font-size: 0.9rem;
    letter-spacing: 1px;
}

/* -----------------------------------------------------------------------------
   HEADER ICON GEOMETRY

   Live markup nests a button inside a link:
       <a href="..."><button class="icon-btn icon" aria-label="Home">
           <span class="material-symbols-outlined">home</span></button></a>

   Interactive content inside an <a> is invalid HTML, and it is why the live
   header's links have no accessible name: the aria-label sits on the inner
   button, so the LINK still announces the icon ligature ("home", "bar_chart",
   "crown"). This build puts the classes on the <a> instead, which fixes both.

   That swap changes the rendered height by 2px. A <button> is inline-block, so a
   block <a> wrapping it gains a baseline gap: 28px of button renders as a 30px
   anchor. `.icon` makes the anchor inline-flex, so the same content renders at
   exactly 28px. Measured on the live page:

       live  <a><button>  -> a 30px tall, icon 4px from the top, 6px below
       plain <a class>    -> a 28px tall, icon 4px from the top, 4px below

   Restoring the 2px at the bottom (not evenly) keeps the icon at the same 4px
   offset as live, so nothing shifts - only the box grows, exactly as the
   baseline gap did.

   Scoped to anchors inside .header (class, not tag, so it survives the header
   being a <header> rather than the live site's <section>): the mobile toggle is
   a real <button> in both builds and must not pick this up.
   ----------------------------------------------------------------------------- */

/*
   The header's icon anchors sit 1px lower than live's on the report page and
   match on every other page. This +2px exists because live's header is not
   self-consistent: its nav container is 30px on the homepage, the tools and
   most pages, but 28px on /my-report/, with IDENTICAL computed styles on the
   anchor (display:block, line-height 24px, font-size 16px, button 28px). That
   points at icon-font metrics differing per page rather than anything settable
   in CSS.

   Live's nested <a><button> structure was removed here because a button inside
   an anchor is invalid HTML and an accessibility problem, which shifts this
   anchor by 2px. This padding restores live's majority height (30px), which is
   the better trade: it matches every page except /my-report/, where live is the
   outlier against itself. Removing it inverts that - the report matches and
   nine other pages do not.
*/
.header a.icon-btn.icon {
    padding-bottom: calc(var(--space-1) + 2px);
}

/* -----------------------------------------------------------------------------
   SEMANTIC LISTS THAT LIVE WROTE AS DIVS

   The live page contains exactly ONE <ul>: the carousel track. Everything else
   that behaves like a list is a <div> full of <span> or <a>:

       live footer:   <div class="social-icons">   <a><i class="fa-brands">…
       live dropdown: <div class="dropdown-menu">  <span class="dropdown-item">

   This build uses real <ul>/<li> for both, because a group of links is a list
   and a group of selectable options is a listbox - it is the markup assistive
   technology expects. The dropdown also uses role=listbox/option with
   aria-selected, which is the correct pattern for choosing a value.

   Two GeneratePress defaults then apply and must be neutralised, or the
   rendering changes:

       ol,ul { margin: 0 0 1.5em 3em }   -> style.css overrides to 0 0 0 1rem
       ul    { list-style: disc }        -> nothing overrides it

   Measured consequence before this rule: the dropdown popup sat 16px to the
   right of where it belongs, and both lists showed disc markers - seven of them
   above the footer social icons, which is how this was caught.

   NOTE: this only became visible once the footer social icons were fixed. On
   the live site those icons render nothing (no brand glyphs), so the list
   collapsed to zero height and the markers had nowhere to show.
   ----------------------------------------------------------------------------- */

.social-icons,
.dropdown-menu {
    list-style: none;
    margin: 0;
}

/* style.css already sets .dropdown-menu padding: var(--space-2); keep it. */
.social-icons > li,
.dropdown-menu > li {
    list-style: none;
}

.social-icons > li > a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
}

/* -----------------------------------------------------------------------------
   .visually-hidden

   The live theme has no visually-hidden utility (it relies on WordPress core's
   .screen-reader-text, which is not loaded on these pages). This build uses
   .visually-hidden for text that should reach screen readers but not the page:

       "Get Started Today<span class="visually-hidden"> (opens in a new tab)</span>"
       the skip link
       the icon-only "how to run a test" link

   Without this rule that parenthetical rendered as visible button text -
   "Get Started Today (opens in a new tab)" - which is how it was caught.

   Clipped rather than display:none, because display:none removes the text from
   the accessibility tree entirely, which defeats the purpose.

   DO NOT PUT THIS ON A <caption>. It was used that way for table descriptions
   and it looked fine in Chrome, which honours position:absolute on a
   table-caption - but it rendered as a visible centred line above the table
   header in another browser, which still lays the caption out as part of the
   table. It also never showed up in a pixel diff, because the tables it sat in
   were inside display:none containers on the static page.

   Tables now carry their description as an aria-label on the <table> instead.
   That needs no CSS and behaves the same everywhere.
   ----------------------------------------------------------------------------- */

.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Keyboard users should still be able to reach the skip link when it matters. */
.skip-link:focus,
.skip-link:focus-visible {
    position: fixed !important;
    top: 0;
    left: 0;
    width: auto;
    height: auto;
    margin: 0;
    clip: auto;
    overflow: visible;
    z-index: 10000;
    background: var(--color-primary);
    color: #fff;
    padding: 0.75rem 1.25rem;
    font-weight: 700;
}

/* -----------------------------------------------------------------------------
   SOCIAL LIST BOX HEIGHT

   With list-style removed, each <li> is still `display: list-item`, so it
   generates a line box at the inherited line-height (24px) even though its only
   child is a 20px icon. That made the list 26px tall instead of 20px and pushed
   the whole footer's bottom row down.

   flex on the <li> makes its height exactly its content, so the row height is
   driven by the icon (20px) rather than by line-height.
   ----------------------------------------------------------------------------- */

.social-icons > li {
    display: flex;
}


/* -----------------------------------------------------------------------------
   ZARAZ CONSENT MODAL HOST

   Zaraz appends .cf_modal_container at the END of <body> in normal flow, and
   gives it content once the modal mounts. Its height therefore changes from 0
   to 40px, then to 32px when the shadow-root CSS lands - three document-height
   changes, each a layout shift, all of it at the very bottom of the page.

   This rule must live in a <head> stylesheet, not in consent-modal.css: that
   file is injected into the modal's SHADOW ROOT and can only style what is
   inside it. The host is outside, so this is the one place it can be reached -
   and it has to be synchronous, hence build-compat.css rather than the injected
   sheet.

   Pinning it to the viewport at zero size means it never contributes to layout
   at all, and the modal inside positions against the viewport as it already
   does. overflow stays visible so the modal is not clipped away.
   -------------------------------------------------------------------------- */
.cf_modal_container {
    position: fixed !important;
    top: auto !important;
    right: auto !important;
    bottom: 24px !important;
    left: 24px !important;
    width: 0 !important;
    height: 0 !important;
    overflow: visible !important;
}

/* Hidden until consent-modal.js has put the shadow-root CSS in place.
   Zaraz mounts the modal at its own default size and the shadow root does not
   exist until it does, so there is always a gap - measured 17-75ms, one to four
   frames, between the modal appearing and our styling landing. Invisible in
   most conditions, obvious on a slow frame. Hiding the host until it is styled
   removes the jump entirely: the modal simply arrives correct.

   opacity, NOT visibility. visibility INHERITS, which means a rule inside the
   shadow root can set visibility:visible on the card and show through the
   hidden host - and something does, so the first attempt at this did not
   actually hide anything. opacity is not inherited; it applies to the host's
   whole subtree and cannot be overridden from inside.

   THE FAILSAFE IS THE POINT. If consent-modal.js fails to load, or throws, a
   permanently hidden host means no consent UI at all - a compliance problem,
   not a cosmetic one. The animation therefore reveals the modal at 1.2s
   regardless of whether the script ever ran. It is CSS-only on purpose: it
   cannot be broken by anything in JS. */
.cf_modal_container {
    opacity: 0 !important;
    animation: cf-consent-reveal-failsafe 0s linear 1.8s forwards !important;
}
.cf_modal_container[data-enterramon-styled] {
    opacity: 1 !important;
    animation: none !important;
}
@keyframes cf-consent-reveal-failsafe {
    to { opacity: 1; }
}
