/* ==========================================================================
   Pentara® site styles: hand-maintained, plain CSS, no build step.

   Loaded after /css/tailwind.min.css (the frozen utility classes). None of
   these rules is inside an @layer, so they win over a utility class wherever
   both apply, exactly as in the approved design export.

   1. Self-hosted fonts
   2. Design tokens and components, from the design export
   3. Additions the production site needed: cookie banner, forms,
      publications list, accessibility
   ========================================================================== */

/* ==========================================================================
   1. FONTS
   ========================================================================== */
/* Self-hosted so no visitor IP is sent to Google Fonts (a GDPR problem in the
   EU without consent). Only the weights the pages actually use are declared;
   the browser downloads a file only when a rule on the page needs it. */
@font-face { font-family: "Open Sans"; src: url("/fonts/open-sans-400.ttf") format("truetype"); font-style: normal; font-weight: 400; font-display: swap; }
@font-face { font-family: "Open Sans"; src: url("/fonts/open-sans-400-italic.ttf") format("truetype"); font-style: italic; font-weight: 400; font-display: swap; }
@font-face { font-family: "Open Sans"; src: url("/fonts/open-sans-500.ttf") format("truetype"); font-style: normal; font-weight: 500; font-display: swap; }
@font-face { font-family: "Open Sans"; src: url("/fonts/open-sans-600.ttf") format("truetype"); font-style: normal; font-weight: 600; font-display: swap; }
@font-face { font-family: "Open Sans"; src: url("/fonts/open-sans-700.ttf") format("truetype"); font-style: normal; font-weight: 700; font-display: swap; }
@font-face { font-family: "Open Sans"; src: url("/fonts/open-sans-700-italic.ttf") format("truetype"); font-style: italic; font-weight: 700; font-display: swap; }
@font-face { font-family: "Open Sans"; src: url("/fonts/open-sans-800.ttf") format("truetype"); font-style: normal; font-weight: 800; font-display: swap; }
@font-face { font-family: "Roboto"; src: url("/fonts/roboto-800.ttf") format("truetype"); font-style: normal; font-weight: 800; font-display: swap; }


/* ==========================================================================
   2. DESIGN TOKENS & COMPONENTS (design export)
   ========================================================================== */
/* ==========================================================================
   REVISED PENTARA BRAND KIT PALETTE  (updated 2026-08-28)
   Verbatim from the Color Guidelines guide in the Moda brand kit. These nine
   are the canonical colors; every applied token below derives from them.
   This SUPERSEDES the earlier Brand Guide.pdf palette (#44455A / #1D678E /
   #3896D0 / #92D050 / #ED8F31), which is no longer used anywhere.
   ========================================================================== */
:root{
  /* primary */
  --brand-blue:   #0C7CC1;   /* Cerulean Blue  — dominant brand color */
  --brand-green:  #7CD63C;   /* Lime Green     — accents and CTAs */
  --brand-orange: #F0862A;   /* Signal Orange  — links + small highlights ONLY */
  --brand-ink:    #1A1A1A;   /* Ink Black      — text and definition */
  /* secondary / neutral */
  --brand-slate:  #607DA7;   /* Slate Blue */
  --brand-gray:   #9CA3B3;   /* Cool Gray */
  --brand-border: #CBD4E3;   /* Border Blue */
  --brand-mist:   #EEF1F6;   /* Mist */
  --brand-cloud:  #F5F7FA;   /* Cloud */
}

/* --------------------------------------------------------------------------
   APPLIED TOKENS
   The kit's neutrals are tuned for surfaces, not for text: Slate Blue is
   4.21:1 on white and Cool Gray 2.53:1, both below the 4.5:1 AA threshold.
   So surface roles take the kit values unchanged, and the three TEXT roles
   take a darkened step of the same kit hue. Every such value is flagged
   DERIVED with its source and measured ratio. No hue outside the kit is used.
   -------------------------------------------------------------------------- */
:root{
  --bg: #ffffff;
  --bg-2: var(--brand-cloud);   /* Cloud  #F5F7FA — panels, alternating bands */
  --bg-3: var(--brand-mist);    /* Mist   #EEF1F6 — the next step down */
  --ink: var(--brand-ink);      /* Ink Black, 17.40:1 */
  --ink-2: #526A8E;             /* DERIVED: Slate Blue -15%, 5.51:1 (kit slate is 4.21:1) */
  --muted: #6D727D;             /* DERIVED: Cool Gray -30%, 4.82:1 (kit gray is 2.53:1) */

  /* The revised kit has ONE blue, and it clears AA as text: #0C7CC1 is 4.50:1
     on white. The old two-tier deep/bright blue split is therefore retired —
     --blue-bright is kept as an alias so nothing referencing it breaks. */
  --blue: var(--brand-blue);
  --blue-bright: var(--brand-blue);

  --green: var(--brand-green);
  --orange: var(--brand-orange);
  /* DERIVED: Signal Orange -30%, 4.90:1. Kit orange is 2.58:1 on white and
     cannot carry .link-warm link text. Bright kit orange is still used
     wherever orange is a fill or a small non-text highlight. */
  --orange-ink: #A85E1D;

  --border: var(--brand-border);  /* Border Blue #CBD4E3 */
  --border-subtle: #E2E7F0;       /* DERIVED: Border Blue @55% on white */

  /* ---------- dark bands: home's lower sections, the CTA band, the footer ----
     DERIVED: Cerulean Blue -25%. The kit blue at full strength is exactly
     4.50:1 against white — it carries white headings but leaves no headroom
     for the secondary text on these bands, which tops out at 3.96:1 and would
     ship below AA. Deepening the same hue by a quarter buys 7.03:1 for white
     and lets the secondary tint land at 5.31:1. */
  --dark: #095D91;
  --dark-2: #074870;          /* DERIVED: Cerulean -42% — panels sitting ON the band */
  --dark-border: #3F81A9;     /* DERIVED: white @22% over the band */
  --dark-ink-2: #D3E2EB;      /* DERIVED: white @82% over the band — 5.31:1 band, 7.30:1 panel */

  /* Signature Pentara gradient. Cerulean is held to 62% before travelling to
     Lime Green — an even 0->100% blend reads teal and loses the blue.
     (Approved by Suzanne, Aug 2026; applies to all Pentara collateral.) */
  --grad: linear-gradient(115deg,
    var(--brand-blue) 0%,
    var(--brand-blue) 62%,
    var(--brand-green) 100%);

  --scroll-progress: 0;
}

