/*
 * site.css — rules migrated out of the WP Headers and Footers plugin.
 *
 * The previous site kept its custom CSS in a plugin (the old child theme left a
 * directory literally named `<< CSS IS PLUGIN` as a note). That CSS was injected
 * into wp_head on every request. It has been migrated here so the theme owns its
 * own styling and the plugin can be removed.
 *
 * Migrated 2026-08-25 from a 6,512-character injected block. Roughly two thirds of
 * it was dead and has been dropped rather than carried over:
 *
 *   - .StickyHeader / .StickyHeader.scrolled  — the old fixed 55px header, replaced
 *     by .masthead in catalogue.css
 *   - every #mega-menu-* / .mega-toggle-* rule — Max Mega Menu no longer renders
 *   - .topnav, .TopNavLeft/Center/Right, .SiteTitle — the old header structure
 *   - :root{--header-h:55px} and the .FeaturedCoverImage margin-top that used it —
 *     that offset existed to clear the old FIXED header; this one is sticky and in
 *     flow, so the offset only produced a gap
 *   - .home .wp-block-cover{margin-top:-130px} — same fixed-header compensation
 *   - .mega-menu-item-4205x show/hide rules — menu item IDs that no longer exist
 *   - .page-id-31549 override — no such page on this install
 *   - `#{$wrap}` and `@include mobile` — uncompiled SCSS that was never valid CSS
 *   - .LatestPostsFooter.ul — malformed selector (".ul" cannot match an element)
 */

/* ---------- page entrance ----------
   REMOVED 2026-09-07. The old site's body fade held the page invisible for 250ms
   then faded it in. With render-blocking stylesheets there is no unstyled flash to
   hide, and the hold cost 250ms+ of LCP on every load; on PageSpeed's mobile run it
   landed either side of the hero image finishing, splitting scores between 94 and 76.
   An opacity animation on <body> also composites the whole page as one layer while it
   runs. Pages now appear at once. */

/* ---------- focus ----------
   The old rule was `outline:1px solid #adadad`, which is 2:1 against the page and
   fails WCAG 2.2 SC 1.4.11 (3:1 for non-text). Raised to the ink token at 2px,
   which the rest of the theme already uses. */
:focus{outline:2px solid var(--ink);outline-offset:1px}
:focus:not(:focus-visible){outline:none}

/* ---------- featured cover hero ----------
   Full-bleed: the block's own horizontal padding is removed. The margin-top half of
   the original rule is deliberately NOT carried over (see the header note above). */
.FeaturedCoverImage{padding-left:0!important;padding-right:0!important}
.FeaturedImageGroup.has-global-padding{padding:0!important}

/* ---------- project URL button (the [eyerev_project_url] shortcode) ---------- */
.wp-block-group.ProjectURL{display:flex;justify-content:center}

/* ---------- buttons ----------
   Shape kept from the old site (30px radius, 15/30 padding, 1px tracking). The
   hover colour was #005177 — WordPress's default blue, which is not a brand colour
   and clashes with the achromatic palette. Now the ink token. */
.wp-block-button__link{border-radius:30px;padding:15px 30px;text-decoration:none;
  font-size:1rem;letter-spacing:1px}
.wp-block-button__link:hover{background-color:var(--ink);color:var(--paper)}

/* ---------- portfolio title truncation ---------- */
.folio-title{margin-right:10px!important;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}

/* ---------- media + text blocks ---------- */
.wp-block-media-text__content{margin-left:13px!important}
.wp-block-media-text > .wp-block-media-text__content{padding:0!important}

/* ---------- client logo wall (/clients/) ----------
   Fixed 135x100 boxes with a hairline, exactly as the old site. Note this forces a
   non-native aspect ratio, so logos are stretched; `object-fit:contain` would fix
   that but would change the current appearance, so it is left alone for now. */
/* flex:0 0 auto is required: this theme makes .wp-block-image a flex container, and
   without it the fixed-width logos are shrunk to 0px wide by flex-shrink. The old
   theme left .wp-block-image as a block, so the original rule never needed it. */
.ClientLogos .wp-block-image img,
.ClientLogos img{width:135px!important;height:100px!important;max-width:none!important;
  flex:0 0 auto;margin:10px auto!important}
.ClientLogos .wp-block-image{border:1px solid var(--line)}

/* ---------- page header movie ---------- */
.PageHeaderMovie{box-shadow:0 5px 10px rgba(30,30,36,.2)}

/* ---------- footer contact lines ----------
   Icons kept from the old site (they ship in this theme's /images/, 20x20 each) but
   the fixed 270x40 box they came with is gone. At 14px in a 355px column the address
   wraps to two lines, which overflowed a 40px-tall box. Now the icon sits in a 30px
   gutter and the line is free to grow.

   The studio name is a column label like "Latest News" and "Environmental Policy",
   so it stays flush left rather than indented — the three detail lines below it are
   what the gutter is for. */
