/* Engaging Data, site stylesheet.
   Implements docs/design/website-design-system.md (§7a: liquid glass).
   Layered on brand-tokens.css, which supplies the --edl-* brand values.

   Structural model: a page is a vertical stack of <section class="band">.
   Each band scopes its own surface/text tokens so dark and light sections can
   alternate down one page, see .claude/skills/engaging-data-frontend/references/site.md

   Surface model: a fixed ambient gradient (body::before) sits behind
   everything. Bands are translucent glass sheets over it; cards, stats,
   buttons, chips and inputs are a second, more opaque layer of glass on top
   of that. backdrop-filter is disabled wholesale under @media print and for
   .panel-slide specifically. Chromium's print-to-PDF pipeline cannot
   render it (see build/generate-pdfs.mjs and the case-study print rules
   below); every glass surface therefore ships an opaque print fallback.
*/

/* ─── Tokens ──────────────────────────────────────────────────────── */

:root {
  /* Band-scoped, dark by default. brand-tokens.css supplies --edl-*. */
  --band-bg:          rgba(30, 32, 38, 0.60);
  --band-surface:     rgba(255, 255, 255, 0.06);
  --band-surface-alt: rgba(93, 149, 255, 0.12);
  --band-text:        #F8F7F4;
  --band-heading:     #FFFFFF;
  /* NOT #555568, that is ~1.5:1 on charcoal. See design system §4. */
  --band-muted:       rgba(248, 247, 244, 0.68);
  --band-divider:     rgba(255, 255, 255, 0.14);

  /* Glass mechanics, border/highlight/blur/shadow for every glass surface.
     Print fallbacks (opaque, no blur) live in the solid pairs below. */
  --band-glass-border:    rgba(255, 255, 255, 0.16);
  --band-glass-highlight: rgba(255, 255, 255, 0.30);
  --band-glass-shadow:    0 12px 40px rgba(0, 0, 0, 0.28);
  --band-blur:    26px;
  --band-blur-sm: 16px;

  /* Opaque equivalents, used only under @media print / .panel-slide. */
  --band-bg-solid:          #2A2A2A;
  --band-surface-solid:     #2B2F38;
  --band-surface-alt-solid: #2E3A57;

  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;  --sp-5: 24px;
  --sp-6: 32px;  --sp-7: 48px;  --sp-8: 64px;  --sp-9: 96px;  --sp-10: 128px;

  --shell: 1200px;
  --shell-narrow: 760px;
  --gutter: 24px;
  --band-pad: 96px;
  --header-h: 72px;
  --header-gap: 16px;
  --radius: 9px;
  --radius-sm: 6px;
  --radius-btn: 10px;

  --font-head: "Calibri Light", "Helvetica Neue Light", Arial, sans-serif;
  --font-body: "Arial", "Calibri", "Helvetica Neue", sans-serif;
}

.band--light {
  --band-bg:          rgba(255, 255, 255, 0.55);
  --band-surface:     rgba(255, 255, 255, 0.55);
  --band-surface-alt: rgba(238, 242, 255, 0.65);
  --band-text:        #2A2A2A;
  --band-heading:     #1E2430;
  --band-muted:       #4B4B5C;
  --band-divider:     rgba(42, 42, 42, 0.12);

  --band-glass-border:    rgba(42, 42, 42, 0.10);
  --band-glass-highlight: rgba(255, 255, 255, 0.65);
  --band-glass-shadow:    0 12px 32px rgba(30, 36, 48, 0.12);

  --band-bg-solid:          #FFFFFF;
  --band-surface-solid:     #F8F7F4;
  --band-surface-alt-solid: #EEF2FF;
}