html{ scroll-behavior:smooth; }

/* Visually hidden but announced by screen readers. Declared explicitly rather
   than relying on the utility being emitted, so the "(opens in a new tab)"
   cues on Publications can never render as visible text. */
.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border-width:0;
}

body{
  font-family:"Open Sans","Roboto",system-ui,sans-serif;
  color:var(--ink);
  background:var(--bg);
  -webkit-font-smoothing:antialiased;
}

h1,h2,h3,h4,h5{ font-family:"Open Sans","Roboto",system-ui,sans-serif; letter-spacing:-0.02em; }

/* ---------- brand surfaces ---------- */
.grad{ background-image:var(--grad); }
.grad-text{
  /* Opens on the BRIGHT brand blue rather than the deep blue. These are short
     display numerals, so a sweep that opened dark spent its whole width in the
     dark end and never reached the green. The revised kit has a single blue, so
     the sweep holds Cerulean across the first 45% — that keeps the bulk of
     these 30px extrabold numerals on the 4.50:1 blue rather than the 1.82:1
     green, then travels. */
  background-image:linear-gradient(100deg,var(--brand-blue) 0%,var(--brand-blue) 45%,var(--brand-green) 100%);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}

/* ---------- section badges ---------- */
.badge{
  display:inline-block; padding:.4rem 1rem; border-radius:.375rem;
  font-size:.7rem; font-weight:800; letter-spacing:.16em; text-transform:uppercase;
  color:#fff; background:var(--blue);
}
/* The green badge is the brightest small element on an interior page, so it
   carries the guide green at FULL strength and flips its text to dark ink
   instead of white. That reads far brighter than the old darkened-green pill
   AND measures better: 9.42:1 here, against 4.78:1 before. */
.badge-green{ background:var(--brand-green); color:var(--ink); }
.badge-ghost{
  display:inline-block; padding:.4rem 1rem; border-radius:.375rem;
  font-size:.7rem; font-weight:800; letter-spacing:.16em; text-transform:uppercase;
  color:#fff; background:rgba(255,255,255,.22);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.35);
}

/* ---------- pentagon texture ---------- */
.pent{ clip-path:polygon(50% 0%, 100% 36%, 82% 96%, 18% 96%, 0% 36%); }

/* ---------- page-level building blocks ---------- */
.page-hero{ background-image:var(--grad); position:relative; overflow:hidden; }

/* ---------- interior page header ----------
   The home page hero owns the full brand gradient. Interior pages use this
   deeper, more compact variant so it reads instantly as "you have moved off
   the home page" — the brand gradient survives as a hairline rule along the
   bottom edge and a soft green glow in the top corner.
   White type and white-pill buttons keep working unchanged on this field. */
.page-hero.sub-hero{
  /* The header sits in the same deepened Cerulean as the footer, the CTA band
     and the hero ticker. The gentle lift toward #0A6CA9 (halfway to the kit
     blue) keeps a little depth so the header isn't a flat slab, and the
     brand-blue corner glow below does the rest. */
  background-image:linear-gradient(135deg, var(--dark) 0%, #0A6CA9 100%);
  border-style:solid;
  border-width:0 0 3px;
  border-color:transparent;
  border-image:var(--grad) 1;
}
/* Soft lift in the top corner, kept in the brand blue family so the interior
   header never competes with the home hero's blue-to-green gradient. */
/* Two glows, not one: brand blue lifting the top-right, and a teal-to-green
   bloom rising from the bottom-right. Together they walk the header through the
   brand's blue-green spectrum again, which is the brightness the interior pages
   lost when slate came out of this gradient — without putting a light green
   field under any white type. The green is capped at .18: white text measures
   4.55:1 even directly on top of it, and it sits bottom-right where the header
   art lives rather than under the headline. */
.page-hero.sub-hero::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(75% 115% at 88% -25%, rgba(56,150,208,.38), rgba(56,150,208,.14) 48%, transparent 72%),
    radial-gradient(58% 125% at 94% 122%, rgba(146,208,80,.18), rgba(86,169,166,.13) 42%, transparent 70%);
}
/* Breadcrumb is small uppercase type, so it needs near-full white to clear
   4.5:1 against the deep blue field — 70% white measured only ~3:1. */