.wp-footer .footer-logo{width:auto;height:auto;padding:0}
.wp-footer p.footer-phone,
.wp-footer p.footer-email,
.wp-footer p.footer-location{
  width:auto;height:auto;min-height:20px;
  padding:0 0 0 30px;
  /* 0 50%, not a fixed offset: the phone/email lines wrap their text in a
     44px-tap-target link, so those paragraphs are 44px tall while the plain
     address line is 24px — a pinned icon only centres on one of them */
  background-repeat:no-repeat;background-size:16px 16px;background-position:0 50%;
  text-align:left}
.wp-footer p.footer-phone{background-image:url(../../images/Phone.png)}
.wp-footer p.footer-email{background-image:url(../../images/Email.png)}
.wp-footer p.footer-location{background-image:url(../../images/Location.png)}

/* ---------- contact page detail lines ----------
   The footer icons reused on the contact page, darkened: the PNGs are light grey
   for the footer, so brightness(0) re-inks them and opacity softens them to match
   body text. The icon sits on a ::before so the filter can't touch the text. */
.contact-line{position:relative;padding-left:30px}
.contact-line::before{content:"";position:absolute;left:0;top:.4em;width:16px;height:16px;
  background:no-repeat center/16px 16px;filter:brightness(0) opacity(.7)}
.contact-phone::before{background-image:url(../../images/Phone.png)}
.contact-email::before{background-image:url(../../images/Email.png)}
.wp-block-post-content p.contact-line{margin-bottom:.5em}


/* =============================================================================
   Accessibility pass — 2026-08-25. Target WCAG 2.2 AA, AAA where reachable.
   ============================================================================= */

/* --- 2.4.11 Focus Not Obscured (AA) ---------------------------------------
   The masthead is sticky, so tabbing to something just below the fold could land it
   underneath the bar. scroll-padding-top keeps the browser's scroll-into-view clear
   of it. 60px bar + 12px breathing room. */
html{scroll-padding-top:72px}

/* --- 1.4.11 Non-text Contrast (AA) ----------------------------------------
   WPForms ships #ccc field borders: 1.43:1 against the page, where a UI component
   boundary needs 3:1. #767676 gives 4.06:1 on the page ground and 4.54:1 on the
   field's own white — comfortably over. */
.wpforms-container input[type="text"],
.wpforms-container input[type="email"],
.wpforms-container input[type="tel"],
.wpforms-container input[type="number"],
.wpforms-container input[type="url"],
.wpforms-container select,
.wpforms-container textarea{
  border:1px solid #767676!important;border-radius:0!important;
  font-family:var(--sans);font-size:16px;color:var(--ink)}
.wpforms-container input:focus-visible,
.wpforms-container select:focus-visible,
.wpforms-container textarea:focus-visible{
  outline:2px solid var(--ink);outline-offset:2px;border-color:var(--ink)!important}

/* --- 3.3.2 Labels or Instructions -----------------------------------------
   The form used `wpforms-label-hide`, so every visible label was clipped to 1px and
   sighted users had only placeholders — which vanish the moment you type, leaving no
   way to check what a field was for. Labels are shown, in the theme's own small-caps
   label idiom. */
.wpforms-container .wpforms-field-label.wpforms-label-hide{
  position:static!important;width:auto!important;height:auto!important;
  clip:auto!important;clip-path:none!important;overflow:visible!important;
  margin:0 0 8px!important;padding:0!important;
  display:block;font-family:var(--sans);font-size:11px;font-weight:500;
  letter-spacing:.18em;text-transform:uppercase;color:var(--ink)}
/* the required marker should not read as decoration only */
.wpforms-container .wpforms-required-label{color:var(--ink);font-weight:500}

/* --- 2.5.8 Target Size Minimum (AA, 24px) and 2.5.5 Enhanced (AAA, 44px) ---
   Standalone links — footer navigation and the Latest News list — were 21–31px tall.
   Inline links inside a sentence are exempt from both criteria, so the footer's phone
   and email lines are deliberately left alone; these are the block-level ones. */
/* 2.5.5 wants 44 in BOTH axes — short labels like "About" were 31px wide at 44 tall,
   so a min-width is needed as well as a min-height. */
.wp-footer .foot-links .wp-block-navigation-item__content{
  min-height:44px;min-width:44px;display:inline-flex;align-items:center;justify-content:center}
.wp-footer .wp-block-latest-posts__list li a{
  min-height:44px;display:flex;align-items:center}

/* The footer's phone and email each sit alone in their own paragraph, so they are
   NOT inline-in-a-sentence and the exemption does not apply — they were 18px tall.
   The icon gutter is preserved by keeping the padding-left from the contact block. */
.wp-footer .footer-phone a,
.wp-footer .footer-email a{display:inline-flex;align-items:center;min-height:44px}
.wp-footer .footer-phone,
.wp-footer .footer-email{margin-bottom:0}

/* the theme's skip link was 43px — one pixel under the AAA target */
.skip-link{min-height:44px;display:inline-flex;align-items:center}