/* ─── Reset & base ────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* The browser's own [hidden] rule is display:none at the lowest precedence, so
   any component that sets display (a.card, .team-member, .step) silently beats
   it and stays visible after `el.hidden = true`. That is how the case-study
   filter came to report "showing 8 of 18" with all 18 tiles still on screen.
   Enforce it once here rather than per component. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; scroll-padding-top: calc(var(--header-h) + var(--header-gap) + 16px); }

body {
  background: #2A2A2A;
  color: #F8F7F4;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Fixed ambient gradient every glass surface blurs. Never scrolls, so the
   glow stays put behind whichever band is in the viewport. Hidden under
   print, position: fixed is unreliable in Chromium's print pagination
   (see build/generate-pdfs.mjs) and every glass surface has an opaque
   print fallback anyway, so there's nothing for it to show through. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(circle at 12% 18%, rgba(57, 103, 217, 0.55), transparent 42%),
    radial-gradient(circle at 88% 12%, rgba(49, 151, 149, 0.45), transparent 46%),
    radial-gradient(circle at 25% 92%, rgba(49, 151, 149, 0.30), transparent 50%),
    radial-gradient(circle at 82% 85%, rgba(57, 103, 217, 0.40), transparent 50%),
    #1E2026;
  pointer-events: none;
}

img, svg, canvas { display: block; max-width: 100%; }
ul { list-style: none; }

h1, h2, h3, h4 {
  font-family: var(--font-head);
  font-weight: 700;
  text-align: left;
  color: var(--band-heading);
  letter-spacing: -0.01em;
}

h1 { font-size: 2.25rem; line-height: 1.08; letter-spacing: -0.02em; max-width: 20ch; }
h2 { font-size: 2.25rem; line-height: 1.15; max-width: 24ch; }
h3 { font-size: 1.25rem; line-height: 1.3; }
h4 { font-size: 1rem; }

p  { max-width: 68ch; }
a  { color: inherit; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

:focus-visible { outline: 2px solid var(--edl-blue); outline-offset: 2px; }
.btn--primary:focus-visible,
.band:not(.band--light) :focus-visible { outline-color: var(--edl-teal); }

.skip-link {
  position: absolute; left: var(--sp-4); top: -100px; z-index: 300;
  background: var(--edl-blue); color: #FFFFFF; padding: var(--sp-3) var(--sp-5);
  border-radius: 2px; text-decoration: none; font-weight: 600;
}
.skip-link:focus { top: var(--sp-4); }

/* ─── Bands ───────────────────────────────────────────────────────── */

.band {
  position: relative;
  background: var(--band-bg);
  backdrop-filter: blur(var(--band-blur)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--band-blur)) saturate(150%);
  color: var(--band-text);
  padding: var(--band-pad) 0;
  box-shadow: inset 0 1px 0 var(--band-glass-highlight);
}
.band__inner { max-width: var(--shell); margin: 0 auto; padding: 0 var(--gutter); }
.band__inner--narrow { max-width: var(--shell-narrow); }

/* Light bands keep the brand's heading colour hierarchy. Dark bands use white
   for every level, blue and teal headings on charcoal read as links. */
.band--light h2 { color: var(--edl-blue); }
.band--light h3 { color: var(--edl-teal); } 

.eyebrow {
  font-size: 1.25rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--edl-teal);
  margin-bottom: var(--sp-3);
}

.lead { font-size: 1.25rem; line-height: 1.5; max-width: 60ch; margin-top: var(--sp-4); }
.muted { color: var(--band-muted); }

.band__head { margin-bottom: var(--sp-7); }
.band__head p { color: var(--band-muted); margin-top: var(--sp-3); }

/* ─── Header ──────────────────────────────────────────────────────── */

.site-header {
  position: fixed; top: var(--header-gap); left: var(--header-gap); right: var(--header-gap);
  z-index: 200;
  max-width: var(--shell); margin: 0 auto;
  height: var(--header-h);
  border-radius: var(--radius);
  background: var(--edl-glass-chrome-bg);
  backdrop-filter: blur(var(--edl-glass-blur)) saturate(160%);
  -webkit-backdrop-filter: blur(var(--edl-glass-blur)) saturate(160%);
  border: 1px solid var(--edl-glass-chrome-border);
  box-shadow: inset 0 1px 0 var(--edl-glass-chrome-highlight), 0 8px 30px rgba(0, 0, 0, 0.22);
}
.site-header__inner {
  height: 100%; padding: 0 var(--gutter);
  display: flex; align-items: center; gap: var(--sp-6);
}
.site-header__logo { display: flex; align-items: center; }
.site-header__logo img { height: 30px; width: auto; }