.page-hero.sub-hero nav[aria-label="Breadcrumb"]{ color:rgba(255,255,255,.92); }
.page-hero.sub-hero nav[aria-label="Breadcrumb"] a{ color:inherit; }
.body-copy{ color:var(--ink-2); line-height:1.75; }
.body-copy p + p{ margin-top:1rem; }
.chip{
  display:inline-flex; align-items:center; border-radius:99px;
  background:var(--bg-3); color:var(--blue);
  padding:.375rem .75rem; font-size:.75rem; font-weight:700;
}
.tick{ position:relative; padding-left:1.5rem; }
/* The bullet used to paint var(--grad), but that gradient is scaled to the
   element — across an 8px marker only its deep-blue opening shows, so every
   bullet read as a flat dark dot. This sweep completes inside the marker, so
   each one is a bright blue-to-green fleck. 65 of them across the service
   pages, which is most of where the interior brightness went. */
.tick::before{
  content:""; position:absolute; left:0; top:.55em; width:.5rem; height:.5rem;
  border-radius:2px;
  background-image:linear-gradient(135deg, var(--brand-blue) 0%, var(--brand-green) 100%);
}
.field{
  width:100%; border-radius:.75rem; border:1px solid var(--border);
  background:#fff; padding:.75rem 1rem; font-size:.9375rem; color:var(--ink);
}
.field:focus{ outline:2px solid var(--blue); outline-offset:1px; border-color:var(--blue); }
.field-label{ display:block; font-size:.75rem; font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-2); margin-bottom:.4rem; }

/* ---------- cards & links ---------- */
.card{ transition:transform .3s cubic-bezier(.22,.7,.28,1), box-shadow .3s ease, border-color .3s ease; }
.link-warm{ color:var(--orange-ink); }
.link-warm:hover{ text-decoration:underline; }
.arrow-link{ transition:gap .2s ease; }
.arrow-link:hover{ gap:.7rem; }

/* ---------- navigation ---------- */
.nav-link{ position:relative; }
.nav-link::after{
  content:""; position:absolute; left:0; right:0; bottom:-6px; height:2px;
  background-image:var(--grad); transform:scaleX(0); transform-origin:left;
  transition:transform .25s ease;
}
.nav-link:hover::after, .nav-group:hover > .nav-link::after{ transform:scaleX(1); }

.nav-group > .nav-panel{
  opacity:0; visibility:hidden; transform:translateY(6px);
  transition:opacity .18s ease, transform .18s ease, visibility .18s;
}
.nav-group:hover > .nav-panel,
.nav-group:focus-within > .nav-panel{ opacity:1; visibility:visible; transform:translateY(0); }

/* ---------- bottom CTA band ----------
   The closing CTA used to repeat the hero's brand gradient, so pages both
   opened AND closed on the same two-colour field. It now carries the footer's
   slate, so the foot of every page reads as one calm solid zone against the
   gradient hero — and the gradient keeps its impact by appearing once.
   The brand gradient survives as a hairline along the top edge (the same device
   .sub-hero uses on its bottom edge), which is what separates this band from
   the slate capabilities section above it on the home page. */
.page-hero.cta-band{
  background-image:none;
  background-color:var(--dark);
  border-style:solid;
  border-width:3px 0 0;
  border-color:transparent;
  border-image:var(--grad) 1;
}
/* .page-hero::after brightens gradient fields as the page scrolls. At the foot
   of the page scroll-progress is ~1, which would wash this band ~14% lighter
   than the footer and break the colour match. */
.page-hero.cta-band::after{ display:none; }
/* The decorative pentagons are authored at opacity .12, which disappeared into
   the old gradient but reads as a hard grey blob on flat slate — on mobile one
   landed right behind the button. Halved to a watermark. */
.page-hero.cta-band > [aria-hidden="true"]{ opacity:.055; }

/* The band is a flat field once the gradient comes off it, so it gets the
   spectrum back as light rather than as a fill: brand blue lifting one corner,
   teal-green blooming from the other. Green capped at .22 — white type measures
   4.60:1 directly on it, so the centred copy is safe even on a narrow screen
   where it reaches the corners. */
.page-hero.cta-band::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(52% 120% at 3% 4%, rgba(56,150,208,.34), rgba(56,150,208,.12) 46%, transparent 70%),
    radial-gradient(52% 120% at 97% 104%, rgba(146,208,80,.22), rgba(86,169,166,.13) 44%, transparent 70%);
}

/* ---------- ticker bar ----------
   The capability ticker at the foot of the home hero. It used to be a
   translucent black wash over the hero gradient, so its right-hand end drifted
   into the gradient's green. It now carries the same guide deep blue as the
   interior page headers (.page-hero.sub-hero), which ties the home page to
   every other page. z-index lifts it above .page-hero::after (the scroll sheen)
   and the decorative pentagons so the field stays a flat, true blue. */
.ticker-bar{
  background:var(--dark);
  z-index:1;
}

/* ---------- marquee ---------- */
.marquee{ mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent); }
.marquee-track{ display:flex; width:max-content; animation:pentara-scroll 38s linear infinite; }
@keyframes pentara-scroll{ from{ transform:translateX(0);} to{ transform:translateX(-50%);} }
@media (prefers-reduced-motion: reduce){ .marquee-track{ animation:none; } }

details summary::-webkit-details-marker{ display:none; }
details summary > span:last-child{ transition:transform .25s ease; }

/* ==========================================================================
   MOTION
   Base states are always visible — animation is polish only, never a
   prerequisite for seeing content.
   ========================================================================== */