/* Post chrome: the category label rendered at 13px tall (an AA failure at 24px) and
   the tag pills at 31px. Both are navigation rather than prose, so the "inline"
   exemption does not cover them.

   In-content list links (e.g. "Explore related buildings") are left at their natural
   24px: they sit inside the article's block of text, which 2.5.5/2.5.8 exempt, and
   they already clear the 24px AA minimum. Forcing 44px there would space a prose list
   out oddly for no real gain. */
.case-hero .wp-block-post-terms a,
.page-head .wp-block-post-terms a{display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;min-width:44px}
.post-tags a{min-height:44px;min-width:44px;display:inline-flex;align-items:center;
  justify-content:center;padding:9px 17px}

/* Archive pagination: page numbers rendered 8x14 and "Older" 40x22 — well under even
   the 24px AA minimum, and among the most-used controls on an archive. */
.wp-block-query-pagination a,
.wp-block-query-pagination .wp-block-query-pagination-numbers a,
.wp-block-query-pagination-next,
.wp-block-query-pagination-previous{
  min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;
  padding:0 12px;text-decoration:none}
.wp-block-query-pagination .page-numbers.current{
  min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center}
.wp-block-query-pagination{gap:4px;flex-wrap:wrap}

/* --- 1.4.1 Use of Colour -------------------------------------------------
   Links inside running text are distinguished by more than colour. */
.entry-content p a:not([class]),
.entry-content li a:not([class]){text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px}
.entry-content p a:not([class]):hover,
.entry-content li a:not([class]):hover{text-decoration-thickness:2px}

/* --- 2.4.7 / 1.4.11 focus visibility on dark grounds ----------------------- */
.wp-footer a:focus-visible,
.mh-burger .is-menu-open a:focus-visible{outline:2px solid #fff;outline-offset:3px}

/* ---------- portfolio grid + filters ----------
   One page, three bodies of work. Cards reuse the archive's .journal-item
   look (photo plate, corner-marked title, centred excerpt) at THREE columns
   on the wide measure — the archives themselves stay two-column. Buttons
   follow the site's small-caps label idiom; targets 44px+. Without JS all
   items show and the buttons are inert. */
.folio-grid-wrap{max-width:1400px;margin-left:auto;margin-right:auto}
.folio-filters{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;margin:8px 0 44px}
.folio-filter{min-height:44px;padding:0 22px;border:1px solid #767676;border-radius:999px;
  background:transparent;cursor:pointer;
  font-family:var(--sans);font-size:11px;font-weight:500;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink)}
.folio-filter:hover{border-color:var(--ink)}
.folio-filter[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff}
.folio-filter:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* blocks.css's prose-list rule (.wp-block-post-content ul → 1.4em indent)
   outweighs .folio-grid alone; the qualified selector below restores the
   reset. Without it the grid sits ~24px off-centre (left-heavy on phones). */
.wp-block-post-content ul.folio-grid{margin:0;padding:0}
.folio-grid{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(40px,4.5vw,60px) 24px}
/* the journal-item card is designed for a 2-col archive; trim it to 3-col scale */
.folio-grid .journal-item .wp-block-post-title{font-size:20px;line-height:1.2;max-width:380px;padding:18px 22px 20px;margin-top:22px}
.folio-grid .journal-item .wp-block-post-excerpt{max-width:380px;font-size:14px}
/* the page-content a11y rule underlines in-content links; card titles and
   plates are standalone controls like the archive's, not prose links */
.folio-grid .journal-item .wp-block-post-title a,
.folio-grid .journal-item .wp-block-post-featured-image a{text-decoration:none}
.folio-grid .journal-item .wp-block-post-excerpt__more-link{text-decoration:none}
@media (max-width:1160px){.folio-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:700px){.folio-grid{grid-template-columns:1fr}}

/* ---------- shared hero layer (poster hero + home scroller) ----------
   Extracted 2026-09-03 when the home scroller was built. The one-sheet
   lockup, the shade grade and the capped frame were authored for the
   poster template (design/poster-hero-directions.html option A, picked
   2026-08-27) and owner-tuned since; the scroller needs the identical
   treatment, so they live here once rather than being copied.

   The rule that matters: a page using either hero carries the `hero-page`
   body class, which supplies --glow/--glow-r and floats the masthead over
   the photograph. Anything that differs between the two templates stays in
   its own block below — currently only the lockup's bottom offset.

   If either treatment is re-tuned, tune it HERE. Two copies of a
   six-property gradient drift within a month; that is why this exists. */

/* dark text/mark glow, tunable: strength 0-1 and radius. Page-level so the
   masthead logo and burger share it with the hero text below. */
.hero-page{--glow:1;--glow-r:19px}

/* the sharp image lives in a centred 2000px frame over footer-ink flanks
   (owner call, 2026-08-28 — a light-flank experiment was reverted the same
   day). Inside the frame the crop anchors to the image's bottom centre, so
   growing viewports eat the sky, not the foreground.
   NOTE the lockup and the controls sit INSIDE this frame, so on an
   ultra-wide monitor the type centres on the photograph, not the window. */
