/* =========================================================
   Brillersys — article, author and archive components.

   Kept separate from main.css on purpose. main.css is the
   design system exactly as it arrived in html/, and staying
   able to diff it against that folder is worth one extra
   request. Everything here is what the WordPress theme had
   to add: the design file had a blog index but no single
   post, author archive, search or pagination view.

   Contrast is held to the sheet it extends. Body copy on
   white takes --muted (4.85:1). --muted-2 is 2.79:1 and is
   never used for text at reading size.
   ========================================================= */

/* ---- accessibility plumbing ---- */
.screen-reader-text{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.skip-link:focus{position:fixed;top:12px;left:12px;z-index:2000;width:auto;height:auto;
  clip:auto;margin:0;padding:12px 20px;background:#fff;color:var(--ink);
  border-radius:var(--r-pill);box-shadow:var(--shadow);font-weight:600}

/* ---- index tiles ----
   main.css styles .entry as a two-column editorial row. The brief changed to
   tiles, so these override it rather than editing main.css, which is kept
   diffable against the html/ design folder. The .entry class stays on the
   markup because the category filter in main.js selects on it. */
.entries{display:grid;grid-template-columns:repeat(auto-fill,minmax(310px,1fr));
  gap:30px;border-bottom:0}
.entry-card{display:flex;flex-direction:column;grid-template-columns:none;
  padding:0;border-top:0;border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;background:#fff;box-shadow:var(--shadow);
  transition:transform .35s var(--ease),box-shadow .35s var(--ease),
             border-color .35s var(--ease)}
.entry-card:hover{transform:translateY(-4px);border-color:transparent;
  box-shadow:var(--shadow-lg)}
.entry-card:focus-visible{outline:2px solid var(--teal-ink);outline-offset:3px}

/* A fixed ratio is right here, unlike the lead image on the post: a grid of
   tiles needs one shape, and 3:2 matches the brs-card crop WordPress makes. */
.entry-thumb{position:relative;aspect-ratio:3/2;background:var(--bg-soft2);
  overflow:hidden;flex:0 0 auto}
.entry-thumb img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .6s var(--ease)}
.entry-card:hover .entry-thumb img{transform:scale(1.05)}
.entry-thumb-fallback{position:absolute;inset:0;display:grid;place-items:center;
  padding:0 22px;text-align:center;background:var(--grad);color:#fff;
  font-family:'Space Grotesk',sans-serif;font-weight:700;font-size:1.05rem;
  letter-spacing:-.01em}

.entry-body{display:flex;flex-direction:column;flex:1 1 auto;padding:22px 24px 20px}
.entry-card h3{font-size:1.16rem;line-height:1.32;margin:9px 0 10px;
  transition:color .2s var(--ease)}
.entry-card:hover h3{color:var(--warm-ink)}
.entry-card p{color:var(--muted);font-size:.95rem;line-height:1.6;margin:0;
  max-width:none;
  /* Three lines, so tiles in a row keep their feet in line whatever the
     excerpt length. The full text is on the post. */
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden}
/* margin-top:auto pins the meta to the bottom of the tile regardless of how
   many lines the title took. */
.entry-foot{display:flex;flex-wrap:wrap;align-items:baseline;gap:.45em;
  margin-top:auto;padding-top:16px;color:var(--muted);font-size:.84rem}
.entry-card .entry-read{color:var(--muted)}
.entry-dot{color:var(--muted-2)}

@media(max-width:640px){
  .entries{grid-template-columns:1fr;gap:24px}
}

/* ---- byline ---- */
.byline{display:flex;align-items:center;gap:13px}
.byline-photo{flex:0 0 auto;line-height:0;border-radius:var(--r-pill);overflow:hidden}
.byline-photo img{width:48px;height:48px;object-fit:cover;border-radius:var(--r-pill)}
.byline-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.byline-name{font-family:'Space Grotesk',sans-serif;font-weight:600;font-size:1rem;
  color:var(--ink);transition:color .2s var(--ease)}
.byline-name:hover{color:var(--warm-ink)}
.byline-meta{font-size:.86rem;color:var(--muted);display:flex;flex-wrap:wrap;
  align-items:baseline;gap:.4em}
.byline-dot{color:var(--muted-2)}

/* ---- post header ----
   Navy rather than the photographic .thero used by the section landing pages:
   a post supplies its own lead image immediately below, and two images stacked
   would compete for the same job. */
