/* ============================================================
   DWELL DESIGNS — portfolio + project shared shell
   Loads AFTER css/dwell.css, so it inherits every brand token
   (--ink, --paper, --accent-deep …), the .glassnav, the .btn
   system, .eyebrow, and the sheet typography. This file only
   turns the fixed single-screen "desk" body into a normal
   scrolling document and adds the page shell every portfolio
   view shares. Per-view layout lives in each page's own block.
   ============================================================ */

/* ---- the desk body is fixed/overflow:hidden; portfolio pages scroll ----
   These pages scroll normally (a scrollbar appears when content overflows). The
   centered glassnav no longer depends on the scrollbar: it centres on 50vw (the
   full viewport) in dwell.css, so it lands in the exact same spot on the fixed
   home page and these scrolling pages. The body stays overflow:visible so it
   does NOT become a second scroll container. */
/* Root background is the deep footer teal so the very bottom of the page (below
   the footer, and behind the iOS Safari bottom bar) reads green, never white.
   The body's own light background covers all the content above, so the top stays
   light — only the area below the footer shows this. */
html { height: auto; background: var(--bg); }
body {
  height: auto; overflow: visible;
  /* Inner pages keep the ORIGINAL solid light background — only the home desk
     uses the dark --bg. Flat colour, no gradient. */
  background: var(--bg-page);
}
body::after { content: none; }              /* drop the desk's fixed vignette */

img { max-width: 100%; }
.pf-wrap { width: min(1200px, 100% - clamp(32px, 6vw, 96px)); margin-inline: auto; }

/* ---- floating nav: reuse .glassnav exactly; just make the brand a real link ---- */
.glassnav .gn-brand { cursor: pointer; }
/* on a scrolling page the pill should stay above content and cast a touch more lift.
   Shadow tuned for the light inner-page bg; keeps the same top highlight as the home
   desk so the cream "Paper Strip" nav reads consistently on every page.
   DESKTOP/TABLET ONLY: on mobile the nav is ONE morphing surface (.topbar shell +
   .topbar::before paper fill). If this shadow reaches the mobile .glassnav — which is
   a transparent inner row there — it re-casts a drop shadow + inset white line, so the
   bar reads as two stacked pills. Guarding it to ≥769 keeps mobile a single shape. */
@media (min-width: 769px) { .glassnav { box-shadow: var(--shadow-nav); } }

/* =====================================================================
   PAGE HEAD — eyebrow + big uppercase title (echoes the sheet <h2>) +
   a short lede, plus an optional quiet filter row. Shared by all styles.
   ===================================================================== */
.pf-top { padding: clamp(120px, 15vh, 168px) 0 0; }
/* TABLET (769–1024): tighten the nav→title gap ~25% vs desktop. The floating nav's
   bottom sits ~74px down, so we scale the whole top-padding clamp (not a flat cut) to
   land the VISIBLE gap ~25% smaller across the range. Desktop (≥1025) + mobile (≤768,
   below) keep their own spacing. Also covers privacy/404 (same .pf-top head); project
   uses .pd-* and is unaffected. */
@media (min-width: 769px) and (max-width: 1024px) {
  .pf-top { padding-top: clamp(105px, 13vh, 145px); }
}
.pf-head { max-width: 62ch; }
.pf-head .eyebrow { margin-bottom: 14px; }
.pf-title {
  margin: 0; font-family: var(--font); font-weight: var(--w-heading);
  font-size: var(--t-display-size); line-height: 1.05; letter-spacing: var(--t-display-track);
  text-transform: var(--t-heading-case, none); color: var(--ink);
}
.pf-title .accent { color: var(--accent-deep); }
.pf-lede {
  margin: 10px 0 0; font-size: var(--t-lede-size); line-height: 1.55;
  color: var(--ink-soft); max-width: 62ch;
}
/* MOBILE: the gap ABOVE the title (floating nav → title) is made equal to the gap
   BELOW the subtext (subtext → first content card). --nav-clearance is the pill's
   top offset + its ~56px height, so `clearance + gap` lands the title exactly `gap`
   below the nav. Each page adds its OWN content-gap token (portfolio's is the
   cs-grid margin below), so every subpage stays vertically symmetric. */