.hero-frame{position:absolute;inset:0;max-width:2000px;margin:0 auto}
.hero-frame__img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center bottom;display:block}

/* the top layer is a scrim for the white masthead marks floating over the
   image — without it a pale sky swallows the logo.
   TUNING (owner iteration, 2026-09-01): every strength (0-1) and height (%)
   is a custom property, so rounds of adjustment are one-value edits — and
   they can be trialled live in DevTools on .hero-shade before committing.
   Reduced from the original heavier grade to show more of the photograph's
   true colour; the text-shadows carry more of the legibility. */
/* ---------- stacking order inside .hero-frame ----------
   Explicit, because the home scroller drives its slides' z-index from
   JavaScript and nothing else here declared one:

       slides   1-5   (set inline by assets/js/home-scroller.js)
       shade    10
       lockup   20
       controls 40     (credit, tick row, pause, cue)

   Both the shade and the lockup were previously z-index:auto, i.e. 0. That was
   harmless on a poster page, where the image is also auto and DOM order decides
   — but the scroller lifts its current slide to z-index 5, which put the
   PHOTOGRAPH above the shade and above the lockup. The result was a hero with
   no title and no button, and an ungraded image behind the credit. Found in
   Chrome 2026-09-03; it is invisible in the embedded pane, which does not
   composite the image layers at all. Do not remove these. */
.hero-shade{position:absolute;inset:0;z-index:10;
  --shade-top:.2;       /* top scrim strength   */
  --shade-top-h:7%;     /* top scrim reach      */
  --shade-btm:.48;      /* bottom edge strength */
  --shade-mid:.15;      /* mid strength         */
  --shade-mid-h:28%;    /* mid stop height      */
  --shade-fade:34%;     /* where it reaches 0   */
  background:linear-gradient(to bottom, rgba(11,11,11,var(--shade-top)) 0%, rgba(11,11,11,0) var(--shade-top-h)),
    linear-gradient(to top, rgba(11,11,11,var(--shade-btm)) 0%, rgba(11,11,11,var(--shade-mid)) var(--shade-mid-h), rgba(11,11,11,.1) calc((var(--shade-mid-h) + var(--shade-fade)) / 2), rgba(11,11,11,0) var(--shade-fade))}

/* hero pages: the photograph runs to the very top of the screen and the
   masthead floats over it — no frosted ground, white marks (logo inverted
   from its dark PNG). Absolute rather than sticky: a transparent bar over
   page copy would be unreadable once scrolled. */
/* wpautop leaves a stray <br> between the shortcode block and the hero
   (autop runs before shortcode expansion); no legitimate <br> can be a direct
   child of either hero's main, so suppress them wholesale */
.poster-main > br,
.home-main > br{display:none}

.hero-page .masthead{position:absolute;top:0;left:0;right:0;
  background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}
.hero-page .mh-logo img{filter:brightness(0) invert(1)
  drop-shadow(0 1px calc(var(--glow-r)*.4) rgba(0,0,0,var(--glow)))}
