/* ===================================================================
   PDF EXPLORER -- All-Out Hardscapes LLC
   Catalog viewer component. Two states:
     1. inline  -- minimal embedded widget sitting in the page
     2. overlay -- full-viewport reader with icon rail, thumbs, search
   Pages are pre-rendered WebP tiles (see scripts/build_pdf_explorer.py),
   never the raw PDF -- the Artscapes catalog is 158 MB.
   =================================================================== */

/* Brand tokens live at :root, NOT on .pdfx.
   The overlay is appended to <body> (it must be, to escape any parent stacking
   context), so it is OUTSIDE .pdfx and never inherited these variables --
   every var(--pdfx-*) inside the overlay resolved to nothing. That silently
   turned the rail background transparent and left 12 declarations unstyled.
   Caught 2026-08-06 when Aaron flagged the rail icons as too light. */
:root {
    --pdfx-chrome: #1a1f2b;   /* AOH brand dark -- matches --dark in style.css */
    --pdfx-chrome-2: #12161e;
    --pdfx-stage: #e8e6e2;
    --pdfx-accent: #09b504;
}

.pdfx {
    position: relative;
    width: 100%;
}

/* ---------- inline state ---------- */
.pdfx-inline {
    position: relative;
    background: var(--pdfx-stage);
    border-radius: 4px;
    overflow: hidden;
    box-shadow: 0 2px 12px rgba(0, 0, 0, .08);
}
.pdfx-inline .pdfx-stage { padding: 22px; }

/* INLINE PAGE SIZING -- same class of bug as the overlay, same reason.
   .pdfx-spread is a flex item with width:auto, so its width was INDEFINITE; the
   .pdfx-page inside it took its width from content, and that content is an <img>
   sized `width:100%` -- circular. Chromium breaks the cycle using the image's
   intrinsic size; WebKit resolves it to zero, collapsing the inline viewer to a
   24px sliver (measured on live production in Playwright WebKit, 2026-08-07).
   Giving the spread a definite width makes the whole chain definite: the flex
   pages get a real width, the inline aspect-ratio then gives a real height, and
   no engine has to guess. Chromium output is byte-identical before and after. */
.pdfx-inline .pdfx-spread { width: 100%; }
.pdfx-inline .pdfx-spread .pdfx-page { flex: 1 1 0; min-width: 0; }

/* stage holds the spread and locks aspect ratio so there is no layout shift */
.pdfx-stage {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
}
.pdfx-spread {
    position: relative;
    display: flex;
    align-items: stretch;
    justify-content: center;
    gap: 0;
    max-width: 100%;
    transition: transform .28s cubic-bezier(.4, 0, .2, 1);
    transform-origin: center center;
}
.pdfx-page {
    position: relative;
    display: block;
    background: #fff;
    box-shadow: 0 6px 22px rgba(0, 0, 0, .18);
    max-width: 100%;
    height: auto;
    -webkit-user-select: none;
    user-select: none;
}
.pdfx-page img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #fff;
}
/* centre seam so a spread reads as an open book */
.pdfx-spread.is-spread .pdfx-page:first-child {
    box-shadow: inset -14px 0 22px -14px rgba(0, 0, 0, .35), 0 6px 22px rgba(0, 0, 0, .18);
}
.pdfx-spread.is-spread .pdfx-page:last-child {
    box-shadow: inset 14px 0 22px -14px rgba(0, 0, 0, .35), 0 6px 22px rgba(0, 0, 0, .18);
}
.pdfx-page.is-loading::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(100deg, #f4f2ef 30%, #e6e3de 50%, #f4f2ef 70%);
    background-size: 220% 100%;
    animation: pdfx-shimmer 1.1s linear infinite;
}
@keyframes pdfx-shimmer { to { background-position: -220% 0; } }