/* ---------- 1. buttons pulse on hover ---------- */
a.rounded-full,
button.rounded-full,
button[type=submit]{
  transition:transform .25s cubic-bezier(.22,.7,.28,1), box-shadow .25s ease, opacity .2s ease;
}
@keyframes pentara-pulse{
  0%,100%{ transform:translateY(-2px) scale(1);     box-shadow:0 10px 26px -14px rgba(56,150,208,.5); }
  50%    { transform:translateY(-2px) scale(1.035); box-shadow:0 16px 34px -14px rgba(56,150,208,.7); }
}
@keyframes pentara-pulse-light{
  0%,100%{ transform:translateY(-2px) scale(1);     box-shadow:0 10px 26px -14px rgba(0,0,0,.35); }
  50%    { transform:translateY(-2px) scale(1.035); box-shadow:0 18px 38px -14px rgba(0,0,0,.45), 0 0 0 6px rgba(255,255,255,.14); }
}
@media (hover:hover){
  a.rounded-full:hover,
  button.rounded-full:hover,
  button[type=submit]:hover{ animation:pentara-pulse 1.6s ease-in-out infinite; }

  /* white buttons on a gradient field get a light halo instead of a blue glow */
  .page-hero a.rounded-full:hover,
  .grad a.rounded-full:hover{ animation-name:pentara-pulse-light; }
}

/* ---------- 2. boxed content shifts slightly on hover ---------- */
.card,
article.rounded-2xl,
.rounded-2xl.border,
.rounded-2xl.bg-white,
section ol > li > a{
  transition:transform .3s cubic-bezier(.22,.7,.28,1), box-shadow .3s ease, border-color .3s ease;
}
@media (hover:hover){
  .card:hover{ transform:translateY(-4px); border-color:#A5D0EA; box-shadow:0 18px 40px -22px rgba(56,150,208,.45); }

  /* scoped to page sections so nav dropdown panels stay perfectly still */
  section article.rounded-2xl:hover,
  section .rounded-2xl.border:hover,
  section .rounded-2xl.bg-white:hover{
    transform:translateY(-3px);
    box-shadow:0 20px 44px -26px rgba(56,150,208,.35);
  }

  /* publication rows slide instead of lifting */
  section ol > li > a:hover{ transform:translateX(5px); }

  /* accordion plus-sign nudges when its card is hovered */
  section details:hover > summary > span:last-child{ transform:scale(1.25); }

  /* framed photography gets a slow zoom rather than a lift */
  .overflow-hidden.rounded-2xl > img{ transition:transform .7s cubic-bezier(.22,.7,.28,1); }
  .overflow-hidden.rounded-2xl:hover > img{ transform:scale(1.04); }
}

/* ---------- 3. light builds as the page scrolls ---------- */
.scroll-progress{
  position:fixed; top:0; left:0; z-index:60;
  height:2px; width:100%;
  background-image:var(--grad);
  transform:scaleX(var(--scroll-progress)); transform-origin:left;
  pointer-events:none;
}
.scroll-light{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  background:radial-gradient(120% 65% at 50% -10%, rgba(146,208,80,.55), rgba(56,150,208,.4) 45%, transparent 72%);
  opacity:calc(var(--scroll-progress) * 0.18);
  mix-blend-mode:soft-light;
}
/* gradient fields brighten subtly with scroll depth */
.page-hero::after,
section.grad::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(115deg, rgba(255,255,255,calc(var(--scroll-progress) * 0.14)), transparent 60%);
}

/* ---------- 4. hero entrance ----------
   The hero sits above the fold, so the scroll observer never fires for it.
   Its parts rise in on load instead, staggered. Base state is visible: if the
   animation never runs (reduced motion, old browser) the hero is simply there. */
.hero-enter > *{ animation:pentara-rise .7s cubic-bezier(.22,.7,.28,1) both; }
.hero-enter > *:nth-child(1){ animation-delay:.05s; }
.hero-enter > *:nth-child(2){ animation-delay:.14s; }
.hero-enter > *:nth-child(3){ animation-delay:.23s; }
.hero-enter > *:nth-child(4){ animation-delay:.32s; }
.hero-enter > *:nth-child(5){ animation-delay:.41s; }
.hero-enter > *:nth-child(6){ animation-delay:.50s; }
.hero-enter-media{ animation:pentara-fade-in .9s cubic-bezier(.22,.7,.28,1) .2s both; }
@keyframes pentara-fade-in{
  from{ opacity:0; transform:translateY(14px) scale(.995); }
  to  { opacity:1; transform:none; }
}

/* reveal on scroll — visible by default, animated only once observed */
.will-reveal{ opacity:1; }
.will-reveal.is-in{ animation:pentara-rise .7s cubic-bezier(.22,.7,.28,1) both; }
@keyframes pentara-rise{
  from{ opacity:0; transform:translateY(18px); }
  to  { opacity:1; transform:none; }
}

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  a.rounded-full:hover,
  button.rounded-full:hover,
  button[type=submit]:hover,
  .hero-enter > *,
  .hero-enter-media,
  .will-reveal.is-in{ animation:none !important; }
  .card:hover,
  article.rounded-2xl:hover,
  .rounded-2xl.border:hover,
  .rounded-2xl.bg-white:hover,
  section ol > li > a:hover,
  .overflow-hidden.rounded-2xl:hover > img{ transform:none; }
  .scroll-light{ display:none; }
}