@media (max-width: 768px) {
  :root { --nav-clearance: calc(clamp(14px, 1.8vh, 22px) + 56px); }
  .pf-top { padding-top: calc(var(--nav-clearance) + 34px); }   /* portfolio: 34px = the cs-grid gap below the subtext */
}

/* =====================================================================
   SHARED PIECES — soft "paper" media treatment matching the desk photos
   ===================================================================== */
.pf-photo {
  display: block; width: 100%; height: 100%; object-fit: cover;
  /* the same faded-scan lift the desk uses on its images (ONE recipe site-wide) */
  filter: var(--photo-filter);
}

/* =====================================================================
   CLOSING CTA BAND — one warm-paper card, brand actions. Shared.
   ===================================================================== */
/* full-width deep-teal closing band (brand ink), light text, inverted buttons.
   A photo sits ON TOP of the solid teal via ::before — two knobs control it:
     --cta-img-opacity : 0 = hidden (solid teal only) … 1 = full photo
     --cta-img-blur    : 0px = sharp … larger = softer
   Tweak the two numbers below, or drag them live with portfolio.html?ctadev. */
.pf-cta {
  --cta-img-opacity: 0.18;
  --cta-img-blur: 7.5px;
  position: relative; isolation: isolate; overflow: hidden;
  margin: clamp(38px, 5.5vw, 66px) 0 0;
  text-align: center;
  background: var(--ink); border-radius: var(--r-card);
  padding: clamp(40px, 5vw, 64px) clamp(28px, 4vw, 56px);
}
/* the photo layer — over the solid colour, under the text/buttons */
.pf-cta::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: url("../assets/images/cta-block-bg.webp") center / cover no-repeat;
  opacity: var(--cta-img-opacity);
  filter: blur(var(--cta-img-blur));
  /* blur samples transparent edges; scale up slightly so no gap shows */
  transform: scale(1.06);
}
.pf-cta-h {
  margin: 0; font-family: var(--font); font-weight: var(--w-heading); text-transform: var(--t-heading-case, none);
  /* bumped a few points over the title role (was --t-title-size 23–32) so the big
     CTA band doesn't read undersized on mobile OR desktop */
  font-size: clamp(26px, 3vw, 38px); line-height: var(--lh-tight); letter-spacing: var(--t-title-track); color: var(--paper);
}
/* sub bumped 14 → 16–18; title→sub gap tightened 10px → 6px (~40% less) */
.pf-cta-sub { margin: 6px auto 0; font-size: clamp(16px, 1.5vw, 18px); line-height: 1.5; color: rgba(245,243,232,.78); max-width: 46ch; }
.pf-cta-actions { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; margin-top: 24px; }
/* buttons re-tuned for the dark band: cream primary, ghost-light secondary */
.pf-cta .btn--solid { background: var(--paper); color: var(--ink); border-color: var(--paper); }
@media (hover: hover) and (pointer: fine) { .pf-cta .btn--solid:hover { background: var(--paper-hi); border-color: var(--paper-hi); color: var(--ink); } }
.pf-cta .btn--paper { background: transparent; color: var(--paper); border-color: rgba(245,243,232,.45); }
@media (hover: hover) and (pointer: fine) { .pf-cta .btn--paper:hover { background: rgba(245,243,232,.12); border-color: var(--paper); color: var(--paper); } }

/* =====================================================================
   FOOTER — full-bleed deep-teal studio footer, reused across the inner
   pages. Breaks out of the centred column to span edge to edge; warm-cream
   type on the homepage's --bg ties these pages back to the home "desk".
   Brand + descriptor + Book-a-call on the left, three link columns
   (Explore / Reach us / Services), a hairline credit bar beneath.
   Every colour is an existing brand token.
   ===================================================================== */