.site-nav { margin-left: auto; }
.site-nav__list { display: flex; align-items: center; gap: 28px; }
.site-nav__list a {
  color: #F8F7F4; text-decoration: none; font-size: 0.9375rem;
  padding: 4px 0; border-bottom: 2px solid transparent;
  transition: border-color 0.15s, color 0.15s;
}
.site-nav__list a:hover,
.site-nav__list a[aria-current="page"] { border-bottom-color: var(--edl-teal); color: #FFFFFF; }

.site-nav__toggle { display: none; }
.site-nav__cta-mobile { display: none; }

/* ─── Buttons ─────────────────────────────────────────────────────── */

.btn {
  display: inline-block;
  padding: 0.7rem 1.5rem;
  border-radius: var(--radius-btn);
  border: 1px solid transparent;
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s, transform 0.15s;
}
.btn--primary {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0) 60%), var(--edl-blue);
  color: #FFFFFF;
  border-color: rgba(255, 255, 255, 0.35);
  box-shadow: 0 6px 18px rgba(41, 82, 184, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.4);
}
.btn--primary:hover { background: linear-gradient(180deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0) 60%), var(--edl-blue-deep); }
.btn--teal {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0) 60%), var(--edl-teal);
  color: #FFFFFF;
  border-color: rgba(255, 255, 255, 0.35);
  box-shadow: 0 6px 18px rgba(38, 116, 111, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.4);
}
.btn--teal:hover { background: linear-gradient(180deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0) 60%), #26746F; }
.btn--ghost {
  background: var(--band-surface);
  backdrop-filter: blur(var(--band-blur-sm));
  -webkit-backdrop-filter: blur(var(--band-blur-sm));
  color: var(--band-text);
  border-color: var(--band-glass-border);
  box-shadow: inset 0 1px 0 var(--band-glass-highlight);
}
.btn--ghost:hover { border-color: rgba(255, 255, 255, 0.6); }
.band--light .btn--ghost { color: var(--edl-blue); border-color: var(--edl-blue); }
.band--light .btn--ghost:hover { background: rgba(238, 242, 255, 0.8); }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-6); }

/* Inline text link with the teal underline treatment */
.link {
  color: var(--edl-blue); font-weight: 600; text-decoration: none;
  border-bottom: 2px solid transparent; transition: border-color 0.15s;
}
.band:not(.band--light) .link { color: var(--edl-text, #F8F7F4); }
.link:hover { border-bottom-color: var(--edl-teal); }
.link::after { content: " \2192"; }

/* ─── Hero ────────────────────────────────────────────────────────── */

.hero { position: relative; overflow: hidden; padding-top: calc(var(--band-pad) + var(--header-h) + var(--header-gap)); }
.hero__rain {
  position: absolute; top: 0; right: 0; width: 45%; height: 100%;
  opacity: 0.18; pointer-events: none; z-index: 0;
}
.hero .band__inner { position: relative; z-index: 1; }
.hero__words {
  font-size: 2.8125rem; line-height: 1.15;
  display: grid; align-content: start; overflow: hidden; height: calc(4 * 1.15em);
}
.hero__words li {
  grid-area: 1 / 1; color: #FFFFFF;
  transform: translateY(500%); opacity: 0;
  transition: transform .4s ease, opacity .4s ease, color .4s ease;
}
.hero__words li > span { display: inline-block; }
.hero__words li.is-active { transform: translateY(0); opacity: 1; color: var(--edl-teal); }
.hero__words li.is-active > span { animation: heroPop .35s ease-out; }
.hero__words li.is-next { transform: translateY(100%); opacity: .5; }
.hero__words li.is-next2 { transform: translateY(200%); opacity: .25; }
.hero__words li.is-next3 { transform: translateY(300%); opacity: .05; }
.hero__words li.is-leaving { transform: translateY(-100%); opacity: 0; }

@keyframes heroPop {
  45% { transform: scale(1.08); }
}
.hero--compact { padding-top: calc(var(--sp-8) + var(--header-h) + var(--header-gap)); padding-bottom: var(--sp-8); }
.hero--compact h1 { font-size: 2.6rem; max-width: none; }

/* ─── Breadcrumb ──────────────────────────────────────────────────── */

.breadcrumb { font-size: 0.8125rem; color: var(--band-muted); margin-bottom: var(--sp-4); }
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: var(--sp-2); list-style: none; }
.breadcrumb li + li::before { content: "/"; margin-right: var(--sp-2); opacity: 0.5; }
.breadcrumb a { color: inherit; text-decoration: none; }
.breadcrumb a:hover { color: var(--band-heading); }

/* ─── Cards ───────────────────────────────────────────────────────── */
/* Glass panel. See design system §7a. */

.card {
  position: relative;
  background: var(--band-surface);
  backdrop-filter: blur(var(--band-blur-sm)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--band-blur-sm)) saturate(150%);
  border: 1px solid var(--band-glass-border);
  border-radius: var(--radius);
  box-shadow: var(--band-glass-shadow), inset 0 1px 0 var(--band-glass-highlight);
  padding: var(--sp-5) var(--sp-5) var(--sp-6);
  transition: box-shadow 0.15s, transform 0.15s;I want to 
}
.card--alt  { background: var(--band-surface-alt); }
.card h3 { color: var(--band-heading); margin-bottom: var(--sp-2); }
.card p  { color: var(--band-muted); font-size: 0.9375rem; }
a.card { display: block; text-decoration: none; color: inherit; }
a.card:hover {
  box-shadow: var(--band-glass-shadow), inset 0 1px 0 var(--band-glass-highlight), 0 16px 40px rgba(0, 0, 0, 0.18);
  transform: translateY(-2px);
}