.hero-page .mh-burger .wp-block-navigation__responsive-container-open{color:#fff}
.hero-page .mh-burger .wp-block-navigation__responsive-container-open svg{fill:#fff;
  filter:drop-shadow(0 1px calc(var(--glow-r)*.4) rgba(0,0,0,var(--glow)))}

/* ---------- the one-sheet lockup ----------
   Centred movie-poster lockup: gold presenter line, tracked Futura-light
   caps title, hairline rule, billing line, outlined CTA. The single gold
   accent matches the tour interface (--wp-accent #d9b64a).
   `bottom` is deliberately NOT set here — each hero positions it. */
.hero-lockup{position:absolute;z-index:20;left:clamp(24px,4.5vw,64px);
  right:clamp(24px,4.5vw,64px);
  display:flex;flex-direction:column;align-items:center;text-align:center}
/* letterspaced centred caps: text-indent equal to the tracking rebalances the
   trailing letter-space so the line optically centres */
/* line-height is declared, not inherited: this element is a <p> on a poster
   page and an <h1> on the home scroller, and the theme gives headings a much
   tighter default. Pinning it keeps both renderings identical. */
.hero-lockup__presenter{margin:0;font-family:var(--sans);font-size:12.5px;
  line-height:2;
  font-weight:600;letter-spacing:.38em;text-indent:.38em;text-transform:uppercase;
  color:#d9b64a;text-shadow:0 1px 3px rgba(0,0,0,calc(var(--glow)*.85)), 0 1px calc(var(--glow-r)*.5) rgba(0,0,0,var(--glow)), 0 0 calc(var(--glow-r)*1.4) rgba(0,0,0,calc(var(--glow)*.5))}
.hero-lockup__title{margin:12px 0 0;font-family:var(--sans);font-weight:300;
  font-size:clamp(26px,3.7vw,54px);line-height:1.25;letter-spacing:.2em;
  text-indent:.2em;text-transform:uppercase;color:#fff;
  text-shadow:0 1px 3px rgba(0,0,0,calc(var(--glow)*.7)), 0 2px var(--glow-r) rgba(0,0,0,var(--glow)), 0 0 calc(var(--glow-r)*2.2) rgba(0,0,0,calc(var(--glow)*.6));max-width:1100px}
.hero-lockup__rule{width:72px;height:1px;background:rgba(255,255,255,.45);
  margin:14px 0 0}
.hero-lockup__billing{margin:12px 0 0;font-family:var(--sans);font-size:11.5px;
  font-weight:600;letter-spacing:.3em;text-indent:.3em;text-transform:uppercase;
  color:rgba(255,255,255,.72);text-shadow:0 1px 3px rgba(0,0,0,calc(var(--glow)*.85)), 0 1px calc(var(--glow-r)*.5) rgba(0,0,0,var(--glow)), 0 0 calc(var(--glow-r)*1.4) rgba(0,0,0,calc(var(--glow)*.5))}
/* One line always ("Enter the gigapixel" wrapped on phones, owner 2026-09-05): the
   side padding and the tracking clamp with the viewport, from a snug 18px/.22em on
   a 360px phone up to the 38px/.38em the design was set at. */
.hero-lockup__cta{display:inline-block;margin-top:26px;padding:12px clamp(18px,4.6vw,38px);
  white-space:nowrap;max-width:calc(100vw - 48px);
  border:1px solid rgba(255,255,255,.85);
  background:rgba(17,17,17,.5);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#fff;
  text-decoration:none;font-family:var(--sans);font-size:clamp(11px,2.9vw,12px);font-weight:500;
  letter-spacing:clamp(.22em,1vw,.38em);text-indent:clamp(.22em,1vw,.38em);text-transform:uppercase;
  transition:background-color .35s ease,color .35s ease}
@media (prefers-reduced-motion:reduce){.hero-lockup__cta{transition:none}}
.hero-lockup__cta:hover{background:rgba(255,255,255,.95);color:var(--ink)}
.hero-lockup__cta:focus-visible{outline:2px solid #fff;outline-offset:3px}
.hero-lockup__hint{margin:20px 0 0;font-family:var(--sans);font-size:12px;
  font-weight:400;letter-spacing:.18em;text-transform:uppercase;
  color:rgba(255,255,255,.65);text-shadow:0 1px 6px rgba(0,0,0,var(--glow))}

@media (max-width:640px){
  /* narrower measure: relax the tracking so titles fit the phone width */
  .hero-lockup__title{letter-spacing:.12em;text-indent:.12em;line-height:1.3}
  .hero-lockup__presenter{letter-spacing:.28em;text-indent:.28em}
  .hero-lockup__hint{display:none}
}

/* ---------- the scroll cue ----------
   Promoted out of the poster block 2026-09-03 when the scroller gained one too
   (owner ask). `bottom` is set by each hero, like .hero-lockup. */
.hero-cue{position:absolute;left:50%;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:5px;
  min-height:44px;min-width:44px;justify-content:flex-end;padding-bottom:4px;
  text-decoration:none;z-index:40}
.hero-cue span{font-family:var(--sans);font-size:11.5px;font-weight:600;
  letter-spacing:.26em;text-transform:uppercase;color:rgba(255,255,255,.7)}
.hero-cue svg{stroke:rgba(255,255,255,.7)}
.hero-cue:hover span{color:#fff}
.hero-cue:hover svg{stroke:#fff}
.hero-cue:focus-visible{outline:2px solid #fff;outline-offset:3px}
/* the cue's landing point, emitted immediately after each hero */
.hero-cue__target{display:block;height:0;overflow:hidden}
/* arrow-only variant (the home scroller). The label is still in the markup as
   .screen-reader-text, so the link keeps an accessible name; only the visual
   word goes. Nudged up slightly because the column has lost its first row. */
.hero-cue--markless{padding-bottom:10px}

/* ---------- poster hero (single-poster template) ----------
   The "one-sheet" direction (design/poster-hero-directions.html option A,
   picked 2026-08-27): full-bleed featured image as the page opening with
   the shared lockup above, and a scroll cue to the story. Pulled up under
   the sticky frosted masthead (55px), which keeps the logo and burger
   legible over any photograph. */
.poster-hero{position:relative;width:100%;min-height:520px;height:90vh;height:90svh;
  margin-top:calc(var(--header-h, 55px) * -1);
  background:#151515;overflow:hidden}
.hero-page .poster-hero{margin-top:0}
.poster-hero .hero-lockup{bottom:clamp(32px,5vh,56px)}
.poster-hero .hero-cue{bottom:12px}
.poster-main .textspine{padding-top:clamp(48px,6vw,80px)}

@media (max-width:640px){
  /* same 90% treatment as desktop — the old 72vh band stopped mid-screen
     and read as the photograph being chopped. svh keeps it steady while
     the iOS URL bar collapses. */
  .poster-hero{height:90vh;height:90svh;min-height:440px}
  .poster-hero .hero-cue{display:none}
}

/* ---------- home scroller (front page) ----------
   Built 2026-09-03 (design/homepage-scroller.html). Direction C from
   design/homepage-directions.html, narrowed by the owner to: FIXED lockup,
   SIMPLE fade, the poster pages' grade and glows, the same 2000px cap over
   #151515. Everything visual above this line is therefore inherited, not
   restated — this block is only the stack, the controls and the credit.

   Frame 1 is in the HTML and is the LCP; frames 2-n are adopted from a
   <template> after the load event by assets/js/home-scroller.js, so the
   above-the-fold cost is a single photograph. */
.home-scroller{position:relative;width:100%;min-height:520px;height:90vh;height:90svh;
  margin-top:calc(var(--header-h, 55px) * -1);
  background:#151515;overflow:hidden}
.hero-page .home-scroller{margin-top:0}
/* The bottom band stacks three things, and they are tuned together. Reading up
   from the bottom edge: the cue at 12px (same as a poster page), the tick row
   above it, then the lockup. Change them as a set — moving one alone opens a
   gap. Revised 2026-09-03 when the cue was added back at the owner's request.

       cue      12px          (~34px tall, so it occupies 12-46)
       credit   54px          (centred; 12px caps, occupies ~54-68) — moved here from
                              bottom-right 2026-09-05 (owner)
       ticks    clamp(84px,9.5vh,104px)
       lockup   clamp(108px,12.5vh,140px)                                     */
.home-scroller .hero-lockup{bottom:clamp(108px,12.5vh,140px)}
.home-scroller .hero-cue{bottom:12px}

/* --- a heavier bottom scrim, for this hero only ---
   The shared grade in .hero-shade is the owner's 2026-09-01 tuning, made
   against the poster pages' photographs, and it stays exactly as it is there.
   The scroller needs more: it runs six frames, and the high-key ones ("The City
   Awaits", "Bishopsgate Rising") put pale stone directly behind a white title,
   where the shared grade leaves the type barely legible. A fixed lockup cannot
   move out of the way the way a poster's one-off composition can.

   This is the whole point of the grade being custom properties — the override
   is four values and the poster pages are untouched.

   Reading up from the bottom edge, the resulting stops are:
       0%   .72   the cue, tick row and credit sit here
       34%  .40   the lockup: presenter, title, rule, billing, CTA
       47%  .10
       60%  0     clean photograph above this line
   Raise --shade-btm and --shade-mid together if a future frame still fights the
   type; raise --shade-fade if the transition edge becomes visible. */
.home-scroller .hero-shade{
  --shade-btm:.72;      /* was .48 */
  --shade-mid:.40;      /* was .15 */
  --shade-mid-h:34%;    /* was 28% */
  --shade-fade:60%;     /* was 34% */
}

/* --- the stack --- */
.home-scroller__stack{position:absolute;inset:0}
.home-scroller__slide{position:absolute;inset:0;opacity:0}
/* no-JS / pre-JS ground truth: frame 1 shows. The script then drives
   opacity and z-index inline, so this is only ever the starting state. */
.home-scroller__slide:first-child{opacity:1}

/* --- the credit, in the __hint voice: centred between the tick row and the cue --- */
.home-scroller__credit{position:absolute;z-index:40;
  left:50%;transform:translateX(-50%);bottom:54px;white-space:nowrap;max-width:calc(100% - 48px);
  overflow:hidden;text-overflow:ellipsis;
  margin:0;text-align:center;font-family:var(--sans);font-size:12px;font-weight:400;
  letter-spacing:.18em;text-transform:uppercase;color:rgba(255,255,255,.65);
  text-shadow:0 1px 6px rgba(0,0,0,var(--glow));transition:opacity .45s ease}
.home-scroller__credit b{font-weight:500;color:rgba(255,255,255,.88)}

/* --- the controls, centred below the lockup --- */
.home-scroller__ui{position:absolute;z-index:40;left:50%;transform:translateX(-50%);
  bottom:clamp(84px,9.5vh,104px);display:flex;align-items:center;gap:16px}
.home-scroller__ticks{display:flex;gap:7px}
/* The BUTTON is the 34x44 target (SC 2.5.8); the 2px bar is drawn inside it by the
   pseudo-elements. Axe measures the element box, not a ::before, which is why the
   previous "invisible hit area on ::before" version failed PageSpeed 2026-09-04.
   The negative vertical margin keeps the row 2px tall in the layout, so nothing
   around it moves. */
.home-scroller__ticks button{position:relative;width:34px;height:44px;margin:-21px 0;padding:0;
  border:0;cursor:pointer;background:transparent;overflow:visible}
.home-scroller__ticks button::before{content:"";position:absolute;left:0;right:0;top:21px;height:2px;
  background:rgba(255,255,255,.34)}
.home-scroller__ticks button::after{content:"";position:absolute;left:0;right:0;top:21px;height:2px;
  background:#fff;transform:scaleX(0);transform-origin:left}
/* The fill IS the pacing indicator, so its duration has to match data-hold.
   The script sets --hold per button from that attribute; the 6s fallback is
   only what an unscripted page would use, and nothing advances there anyway. */
.home-scroller__ticks button[aria-current="true"]::after{transform:scaleX(1);
  transition:transform var(--hold,6s) linear}
.home-scroller__ticks button.is-done::after{transform:scaleX(1);transition:none}
.home-scroller__ticks button:focus-visible{outline:2px solid #fff;outline-offset:0}
/* --- the pause control ---
   The visible transport (prev / pause / next circles) was removed 2026-09-03 at
   the owner's request: it read as player furniture over the photograph. Auto-
   advancing content still needs a pause mechanism (SC 2.2.2), so the control
   survives as a focus-revealed button, exactly the idiom .skip-link already uses
   in this stylesheet. It sits above the ticks, is 1px and clipped until focused,
   and is absolutely positioned so it never affects the ticks' layout.
   The ticks are the pointer-user half of the same requirement: using one stops
   auto-advance for the rest of the visit. */
.home-scroller__pause{position:absolute;left:50%;bottom:100%;margin-bottom:14px;
  transform:translateX(-50%);
  width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);
  white-space:nowrap;border:0;background:none;color:#fff;cursor:pointer}
.home-scroller__pause:focus{width:auto;height:auto;clip:auto;overflow:visible;
  padding:10px 22px;border:1px solid rgba(255,255,255,.75);border-radius:30px;
  background:rgba(17,17,17,.6);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  font-family:var(--sans);font-size:11px;font-weight:500;letter-spacing:.2em;
  text-indent:.2em;text-transform:uppercase;
  outline:2px solid #fff;outline-offset:3px}

@media (prefers-reduced-motion:reduce){
  /* the script also refuses to auto-advance; this covers the transition
     itself so a manual jump is an instant cut rather than a fade */
  .home-scroller__slide{transition:none !important}
  .home-scroller__ticks button[aria-current="true"]::after{transition:none}
  .home-scroller__credit{transition:none}
}
@media (max-width:640px){
  .home-scroller{height:90vh;height:90svh;min-height:440px}
  /* the credit is centred under the ticks now; on phones the title alone fits,
     so the " · Gigapixel panorama" descriptor is dropped rather than truncated */
  .home-scroller__credit{font-size:11px}
  .home-scroller__credit-kind{display:none}
  .home-scroller .hero-lockup{bottom:clamp(98px,12vh,120px)}
}

/* ---------- contact enquiry form (Zoho via /enquiry Worker) ----------
   Raw-HTML Zoho Forms form on /contact/, ported from the Eye Revolution
   contact build (2026-09-01): same field idiom as the WPForms a11y rules
   above, which these replace once WPForms is retired. Validation UX lives
   in assets/js/enquiry-form.js; bot defence is a honeypot + time trap in
   that file and Cloudflare Turnstile verified server-side by the /enquiry
   Worker (ContactForm/enquiry-worker/worker.js). */
.enq-form{max-width:560px}
/* float labels (v2, owner ask 2026-09-01: names inside the fields, compact):
   the real <label> sits inside the field and shrinks to a caption inside its
   top edge on focus/fill — never vanishing like a placeholder would (3.3.2).
   Requires the label to FOLLOW its control in the markup, and placeholder=" "
   on the control for the :placeholder-shown trigger. */
.enq-form .field{position:relative;margin:0 0 14px}
.enq-form label{position:absolute;left:15px;top:15px;margin:0;pointer-events:none;
  font-family:var(--sans);font-size:14.5px;font-weight:400;letter-spacing:.02em;
  text-transform:none; /* beats catalogue.css .field label uppercase */
  color:var(--ink-2);
  transition:top .15s ease,font-size .15s ease}
@media (prefers-reduced-motion:reduce){.enq-form label{transition:none}}
.enq-form label .req{font-weight:400;color:var(--ink-3)}
.enq-form input[type="text"],
.enq-form input[type="email"],
.enq-form textarea{width:100%;min-height:52px;padding:22px 14px 6px;
  border:1px solid #767676;border-radius:7px;background:var(--paper);
  box-shadow:inset 0 1px 5px rgba(30,30,36,.07);
  font-family:var(--sans);font-size:16px;color:var(--ink)}
.enq-form textarea{min-height:110px;resize:vertical}
.enq-form input:focus + label,
.enq-form input:not(:placeholder-shown) + label,
.enq-form textarea:focus + label,
.enq-form textarea:not(:placeholder-shown) + label{top:5px;font-size:10.5px;
  color:var(--ink-3)}

.enq-form input:focus-visible,
.enq-form textarea:focus-visible{outline:2px solid var(--ink);outline-offset:2px;
  border-color:var(--ink)}
.enq-form [aria-invalid="true"]{border-color:#9b2c2c}
.enq-form .field-err{margin:8px 0 0;font-family:var(--sans);font-size:13px;
  font-weight:400;color:#9b2c2c}
.enq-form .enq-status{min-height:0;margin:0;font-family:var(--sans);
  font-size:14px;color:var(--ink-2)}
.enq-form .enq-status:not(:empty){margin:0 0 10px}
.enq-form .cf-turnstile{margin:2px 0 10px}
.enq-form .enq-send{display:inline-flex;align-items:center;min-height:48px;
  padding:0 36px;border:0;border-radius:7px;background:var(--ink);cursor:pointer;
  color:#fff;font-family:var(--sans);font-size:14.5px;font-weight:400;
  letter-spacing:.04em;
  transition:background-color .35s ease,color .35s ease}
@media (prefers-reduced-motion:reduce){.enq-form .enq-send{transition:none}}
/* hover fades to the gold accent; ink text keeps the contrast honest */
.enq-form .enq-send:hover{background:#d9b64a;color:var(--ink)}
.enq-form .enq-send:focus-visible{outline:2px solid var(--ink);outline-offset:3px}

/* ---------- home "Explore" loop: the portfolio card, dark ----------
   The home page's Query Loop (className home-folio, page 4093) reuses the
   portfolio's .journal-item look — photo plate, corner-marked serif title,
   centred excerpt, Read more — on the #151515 band. Core's grid li has no
   .journal-item class, so the rules are restated here scoped to .home-folio.
   Colours: title #fff, excerpt #b8b8b8 (9.6:1 on the band), accent the tour-UI
   gold #d9b64a (9.6:1) for hover and Read more. */
/* blocks.css's prose-list rule (.wp-block-post-content ul → 1.4em indent) also hits the loop's <ul>,
   pushing the cards ~26px right of the heading; the qualified selector resets it (same fix as .folio-grid). */
.wp-block-post-content .home-folio ul.wp-block-post-template{margin:0;padding:0}
.home-folio .wp-block-post-template{gap:clamp(40px,4.5vw,60px) 24px}
.home-folio .wp-block-post{margin:0;padding:0;border:0;max-width:none}
.home-folio .wp-block-post-featured-image{position:relative;margin:0;overflow:hidden;background:#000;aspect-ratio:16/9}
.home-folio .wp-block-post-featured-image a,
.home-folio .wp-block-post-featured-image img{display:block;width:100%;height:100%}
.home-folio .wp-block-post-featured-image img{object-fit:cover;transition:transform .65s cubic-bezier(.2,.6,.2,1)}
.home-folio .wp-block-post:hover .wp-block-post-featured-image img{transform:scale(1.02)}
.home-folio .wp-block-post-title{position:relative;max-width:380px;margin:22px auto 0;padding:18px 22px 20px;text-align:center;
  font-family:var(--serif);font-weight:500;font-size:20px;line-height:1.2;letter-spacing:-.005em;text-transform:none;color:#fff;
  background-image:linear-gradient(var(--gold-line),var(--gold-line)),linear-gradient(var(--gold-line),var(--gold-line)),linear-gradient(var(--gold-line),var(--gold-line)),linear-gradient(var(--gold-line),var(--gold-line)),linear-gradient(var(--gold-line),var(--gold-line)),linear-gradient(var(--gold-line),var(--gold-line)),linear-gradient(var(--gold-line),var(--gold-line)),linear-gradient(var(--gold-line),var(--gold-line));
  background-repeat:no-repeat;
  background-size:14px 1px,1px 14px,14px 1px,1px 14px,14px 1px,1px 14px,14px 1px,1px 14px;
  background-position:left top,left top,right top,right top,left bottom,left bottom,right bottom,right bottom}
/* blocks.css's .wp-block-post-content p and site.css's .entry-content li a:not([class]) outrank the plain
   card selectors, so the text rules below carry the extra .wp-block-post class to win on specificity. */
.home-folio .wp-block-post .wp-block-post-title a{color:inherit;text-decoration:none}
.home-folio .wp-block-post .wp-block-post-excerpt p{color:#b8b8b8;font-size:14px;line-height:1.6;margin:0}
.home-folio .wp-block-post:hover .wp-block-post-title{color:#d9b64a}
.home-folio .wp-block-post-excerpt{max-width:380px;margin:14px auto 0;text-align:center;font-size:14px;line-height:1.6;color:#b8b8b8}
.home-folio .wp-block-post-excerpt__more-link{color:#d9b64a;text-decoration:none;border-bottom:1px solid rgba(217,182,74,.6)}
.home-folio .wp-block-post-excerpt__more-link:hover{border-bottom-color:#d9b64a}
.home-folio .wp-block-post-title a:focus-visible,
.home-folio .wp-block-post-excerpt__more-link:focus-visible,
.home-folio .wp-block-post-featured-image a:focus-visible{outline:2px solid #d9b64a;outline-offset:3px}
@media (prefers-reduced-motion:reduce){.home-folio .wp-block-post-featured-image img{transition:none}.home-folio .wp-block-post:hover .wp-block-post-featured-image img{transform:none}}

/* /prints/ headings were h3 straight under the h1 (axe heading-order). They are
   now h2 for the outline, with the h3 scale kept so the page looks the same. */
.wp-block-post-content h2.wp-block-heading.h3-scale{font-weight:400;font-size:21px;letter-spacing:.048em;line-height:1.6;margin:var(--space-sm) 0 .6em}