/* ---------- nav chevrons ---------- */
.pdfx-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 6;
    width: 46px; height: 66px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255, 255, 255, .82);
    color: var(--pdfx-chrome);
    border: none; border-radius: 3px;
    cursor: pointer;
    opacity: 0;
    transition: opacity .2s ease, background .2s ease;
}
.pdfx:hover .pdfx-nav,
.pdfx-nav:focus-visible { opacity: 1; }
.pdfx-nav:hover { background: #fff; }
.pdfx-nav[disabled] { opacity: 0 !important; pointer-events: none; }
.pdfx-prev { left: 6px; }
.pdfx-next { right: 6px; }
/* Overlay arrows sit on the light grey stage, so they take the brand dark too. */
.pdfx-overlay .pdfx-nav {
    background: rgba(255, 255, 255, .78);
    color: var(--pdfx-chrome);
    opacity: .95;
}
.pdfx-overlay .pdfx-nav:hover { background: #fff; color: var(--pdfx-chrome); }

/* ---------- inline bottom bar ---------- */
.pdfx-bar {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 7;
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    padding: 10px 14px;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, .92) 45%);
    pointer-events: none;
}
.pdfx-bar > * { pointer-events: auto; }
.pdfx-counter {
    display: inline-flex; align-items: center; gap: 8px;
    font-family: var(--font-body);
    font-size: .8rem; font-weight: 600; color: var(--pdfx-chrome);
    letter-spacing: .02em;
}
.pdfx-counter button {
    background: none; border: none; cursor: pointer;
    color: inherit; padding: 2px; line-height: 0; border-radius: 3px;
}
.pdfx-counter button:hover { color: var(--pdfx-accent); }
.pdfx-counter button[disabled] { opacity: .3; cursor: default; }
.pdfx-open {
    display: inline-flex; align-items: center; gap: 7px;
    background: #fff; color: var(--pdfx-chrome);
    border: 1px solid rgba(0, 0, 0, .12); border-radius: 3px;
    padding: 8px 14px;
    font-family: var(--font-body); font-size: .78rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .06em;
    cursor: pointer;
    transition: background .2s ease, color .2s ease, border-color .2s ease;
}
.pdfx-open:hover { background: var(--pdfx-chrome); color: #fff; border-color: var(--pdfx-chrome); }

/* ===================================================================
   OVERLAY STATE
   =================================================================== */
.pdfx-overlay {
    position: fixed; inset: 0;
    z-index: 9000;
    display: grid;
    grid-template-columns: 56px auto 1fr;
    background: #d9d7d3;
    opacity: 0;
    visibility: hidden;
    transition: opacity .24s ease, visibility .24s ease;
}
.pdfx-overlay.is-open { opacity: 1; visibility: visible; }
body.pdfx-locked { overflow: hidden; }

/* -- left icon rail -- */
/* Light rail with brand-dark icons (Aaron's call 2026-08-06 -- #1A1F2B). */
.pdfx-rail {
    grid-column: 1;
    display: flex; flex-direction: column; align-items: center;
    gap: 4px;
    padding: 12px 0;
    background: #f2f0ed;
    border-right: 1px solid rgba(26, 31, 43, .12);
}
.pdfx-rail button {
    width: 38px; height: 38px;
    display: flex; align-items: center; justify-content: center;
    background: none; border: none; border-radius: 4px;
    color: var(--pdfx-chrome);
    cursor: pointer;
    transition: background .18s ease, color .18s ease;
}
.pdfx-rail button:hover { background: rgba(26, 31, 43, .1); color: var(--pdfx-chrome); }
.pdfx-rail button.is-active { background: var(--pdfx-accent); color: #fff; }
.pdfx-rail .pdfx-rail-sep { flex: 1; }

/* -- thumbnail panel -- */
.pdfx-thumbs {
    grid-column: 2;
    width: 0;
    overflow: hidden;
    background: #f2f0ed;
    border-right: 1px solid rgba(0, 0, 0, .1);
    transition: width .24s cubic-bezier(.4, 0, .2, 1);
}
.pdfx-overlay.thumbs-open .pdfx-thumbs { width: 210px; }
.pdfx-thumbs-inner {
    height: 100%;
    overflow-y: auto;
    padding: 14px 12px;
    width: 210px;
}
.pdfx-thumb {
    position: relative;
    display: block;
    width: 100%;
    margin-bottom: 12px;
    padding: 0;
    background: none; border: 2px solid transparent; border-radius: 3px;
    cursor: pointer;
    line-height: 0;
}
.pdfx-thumb img {
    width: 100%; height: auto;
    display: block;
    background: #fff;
    box-shadow: 0 1px 5px rgba(0, 0, 0, .18);
    /* JS sets aspect-ratio inline from the PDF page box so each row reserves its
       height before the image arrives; this keeps the virtualisation maths honest. */
}
.pdfx-thumb-pair { display: flex; gap: 1px; }
.pdfx-thumb-pair img { width: 50%; }
.pdfx-thumb.is-current { border-color: var(--pdfx-accent); }
.pdfx-thumb-label {
    position: absolute; top: 3px; left: 3px;
    background: rgba(26, 31, 43, .78);
    color: #fff;
    font-family: var(--font-body);
    font-size: .62rem; font-weight: 600;
    padding: 2px 5px; border-radius: 2px;
    line-height: 1.2;
}

/* -- main reading area -- */
.pdfx-main {
    grid-column: 3;
    position: relative;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
    background: #d9d7d3;
}
.pdfx-main .pdfx-stage {
    width: 100%; height: 100%;
    padding: 34px 58px 54px;
}
.pdfx-main .pdfx-spread { cursor: grab; }
.pdfx-main .pdfx-spread.is-panning { cursor: grabbing; transition: none; }

/* PAGE SIZING IN THE OVERLAY -- READ BEFORE CHANGING.
   This used to be `height: 100%; width: auto`. That is a percentage height resolved
   against .pdfx-spread, which is a CONTENT-SIZED flex item (its parent .pdfx-stage is
   `align-items: center`), so the spread's height is INDEFINITE. Per spec the percentage
   then resolves to auto/zero -- WebKit does exactly that and collapses the page to 0x0,
   which renders as a bare grey stage on iOS Safari, iPadOS and Safari on Mac. Chromium
   masks the bug by guessing from the image's intrinsic size, so Android looked perfect.
   Reported by Randy and Claire 2026-08-07; reproduced in Playwright WebKit at 393x852
   (page rect 0x0 in WebKit vs 384x485 in Chromium on the same live URL).

   The page box is now sized in EXPLICIT PIXELS by Explorer.fitOverlay() in
   pdf-explorer.js, which is engine-agnostic. The rules below are only the pre-fit
   fallback and the clamp -- no percentage heights anywhere in this chain. */
.pdfx-main .pdfx-page {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
}
.pdfx-main .pdfx-page img { width: 100%; height: 100%; object-fit: contain; }

.pdfx-close {
    position: absolute; top: 12px; right: 14px;
    z-index: 20;
    width: 36px; height: 36px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255, 255, 255, .9);
    border: none; border-radius: 4px;
    color: var(--pdfx-chrome);
    cursor: pointer;
}
.pdfx-close:hover { background: #fff; color: var(--pdfx-accent); }

.pdfx-overlay .pdfx-bar {
    background: none;
    justify-content: center;
    padding-bottom: 14px;
}
.pdfx-overlay .pdfx-counter {
    background: rgba(255, 255, 255, .9);
    padding: 6px 12px;
    border-radius: 3px;
}

/* -- zoom cluster -- */
.pdfx-zoom {
    position: absolute; right: 14px; bottom: 14px;
    z-index: 12;
    display: flex; align-items: center; gap: 2px;
    background: rgba(255, 255, 255, .9);
    border-radius: 3px;
    padding: 4px;
}
.pdfx-zoom button {
    width: 30px; height: 30px;
    display: flex; align-items: center; justify-content: center;
    background: none; border: none; border-radius: 3px;
    color: var(--pdfx-chrome); cursor: pointer;
}
.pdfx-zoom button:hover { background: rgba(0, 0, 0, .08); }
.pdfx-zoom-level {
    min-width: 46px; text-align: center;
    font-family: var(--font-body); font-size: .74rem; font-weight: 600;
    color: var(--pdfx-chrome);
}

/* -- search panel -- */
.pdfx-search {
    position: absolute; top: 0; left: 0;
    z-index: 15;
    width: 320px; max-width: 82vw;
    max-height: 100%;
    display: none;
    flex-direction: column;
    background: #fff;
    box-shadow: 4px 0 24px rgba(0, 0, 0, .18);
}
.pdfx-overlay.search-open .pdfx-search { display: flex; }
.pdfx-search-head {
    display: flex; align-items: center; gap: 8px;
    padding: 14px;
    border-bottom: 1px solid var(--border);
}
.pdfx-search-head input {
    flex: 1;
    border: 1px solid var(--border); border-radius: 3px;
    padding: 9px 11px;
    font-family: var(--font-body); font-size: .88rem;
    color: var(--text);
}
.pdfx-search-head input:focus { outline: 2px solid var(--pdfx-accent); outline-offset: -1px; }
.pdfx-search-count {
    padding: 8px 14px;
    font-family: var(--font-body); font-size: .74rem;
    color: var(--muted);
    border-bottom: 1px solid var(--border);
}
.pdfx-search-results { overflow-y: auto; flex: 1; }
.pdfx-hit {
    display: block; width: 100%; text-align: left;
    background: none; border: none;
    border-bottom: 1px solid var(--border);
    padding: 11px 14px;
    cursor: pointer;
    font-family: var(--font-body);
}
.pdfx-hit:hover { background: var(--light); }
.pdfx-hit-page {
    display: block;
    font-size: .68rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .07em; color: var(--pdfx-accent);
    margin-bottom: 3px;
}
.pdfx-hit-text { font-size: .8rem; color: var(--text-light); line-height: 1.45; }
.pdfx-hit-text mark { background: rgba(9, 181, 4, .22); color: var(--text); padding: 0 1px; }

/* ===================================================================
   COMPACT HERO (page-scoped)
   The sitewide .hero-short is min-height:45vh with .hero-content padding:80px 0.
   That is sized for a photographic hero -- the empty space reads as imagery.
   This page uses a FLAT brand color, so the same padding reads as a big empty
   navy slab: 428px tall for 210px of actual text (218px of nothing).
   Scoped to this page only -- does NOT touch the sitewide hero.
   =================================================================== */
.hero-compact { min-height: 0; }
.hero-compact .hero-content { padding: 44px 0; }
.hero-compact .hero-badge { margin-bottom: 18px; }
.hero-compact h1 { margin-bottom: 12px; }
.hero-compact .hero-sub { margin-bottom: 0; }
@media (max-width: 680px) {
    .hero-compact .hero-content { padding: 32px 0; }
}

/* ===================================================================
   PAGE SECTIONS (catalog blocks on techo-bloc-product-guide.php)
   =================================================================== */
.catalog-block { padding: 84px 0; }
.catalog-block + .catalog-block { border-top: 1px solid var(--border); }
.catalog-layout {
    display: grid;
    grid-template-columns: 0.85fr 1.15fr;
    gap: 56px;
    align-items: center;
}
/* Alternating: viewer on the left, copy on the right.
   The column TRACKS must swap too -- `order` alone leaves the viewer in the narrow
   0.85fr track, which visibly shrinks it on every reversed block. */
.catalog-block.is-reversed .catalog-layout { grid-template-columns: 1.15fr 0.85fr; }
.catalog-block.is-reversed .catalog-copy { order: 2; }
.catalog-block.is-reversed .catalog-viewer { order: 1; }

.catalog-copy .catalog-rule {
    width: 100%; height: 1px;
    background: var(--pdfx-chrome);
    margin-bottom: 18px;
}
.catalog-eyebrow {
    display: block;
    font-family: var(--font-body);
    font-size: .74rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .12em;
    color: var(--muted);
    margin-bottom: 14px;
}
.catalog-copy h2 { margin-bottom: 16px; }
.catalog-copy p { color: var(--text-light); line-height: 1.75; margin-bottom: 16px; }
.catalog-meta {
    display: flex; flex-wrap: wrap; gap: 18px;
    margin: 22px 0 26px;
    padding-top: 18px;
    border-top: 1px solid var(--border);
}
.catalog-meta div { display: flex; flex-direction: column; gap: 2px; }
.catalog-meta dt {
    font-family: var(--font-body); font-size: .68rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .09em; color: var(--muted);
}
.catalog-meta dd {
    margin: 0;
    font-family: var(--font-heading); font-size: 1.3rem; font-weight: 700;
    color: var(--pdfx-chrome);
}
.catalog-actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* download strip under each viewer */
.catalog-download {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 18px;
    margin-top: 28px;
    padding-top: 22px;
    border-top: 1px solid var(--border);
}
.catalog-download p { margin: 0; color: var(--text-light); font-size: .94rem; }
.catalog-download p strong { color: var(--text); }

/* editorial notice for placeholder copy -- REMOVE once Claire/Randy sign off */
.copy-review-note {
    background: #fffbe6;
    border: 1px solid #f0e2a8;
    border-left: 4px solid #e8c53d;
    border-radius: 3px;
    padding: 14px 18px;
    margin-bottom: 40px;
    font-family: var(--font-body);
    font-size: .86rem;
    color: #6b5a12;
}
.copy-review-note strong { color: #4d400a; }

/* ---------- responsive ---------- */
@media (max-width: 1080px) {
    .catalog-layout,
    .catalog-block.is-reversed .catalog-layout { grid-template-columns: 1fr; gap: 34px; }
    .catalog-block.is-reversed .catalog-copy,
    .catalog-block.is-reversed .catalog-viewer { order: 0; }
}
@media (max-width: 900px) {
    .pdfx-overlay { grid-template-columns: 48px auto 1fr; }
    .pdfx-overlay.thumbs-open .pdfx-thumbs { width: 150px; }
    .pdfx-thumbs-inner { width: 150px; padding: 10px 8px; }
    .pdfx-main .pdfx-stage { padding: 12px 34px 46px; }
    .pdfx-rail button { width: 34px; height: 34px; }
}

/* Narrow screens: the reader is single-page (see SPREAD_MIN_W in pdf-explorer.js),
   so give the page nearly the whole viewport instead of floating it in grey.
   The icon rail becomes a horizontal BOTTOM bar -- a 48px vertical rail costs 12% of
   a 390px screen, which is width the page should be using. */
@media (max-width: 759px) {
    .pdfx-overlay {
        grid-template-columns: auto 1fr;
        grid-template-rows: 1fr auto;
    }
    .pdfx-thumbs { grid-column: 1; grid-row: 1; }
    .pdfx-main { grid-column: 2; grid-row: 1; }
    .pdfx-rail {
        grid-column: 1 / -1;
        grid-row: 2;
        flex-direction: row;
        justify-content: space-around;
        align-items: center;
        gap: 2px;
        padding: 6px 4px;
        padding-bottom: calc(6px + env(safe-area-inset-bottom, 0px));
        border-top: 1px solid rgba(26, 31, 43, .14);
        border-right: none;
    }
    .pdfx-rail .pdfx-rail-sep { display: none; }
    .pdfx-rail button { width: 44px; height: 40px; }
    .pdfx-main .pdfx-stage { padding: 6px 4px 40px; }
    .pdfx-main .pdfx-page { max-height: 100%; }
    .pdfx-main .pdfx-page img { max-width: 100%; }
    .pdfx-overlay .pdfx-nav {
        width: 34px; height: 48px;
        background: rgba(255, 255, 255, .82);
        color: var(--pdfx-chrome);
        opacity: 1;
    }
    .pdfx-prev { left: 2px; }
    .pdfx-next { right: 2px; }
    .pdfx-overlay .pdfx-bar { padding-bottom: 8px; }
    .pdfx-zoom { right: 6px; bottom: 6px; padding: 3px; }
    .pdfx-zoom button { width: 27px; height: 27px; }
    .pdfx-zoom-level { min-width: 40px; font-size: .7rem; }
}
@media (max-width: 680px) {
    .catalog-block { padding: 56px 0; }
    .pdfx-inline .pdfx-stage { padding: 12px; }
    .pdfx-nav { opacity: .9; width: 38px; height: 54px; }
    .pdfx-open { padding: 7px 11px; font-size: .7rem; }
    .catalog-download { flex-direction: column; align-items: flex-start; }
    .pdfx-zoom { right: 8px; bottom: 8px; }
}

@media (prefers-reduced-motion: reduce) {
    .pdfx-spread, .pdfx-overlay, .pdfx-thumbs { transition: none; }
    .pdfx-page.is-loading::after { animation: none; }
}

/* ---- Jump to page (added 2026-08-14) --------------------------------------
   Sits inline with the page counter + arrows in the bottom-left bar. Styled to
   match .pdfx-open and .pdfx-counter: same chrome color, same 3px radius, same
   hairline border. Deliberately understated -- Aaron asked for small, elegant
   and professional, in the existing icon vocabulary. */
.pdfx-jump {
    display: inline-flex; align-items: center;
    margin-left: 4px;
    border: 1px solid rgba(0, 0, 0, .14);
    border-radius: 3px;
    background: #fff;
    overflow: hidden;
    transition: border-color .18s ease, box-shadow .18s ease;
}
.pdfx-jump:focus-within {
    border-color: var(--pdfx-accent);
    box-shadow: 0 0 0 2px rgba(9, 181, 4, .16);
}
.pdfx-jump-input {
    width: 38px;
    border: 0; outline: 0; background: transparent;
    padding: 5px 4px 5px 7px;
    font-family: var(--font-body);
    font-size: .74rem; font-weight: 600; color: var(--pdfx-chrome);
    text-align: center;
    -moz-appearance: textfield;
}
.pdfx-jump-input::placeholder { color: rgba(26, 31, 43, .42); font-weight: 500; }
.pdfx-jump-input::-webkit-outer-spin-button,
.pdfx-jump-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pdfx-jump-go {
    display: inline-flex; align-items: center; justify-content: center;
    background: none; border: 0; border-left: 1px solid rgba(0, 0, 0, .10);
    color: var(--pdfx-chrome);
    padding: 5px 6px; line-height: 0; cursor: pointer;
    transition: background .18s ease, color .18s ease;
}
.pdfx-jump-go:hover { background: var(--pdfx-chrome); color: #fff; }
.pdfx-jump-go:focus-visible { outline: 2px solid var(--pdfx-accent); outline-offset: -2px; }
.pdfx-jump.is-bad { border-color: #c0392b; animation: pdfxJumpShake .3s ease; }
.pdfx-jump.is-bad .pdfx-jump-input { color: #c0392b; }
@keyframes pdfxJumpShake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-3px); }
    75% { transform: translateX(3px); }
}
/* In the full-screen overlay the counter sits on a translucent white pill,
   so the control needs to stay legible against it. */
.pdfx-overlay .pdfx-jump { background: #fff; }
@media (max-width: 600px) {
    .pdfx-jump-input { width: 32px; font-size: .7rem; padding-left: 5px; }
}