.card__meta {
  font-size: 0.6875rem; letter-spacing: 0.12em; text-transform: uppercase;
  font-weight: 600; color: var(--edl-teal); margin-bottom: var(--sp-3);
}

/* These five were added with the case-study template and then lost when the
   dev branch's stylesheet was taken wholesale during a merge. The markup kept
   using them, so the Journey bullets, case-study quotes and h1 second lines
   rendered unstyled. See the class-coverage check in build/build.mjs. */

/* Journey phases and service outcomes. Needs the list marker restored
   explicitly because the base reset sets `ul { list-style: none }`. */
.card__list { margin: var(--sp-4) 0; padding-left: 1.1rem; }
.card__list li {
  list-style: disc;
  color: var(--band-muted);
  font-size: 0.9375rem;
  margin-top: var(--sp-2);
}
.card__list li::marker { color: var(--edl-teal); }

/* Service subtitle. Qualified with p so it outranks `.card p` on colour
   rather than resorting to !important. */
p.card__sub {
  color: var(--edl-teal);
  font-weight: 600;
  font-size: 0.9375rem;
  margin-bottom: var(--sp-3);
}
.band--light p.card__sub { color: var(--edl-blue); }

/* Client quote on a case study. */
.pull-quote {
  margin-top: var(--sp-6);
  padding: var(--sp-5) var(--sp-6);
  background: var(--band-surface);
  border-left: 3px solid var(--edl-teal);
  border-radius: var(--radius-sm);
  font-style: italic;
  color: var(--band-text);
  max-width: 68ch;
}
.pull-quote cite {
  display: block; margin-top: var(--sp-4);
  font-style: normal; font-size: 0.8125rem; color: var(--band-muted);
}

/* Second line of a case-study h1. */
.h1-sub { color: var(--edl-teal); }

.card__logo {
  display: block;
  height: 2.5rem;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  margin-bottom: var(--sp-3);
}

/* Card whose logo fills the whole tile, swapping to its meta/h3/p blurb on hover. */
.card--logo-fill {
  position: relative;
  overflow: hidden;
  padding: 0;
  min-height: 12rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.card--logo-fill .card__logo {
  position: absolute;
  inset: 0;
  height: 100%;
  width: 100%;
  margin: 0;
  padding: var(--sp-5);
  transition: opacity 0.15s;
}
.card--logo-fill::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--band-surface);
  opacity: 0;
  transition: opacity 0.15s;
}
.card--logo-fill .card__meta,
.card--logo-fill h3,
.card--logo-fill p {
  position: relative;
  z-index: 1;
  opacity: 0;
  margin: 0;
  padding: 0 var(--sp-5);
  transition: opacity 0.15s;
}
.card--logo-fill h3 { margin-top: var(--sp-2); }
.card--logo-fill p { margin-top: var(--sp-2); }
.card--logo-fill:hover .card__logo { opacity: 0; }
.card--logo-fill:hover::after,
.card--logo-fill:hover .card__meta,
.card--logo-fill:hover h3,
.card--logo-fill:hover p {
  opacity: 1;
}

/* Team member card: headshot to the left of name/title. */
.team-member { display: flex; align-items: center; gap: var(--sp-4); }
.team-member__photo {
  flex-shrink: 0; width: 112px; height: 112px; border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.45);
}
.team-member h3 { margin-bottom: 2px; }