.site-footer {
  margin-top: clamp(60px, 8vw, 110px);
  width: 100vw; margin-left: calc(50% - 50vw);
  background: var(--bg); color: var(--paper);
  /* green fills the home-indicator safe area so the iOS bottom bar reads green */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.site-footer .sf-in {
  width: min(1200px, 100% - clamp(32px, 6vw, 96px)); margin-inline: auto;
  padding: clamp(46px, 5.5vw, 76px) 0 0;
}
/* cream link + turquoise-eyebrow defaults on the dark band */
.site-footer a { text-decoration: none; color: rgba(245,243,232,.86); transition: color .16s ease; }
@media (hover: hover) and (pointer: fine) { .site-footer a:hover { color: var(--accent); } }
.site-footer .sf-label {
  margin: 0 0 15px; font-family: var(--font); font-weight: var(--w-semibold);
  font-size: var(--t-label-size); letter-spacing: var(--t-label-track); text-transform: uppercase; color: rgba(140,207,216,.72);
}

/* top row: brand column + three link columns */
.site-footer .sf-top { display: grid; grid-template-columns: 1.5fr .9fr 1.2fr 1.15fr; gap: 34px 40px; align-items: start; }
.site-footer .sf-brand { margin: 0; font-family: var(--font); font-weight: var(--w-heading); color: var(--paper);
  font-size: clamp(28px, 3.2vw, 40px); line-height: 1; letter-spacing: var(--t-display-track);
  text-transform: var(--t-heading-case, none); }
.site-footer .sf-tag { margin: 14px 0 0; font-size: var(--t-body-sm-size); line-height: 1.55; color: rgba(245,243,232,.62); max-width: 34ch; }
.site-footer .sf-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 11px; }
.site-footer .sf-list a { font-size: var(--t-body-sm-size); font-weight: var(--w-medium); }

/* Book a call — cream on teal */
.site-footer a.sf-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; margin-top: 22px;
  font-family: var(--font); font-weight: var(--w-btn); font-size: var(--t-nav-size);
  letter-spacing: var(--t-button-track, 0); text-transform: var(--t-button-case, none);
  word-spacing: var(--t-caps-wordgap, 0);
  padding: 12px 22px; border-radius: var(--r-btn);
  background: var(--paper); color: var(--ink); border: 1px solid var(--paper); transition: background .16s ease, color .16s ease; }
@media (hover: hover) and (pointer: fine) { .site-footer a.sf-btn:hover { background: var(--paper-hi); color: var(--ink); } }
.site-footer a.sf-btn svg { width: 16px; height: 16px; fill: currentColor; }

/* Footer brand column (tablet & desktop, ≥769 — mobile is the ≤768 block below;
   both aligned to the system breakpoint, DESIGN.md §5):
   shrink-wrap the column to the brand TITLE and stretch the Book-a-call CTA to that
   exact width, so the button's left/right edges align with "Dwell Designs" above it.
   The tag uses the width:0 / min-width:100% trick so it wraps to the title width
   WITHOUT expanding the column past the title (the title stays the reference edge;
   the CTA's own content is narrower, so it follows the title too). */
@media (min-width: 769px) {
  .site-footer .sf-brandcol { display: flex; flex-direction: column; align-items: flex-start;
    width: fit-content; max-width: 100%; }
  .site-footer .sf-brandcol .sf-tag { width: 0; min-width: 100%; max-width: none; }
  .site-footer a.sf-btn { width: 100%; }
}

/* external link: label + up-right arrow that nudges on hover */
.site-footer a.sf-exlink { display: inline-flex; align-items: center; gap: 6px; }
.site-footer .sf-arr { width: 13px; height: 13px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; transition: transform .16s ease; }
@media (hover: hover) and (pointer: fine) { .site-footer a.sf-exlink:hover .sf-arr { transform: translate(2px, -2px); } }

/* email — click to COPY (not mailto). The label sits in a one-line window;
   on copy the track rolls up to reveal "Email copied!", then rolls back.
   NB: class is sf-email (NOT sf-copy — that's the copyright line below). */
.site-footer .sf-email {
  appearance: none; border: 0; background: none; margin: 0; padding: 0;
  font-family: var(--font); font-weight: var(--w-medium); font-size: var(--t-body-sm-size); line-height: 1.55;
  color: rgba(245,243,232,.86); cursor: pointer; text-align: left;
  display: block; height: 1.55em; overflow: hidden;
}
@media (hover: hover) and (pointer: fine) { .site-footer .sf-email:hover { color: var(--accent); } }
.site-footer .sf-email-track { display: flex; flex-direction: column;
  transition: transform .45s cubic-bezier(.22, 1, .36, 1); }