.phero{background:#124451;color:#fff;padding:132px 0 54px}
.phero h1{color:#fff;font-size:clamp(2.1rem,4.4vw,3.2rem);font-weight:700;
  letter-spacing:-.025em;margin:18px 0 0;max-width:20ch}
.phero-lede{color:rgba(255,255,255,.82);font-size:1.12rem;line-height:1.65;
  margin:18px 0 0;max-width:60ch}
.phero .byline{margin-top:30px;padding-top:26px;
  border-top:1px solid rgba(255,255,255,.16)}
.phero .byline-name{color:#fff}
.phero .byline-name:hover{color:var(--warm-2)}
/* .82 alpha on #124451 is 6.6:1; the dots at .55 are decorative separators. */
.phero .byline-meta{color:rgba(255,255,255,.82)}
.phero .byline-dot{color:rgba(255,255,255,.55)}
.phero .byline-photo img{border:1px solid rgba(255,255,255,.28)}

/* breadcrumb, shared by the post, archive and author headers */
.crumbs{display:inline-flex;align-items:center;gap:.5em;font-size:.8rem;
  font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--warm-2)}
.crumbs a{color:inherit;transition:color .2s var(--ease)}
.crumbs a:hover{color:#fff}
.thero .crumbs{color:#F5B072}

/* ---- lead image ----
   Sits below the navy header rather than overlapping it. It was pulled up into
   the band to bridge the header and the body, but with a tall image that reads
   as the picture colliding with the byline above it. */
.plead{margin:0}
.plead .wrap{margin-top:44px}
/* No forced aspect ratio. The featured images run from 1:1 to nearly 3:1, and
   cropping them to 16:9 threw away almost half of the square ones. Capping the
   height instead lets a tall image shrink and centre rather than lose its top
   and bottom, and a wide one still runs full width. */
.plead img{max-width:100%;width:auto;height:auto;max-height:min(68vh,600px);
  margin:0 auto;border-radius:var(--r-lg);box-shadow:var(--shadow-lg);display:block}
.plead figcaption{color:var(--muted);font-size:.86rem;line-height:1.6;
  margin:12px 2px 0;max-width:70ch}

/* ---- article body ----
   One measure for everything in the article: 72ch of Inter at 1.09rem lands a
   little over 720px, which is where the rest of the site sets body copy. */
.pbody{padding-top:44px}
.prose{max-width:72ch;margin:0 auto;font-size:1.09rem;line-height:1.78;
  color:var(--ink-2)}
.prose > * + *{margin-top:1.35em}
.prose h2{font-size:clamp(1.5rem,2.6vw,2rem);line-height:1.22;
  margin-top:2.1em;margin-bottom:.1em;letter-spacing:-.02em}
.prose h3{font-size:clamp(1.2rem,2vw,1.5rem);line-height:1.3;
  margin-top:1.8em;margin-bottom:.1em}
.prose h4{font-size:1.1rem;margin-top:1.6em;margin-bottom:.1em}
.prose h2 + *,.prose h3 + *,.prose h4 + *{margin-top:.6em}
.prose a{color:var(--blue-ink);text-decoration:underline;
  text-underline-offset:3px;text-decoration-thickness:1px}
.prose a:hover{color:var(--ink)}
.prose strong{color:var(--ink);font-weight:600}
.prose ul,.prose ol{padding-left:1.4em}
.prose li + li{margin-top:.5em}
.prose ul{list-style:disc}
.prose ol{list-style:decimal}
.prose img{border-radius:var(--r);width:100%;height:auto}
.prose figure{margin-inline:0}
.prose figcaption{color:var(--muted);font-size:.86rem;line-height:1.6;
  margin-top:10px;text-align:left}
.prose blockquote{border-left:3px solid var(--warm);padding-left:22px;
  font-family:'Space Grotesk',sans-serif;font-size:1.2rem;line-height:1.5;
  font-weight:500;color:var(--ink);letter-spacing:-.01em}
.prose blockquote cite{display:block;margin-top:10px;font-family:'Inter',sans-serif;
  font-size:.9rem;font-weight:500;font-style:normal;color:var(--muted)}
.prose code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:.9em;background:var(--bg-soft2);border:1px solid var(--line);
  border-radius:6px;padding:.15em .4em}
.prose pre{background:#0E1116;color:#E6E9EE;border-radius:var(--r);
  padding:20px 22px;overflow-x:auto;font-size:.9rem;line-height:1.6}
.prose pre code{background:none;border:0;padding:0;color:inherit;font-size:inherit}
.prose hr{border:0;border-top:1px solid var(--line);margin-block:2.4em}
/* A table can be wider than the measure; it scrolls in its own box rather than
   pushing the page sideways. */
.prose figure.wp-block-table,.prose .wp-block-table{overflow-x:auto}
.prose table{width:100%;border-collapse:collapse;font-size:.96rem}
.prose th,.prose td{border:1px solid var(--line);padding:10px 14px;text-align:left}
.prose th{background:var(--bg-soft);font-weight:600;color:var(--ink)}
/* Blocks allowed to break the measure and run to the section width. */
.prose .alignwide{max-width:min(1000px,100%);margin-inline:auto}
.prose .alignfull{max-width:none}
.prose .aligncenter{text-align:center;margin-inline:auto}
.prose .wp-block-embed__wrapper{position:relative}
.prose .wp-block-image{margin-inline:0}

/* credit line for a cross-posted piece */
.pcredit{max-width:72ch;margin:0 auto 30px;padding:12px 18px;
  background:var(--bg-soft);border-left:3px solid var(--warm);
  border-radius:0 var(--r) var(--r) 0;color:var(--muted);font-size:.92rem}
.pcredit a{color:var(--warm-ink);font-weight:600}

/* ---- category tags under the article ---- */
.ptags{max-width:72ch;margin:52px auto 0;padding-top:26px;
  border-top:1px solid var(--line);display:flex;flex-wrap:wrap;gap:9px}
.ptags a{font-size:.82rem;font-weight:500;color:var(--ink-2);
  background:var(--bg-soft);border:1px solid var(--line);
  border-radius:var(--r-pill);padding:7px 14px;
  transition:border-color .2s var(--ease),color .2s var(--ease)}
.ptags a:hover{border-color:var(--warm);color:var(--warm-ink)}

/* ---- author card ---- */
.authorcard{max-width:72ch;margin:44px auto 0;display:grid;
  grid-template-columns:112px 1fr;gap:26px;align-items:start;
  background:var(--bg-soft);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:30px 32px}
.authorcard-photo{width:112px;height:112px;object-fit:cover;
  border-radius:var(--r-pill);display:block}
.authorcard-label{font-size:.72rem;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--warm-ink)}
.authorcard-name{font-size:1.32rem;margin:8px 0 0}
.authorcard-name a{transition:color .2s var(--ease)}
.authorcard-name a:hover{color:var(--warm-ink)}
.authorcard-role{color:var(--muted);font-size:.92rem;font-weight:600;margin:4px 0 0}
.authorcard-bio{color:var(--muted);font-size:.98rem;line-height:1.7;
  margin:12px 0 0;max-width:60ch}
.authorcard-links{display:flex;flex-wrap:wrap;gap:16px;margin:14px 0 0}
.authorcard-links a{font-size:.88rem;font-weight:600;color:var(--blue-ink)}
.authorcard-links a:hover{color:var(--ink)}

/* ---- author archive header ---- */
.ahero-author{background:#124451;color:#fff;padding:132px 0 60px}
.ahero-author-inner{display:grid;grid-template-columns:160px 1fr;gap:36px;
  align-items:center;margin-top:24px}
.ahero-photo{width:160px;height:160px;object-fit:cover;
  border-radius:var(--r-pill);border:1px solid rgba(255,255,255,.28);display:block}
.ahero-author .eyebrow{color:var(--warm-2)}
.ahero-author .eyebrow::before{background:var(--warm-2)}
.ahero-author h1{color:#fff;font-size:clamp(2rem,4.2vw,3rem);margin:14px 0 0}
.ahero-role{color:var(--warm-2);font-size:1rem;font-weight:600;margin:8px 0 0}
.ahero-bio{color:rgba(255,255,255,.82);font-size:1.04rem;line-height:1.7;
  margin:14px 0 0;max-width:62ch}
.ahero-links{display:flex;flex-wrap:wrap;gap:18px;margin:18px 0 0}
.ahero-links a{font-size:.9rem;font-weight:600;color:#fff;
  border-bottom:1px solid rgba(255,255,255,.4);padding-bottom:2px}
.ahero-links a:hover{border-color:var(--accent);color:var(--accent)}

/* ---- keep reading ---- */
.related{background:var(--bg-soft)}
.related .sec-head{margin-bottom:12px}
.related .entries{border-bottom:0}

/* ---- pagination ---- */
.pager{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin-top:44px}
.pager .page-numbers{display:inline-flex;align-items:center;justify-content:center;
  min-width:42px;height:42px;padding:0 14px;border-radius:var(--r-pill);
  border:1px solid var(--line-2);font-size:.92rem;font-weight:600;
  color:var(--ink-2);transition:border-color .2s var(--ease),color .2s var(--ease)}
.pager a.page-numbers:hover{border-color:var(--warm);color:var(--warm-ink)}
.pager .page-numbers.current{background:var(--warm-ink);border-color:var(--warm-ink);
  color:#fff}
.pager .dots{border-color:transparent}

/* ---- search form ---- */
.searchform{display:flex;gap:10px;flex-wrap:wrap;margin:0 0 34px;max-width:560px}
.searchform input[type=search]{flex:1 1 220px;font:inherit;font-size:1rem;
  padding:12px 18px;border:1px solid var(--line-2);border-radius:var(--r-pill);
  background:#fff;color:var(--ink)}
.searchform input[type=search]:focus{outline:2px solid var(--teal-ink);
  outline-offset:1px;border-color:transparent}

@media(max-width:760px){
  .phero{padding:110px 0 44px}
  .plead .wrap{margin-top:28px}
  .authorcard{grid-template-columns:1fr;gap:18px;padding:26px 24px}
  .authorcard-photo{width:88px;height:88px}
  .ahero-author{padding:110px 0 48px}
  .ahero-author-inner{grid-template-columns:1fr;gap:22px}
  .ahero-photo{width:112px;height:112px}
  .prose{font-size:1.04rem}
}

/* ---- form results and the bot trap ----
   The honeypot is removed from the accessibility tree and from the tab order in
   the markup; this takes it out of the visual flow too, without display:none,
   which some bots check for. */
.brs-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form-result{margin:0 0 22px;padding:14px 20px;border-radius:var(--r);
  font-size:.98rem;line-height:1.6;max-width:70ch;scroll-margin-top:110px}
.form-result--ok{background:rgba(14,122,120,.09);border-left:3px solid var(--teal-ink);
  color:var(--ink)}
.form-result--bad{background:rgba(180,83,31,.09);border-left:3px solid var(--warm-ink);
  color:var(--ink)}
.form-result:focus{outline:2px solid var(--teal-ink);outline-offset:3px}

/* ---- monogram, used when an author has no portrait ----
   Sized inline by brs_monogram_avatar(), which also passes the tint as
   --monogram-bg rather than as a background, so the dark grounds below can
   override it. */
.monogram{display:inline-flex;align-items:center;justify-content:center;
  border-radius:var(--r-pill);background:var(--monogram-bg,#124451);color:#fff;
  font-family:'Space Grotesk',sans-serif;font-weight:700;letter-spacing:.02em;
  line-height:1;flex:0 0 auto;-webkit-user-select:none;user-select:none}
/* The post and author headers are #124451 themselves, so the brand tint would
   disappear into them. A translucent white disc reads on both, and white on it
   stays above 7:1. */
.phero .monogram,.ahero-author .monogram{background:rgba(255,255,255,.16);
  border:1px solid rgba(255,255,255,.30)}

/* ---- home page Insights list ----
   The design's .note entries were placeholders with nowhere to point, so its
   heading carried no link state. They are real posts now. */
.note h3 a{color:inherit;transition:color .2s var(--ease)}
.note h3 a:hover{color:var(--warm-ink)}
.note h3 a:focus-visible{outline:2px solid var(--teal-ink);outline-offset:3px;
  border-radius:4px}

/* ---- Focus Areas carousel: start at the left ----
   The design centred the focused card, padding the track by half its width so
   card 01 sat in the middle. At rest that leaves the left half of a full-width
   navy band empty, with the heading floating above nothing. Cards now begin at
   the content's left edge and snap to the start, which also lines their left
   edge up with the section heading above them. */
.focus .steps{padding-inline:0}
.focus .step{scroll-snap-align:start}
/* The fade existed to dissolve partial cards at both edges. With a left start
   the first card is flush against the edge, so fading it would just look like
   clipping; only the right-hand overflow still needs it. */
.focus .steps{-webkit-mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 56px),transparent 100%);
  mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 56px),transparent 100%)}
@media(max-width:700px){
  .focus .steps{-webkit-mask-image:none;mask-image:none}
}

/* ---- decorative traces: keep them out of the text ---------------------
   Each band anchors two fixed 2000px SVGs to opposite corners, and hides
   them below a breakpoint because "there is no side margin for a loop to
   sit in". The breakpoint was the wrong instrument: what matters is how
   much gutter there is beside the 1200px content column, and the loops
   reach ~270px in from their edge (~392px on the event page). Anywhere the
   gutter is narrower than that, the cable ran straight through the copy —
   at 1500px wide it crossed the "Aspire · Innovate · Measure · Learn" line.

   Offsetting by the shortfall instead lets the motif degrade rather than
   collide: full loop on a wide monitor, progressively clipped as the gutter
   closes, and only the straight cable left by the time the column reaches
   the edge. --trace-reach is how far each set of paths actually extends. */
.disc .trace,.statement .trace{--trace-reach:290px}
.demos .trace{--trace-reach:410px}
.disc .trace-t,.statement .trace-t,.demos .trace-t{
  right:min(0px,calc((100% - 1200px) / 2 - var(--trace-reach)))}
.disc .trace-b,.statement .trace-b,.demos .trace-b{
  left:min(0px,calc((100% - 1200px) / 2 - var(--trace-reach)))}

/* ---- services wheel on small screens ---------------------------------
   Below 980px the design unwinds the wheel: the SVG goes, the buttons lose
   their transforms and become a wrapped row, and the hub becomes a plain
   panel. But .wheel-btns keeps position:absolute and inset:0 from the
   desktop rule, so the row of buttons stays a layer pinned over .wheel —
   landing exactly on top of the hub panel, both 230px tall at the same
   offset. The section looked empty because everything was stacked in one
   place. Taking it back into flow is the missing half of that unwinding. */
@media(max-width:980px){
  .wheel-btns{position:static;inset:auto}
}

/* =========================================================
   iOS Safari
   Four places where the home page behaves differently there
   than on Android Chrome. None of them are visible on a
   desktop browser, which is why they survived the design.
   ========================================================= */

/* 1. The pinned hero.
   body carries overflow-x:hidden, which makes the body a scroll container,
   and iOS Safari then refuses to honour position:sticky on a descendant.
   .subhero-video is sticky so the page scrolls over the hero — the single
   biggest difference between the two platforms on the home page.
   overflow-x:clip contains the same horizontal overflow without creating a
   scroll container, so sticky keeps working. Guarded, because a browser
   without clip support must keep the hidden it already has. */
@supports (overflow-x: clip) {
  body { overflow-x: clip }
}

/* 2. Hero height.
   iOS resolves vh against the LARGE viewport, the one with the address bar
   scrolled away, so a 92vh hero is taller than what the reader can actually
   see on load and the scroll cue starts below the fold. svh is the small
   viewport — the address bar showing — which is the state the page loads in. */
@supports (height: 100svh) {
  .subhero { min-height: 92svh }
  .subhero-video { min-height: 92svh }
}

/* 3. Frosted panels.
   Safari still needs the prefix, so on iOS these rendered as flat translucent
   white rectangles over the photograph rather than blurring it. */
.feat-media .mtag,
.feat-media .ic,
.hl-ic { -webkit-backdrop-filter: blur(8px) }

/* 4. The mobile menu panel.
   It was pinned with inset:60px, a guess at the bar's height. The bar is
   about 68px at rest and 60px once scrolled, so the panel overlapped it by
   8px at the top of the page and moved as the bar shrank. Anchoring to the
   bar itself rather than to the viewport makes it follow whatever height the
   bar happens to be; .nav is fixed, so it is the containing block. */
@media (max-width: 1000px) {
  .nav-links {
    position: absolute;
    top: 100%;
    right: 0;
    bottom: auto;
    left: 0;
  }
}

/* ---- the mobile menu over a transparent bar --------------------------
   On a page with a full-bleed hero the bar starts transparent with white
   content, and opening the menu turns it white via .nav-over.menu-open.
   The background was switched but the contents were not: the logo, the
   links and the burger are all still coloured by .nav-over:not(.scrolled),
   which is still true because the reader has not scrolled yet. White on
   white — the only readable item was the current page, in light blue.
   Scrolling first added .scrolled and hid the whole problem.

   Same specificity as the rules being overridden, so ordering decides it. */
.nav-over.menu-open .brand img{filter:none}
.nav-over.menu-open .nav-links a{color:var(--ink-2)}
.nav-over.menu-open .nav-links a:hover{color:var(--ink)}
.nav-over.menu-open .nav-links a.active{color:var(--blue-ink)}
.nav-over.menu-open .nav-sep{background:var(--line-2)}
.nav-over.menu-open .burger span{background:var(--ink)}