.grid { display: grid; gap: var(--sp-4); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

/* ─── Pillars ─────────────────────────────────────────────────────── */

.pillar__num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--edl-blue); color: #FFFFFF;
  font-family: var(--font-head); font-weight: 700; font-size: 1.1rem;
  margin-bottom: var(--sp-4);
  box-shadow: 0 6px 16px rgba(41, 82, 184, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.45);
}
.card--teal .pillar__num { background: var(--edl-teal); }
.pillar__links { margin-top: var(--sp-4); border-top: 1px solid var(--band-divider); padding-top: var(--sp-3); }
.pillar__links li { margin-top: var(--sp-2); }
.pillar__links a {
  color: var(--band-text); text-decoration: none; font-size: 0.9375rem;
  border-bottom: 1px solid transparent;
}
.pillar__links a:hover { border-bottom-color: var(--edl-teal); }

/* ─── Steps ───────────────────────────────────────────────────────── */

.step {
  display: flex; align-items: flex-start; gap: var(--sp-5);
  padding: var(--sp-5) 0; border-bottom: 1px solid var(--band-divider);
}
.step:last-child { border-bottom: none; }
.step__circle {
  flex-shrink: 0; width: 44px; height: 44px; border-radius: 50%;
  background: var(--edl-blue); color: #FFFFFF;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-head); font-weight: 700; font-size: 1.1rem;
  box-shadow: 0 6px 16px rgba(41, 82, 184, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.45);
}
.step__circle--teal { background: var(--edl-teal); }
.step h4 { color: var(--band-heading); margin-bottom: var(--sp-1); }
.step p  { color: var(--band-muted); font-size: 0.9375rem; }

/* ─── Stats ───────────────────────────────────────────────────────── */

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--sp-4); }
.stat {
  background: var(--band-surface);
  backdrop-filter: blur(var(--band-blur-sm)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--band-blur-sm)) saturate(150%);
  border: 1px solid var(--band-glass-border);
  border-left: 3px solid var(--edl-blue);
  border-radius: var(--radius);
  box-shadow: var(--band-glass-shadow), inset 0 1px 0 var(--band-glass-highlight);
  padding: var(--sp-5);
  /* Column + margin-top:auto on the label keeps every label on the same
     baseline across a row, so a value that needs two lines ("Self-Sufficient"
     breaking on its hyphen) doesn't shunt its own label out of line with its
     neighbours'. */
  display: flex;
  flex-direction: column;
}
.stat--teal { border-left-color: var(--edl-teal); }
/* 2rem, not 2.75rem: these hold short labels as well as figures ("8 Months",
   "Oracle + WhereScape"), and at 2.75rem the multi-word ones wrapped while
   their single-token neighbours did not, so those tiles read as broken. 2rem
   fits the longest value on one line in both the three-up and five-up rows. */
.stat__num {
  overflow-wrap: break-word;
  font-family: var(--font-head); font-size: 2rem; font-weight: 700;
  line-height: 1; color: var(--band-heading);
}
.stat__desc { font-size: 0.8125rem; color: var(--band-muted); margin-top: auto; padding-top: var(--sp-2); }

/* ─── Rail ────────────────────────────────────────────────────────── */
/* Native overflow + scroll-snap. Nothing auto-advances. */

.rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(290px, 340px);
  gap: var(--sp-4); overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: var(--sp-3);
  /* No visible scrollbar: the arrow buttons and auto-rotation are the
     affordance now (see .rail-wrap and site.js). Scroll, swipe, trackpad and
     keyboard still work, and the rail keeps its tabindex/role, so hiding the
     bar costs no functionality. */
  scrollbar-width: none;
}
.rail > * { scroll-snap-align: start; }
.rail::-webkit-scrollbar { display: none; }

/* Arrow buttons are enhancement over the rail's native scroll/swipe/keyboard
   behaviour, see site.js. Hidden under 900px, touch drag covers it there. */
.rail-wrap { position: relative; }
.rail__btn {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border-radius: 50%; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  background: var(--edl-blue); color: #FFFFFF; border: none; cursor: pointer;
  box-shadow: 0 6px 16px rgba(41, 82, 184, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.45);
}
.rail__btn:hover { background: var(--edl-blue-deep); }
.rail__btn:disabled { opacity: 0.35; cursor: default; }
.rail__btn--prev { left: 0; }
.rail__btn--next { right: 0; }
@media (max-width: 900px) { .rail__btn { display: none; } }

/* ─── Value grid ──────────────────────────────────────────────────── */

.value-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-7) var(--sp-6); }
.value-grid h3 { color: var(--band-heading); font-size: 1.0625rem; margin-bottom: var(--sp-2); }
.value-grid p  { color: var(--band-muted); font-size: 0.9375rem; }
.value-grid > div { border-top: 2px solid var(--edl-teal); padding-top: var(--sp-4); }