/* both faces are identical to the sibling links — same size, weight, colour */
.site-footer .sf-email-face { height: 1.55em; line-height: 1.55; white-space: nowrap; }
.site-footer .sf-email.copied .sf-email-track { transform: translateY(-50%); }
@media (prefers-reduced-motion: reduce) { .site-footer .sf-email-track { transition-duration: .001s; } }

/* hairline credit bar — the credit reads as one colour, link just underlined */
.site-footer .sf-bar { margin-top: clamp(38px, 4.4vw, 60px); }
.site-footer .sf-hair { border: 0; border-top: 1px solid rgba(245,243,232,.14); margin: 0; }
.site-footer .sf-row { display: flex; align-items: center; justify-content: space-between;
  gap: 12px 40px; flex-wrap: wrap; padding: 20px 0 clamp(20px, 2.4vw, 30px); }
/* .62 alpha (not .5): 13px fine print on the deep-teal band needs ≥4.5:1 (WCAG AA);
   .5 measured 4.25:1, .62 measures 5.67:1. */
.site-footer .sf-copy { font-size: var(--t-fine-size); color: rgba(245,243,232,.62); }
.site-footer .sf-credit { font-size: var(--t-fine-size); color: rgba(245,243,232,.62); }
.site-footer .sf-copy a { color: inherit; text-decoration: underline; text-underline-offset: 3px;
  text-decoration-thickness: 1px; text-decoration-color: rgba(245,243,232,.32); }
@media (hover: hover) and (pointer: fine) { .site-footer .sf-copy a:hover { color: rgba(245,243,232,.85); } }
.site-footer .sf-credit a { color: inherit; text-decoration: underline; text-underline-offset: 3px;
  text-decoration-thickness: 1px; text-decoration-color: rgba(245,243,232,.32); }
@media (hover: hover) and (pointer: fine) { .site-footer .sf-credit a:hover { color: rgba(245,243,232,.85); text-decoration-color: rgba(245,243,232,.5); } }

/* =====================================================================
   Reveal-on-scroll (progressive; no-JS / reduced-motion fall back to visible)
   One restrained gesture: content settles up a few px and fades in as it enters
   the viewport. Transform + opacity only, never layout. portfolio.js adds .in
   when the element intersects and applies a small per-batch stagger so grouped
   items (portfolio grid, services list) don't arrive in lockstep.

   The hidden start state is gated on html.reveal-ready, which a tiny <head>
   guard sets BEFORE first paint (so there's no visible-then-hidden flash) and
   ONLY when IntersectionObserver exists. Without JS, or on reduced-motion, the
   guard/state never apply and every .reveal is simply present on load.
   ===================================================================== */
@media (prefers-reduced-motion: no-preference) {
  .reveal-ready .reveal {
    opacity: 0; transform: translateY(14px);
    transition: opacity .5s ease, transform .55s cubic-bezier(.22, 1, .36, 1);
  }
  .reveal-ready .reveal.in { opacity: 1; transform: none; }
}

@media (max-width: 768px) {
  .site-footer .sf-top { grid-template-columns: 1fr 1fr; }
  /* brand column spans full width and centres its name / tag / CTA */
  .site-footer .sf-brandcol { grid-column: 1 / -1; display: flex; flex-direction: column;
    align-items: center; text-align: center; }
  .site-footer .sf-brandcol .sf-tag { max-width: 42ch; }
  /* match the Services card's Book-a-call width: stretch, but inset by the same
     horizontal padding the cards use, so it isn't full-bleed to the footer edges */
  .site-footer .sf-brandcol a.sf-btn { width: auto; align-self: stretch; justify-content: center;
    margin-left: clamp(26px, 3vw, 44px); margin-right: clamp(26px, 3vw, 44px); }
  /* Explore & Reach-us columns also centred, for one cohesive centred footer */
  .site-footer .sf-col { text-align: center; align-items: center; }
  .site-footer .sf-list { align-items: center; }
  .site-footer .sf-email-track { align-items: center; }
  /* tighten the gap between the columns and the hairline divider */
  .site-footer .sf-bar { margin-top: 24px; }
  /* bottom bar: stack the copyright + credit, centre them, tighter line gap */
  .site-footer .sf-row { flex-direction: column; align-items: center; text-align: center; gap: 3px;
    padding: 18px 0 clamp(18px, 2.4vw, 26px); }
}
/* phones: brand on top (full width), then Explore + Reach us side by side.
   Services column is dropped on mobile; Reach us takes the wider track so the
   long email address fits without overflowing. */