/* ==========================================================================
   Header nav baseline alignment
   The logo wordmark's baseline sits low inside its image box, so nav text
   centred on that box reads a few pixels high. This nudges the nav down to
   match the wordmark. ADJUST THE ONE NUMBER BELOW (try 3px - 8px).
   ========================================================================== */
:root { --nav-baseline-nudge: 7px; }

header nav[aria-label="Primary"] {
  transform: translateY(var(--nav-baseline-nudge));
}

/* ==========================================================================
   WHITE-PAPER POP-UP (every page)
   Opens by itself once per visitor, then only from the tab pinned to the
   right edge. Markup and behaviour live in wwwroot/js/site.js.
   ========================================================================== */
.cta-pop{
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 1.25rem;
  opacity: 0; visibility: hidden;
  transition: opacity .28s ease, visibility .28s ease;
}
.cta-pop.is-open{ opacity: 1; visibility: visible; }
.cta-pop__scrim{
  position: absolute; inset: 0;
  background: rgba(26,26,26,.55);
  backdrop-filter: blur(2px);
}
.cta-pop__panel{
  position: relative;
  width: 100%; max-width: 30rem;
  max-height: calc(100vh - 2.5rem);
  overflow: auto;
  background: #fff;
  border: 1px solid var(--border-subtle);
  border-radius: 1rem;
  box-shadow: 0 24px 60px -12px rgba(26,26,26,.32);
  transform: translateY(14px) scale(.985);
  transition: transform .32s cubic-bezier(.22,.7,.28,1);
}
.cta-pop.is-open .cta-pop__panel{ transform: none; }
.cta-pop__bar{
  height: 5px;
  background: linear-gradient(90deg, var(--dark), var(--brand-blue) 55%, var(--brand-green));
  border-radius: 1rem 1rem 0 0;
}
.cta-pop__body{ padding: 1.5rem 1.5rem 1.35rem; }
.cta-pop__close{
  position: absolute; top: .95rem; right: .95rem;
  width: 2rem; height: 2rem;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-subtle); border-radius: 999px;
  background: #fff; color: var(--ink-2);
  font-size: 1rem; line-height: 1; cursor: pointer;
  transition: background .18s ease, color .18s ease;
}
.cta-pop__close:hover{ background: var(--bg-2); color: var(--ink); }
.cta-pop__eyebrow{
  display: inline-block;
  font-size: .625rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: #fff; background: var(--blue);
  padding: .3rem .6rem; border-radius: .3rem;
}
.cta-pop__title{
  margin: .85rem 0 .45rem;
  font-size: 1.375rem; line-height: 1.22; font-weight: 700; color: var(--ink);
  padding-right: 1.75rem;
}
.cta-pop__lede{ font-size: .875rem; line-height: 1.55; color: var(--ink-2); margin: 0 0 1.1rem; }
.cta-pop__grid{ display: grid; gap: .7rem; }
.cta-pop__row{ display: grid; gap: .7rem; grid-template-columns: 1fr 1fr; }
@media (max-width: 30rem){ .cta-pop__row{ grid-template-columns: 1fr; } }
.cta-pop__field{ display: grid; gap: .3rem; }
.cta-pop__label{
  font-size: .625rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
}
.cta-pop__input,
.cta-pop__select{
  width: 100%;
  font: inherit; font-size: .875rem; color: var(--ink);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: .5rem;
  padding: .55rem .7rem;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.cta-pop__input:focus,
.cta-pop__select:focus{
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(56,150,208,.18);
}
.cta-pop__submit{
  width: 100%;
  margin-top: .35rem;
  font: inherit; font-size: .9375rem; font-weight: 600; color: #fff;
  background: var(--blue);
  border: 0; border-radius: .5rem;
  padding: .7rem 1rem; cursor: pointer;
  transition: background .18s ease, transform .18s ease;
}
.cta-pop__submit:hover{ background: var(--brand-blue); transform: translateY(-1px); }
.cta-pop__fine{
  margin: .75rem 0 0;
  font-size: .75rem; line-height: 1.5; color: var(--muted); text-align: center;
}
.cta-pop__thanks{ display: none; text-align: center; padding: .5rem 0 .25rem; }
.cta-pop.is-sent .cta-pop__form{ display: none; }
.cta-pop.is-sent .cta-pop__thanks{ display: block; }
.cta-pop__check{
  width: 2.75rem; height: 2.75rem; margin: 0 auto .8rem;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px; background: var(--green); color: #16300a;
  font-size: 1.25rem; font-weight: 700;
}
@media (prefers-reduced-motion: reduce){
  .cta-pop, .cta-pop__panel, .cta-pop__submit{ transition: none; }
  .cta-pop__panel{ transform: none; }
}

/* --- dismissed state: floating tab pinned to the right edge --- */
.cta-tab{
  position: fixed; z-index: 99;
  top: 50%; right: 0;
  display: flex; align-items: center; gap: .5rem;
  writing-mode: vertical-rl;
  font: inherit; font-size: .8125rem; font-weight: 600; letter-spacing: .02em;
  color: #fff;
  background: linear-gradient(180deg, var(--dark), var(--brand-blue) 60%, var(--brand-green));
  border: 0; border-radius: .6rem 0 0 .6rem;
  padding: 1rem .6rem;
  cursor: pointer;
  box-shadow: 0 10px 30px -8px rgba(26,26,26,.38);
  transform: translate(100%, -50%);
  opacity: 0; visibility: hidden;
  transition: transform .32s cubic-bezier(.22,.7,.28,1), opacity .24s ease, visibility .24s ease;
}
.cta-tab.is-in{
  transform: translate(0, -50%);
  opacity: 1; visibility: visible;
}
.cta-tab:hover{ padding-right: .85rem; }
.cta-tab:focus-visible{ outline: 3px solid rgba(56,150,208,.55); outline-offset: 2px; }
.cta-tab__icon{
  writing-mode: horizontal-tb;
  font-size: .625rem; line-height: 1;
  transform: rotate(90deg);
  opacity: .9;
}
@media (max-width: 30rem){
  .cta-tab{ font-size: .75rem; padding: .85rem .5rem; }
}
@media (prefers-reduced-motion: reduce){
  .cta-tab{ transition: opacity .2s ease, visibility .2s ease; transform: translate(0, -50%); }
}

/* --- white-paper variant: cover thumbnail, required/optional labels, error --- */
.cta-pop__head{
  display: grid;
  grid-template-columns: 108px 1fr;
  gap: 1rem;
  align-items: start;
  margin-bottom: .9rem;
}
.cta-pop__head .cta-pop__title{
  font-size: 1.125rem; line-height: 1.28; margin: .55rem 0 0; padding-right: 0;
}
.cta-pop__cover{
  width: 108px; aspect-ratio: 3 / 4; border-radius: .5rem;
  background: var(--bg-2) url("/images/site/white-paper-cover.jpg") center / cover no-repeat;
}
@media (max-width: 26rem){
  .cta-pop__head{ grid-template-columns: 84px 1fr; gap: .75rem; }
  .cta-pop__cover{ width: 84px; }
  .cta-pop__head .cta-pop__title{ font-size: 1.0625rem; }
}
.cta-pop__req,
.cta-pop__opt{
  margin-left: .35rem;
  font-size: .5625rem; letter-spacing: .08em; font-weight: 700;
}
.cta-pop__req{ color: var(--orange-ink); }
.cta-pop__opt{ color: var(--border); }
.cta-pop__input.is-invalid{
  border-color: var(--orange-ink);
  box-shadow: 0 0 0 3px rgba(166,100,34,.14);
}
.cta-pop__error{
  margin: .1rem 0 0;
  font-size: .75rem; color: var(--orange-ink);
}

/* --------------------------------------------------------------------------
   HIDDEN WHITE-PAPER VIEWER (Pages/White-Papers): the paper's pages as a
   stack of sheets, each image rendered by tools/Render-PdfPages.ps1.
   -------------------------------------------------------------------------- */
.wp-pages{
  display: grid; gap: 1.5rem;
  max-width: 900px; margin: 0 auto; padding: 0; list-style: none;
}
.wp-page img{
  display: block; width: 100%; height: auto;
  background: #fff;
  border: 1px solid var(--border-subtle);
  border-radius: .5rem;
  box-shadow: 0 18px 40px -22px rgba(26,26,26,.35);
}
.wp-foot{
  display: flex; flex-wrap: wrap; justify-content: center; gap: .75rem;
  max-width: 900px; margin: 2.5rem auto 0;
}

/* --------------------------------------------------------------------------
   ANCHOR LANDINGS
   The header is sticky (~61px). Without this, a deep link like
   /about-us#leadership scrolls the section's heading UNDER the header and the
   section reads as truncated. Every element that can be an anchor target
   reserves the header's height plus breathing room.
   -------------------------------------------------------------------------- */
[id]{ scroll-margin-top: 116px; }
@media (max-width: 64rem){ [id]{ scroll-margin-top: 76px; } }

/* ==========================================================================
   CAPABILITY ROWS (.cap-row)
   The eight services were eight bordered cards — a heavy grid for what is
   really a link list. These are open rows divided by hairlines: same copy,
   same destinations, roughly a third of the vertical space. The hover state
   keeps the site's existing motion language (a nudge, not a lift).
   ========================================================================== */
.cap-row{
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: .25rem 1rem;
  padding: 1.15rem .25rem;
  border-top: 1px solid var(--border-subtle);
  transition: border-color .3s ease, padding-left .25s ease;
}
.cap-row:hover{ border-color: var(--blue); padding-left: .6rem; }
.cap-row__name{
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
}
.cap-row__desc{
  grid-column: 1 / 2;
  font-size: .875rem;
  line-height: 1.6;
  color: var(--ink-2);
}
.cap-row__arrow{
  grid-row: 1 / 3;
  grid-column: 2 / 3;
  align-self: center;
  font-weight: 700;
  color: var(--blue);
  transition: transform .25s ease;
}
.cap-row:hover .cap-row__arrow{ transform: translateX(3px); }

/* ==========================================================================
   CHART ACCENTS (.chart-accent)
   Inline-SVG data graphics beside the section intros on the home page:
   survival curves, a forest plot, a change-from-baseline chart. Drawn in the
   kit palette so nothing needs a later photo swap. Desktop only (lg:), so the
   shortened phone page keeps its length.
   ========================================================================== */
.chart-accent{ margin:0; padding:1.1rem 1.1rem .9rem; background:#fff; border:1px solid var(--border-subtle); border-radius:1rem; }
.chart-accent svg{ display:block; width:100%; height:auto; }
.chart-accent figcaption{ margin-top:.7rem; font-size:.75rem; line-height:1.5; color:var(--muted); }
.chart-accent--tint{ background:var(--bg-2); }

/* ---------------------------------------------------------------------------
   PROGRAMME TIMELINE (home, "When to bring us in", 2026-09-21)
   --------------------------------------------------------------------------- */
.tl { position: relative; list-style: none; margin: 0; padding: 0; }
.tl__stop { position: relative; padding-top: 1.75rem; }
.tl__stop::before { content: ""; position: absolute; left: 0; right: -0.75rem; top: 7px; height: 2px; background: rgba(255,255,255,.22); }
.tl__stop:last-child::before { right: 0; }
@media (max-width: 63.98rem) { .tl__stop:nth-child(3n)::before { right: 0; } }
.tl__dot { position: absolute; left: 0; top: 0; width: 16px; height: 16px; border-radius: 999px; background: var(--dark); border: 2px solid rgba(255,255,255,.6); }
.tl__stop--key .tl__dot { background: var(--green); border-color: var(--green); box-shadow: 0 0 0 5px rgba(124,214,60,.22); }
.tl__stop--wall .tl__dot { background: var(--orange); border-color: var(--orange); box-shadow: 0 0 0 5px rgba(240,134,42,.22); }
.tl__stage { font-size: .72rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.72); }
.tl__stop--key .tl__stage { color: var(--green); }
.tl__stop--wall .tl__stage { color: var(--orange); }
.tl__do { margin-top: .5rem; font-size: .9rem; font-weight: 700; line-height: 1.35; color: #fff; }
.tl__late { margin-top: .5rem; font-size: .8rem; line-height: 1.45; color: var(--dark-ink-2); }

/* ---------- legal pages (terms, privacy) ---------- */
.legal{ color:var(--ink-2); font-size:1rem; line-height:1.7; }
.legal h2{ margin-top:2.5rem; font-family:Roboto,ui-sans-serif,system-ui,sans-serif; font-weight:800; font-size:1.5rem; line-height:1.25; color:var(--ink); }
.legal h2:first-child{ margin-top:0; }
.legal h3{ margin-top:1.75rem; font-weight:700; font-size:1.0625rem; color:var(--ink); }
.legal p{ margin-top:1rem; }
.legal ul{ margin-top:1rem; padding-left:1.4rem; list-style:disc; }
.legal li{ margin-top:.5rem; }
.legal li::marker{ color:var(--blue); }
.legal a{ color:var(--blue); font-weight:600; text-decoration:underline; text-underline-offset:2px; }
.legal a:hover{ color:var(--orange, #f0862a); }
.legal .caps{ font-size:.9375rem; letter-spacing:.01em; }


/* ==========================================================================
   3. PRODUCTION ADDITIONS
   ========================================================================== */
/* ==========================================================================
   Additions to the exported design system. Everything here exists because the
   production site needs something the static export did not have: a cookie
   consent banner, keyboard skip link, live form states, and the DB-driven
   publication list. Colours stay inside the brand tokens from theme.css.
   ========================================================================== */

/* ---------- skip link ---------- */
.skip-link{
  position:absolute; left:1rem; top:-3rem; z-index:70;
  border-radius:.5rem; background:var(--blue); color:#fff;
  padding:.6rem 1rem; font-size:.875rem; font-weight:700;
  transition:top .15s ease;
}
.skip-link:focus{ top:1rem; }

/* Visible focus for keyboard users everywhere. The export only styled .field. */
:where(a, button, summary, [tabindex]):focus-visible{
  outline:2px solid var(--blue); outline-offset:2px; border-radius:.25rem;
}
.page-hero :where(a, button):focus-visible,
footer :where(a, button):focus-visible{ outline-color:#fff; }

/* Long URLs in the legal pages (policies.google.com/...) must wrap on a 360px phone. */
.legal a{ overflow-wrap:anywhere; }

/* ---------- current page in the primary nav ---------- */
.nav-link[aria-current="page"]::after{ transform:scaleX(1); }

/* ---------- cookie consent ----------
   Accept and Reject are the same size and weight: regulators treat a
   visually weaker "reject" as not a free choice. */
.consent{
  position:fixed; inset:auto 1rem 1rem 1rem; z-index:90;
  max-width:34rem; margin-left:auto;
  border:1px solid var(--border-subtle); border-radius:1rem;
  background:#fff; color:var(--ink);
  box-shadow:0 24px 60px -18px rgba(26,26,26,.35);
  padding:1.25rem 1.25rem 1.1rem;
}
.consent[hidden]{ display:none; }
.consent__title{ font-size:1rem; font-weight:800; }
.consent__text{ margin-top:.4rem; font-size:.8125rem; line-height:1.55; color:var(--ink-2); }
.consent__text a{ color:var(--blue); font-weight:700; text-decoration:underline; text-underline-offset:2px; }
.consent__actions{ margin-top:1rem; display:grid; grid-template-columns:1fr 1fr; gap:.6rem; }
.consent__btn{
  border-radius:999px; padding:.7rem 1rem; font-size:.875rem; font-weight:700;
  border:1px solid var(--blue); cursor:pointer;
}
.consent__btn--accept{ background:var(--blue); color:#fff; }
.consent__btn--reject{ background:#fff; color:var(--blue); }
@media (max-width: 26rem){ .consent__actions{ grid-template-columns:1fr; } }

/* ---------- form states ---------- */
.field[aria-invalid="true"]{ border-color:var(--orange-ink); }
.form-alert{ border-radius:.75rem; padding:.75rem 1rem; font-size:.875rem; font-weight:600; }
.form-alert--error{ background:#fdecec; color:#b42318; }
.form-alert--ok{ background:var(--bg-2); color:var(--ink-2); border:1px solid var(--border-subtle); }
.form-note{ font-size:.75rem; line-height:1.55; color:var(--muted); }
.form-note a{ color:var(--blue); font-weight:700; text-decoration:underline; text-underline-offset:2px; }
button[type=submit][disabled]{ opacity:.6; cursor:default; animation:none !important; transform:none !important; }
/* The busy cursor only while a request is in flight (site.js sets aria-busy); a
   button left disabled after a successful send must not keep spinning. */
button[type=submit][aria-busy="true"]{ cursor:progress; }
/* Honeypot: off-screen rather than display:none, which some bots skip. */
.hp{ position:absolute !important; left:-10000px !important; width:1px; height:1px; overflow:hidden; }

/* ---------- Pentara Insights newsletter (footer on every page, section on home) ----------
   Markup in Pages/Shared/_Footer.cshtml and Pages/Default.cshtml. Plain CSS because the
   frozen Tailwind build has none of the export's utility classes for these. */
.footer-news{
  margin-top:2.5rem; display:grid; gap:1.5rem;
  border:1px solid var(--dark-border); border-radius:1rem; background:var(--dark-2);
  padding:1.5rem;
}
@media (min-width: 40rem){ .footer-news{ padding:1.5rem 2rem; } }
@media (min-width: 48rem){ .footer-news{ margin-top:3rem; } }
@media (min-width: 64rem){ .footer-news{ grid-template-columns:1fr 26rem; align-items:center; } }
.footer-news__title{ margin-top:.5rem; font-size:1rem; font-weight:800; color:#fff; }
@media (min-width: 40rem){ .footer-news__title{ font-size:1.125rem; } }
.footer-news__row{ display:flex; flex-direction:column; gap:.75rem; }
@media (min-width: 40rem){ .footer-news__row{ flex-direction:row; } }
.footer-news__input{
  width:100%; border-radius:999px; border:1px solid var(--dark-border);
  background:rgba(255,255,255,.1); padding:.75rem 1.25rem; font-size:.875rem; color:#fff;
}
.footer-news__input::placeholder{ color:rgba(255,255,255,.6); }
.footer-news__input:focus{ outline:none; border-color:var(--green); }
.footer-news__input[aria-invalid="true"]{ border-color:var(--orange); }
.footer-news__ok{ background:rgba(255,255,255,.1); color:#fff; border:1px solid var(--dark-border); }

.news-grid{ display:grid; gap:2.5rem; }
@media (min-width: 64rem){ .news-grid{ grid-template-columns:1fr 1.1fr; align-items:center; gap:4rem; } }
.news-dot{ margin-top:.375rem; width:.5rem; height:.5rem; flex-shrink:0; border-radius:999px; background:var(--green); }
.news-card{ border:1px solid var(--border); border-radius:1rem; background:var(--bg-2); padding:1.75rem; }
@media (min-width: 40rem){ .news-card{ padding:2.25rem; } }
.news-avatar{ width:2.75rem; height:2.75rem; border-radius:999px; object-fit:cover; box-shadow:0 0 0 2px #fff; }

/* ---------- publications list (DB-driven) ---------- */
/* Search matches: PublicationsService wraps them in <span class="highlight">. */
.pub-list .highlight{
  background:rgba(124,214,60,.35); color:inherit; border-radius:.2rem; padding:0 .1em;
}
.facet{ position:relative; }
.facet > summary{
  display:flex; align-items:center; justify-content:space-between; gap:.5rem;
  cursor:pointer; list-style:none;
}
.facet__list{
  margin-top:.5rem; max-height:15rem; overflow-y:auto;
  border:1px solid var(--border); border-radius:.75rem; background:#fff;
  padding:.35rem;
}
.facet__list label{
  display:flex; align-items:flex-start; gap:.5rem; border-radius:.5rem;
  padding:.4rem .5rem; font-size:.8125rem; line-height:1.35; cursor:pointer;
}
.facet__list label:hover{ background:var(--bg-2); }
.facet__list input{ margin-top:.15rem; accent-color:var(--blue); }
.pub-abstract > summary{ list-style:none; cursor:pointer; }
.pub-abstract[open] > summary span[aria-hidden]{ transform:rotate(45deg); }
.pub-abstract > summary span[aria-hidden]{ display:inline-block; transition:transform .2s ease; }
/* Pentara leaders in a byline link to their bio on /about-us. */
.pub-author{ color:var(--blue); font-weight:600; }
.pub-author:hover{ text-decoration:underline; }
.pub-match{ color:var(--muted); font-weight:600; }
/* Not in the frozen utility build: long titles, DOIs and abstract tokens wrap
   instead of widening the page on phones. */
.break-words{ overflow-wrap:break-word; }
/* Topic chips on a publication page; each opens the list filtered to that keyword. */
.pub-topic{ display:inline-block; border:1px solid var(--border); border-radius:9999px; padding:.4rem .9rem;
  font-size:.8125rem; font-weight:600; color:var(--blue); background:#fff; transition:border-color .2s ease; }
.pub-topic:hover{ border-color:var(--blue); }
.pub-title{ color:inherit; }
.pub-title:hover{ color:var(--blue); text-decoration:underline; }
/* A linked profile lands below the sticky header, not under it. */
.profile{ scroll-margin-top:7rem; }

@media (prefers-reduced-motion: reduce){
  .skip-link{ transition:none; }
}