/* ─── Logo wall ───────────────────────────────────────────────────── */

.logo-wall {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: var(--sp-6); align-items: center;
}
.logo-wall img {
  height: 38px; width: auto; margin: 0 auto;
  filter: grayscale(1); opacity: 0.55;
  transition: filter 0.15s, opacity 0.15s;
}
.logo-wall a:hover img, .logo-wall a:focus-visible img { filter: none; opacity: 1; }

/* ─── CTA band ────────────────────────────────────────────────────── */

.cta-band h2 { margin-bottom: var(--sp-3); }
.cta-band p  { color: var(--band-muted); }


/* ─── Prose (article body) ────────────────────────────────────────── */

.prose { max-width: var(--shell-narrow); }
.prose > * + * { margin-top: var(--sp-5); }
.prose h2 { font-size: 1.75rem; margin-top: var(--sp-8); }
.prose h3 { font-size: 1.25rem; margin-top: var(--sp-6); }
.prose ul, .prose ol { padding-left: var(--sp-5); }
.prose ul li { list-style: disc; margin-top: var(--sp-2); }
.prose ol li { list-style: decimal; margin-top: var(--sp-2); }
.prose blockquote {
  border-left: 3px solid var(--edl-teal); padding-left: var(--sp-5);
  font-size: 1.125rem; color: var(--band-text);
}
.prose a { color: var(--edl-blue); font-weight: 600; }

/* ─── Tag chips ───────────────────────────────────────────────────── */

/* Case-study listing filters: the "Who We Help" / "How We Help" groups. */
.filters { display: flex; flex-wrap: wrap; gap: var(--sp-6); margin-bottom: var(--sp-6); }
.filters__group { flex: 1 1 320px; }
.filters__group .eyebrow { margin-bottom: var(--sp-3); }

.tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.tag {
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em;
  padding: 4px 12px; border-radius: var(--radius-btn);
  background: var(--band-surface);
  backdrop-filter: blur(var(--band-blur-sm));
  -webkit-backdrop-filter: blur(var(--band-blur-sm));
  border: 1px solid var(--band-glass-border); color: var(--band-muted);
  text-decoration: none;
}
.tag:hover { border-color: var(--edl-teal); color: var(--band-heading); }

/* ─── Forms ───────────────────────────────────────────────────────── */

.field { display: flex; flex-direction: column; gap: var(--sp-1); margin-bottom: var(--sp-4); }
.field label {
  font-size: 0.75rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--band-muted);
}
.field input, .field textarea, .field select {
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(var(--band-blur-sm));
  -webkit-backdrop-filter: blur(var(--band-blur-sm));
  border: 1px solid var(--band-glass-border); border-radius: var(--radius-sm);
  padding: 0.65rem 0.85rem; color: #2A2A2A;
  font-family: inherit; font-size: 0.9375rem; width: 100%;
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: 2px solid var(--edl-blue); outline-offset: 0; border-color: var(--edl-blue);
}

/* ─── Footer ──────────────────────────────────────────────────────── */