@media (max-width: 560px) {
  .site-footer .sf-top { grid-template-columns: 0.82fr 1.18fr; gap: 30px 20px; }
  .site-footer .sf-brandcol { grid-column: 1 / -1; }
  .site-footer nav[aria-label="Services"] { display: none; }
  .site-footer .sf-list a { word-break: break-word; }
  .site-footer .sf-email { font-size: 13.5px; letter-spacing: -.01em; }
}

/* =====================================================================
   PROJECT PAGE — justified photo gallery + slideshow lightbox
   Rows auto-pack mixed-aspect images to full width (JS). Rounded, branded.
   ===================================================================== */
.pg-bar { display: flex; justify-content: flex-end; margin: clamp(26px, 4vw, 44px) 0 16px; }
.pg-launch {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font); font-weight: var(--w-btn); font-size: var(--t-fine-size);
  letter-spacing: var(--t-button-track, 0); text-transform: var(--t-button-case, none);
  word-spacing: var(--t-caps-wordgap, 0);
  color: var(--ink); background: transparent; cursor: pointer;
  border: 1px solid rgba(14,61,69,.35); border-radius: var(--r-pill); padding: 10px 20px;
  transition: background .14s ease, color .14s ease, border-color .14s ease;
}
@media (hover: hover) and (pointer: fine) { .pg-launch:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); } }
.pg-launch svg { width: 17px; height: 11px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.pg-launch:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 2px; }
/* touch press feedback (see the note in dwell.css) — subtle push-in on the inner-page
   tap targets: footer CTA, launch-viewer, lightbox controls. :active works on touch. */
.sf-btn:active, .pg-launch:active, .pg-lb-close:active { transform: scale(.97); }
/* .pg-lb-nav is vertically centred with translateY(-50%) — COMPOSE the press scale
   with it (don't overwrite, or the lightbox arrow jumps down on press). */
.pg-lb-nav:active { transform: translateY(-50%) scale(.97); }

/* gallery: items stack as a fallback; JS adds .pg-ready and absolutely positions them */
.pg-gallery { position: relative; width: 100%; }
.pg-item {
  position: relative; display: block; width: 100%; margin: 0 0 12px; padding: 0;
  overflow: hidden; border-radius: var(--r-media); background: var(--surface-media); cursor: pointer;
  border: 1px solid rgba(14,61,69,.1);
}
.pg-item img { display: block; width: 100%; height: auto; object-fit: cover; transition: transform .45s cubic-bezier(.22,1,.36,1), opacity .6s ease; }
.pg-ready .pg-item { position: absolute; margin: 0; }
.pg-ready .pg-item img { height: 100%; }
@media (hover: hover) and (pointer: fine) { .pg-item:not(.has-before):hover img { transform: scale(1.02); } }
/* photos "develop in": each image fades up once it finishes loading. Only images
   that weren't already cached get .pg-fade (set by portfolio.js), so there's no
   flash; reduced-motion users skip the fade and see them immediately. */
@media (prefers-reduced-motion: no-preference) {
  .pg-item img.pg-fade { opacity: 0; }
  .pg-item img.pg-fade.pg-in { opacity: 1; }
}
.pg-item:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 2px; }

/* before/after hover (desktop only — gated by the pointer query, per DESIGN.md
   §4.1): the before shot sits absolutely over the after, opacity 0, and
   cross-fades in on hover instead of the usual zoom. Touch shows the after
   only (badge stays hidden — this is a desktop-only affordance, no touch
   fallback), and the lightbox never reads .pg-before-img (it's the SECOND
   <img> in the item, so js/portfolio.js's querySelector("img") still grabs
   the after). */
.pg-item .pg-before-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .5s ease; pointer-events: none;
}
/* reuses the lightbox controls' dark-glass chip recipe (rgba(8,28,32,.4) +
   paper text) — the one "chip floating on a photo" treatment site-wide.
   Always visible on hover-capable devices (not hover-triggered) so the
   affordance is discoverable before the pointer ever lands on the photo;
   the icon signals "interactive," the word names what's currently shown. */