.site-footer {
  position: relative;
  background: var(--edl-glass-chrome-bg);
  backdrop-filter: blur(var(--edl-glass-blur)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--edl-glass-blur)) saturate(150%);
  border-top: 1px solid var(--edl-glass-chrome-border);
  box-shadow: inset 0 1px 0 var(--edl-glass-chrome-highlight);
  color: #F8F7F4; padding: var(--sp-8) 0 var(--sp-6);
}
.site-footer__inner { max-width: var(--shell); margin: 0 auto; padding: 0 var(--gutter); }
.site-footer__cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-6); }
.site-footer h4 {
  font-size: 0.6875rem; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--edl-teal); margin-bottom: var(--sp-3);
}
.site-footer li { margin-top: var(--sp-2); }
.site-footer a { color: rgba(248, 247, 244, 0.72); text-decoration: none; font-size: 0.9375rem; }
.site-footer a:hover { color: #FFFFFF; }
.site-footer__pitch { font-size: 0.9375rem; color: rgba(248, 247, 244, 0.62); margin-bottom: var(--sp-4); }
.site-footer .btn--primary { color: #FFFFFF; }
.site-footer__legal {
  margin-top: var(--sp-7); padding-top: var(--sp-5);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  display: flex; flex-wrap: wrap; gap: var(--sp-5);
  font-size: 0.8125rem; color: rgba(248, 247, 244, 0.62);
}

/* ─── Responsive ──────────────────────────────────────────────────── */

@media (max-width: 900px) {
  :root { --band-pad: 64px; --header-h: 60px; }

  h1 { font-size: 2.4rem; }
  h2 { font-size: 1.85rem; }

  .site-header__cta { display: none; }
  .site-nav__cta-mobile { display: block; margin-top: var(--sp-5); }

  .site-nav__toggle {
    display: block; margin-left: auto; width: 44px; height: 44px;
    background: transparent; border: none; cursor: pointer; position: relative;
  }
  .site-nav__bars,
  .site-nav__bars::before,
  .site-nav__bars::after {
    position: absolute; left: 11px; width: 22px; height: 2px;
    background: #F8F7F4; transition: transform 0.2s, opacity 0.2s;
  }
  .site-nav__bars { top: 21px; }
  .site-nav__bars::before { content: ""; top: -7px; left: 0; }
  .site-nav__bars::after  { content: ""; top: 7px; left: 0; }
  .site-header--menu-open .site-nav__bars { background: transparent; }
  .site-header--menu-open .site-nav__bars::before { transform: translateY(7px) rotate(45deg); }
  .site-header--menu-open .site-nav__bars::after  { transform: translateY(-7px) rotate(-45deg); }

  .site-nav { margin-left: 0; }
  .site-nav__list {
    position: fixed; inset: calc(var(--header-h) + var(--header-gap) * 2) 0 0 0;
    flex-direction: column; align-items: flex-start; gap: var(--sp-5);
    background: var(--edl-glass-chrome-bg);
    backdrop-filter: blur(var(--edl-glass-blur)) saturate(150%);
    -webkit-backdrop-filter: blur(var(--edl-glass-blur)) saturate(150%);
    padding: var(--sp-7) var(--gutter);
    transform: translateX(100%); transition: transform 0.2s ease-out;
    overflow-y: auto;
  }
  .site-header--menu-open .site-nav__list { transform: none; }
  .site-nav__list a { font-size: 1.25rem; }

  .grid--3, .grid--4, .value-grid { grid-template-columns: repeat(2, 1fr); }
  .site-footer__cols { grid-template-columns: repeat(2, 1fr); }
  .hero__rain { width: 70%; opacity: 0.12; }
}

@media (max-width: 640px) {
  :root { --band-pad: 56px; --gutter: 16px; }

  h1 { font-size: 2.1rem; }
  h2 { font-size: 1.6rem; }
  body { font-size: 1rem; }
  .lead { font-size: 1.125rem; }
  .stat__num { font-size: 2.25rem; }

  .grid--2, .grid--3, .grid--4, .value-grid { grid-template-columns: 1fr; }
  /* Two-up leaves ~123px of content width, which an unbreakable word like
     "WhereScape" overruns by 60px at this size. Full width fits it. */
  .stats { grid-template-columns: 1fr; }
  .site-footer__cols { grid-template-columns: 1fr; }
  .btn { width: 100%; text-align: center; }
  .btn-row { flex-direction: column; }
  .site-nav__list a { width: 100%; }
}

/* ─── Page transitions ────────────────────────────────────────────── */

/* Cross-document view transitions: the browser snapshots the outgoing page,
   loads the next one and cross-fades between them. No JavaScript, no click
   interception, back/forward unaffected. Chrome, Edge and Safari honour it;
   Firefox ignores the at-rule and navigates normally, so this is purely an
   enhancement. Kept short deliberately: a page transition is charming once
   and tiresome by the twentieth click. */
@view-transition { navigation: auto; }

/* Cross-fading the whole page was imperceptible: every page shares the same
   header, footer and fixed ambient gradient, so those pixels are identical in
   both snapshots and nothing appears to move. Naming the content area lets it
   animate on its own while the chrome stays put, and a small rise gives the
   eye something to catch. 24px over an even curve: an aggressive ease-out was
   measurably 99% complete by 240ms of a nominal 350ms, so the motion was real
   but imperceptible. Keep the move modest, this fires on every internal link. */
main { view-transition-name: edl-content; }

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 700ms;
  animation-timing-function: ease;
}

::view-transition-old(edl-content) {
  animation: 260ms ease both edl-content-out;
}
::view-transition-new(edl-content) {
  animation: 900ms cubic-bezier(0.4, 0, 0.2, 1) both edl-content-in;
}

@keyframes edl-content-out {
  to { opacity: 0; transform: translateY(-10px); }
}
@keyframes edl-content-in {
  from { opacity: 0; transform: translateY(24px); }
}

/* Full-page transitions are a common motion-sensitivity trigger, so opt out
   entirely rather than just shortening them. */
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* ─── Motion ──────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ─── Print ───────────────────────────────────────────────────────── */

/* Case-study panels opt out via .panel-slide, they print as full-bleed A4
   landscape pages with their own colours (see build/generate-pdfs.mjs, which
   requires one PDF page per panel). Everything else prints as a plain document. */
@media print {
  /* backdrop-filter cannot render in Chromium's print-to-PDF pipeline (see
     build/generate-pdfs.mjs), every glass surface gets an opaque fallback
     here, and the fixed ambient gradient is removed outright since
     position: fixed is unreliable across paginated print output. */
  body::before { display: none !important; }
  .site-header, .site-footer, .skip-link, .hero__rain, .print-hide { display: none !important; }

  .band:not(.panel-slide) {
    padding: 24px 0; background: #FFFFFF !important; color: #000000 !important;
    backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
    box-shadow: none !important;
  }
  .band:not(.panel-slide) h1,
  .band:not(.panel-slide) h2,
  .band:not(.panel-slide) h3,
  .band:not(.panel-slide) h4 { color: #000000 !important; }
  .band:not(.panel-slide) .card {
    border: 1px solid #D9D9D9; border-top: 3px solid #3967D9; border-radius: 2px;
    background: #FFFFFF !important; backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
    box-shadow: none !important;
  }

  /* .panel-slide (case-study PDFs) prints with its own solid colours
     instead, same intent as the glass version, none of the mechanism. */
  .panel-slide {
    background: var(--band-bg-solid) !important;
    backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
    box-shadow: none !important;
  }
  .panel-slide .card, .panel-slide .stat { background: var(--band-surface-solid) !important; }
  .panel-slide .card--alt { background: var(--band-surface-alt-solid) !important; }
  .panel-slide .card,
  .panel-slide .stat,
  .panel-slide .btn,
  .panel-slide .tag,
  .panel-slide .field input,
  .panel-slide .field textarea,
  .panel-slide .field select {
    backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
    box-shadow: none !important;
  }
}

/* Required by the shared contact-panel.js booking component (footer partial). */
@keyframes cpSlideIn { from { transform: translateX(100%); } to { transform: translateX(0); } }
@keyframes cpSlideOut { from { transform: translateX(0); } to { transform: translateX(100%); } }
@keyframes cpFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes cpFadeOut { from { opacity: 1; } to { opacity: 0; } }
@keyframes cpFieldAppear { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes cpCheckDraw { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
@keyframes cpScaleIn { from { transform: scale(0.85); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* Static placeholder for #contact-booking-root, visible immediately on the
   contact page while React/Babel/contact-panel.js (~3MB from CDN) load in the
   background. ReactDOM.createRoot(...).render() replaces this element's
   children wholesale once the real panel mounts, so no cleanup JS is needed. */
.cp-skeleton {
  position: relative;
  background-color: #2a2a2a;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,0.18);
  padding: 28px 32px 32px;
}
.cp-skeleton::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, #3967D9, #5B85E6, #3967D9);
}
.cp-skeleton__eyebrow { font-size: 12px; font-weight: 500; color: #3967D9; text-transform: uppercase; letter-spacing: 3px; margin-bottom: 4px; }
.cp-skeleton__sub { font-size: 15px; color: rgba(255,255,255,0.5); margin-bottom: 28px; }
.cp-skeleton__nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.cp-skeleton__navdot { width: 32px; height: 32px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.12); }
.cp-skeleton__month { width: 120px; height: 14px; border-radius: 4px; background: rgba(255,255,255,0.12); }
.cp-skeleton__calendar,
.cp-skeleton__month {
  background: linear-gradient(90deg, rgba(255,255,255,0.06) 25%, rgba(255,255,255,0.14) 37%, rgba(255,255,255,0.06) 63%);
  background-size: 400% 100%;
  animation: cpSkeletonPulse 1.6s ease infinite;
}
.cp-skeleton__calendar { height: 230px; border-radius: 8px; }
@keyframes cpSkeletonPulse { 0% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
@media (prefers-reduced-motion: reduce) {
  .cp-skeleton__calendar, .cp-skeleton__month { animation: none; }
}