.pg-before-badge {
  position: absolute; right: var(--space-2); bottom: var(--space-2); z-index: 1;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px var(--space-3);
  background: rgba(8,28,32,.4); border: 1px solid rgba(245,243,232,.4);
  border-radius: var(--r-xs);
  font-family: var(--font); font-weight: var(--w-semibold); font-size: var(--t-label-size);
  letter-spacing: var(--t-label-track); line-height: 1.2; text-transform: uppercase;
  color: var(--paper);
  opacity: 0; pointer-events: none;
}
.pg-badge-icon { width: 13px; height: 8px; fill: none; stroke: currentColor; stroke-width: 1.5; flex: 0 0 auto; }
.pg-badge-hover { display: none; }
@media (hover: hover) and (pointer: fine) {
  .pg-item.has-before .pg-before-badge { opacity: 1; }
  .pg-item.has-before:hover .pg-before-img { opacity: 1; }
  .pg-item.has-before:hover .pg-badge-rest { display: none; }
  .pg-item.has-before:hover .pg-badge-hover { display: inline; }
}

/* lightbox / slideshow viewer */
.pg-lb {
  position: fixed; inset: 0; z-index: 2000; display: flex; flex-direction: column; color: var(--paper);
  opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility 0s linear .3s;
  overscroll-behavior: contain;   /* don't chain any scroll to the page behind the viewer */
}
/* the dark veil + blur live on an ABSOLUTE child, never on the fixed .pg-lb
   itself — iOS 26 Safari samples background-color/backdrop-filter from fixed
   elements (even closed ones hidden via visibility) to tint its top/bottom
   chrome, and this near-opaque veil was reaching the sampler on every page
   that loads the viewer. Absolute children are ignored by the sampler. */
.pg-lb::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: rgba(8,28,32,.96); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.pg-lb.open { opacity: 1; visibility: visible; transition: opacity .3s ease; }
.pg-lb-bar { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; padding: calc(20px + env(safe-area-inset-top, 0px)) clamp(16px, 3vw, 32px) 20px; }
.pg-lb-count { font-family: var(--font); font-weight: var(--w-medium); font-size: var(--t-fine-size); letter-spacing: 0; color: rgba(245,243,232,.7); }
.pg-lb-close, .pg-lb-nav {
  border-radius: 50%; border: 1px solid rgba(245,243,232,.4); background: rgba(8,28,32,.4);
  color: var(--paper); cursor: pointer; padding: 0; display: flex; align-items: center; justify-content: center;
  transition: background .15s ease;
}
.pg-lb-close { width: 44px; height: 44px; }
@media (hover: hover) and (pointer: fine) { .pg-lb-close:hover, .pg-lb-nav:hover { background: rgba(245,243,232,.14); } }
.pg-lb-stage { position: relative; flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; padding: 0 clamp(14px, 6vw, 92px); }
.pg-lb-stage img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--r-media); box-shadow: 0 24px 70px rgba(0,0,0,.5); }
.pg-lb-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 52px; height: 52px; z-index: 2; }
.pg-lb-prev { left: clamp(8px, 2vw, 24px); } .pg-lb-next { right: clamp(8px, 2vw, 24px); }
.pg-lb-thumbs { flex: 0 0 auto; overflow-x: auto; padding: 14px 0 calc(22px + env(safe-area-inset-bottom, 0px)); scrollbar-width: none; }
.pg-lb-thumbs::-webkit-scrollbar { display: none; }
.pg-lb-thumbs .row { display: flex; gap: 8px; width: max-content; margin: 0 auto; padding: 0 clamp(16px, 3vw, 32px); }
.pg-lb-thumb { width: 68px; height: 48px; flex: 0 0 auto; border-radius: var(--r-media); overflow: hidden; padding: 0; border: 0; background: none; cursor: pointer; opacity: .4; outline: 1.5px solid transparent; transition: opacity .2s ease; }
.pg-lb-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pg-lb-thumb.on { opacity: 1; outline-color: var(--accent); }
@media (max-width: 768px) { .pg-lb-nav { width: 44px; height: 44px; } .pg-lb-thumb { width: 54px; height: 38px; } }
