/* ==========================================================================
   Xora Labs design system
   Light ground #f2f6ff with deliberate full-bleed dark bands.
   Emerald #0B7A5A is the accent on light; mint #00FFA8 only ever on dark.
   Type is Archivo throughout, the same family as the wordmark.
   ========================================================================== */

:root {
  --ground:     #f2f6ff;
  --surface:    #ffffff;
  --surface-2:  #fbfcff;

  --ink:        #0a0e14;
  --ink-2:      #414b60;
  --ink-3:      #6d7689;

  --line:       #dbe3f5;
  --line-2:     #e9eefb;

  --brand:      #0B7A5A;
  --brand-dark: #085f46;
  --brand-deep: #05332a;

  /* the nav bar height, relied on by the dropdown offset and by the landing
     hero that now sits underneath the bar */
  --nav-h:      74px;
  --brand-tint: #e6f4ef;

  --mint:       #00FFA8;
  --dark:       #070c0a;
  --dark-2:     #0d1613;
  --dark-line:  rgba(255, 255, 255, 0.13);
  --dark-ink-2: #9fb3ab;

  --max:        1180px;
  --pad:        clamp(20px, 4vw, 40px);
  --section:    clamp(76px, 9vw, 128px);
  --r:          14px;
  --r-lg:       20px;

  --shadow:     0 1px 2px rgba(10, 14, 20, .04), 0 8px 28px rgba(10, 14, 20, .05);
  --shadow-lg:  0 2px 4px rgba(10, 14, 20, .05), 0 24px 60px rgba(10, 14, 20, .09);

  --font:       "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --mono:       "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 92px;
  /* clip, not hidden: hidden on body alone still lets <html> pan sideways */
  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  overflow-wrap: break-word;
}

img, svg, canvas, pre, table { max-width: 100%; }
a { color: inherit; }

/* ---------------------------------------------------------------- layout */

.wrap {
  width: min(var(--max), 100%);
  margin-inline: auto;
  padding-inline: var(--pad);
}

.section { padding-block: var(--section); }
.section-sm { padding-block: clamp(52px, 6vw, 84px); }

.band {
  background: var(--dark);
  color: #eef4f1;
  position: relative;
  overflow: hidden;
}

.band h1, .band h2, .band h3, .band strong { color: #fff; }
.band p { color: var(--dark-ink-2); }

/* ---------------------------------------------------------------- type */

h1, h2, h3, h4 {
  margin: 0;
  line-height: 1.08;
  letter-spacing: -0.03em;
  font-weight: 700;
}

.display {
  font-size: clamp(32px, 6.2vw, 72px);
  letter-spacing: -0.04em;
  line-height: 1.02;
}

h2 { font-size: clamp(29px, 3.7vw, 44px); }
h3 { font-size: clamp(19px, 1.5vw, 22px); letter-spacing: -0.02em; }

p { margin: 0; }
.lede { font-size: clamp(17px, 1.35vw, 20px); color: var(--ink-2); line-height: 1.62; }
.band .lede { color: var(--dark-ink-2); }

.muted { color: var(--ink-3); }
.measure { max-width: 62ch; }
.measure-sm { max-width: 48ch; }

.accent { color: var(--brand); }
.band .accent { color: var(--mint); }

/* eyebrow label */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 20px;
}

.eyebrow::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 2px;
  background: var(--brand);
  transform: skewX(-20deg);
}

.band .eyebrow { color: var(--dark-ink-2); }
.band .eyebrow::before { background: var(--mint); }

.section-head { max-width: 720px; margin-bottom: clamp(38px, 4.5vw, 60px); }
.section-head[style*="flex"] { flex-wrap: wrap; }
.section-head p { margin-top: 18px; }

/* ---------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 24px;
  border-radius: 11px;
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform .15s ease, background .18s ease, border-color .18s ease, color .18s ease;
  white-space: nowrap;
}

.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn-primary { background: var(--ink); color: #fff; }
.btn-primary:hover { background: #1b2330; }

.btn-brand { background: var(--brand); color: #fff; }
.btn-brand:hover { background: var(--brand-dark); }

.btn-ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { border-color: #c3d0ea; background: #fff; }

.band .btn-primary { background: var(--mint); color: #04231a; }
.band .btn-primary:hover { background: #4dffc2; }
.band .btn-ghost { color: #fff; border-color: var(--dark-line); }
.band .btn-ghost:hover { background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .3); }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }

.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-weight: 600;
  font-size: 15px;
  color: var(--brand);
  text-decoration: none;
}
.arrow-link svg { transition: transform .18s ease; }
.arrow-link:hover svg { transform: translateX(3px); }
.band .arrow-link { color: var(--mint); }

/* ---------------------------------------------------------------- nav */

.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(242, 246, 255, .82);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease, background .2s ease;
}

/* The transition above is there for the scroll fade, but CSS cannot tell why
   a class changed, so it also fired when the mobile menu opened. Everything
   else in the bar is a display or colour swap with no transition, so the bar
   arrived 200ms after the panel, the burger and the lockup. The menu handler
   adds this for the duration of the toggle and drops it again, so the scroll
   fade is untouched. */
.nav.no-anim { transition: none; }

.nav.is-stuck { border-bottom-color: var(--line); }

.nav-in {
  display: flex;
  align-items: center;
  gap: 28px;
  height: var(--nav-h);
}

.nav-logo { display: flex; align-items: center; flex: none; }
.nav-logo img { height: 30px; width: auto; display: block; }

.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
}

.nav-links a {
  padding: 8px 13px;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink-2);
  text-decoration: none;
  transition: color .16s ease, background .16s ease;
}

.nav-links a:hover { color: var(--ink); background: rgba(10, 14, 20, .05); }

.nav-cta { margin-left: 10px; }
.nav-cta .btn { padding: 11px 19px; font-size: 14.5px; }

.nav-toggle {
  display: none;
  margin-left: auto;
  width: 42px; height: 42px;
  align-items: center; justify-content: center;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: transparent;
  cursor: pointer;
}

.nav-toggle span {
  display: block;
  width: 17px; height: 2px;
  background: var(--ink);
  position: relative;
}
.nav-toggle span::before,
.nav-toggle span::after {
  content: ""; position: absolute; left: 0;
  width: 17px; height: 2px; background: var(--ink);
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after  { top: 6px; }

/* ---------------------------------------------------------------- hero */

.hero { position: relative; padding-block: clamp(72px, 11vw, 132px); }

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr);
  gap: clamp(36px, 5vw, 64px);
  align-items: center;
}

.hero h1 { margin-bottom: 26px; }
.hero .lede { max-width: 54ch; }
.hero .btn-row { margin-top: 34px; }

.hero-chains {
  margin-top: 46px;
  padding-top: 26px;
  border-top: 1px solid var(--dark-line);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 22px;
  font-size: 13.5px;
  color: var(--dark-ink-2);
}

.hero-chains b {
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  font-size: 11.5px;
  color: #7d8f88;
}

/* ---------------------------------------------------------------- stats */

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.stat { background: var(--ground); padding: 30px 26px; }
.stat b {
  display: block;
  font-size: clamp(26px, 2.7vw, 34px);
  letter-spacing: -0.035em;
  line-height: 1;
  margin-bottom: 9px;
}
.stat span { font-size: 14.5px; color: var(--ink-3); }

/* ---------------------------------------------------------------- cards */

.grid { display: grid; gap: 18px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.card {
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 30px 28px;
  display: flex;
  flex-direction: column;
  gap: 13px;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}

.card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: #cdd9f0; }
.card p { color: var(--ink-2); font-size: 15.5px; line-height: 1.6; }
.card .card-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

.band .card {
  background: var(--dark-2);
  border-color: var(--dark-line);
}
.band .card:hover { border-color: rgba(255, 255, 255, .26); box-shadow: none; }
.band .card p { color: var(--dark-ink-2); }

.ico {
  width: 42px; height: 42px;
  border-radius: 11px;
  display: grid; place-items: center;
  background: var(--brand-tint);
  color: var(--brand);
  flex: none;
}
.band .ico { background: rgba(0, 255, 168, .1); color: var(--mint); }

.badge {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  padding: 5px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.badge-live     { background: var(--brand-tint); color: var(--brand-dark); }
.badge-beta     { background: #e8e7fb; color: #453a89; }
.badge-research { background: #eceffa; color: #4a5573; }

.band .badge-live     { background: rgba(0,255,168,.13); color: var(--mint); }
.band .badge-beta     { background: rgba(150,132,255,.16); color: #bdb2ff; }
.band .badge-research { background: rgba(255,255,255,.09); color: #b9c7d6; }

/* feature list */
.ticks { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 11px; }
.ticks li {
  position: relative;
  padding-left: 27px;
  font-size: 15.5px;
  color: var(--ink-2);
  line-height: 1.55;
}
.ticks li::before {
  content: "";
  position: absolute;
  left: 0; top: 8px;
  width: 13px; height: 8px;
  border-left: 2px solid var(--brand);
  border-bottom: 2px solid var(--brand);
  transform: rotate(-45deg);
}
.band .ticks li { color: var(--dark-ink-2); }
.band .ticks li::before { border-color: var(--mint); }

/* ---------------------------------------------------------------- split */

.split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(32px, 5vw, 68px);
  align-items: center;
}

/* code panel */
.code {
  min-width: 0;
  background: var(--dark);
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
}

.code-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 13px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, .09);
}
.code-bar i { width: 10px; height: 10px; border-radius: 50%; background: rgba(255,255,255,.16); }
.code-bar span {
  margin-left: 8px;
  font-family: var(--mono);
  font-size: 12.5px;
  color: #7d8f88;
}

.code pre {
  margin: 0;
  padding: 22px 20px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 13.2px;
  line-height: 1.75;
  color: #d6e2dc;
}
.code .k { color: var(--mint); }
.code .s { color: #ffd27a; }
.code .c { color: #5f7169; }
.code .n { color: #8fb8ff; }

/* analytics mock */
.panel {
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 26px;
  box-shadow: var(--shadow);
}

.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin-bottom: 22px;
}
.panel-head b { font-size: 15.5px; }
.panel-head span { font-size: 13px; color: var(--ink-3); }

.bars { display: flex; align-items: flex-end; gap: 9px; height: 148px; }
.bars i {
  flex: 1;
  border-radius: 5px 5px 2px 2px;
  background: var(--line);
  display: block;
}
.bars i.on { background: var(--brand); }

.rows { margin-top: 22px; display: grid; gap: 1px; background: var(--line-2); border-radius: 10px; overflow: hidden; }
.row {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 12px;
  padding: 12px 14px;
  background: var(--surface);
  font-size: 14px;
}
.row b { font-weight: 600; }
.row span { color: var(--ink-3); text-align: right; }
.row .up { color: var(--brand); font-weight: 600; }

/* ---------------------------------------------------------------- posts */

.post {
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 26px;
  text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.post:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: #cdd9f0; }
.post .meta { font-size: 13px; color: var(--ink-3); display: flex; gap: 10px; align-items: center; }
.post .meta i { width: 3px; height: 3px; border-radius: 50%; background: currentColor; display: block; }
.post h3 { letter-spacing: -0.022em; }
.post p { font-size: 15px; color: var(--ink-2); }
.post .tag {
  align-self: flex-start;
  font-size: 11.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--brand); background: var(--brand-tint);
  padding: 4px 9px; border-radius: 6px;
}

/* ---------------------------------------------------------------- cta */

.cta-box { text-align: center; max-width: 660px; margin-inline: auto; }
.cta-box h2 { margin-bottom: 18px; }
.cta-box .btn-row { justify-content: center; margin-top: 32px; }

/* ---------------------------------------------------------------- reveal */

.reveal { opacity: 0; transform: translateY(16px); }
.reveal.in {
  opacity: 1; transform: none;
  transition: opacity .6s cubic-bezier(.16,1,.3,1), transform .6s cubic-bezier(.16,1,.3,1);
}
.reveal.d1 { transition-delay: .06s; }
.reveal.d2 { transition-delay: .12s; }
.reveal.d3 { transition-delay: .18s; }

:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 6px; }
.band :focus-visible { outline-color: var(--mint); }

/* ---------------------------------------------------------------- article */

.article { max-width: 720px; margin-inline: auto; }
.article h2 { font-size: clamp(24px, 2.6vw, 32px); margin-top: 46px; margin-bottom: 16px; }
.article h3 { margin-top: 34px; margin-bottom: 12px; }
.article p { margin-top: 18px; color: var(--ink-2); }
.article ul { margin-top: 18px; padding-left: 22px; color: var(--ink-2); }
.article li { margin-bottom: 9px; }
.article .hr { height: 1px; background: var(--line); margin: 46px 0; }
.article blockquote {
  margin: 30px 0; padding: 20px 24px;
  border-left: 3px solid var(--brand);
  background: var(--surface);
  border-radius: 0 12px 12px 0;
  font-size: 17px; color: var(--ink-2);
}

/* ---------------------------------------------------------------- responsive */

/* 959, not 980: Chrome's "Desktop site" uses a 980px layout viewport, and at
   980 exactly this query would fire and hand it the mobile layout. */
@media (max-width: 959px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr); }
  .split { grid-template-columns: minmax(0, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* The nav needs ~800px for six links plus the CTA, so it collapses earlier
   than the content grids do. */
@media (max-width: 900px) {
  .nav-links, .nav-cta { display: none; }
  .nav-toggle { display: flex; }
  .nav.open .nav-links {
    display: flex;
    position: absolute;
    top: var(--nav-h); left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 14px var(--pad) 20px;
    background: var(--ground);
    border-bottom: 1px solid var(--line);
    margin: 0;
  }
  .nav.open .nav-links a { padding: 12px 14px; font-size: 16px; }
}

@media (max-width: 720px) {
  /* Denser layout: the same content, roughly a third less scrolling. Achieved
     by tightening the grid rather than scaling the viewport, so the phone's
     own text-size setting is still respected. */
  :root { --section: 52px; }
  body { line-height: 1.52; }
  h2 { font-size: clamp(26px, 6.6vw, 34px); }
  .lede { line-height: 1.55; }
  .card p, .post p { font-size: 15px; line-height: 1.5; }
  .ticks li { line-height: 1.45; }

  .grid-2, .grid-3 { grid-template-columns: minmax(0, 1fr); }
  .btn { width: 100%; }
  .btn-row .btn { width: auto; flex: 1 1 auto; }

  .section-sm { padding-block: 34px; }
  .hero { padding-block: 54px 60px; }
  .hero h1 { margin-bottom: 18px; }
  .hero .btn-row { margin-top: 26px; }
  .hero-chains { margin-top: 30px; padding-top: 20px; }

  .section-head { margin-bottom: 26px; }
  .section-head p { margin-top: 14px; }
  .eyebrow { margin-bottom: 14px; }

  .card { padding: 22px 20px; gap: 10px; }
  .grid { gap: 14px; }
  .stat { padding: 20px 18px; }
  .ticks { gap: 8px; }
  .ticks li { padding-left: 24px; }
  .post { padding: 20px; }
  .role { padding: 22px 20px; }
  .form { padding: 22px 20px; }
  .field { margin-bottom: 15px; }
}

@media (max-width: 560px) {
  body { font-size: 16px; }
  .code pre { font-size: 12.2px; }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .reveal { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- forms */

.form {
  border-radius: var(--r-lg);
  padding: clamp(26px, 3.4vw, 38px);
}

.field { margin-bottom: 20px; }
.field:last-of-type { margin-bottom: 26px; }

.field label {
  display: block;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  margin-bottom: 8px;
}

.field .hint { font-weight: 400; color: var(--ink-3); }

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--ground);
  font-family: var(--font);
  font-size: 15.5px;
  color: var(--ink);
  transition: border-color .16s ease, background .16s ease;
}

.field textarea { min-height: 132px; resize: vertical; line-height: 1.6; }

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--brand);
  background: var(--surface);
  box-shadow: 0 0 0 3px rgba(11, 122, 90, .15);
}

.field input::placeholder,
.field textarea::placeholder { color: #9aa4b8; }


/* --- contact form: the fields that change with the topic ------------------
   The enquiry form asks different questions depending on what someone is
   writing about, because "tell us about your project" produces worse briefs
   than four specific questions. The block is injected and re-injected as the
   topic select changes, so it needs to announce itself rather than appear
   silently. */
.field-group {
  margin-bottom: 20px;
  padding: 18px 18px 4px;
  border: 1px solid var(--line-2);
  border-radius: 12px;
  background: rgba(255, 255, 255, .5);
}
.field-group > .field-group-label {
  display: block;
  font-family: var(--mono);
  font-size: 11.5px; font-weight: 500; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-3);
  margin-bottom: 14px;
}
.field-group .field:last-of-type { margin-bottom: 18px; }
@media (prefers-reduced-motion: no-preference) {
  .field-group { animation: fg-in .22s ease both; }
}
@keyframes fg-in { from { opacity: 0; transform: translateY(-4px); } }

/* the two-column row for short paired answers */
.field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
@media (max-width: 560px) { .field-row { grid-template-columns: minmax(0, 1fr); } }

.checks { display: grid; gap: 10px; }

.check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--ground);
  cursor: pointer;
  font-size: 15px;
  transition: border-color .16s ease, background .16s ease;
}

.check:hover { border-color: #c3d0ea; }
.check input { width: auto; margin-top: 3px; flex: none; accent-color: var(--brand); }
.check span { line-height: 1.45; }

.form-note {
  margin-top: 16px;
  font-size: 13.5px;
  color: var(--ink-3);
  line-height: 1.55;
}

.form-status {
  margin-top: 16px;
  padding: 13px 16px;
  border-radius: 10px;
  font-size: 14.5px;
  font-weight: 500;
  display: none;
}
.form-status.show { display: block; }
.form-status.ok   { background: var(--brand-tint); color: var(--brand-dark); }
.form-status.err  { background: #fdeaea; color: #96322b; }

/* ---------------------------------------------------------------- roles */

.role {
  display: block;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 26px 28px;
  text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.role:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: #cdd9f0; }
.role .role-top {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 10px 16px; margin-bottom: 10px; flex-wrap: wrap;
}
.role h3 { letter-spacing: -0.022em; }
.role p { color: var(--ink-2); font-size: 15.5px; margin-top: 4px; }
.role .role-meta {
  margin-top: 16px; display: flex; flex-wrap: wrap; gap: 8px 18px;
  font-size: 13.5px; color: var(--ink-3);
}
.role .role-meta b { font-weight: 600; color: var(--ink-2); }

/* ==========================================================================
   Landing page, homepage only.
   Light throughout, one accent (emerald), more air than the inner pages.
   ========================================================================== */

.landing { --section: clamp(88px, 11vw, 156px); }

/* --- hero, on the light ground ------------------------------------------ */
.hero-light {
  position: relative;
  overflow: hidden;
  padding-block: clamp(52px, 8vw, 104px) clamp(44px, 7vw, 84px);
}
.hero-light::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(52% 60% at 84% 42%, rgba(11,122,90,.10), transparent 70%),
    radial-gradient(40% 44% at 6% 90%, rgba(11,122,90,.06), transparent 70%);
}
.hero-light .wrap { position: relative; }
@media (min-width: 981px) {
  .hero-light .hero-grid { grid-template-columns: minmax(0, 1.22fr) minmax(0, .78fr); }
}
.hero-light .display {
  font-size: clamp(42px, 6.6vw, 84px);
  letter-spacing: -0.045em;
  line-height: .98;
}
.hero-light .lede { margin-top: 26px; max-width: 46ch; font-size: clamp(18px, 1.6vw, 22px); }
.hero-light .cta-wrap { margin-top: 36px; }
.hero-light .cta-wrap .btn { padding: 16px 30px; font-size: 16.5px; }

/* --- proof strip --------------------------------------------------------- */
.proof { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--surface-2); }
.proof-row {
  display: grid; grid-template-columns: 200px 1fr; gap: 20px 28px;
  align-items: baseline; padding: 24px 0;
}
.proof-row + .proof-row { border-top: 1px solid var(--line-2); }
.proof-k { font-size: 12.5px; letter-spacing: .11em; text-transform: uppercase; font-weight: 600; color: var(--ink-3); }
.proof-v { display: flex; flex-wrap: wrap; gap: 10px 28px; font-weight: 600; font-size: 17px; color: var(--ink); }
.proof-v .soft { color: var(--ink-3); font-weight: 500; }
/* client logos: drop <img>/<span> into .proof-logos; the row hides while empty */
.proof-logos img { height: 28px; width: auto; opacity: .8; }
.proof-row:has(.proof-logos:empty) { display: none; }

/* --- three services ------------------------------------------------------ */
a.card { text-decoration: none; color: inherit; }
.svc3 .card { padding: 36px 32px; gap: 14px; }
.svc3 .card h3 { font-size: clamp(21px, 1.8vw, 25px); }
.svc3 .card p { font-size: 16.5px; }
.svc3 .card .arrow-link { margin-top: auto; padding-top: 10px; }

/* --- products teaser ----------------------------------------------------- */
.teaser {
  display: grid; grid-template-columns: minmax(0, 1.25fr) auto; gap: 40px;
  align-items: center;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: clamp(30px, 4.2vw, 56px);
  box-shadow: var(--shadow);
}
.teaser h2 { font-size: clamp(26px, 3vw, 38px); }
.teaser .lede { margin-top: 14px; font-size: 17px; }

/* --- contact band, the one bold use of the accent ----------------------- */
/* The closing band used to be flat --brand, a mid green. Mid tones are the
   hardest value to make read as premium, and once every other surface on the
   site gained depth this one was the only flat rectangle left. Deep ground
   plus drifting light instead; white text gains contrast rather than losing
   it. */
.contact-band {
  background: var(--brand-deep); color: #fff;
  position: relative; overflow: hidden;
}
.contact-band > .wrap { position: relative; z-index: 2; }
.contact-band h2 { color: #fff; font-size: clamp(34px, 4.8vw, 60px); }
.contact-band .lede { color: rgba(255,255,255,.84); }
.contact-band .eyebrow { color: rgba(255,255,255,.78); }
.contact-band .eyebrow::before { background: #fff; }
.contact-band .btn-primary { background: #fff; color: var(--brand-dark); }
.contact-band .btn-primary:hover { background: #e9f6f0; }
/* The dark bands, the page headers and the hero each define a light ghost
   button; the closing band never did, so the base near-black colour was
   landing on deep emerald. Only the careers band carries one today, but the
   rule belongs on the surface rather than on that one page. */
.contact-band .btn-ghost {
  color: #fff;
  border-color: rgba(255, 255, 255, .34);
  background: rgba(255, 255, 255, .05);
}
.contact-band .btn-ghost:hover {
  background: rgba(255, 255, 255, .12);
  border-color: rgba(255, 255, 255, .55);
}
.contact-band .mail { display: inline-block; margin-top: 22px; color: #fff; font-weight: 600; text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.4); }
.contact-band .mail:hover { border-bottom-color: #fff; }
.contact-band :focus-visible { outline-color: #fff; }

/* --- footer ---------------------------------------------------------------
   Replaces the one-row footer. A single row was the right shape when this was
   one landing page; across 23 pages it had nowhere to put the email, the
   positioning line or the legal links, and nine links in a row sat at the
   limit of what reads.

   Light rather than dark on purpose. The deep emerald closing band sits
   directly above it and should stay the visual full stop; two dark surfaces
   stacked would read as a single heavy block.

   Class names are footer-scoped. The old markup used `class="wrap row"`, which
   collided with the unrelated .row data-table component and inherited its
   white fill and padding, so the footer rendered as a white slab floating on
   the ground rather than a flat strip. */
.site-footer {
  background: var(--ground);
  border-top: 1px solid var(--line);
  padding-top: clamp(24px, 2.4vw, 32px);
  color: var(--ink-3);
}

.foot-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 20px 40px;
  padding-bottom: clamp(18px, 1.9vw, 24px);
}

.foot-brand img { height: 28px; width: auto; display: block; }
.foot-brand p {
  margin-top: 10px; max-width: 40ch;
  font-size: 15px; line-height: 1.6; color: var(--ink-2);
}
.site-footer h4 {
  font-size: 12.5px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink); margin-bottom: 10px;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.site-footer a { color: var(--ink-2); text-decoration: none; font-size: 15px; }
.site-footer a:hover { color: var(--brand); }

.foot-base {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 26px;
  border-top: 1px solid var(--line);
  padding-block: 12px 15px;
  font-size: 14px;
}
.foot-base nav { display: flex; flex-wrap: wrap; gap: 2px; margin-left: auto; }
.foot-base a { font-size: 14px; }

@media (max-width: 720px) {
  .foot-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .foot-brand { grid-column: 1 / -1; }

}
/* The link lists stay paired even on the narrowest phones. Dropping them to a
   single column added roughly 200px of scrolling for no gain: the labels are
   short enough to sit in half a 390px screen. */
@media (max-width: 400px) {
  .foot-grid { gap: 26px 20px; }
}

/* --- inner page header --------------------------------------------------- */
.page-head { padding-block: clamp(56px, 8vw, 96px) clamp(20px, 3vw, 36px); }
.page-head h1 { font-size: clamp(36px, 5.4vw, 64px); letter-spacing: -0.04em; max-width: 20ch; }
.page-head .lede { margin-top: 18px; max-width: 58ch; }

@media (max-width: 900px) {
  .proof-row { grid-template-columns: 1fr; gap: 10px; padding: 20px 0; }
  .teaser { grid-template-columns: 1fr; gap: 24px; }
}
@media (max-width: 720px) {
  .hero-light .display { max-width: none; }
  .hero-light .cta-wrap .btn { width: 100%; }
}

/* ==========================================================================
   Service-page components: process, coverage, tooling, severity, FAQ.
   ========================================================================== */

/* --- dark page header, used by Security ---------------------------------- */
.head-dark { background: var(--dark); color: #eef4f1; padding-block: clamp(40px, 5.6vw, 74px) clamp(34px, 5vw, 60px); }
.head-dark h1 { color: #fff; font-size: clamp(36px, 5.4vw, 66px); letter-spacing: -0.04em; max-width: 17ch; }
.head-dark .lede { color: var(--dark-ink-2); margin-top: 20px; max-width: 60ch; }
.head-dark .eyebrow { color: var(--dark-ink-2); }

/* The aurora sweeps a bright green core under this text, and at its peak the
   standard --dark-ink-2 body grey measured 4.42 against it, just under the
   4.5 floor. Lifted only on the bands that carry the glow; the footer and the
   static dark bands keep the original grey. */
.head-dark .lede, .head-dark .eyebrow { color: #bdcfc7; }
.head-dark .eyebrow::before { background: var(--mint); }
.head-dark .btn-row { margin-top: 34px; }
.head-dark .btn-primary { background: var(--mint); color: #04231a; }
.head-dark .btn-primary:hover { background: #4dffc2; }
.head-dark .btn-ghost { color: #fff; border-color: var(--dark-line); }
.head-dark .btn-ghost:hover { background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.3); }
.head-dark :focus-visible { outline-color: var(--mint); }

/* --- numbered process ---------------------------------------------------- */
.steps { counter-reset: s; display: grid; gap: 2px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; }
.step { background: var(--surface); padding: 26px 28px; display: grid; grid-template-columns: 54px 1fr; gap: 20px; align-items: start; }
.step::before {
  counter-increment: s; content: counter(s, decimal-leading-zero);
  font-family: var(--mono); font-size: 14px; font-weight: 500; color: var(--brand);
  background: var(--brand-tint); border-radius: 9px; padding: 8px 0; text-align: center;
}
.step h3 { font-size: 19px; margin-bottom: 7px; }
.step p { color: var(--ink-2); font-size: 15.5px; line-height: 1.55; }

/* --- coverage matrix ----------------------------------------------------- */
.matrix { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; }
.cell { background: var(--surface); padding: 24px 24px 26px; }
.cell h4 { font-size: 12px; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; margin-bottom: 14px; }
.cell ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.cell li { font-size: 15.5px; color: var(--ink); font-weight: 500; line-height: 1.4; }


/* --- matrix and steps: separate cards, not one box ruled into columns -----
   Both were built as a single bordered container with hairline gaps showing a
   line colour through, so three columns read as one card split by rules. That
   was consistent when every card on the site was a flat white box. Against the
   glass language everywhere else it now reads as a different system, so they
   are real cards with real gaps between them.

   These come after the base rules on purpose: the originals set background,
   border, radius and overflow on the container, and every one of those has to
   be unwound rather than merely overridden. */
.matrix {
  gap: 16px;
  background: none;
  border: 0;
  border-radius: 0;
  overflow: visible;
}
.cell {
  border-radius: var(--r-lg);
  padding: 26px 24px 28px;
}
.cell h4 { color: var(--ink-3); }

.steps {
  gap: 14px;
  background: none;
  border: 0;
  border-radius: 0;
  overflow: visible;
}
.step { border-radius: var(--r-lg); }

@media (max-width: 900px) {
  .matrix { gap: 14px; }
  .steps { gap: 12px; }
}


/* --- the capability cards open a detail sheet -----------------------------
   They are <button> elements rather than divs with a click handler, so they
   are reachable and operable from the keyboard without any ARIA gymnastics.
   That means undoing the styling a button arrives with. */
button.cap-col {
  font: inherit;
  color: inherit;
  text-align: left;
  width: 100%;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.cap-more {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 14px;
  font-size: 14px; font-weight: 600; color: var(--brand);
}
.cap-col:hover .cap-more { gap: 9px; }
.cap-more svg { transition: transform .18s ease; }
.cap-col:hover .cap-more svg { transform: translateX(2px); }

/* --- the detail sheet -----------------------------------------------------
   A native <dialog>, so focus trapping, Escape to close and the backdrop come
   from the platform rather than from code that has to be kept correct. Where
   showModal is missing the card falls through to the page it links to, which
   is a worse experience but never a dead control. */
.sheet {
  /* The same construction as the cards, tuned for a panel that floats over a
     dimmed page rather than sitting on one. Flat white made it the one surface
     on the site not speaking the glass language; flat grey would have fixed
     the whiteness and introduced dullness instead.

     The opacity is the number the contrast sampling settled on, not a guess.
     Text on a translucent panel sits on a ground that moves with whatever is
     behind it, so this was measured against the darkest and lightest parts of
     the page before it was set. */
  border: 1px solid rgba(255, 255, 255, .6);
  padding: 0;
  width: min(560px, calc(100% - 32px));
  border-radius: var(--r-lg);
  background: linear-gradient(165deg, rgba(250, 252, 255, .88) 0%, rgba(231, 239, 252, .84) 100%);
  -webkit-backdrop-filter: blur(24px) saturate(175%);
  backdrop-filter: blur(24px) saturate(175%);
  color: var(--ink);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .9),
    inset 0 -1px 0 rgba(28, 52, 92, .07),
    0 40px 90px -34px rgba(12, 24, 48, .55);
}
/* The blur lives here rather than on the panel. ::backdrop reliably filters
   the page behind the whole dialog, whereas backdrop-filter on a top-layer
   element is inconsistent between engines. The panel is translucent, so it
   shows this dimmed and blurred page through itself: one blur, done once, in
   the place that actually works. */
.sheet::backdrop {
  background: rgba(8, 14, 26, .58);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
.sheet-in { padding: clamp(26px, 4vw, 38px); position: relative; }
.sheet-in h3 {
  font-size: clamp(21px, 2.2vw, 27px);
  letter-spacing: -0.025em;
  margin: 10px 0 14px;
  max-width: 22ch;
}
/* A touch darker than the --ink-2 used on solid surfaces. Measured against
   the panel's darkest ground, the standard body grey came out at 5.81, which
   passes AA but misses the 7.0 the rest of the site holds. Darkening the text
   buys that back without making the panel more opaque and losing the glass. */
.sheet-in p,
.sheet-in .ticks li { color: #333c4d; font-size: 15.5px; line-height: 1.6; }
.sheet-in .ticks { margin-top: 20px; }
.sheet-in .btn { margin-top: 26px; }

.sheet-x {
  position: absolute; top: 13px; right: 13px;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 1px solid rgba(120, 150, 196, .3);
  border-radius: 9px;
  background: rgba(255, 255, 255, .55);
  color: var(--ink-2);
  cursor: pointer;
}
.sheet-x:hover { color: var(--ink); border-color: #c3d0ea; }

@media (prefers-reduced-motion: no-preference) {
  .sheet[open] { animation: sheet-in .2s cubic-bezier(.16, 1, .3, 1) both; }
}
@keyframes sheet-in { from { opacity: 0; transform: translateY(8px) scale(.985); } }

@media (max-width: 560px) {
  .sheet-in { padding: 24px 20px 26px; }
  .sheet-in h3 { max-width: none; }
}

/* --- tooling chips ------------------------------------------------------- */
.tools { display: flex; flex-wrap: wrap; gap: 9px; }
.tool { font-family: var(--mono); font-size: 13.5px; font-weight: 500; color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: 9px; padding: 8px 14px; }
.band .tool, .head-dark .tool { background: var(--dark-2); border-color: var(--dark-line); color: #c6d6cf; }

/* --- severity legend ----------------------------------------------------- */
.sev { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; }
.sev div { border-radius: 12px; padding: 16px 16px 18px; border: 1px solid var(--line); background: var(--surface); }
.sev b { display: block; font-size: 13px; letter-spacing: .07em; text-transform: uppercase; margin-bottom: 6px; }
.sev span { font-size: 13.5px; color: var(--ink-3); line-height: 1.45; }
.sev .s1 { border-top: 3px solid #b3261e; } .sev .s1 b { color: #b3261e; }
.sev .s2 { border-top: 3px solid #c8622a; } .sev .s2 b { color: #c8622a; }
.sev .s3 { border-top: 3px solid #9a7b16; } .sev .s3 b { color: #9a7b16; }
.sev .s4 { border-top: 3px solid #3f6f8f; } .sev .s4 b { color: #3f6f8f; }
.sev .s5 { border-top: 3px solid #6b7488; } .sev .s5 b { color: #6b7488; }

/* --- homepage pillars ---------------------------------------------------- */
.pillars { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
.pillar { display: flex; flex-direction: column; gap: 14px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 34px 30px 30px; text-decoration: none; color: inherit;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease; }
.pillar:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: #cdd9f0; }
.pillar h3 { font-size: clamp(21px, 1.9vw, 26px); }
.pillar p { color: var(--ink-2); font-size: 16px; line-height: 1.55; }
.pillar ul { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 7px; }
.pillar li { font-size: 14.5px; color: var(--ink-3); }
.pillar li { position: relative; padding-left: 17px; }
.pillar li::before { content: ""; position: absolute; left: 0; top: .72em;
  width: 9px; height: 1px; background: currentColor; opacity: .55; }
.pillar .arrow-link { margin-top: auto; padding-top: 14px; }

/* --- FAQ ----------------------------------------------------------------- */
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary { cursor: pointer; list-style: none; padding: 22px 44px 22px 0; position: relative;
  font-weight: 600; font-size: 17.5px; letter-spacing: -0.01em; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: ""; position: absolute; right: 8px; top: 50%; width: 11px; height: 11px;
  border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3);
  transform: translateY(-70%) rotate(45deg); transition: transform .2s ease; }
.faq details[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq p { padding: 0 0 24px; color: var(--ink-2); max-width: 72ch; }

/* --- deliverables -------------------------------------------------------- */
.deliver { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 40px; }
.deliver > div { display: grid; grid-template-columns: 26px 1fr; gap: 12px; align-items: start; }
.deliver svg { margin-top: 3px; color: var(--brand); }
.deliver b { display: block; font-size: 16px; margin-bottom: 3px; }
.deliver span { font-size: 15px; color: var(--ink-2); line-height: 1.5; }

/* --- resources hub ------------------------------------------------------- */
.res-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }

@media (max-width: 900px) {
  .matrix, .pillars, .res-grid { grid-template-columns: minmax(0, 1fr); }
  .sev { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .deliver { grid-template-columns: minmax(0, 1fr); }
  .step { grid-template-columns: 44px 1fr; gap: 16px; padding: 22px 20px; }
}
@media (max-width: 560px) { .sev { grid-template-columns: minmax(0, 1fr); } }

/* ==========================================================================
   Capability band, replacing the keyword-list proof strip.
   Three columns answering what a visitor asks immediately after the hero:
   can you work where I work, is it safe, and will you still be here after.
   ========================================================================== */

.cap { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--surface-2); }
.cap-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; }
.cap-col { padding: clamp(30px, 3.4vw, 46px) clamp(22px, 2.6vw, 40px); }
.cap-col + .cap-col { border-left: 1px solid var(--line); }
.cap-col .ico { margin-bottom: 16px; }
.cap-col h3 { font-size: clamp(18px, 1.5vw, 21px); letter-spacing: -0.02em; margin-bottom: 9px; }
.cap-col p { font-size: 15.5px; line-height: 1.55; color: var(--ink-2); }
.cap-col .soft { color: var(--ink-3); }


@media (max-width: 900px) {
  .cap-grid { grid-template-columns: minmax(0, 1fr); }

}

/* ==========================================================================
   Product blocks, larger than a card, because a product needs to explain
   what it is, who it is for and why it exists, not just carry a name.
   ========================================================================== */

.product {
  border-radius: var(--r-lg);
  padding: clamp(28px, 3.4vw, 46px);
}
/* The first product carries the line, so the page has a lead rather than three
   blocks of equal weight stacked in arbitrary order. */
.product:first-of-type::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: linear-gradient(90deg, var(--mint), var(--brand) 70%);
}
.product + .product { margin-top: 18px; }
.product-top { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-bottom: 16px; }
.product-top h2 { font-size: clamp(26px, 3vw, 38px); letter-spacing: -0.035em; }
.product-top .kind { font-size: 13px; color: var(--ink-3); font-weight: 500; }
.product-top .badge { margin-left: auto; }
.product .lede { max-width: 62ch; }
.product-grid { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: clamp(26px, 3.4vw, 52px); margin-top: 30px; }
.product-grid h4 { font-size: 12px; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; margin-bottom: 13px; }
.product-grid .ticks li { font-size: 15.5px; }
.product-why { border-left: 2px solid var(--brand); padding-left: 20px; }
.product-why p { font-size: 15.5px; line-height: 1.6; color: var(--ink-2); }
.product-why p + p { margin-top: 12px; }
.product-who { margin-top: 24px; }
.product-who p { font-size: 15.5px; color: var(--ink-2); line-height: 1.55; }

.badge-soon { background: #eceffa; color: #44506e; }

/* thesis band */
.thesis { background: var(--dark); color: #eef4f1; }
.thesis h2 { color: #fff; }
.thesis .lede, .thesis p { color: var(--dark-ink-2); }
.thesis .eyebrow { color: var(--dark-ink-2); }
.thesis .eyebrow::before { background: var(--mint); }
/* Three cells ruled into one box was the same construction the capability
   matrix and the process steps used, under a different class name. */
.thesis .num { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px;
  margin-top: 34px; }
.thesis .num > div {
  /* A dark translucent fill rather than a light one. Tinted lighter than the
     band, the cells lit up wherever the aurora passed behind them and the body
     text fell to 6.16. Sitting them on the glow instead of glowing with it
     keeps the cell a stable reading surface and separates it from the band. */
  background: rgba(4, 9, 8, .5);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border: 1px solid var(--dark-line);
  border-radius: var(--r-lg);
  padding: 26px 24px 28px;
}
.thesis .num b { display: block; font-family: var(--mono); font-size: 13px; color: var(--mint); margin-bottom: 12px; }
.thesis .num h3 { font-size: 19px; color: #fff; margin-bottom: 8px; }
.thesis .num p { font-size: 15px; line-height: 1.55; }

@media (max-width: 900px) {
  .product-grid { grid-template-columns: minmax(0, 1fr); }
  .thesis .num { grid-template-columns: minmax(0, 1fr); }
  .product-top .badge { margin-left: 0; }
}

code { font-family: var(--mono); font-size: .92em; background: var(--line-2);
  border-radius: 5px; padding: 1px 5px; }

/* ==========================================================================
   Motion, homepage.
   Everything here is decoration. The page is complete and readable with all of
   it disabled, which is exactly what prefers-reduced-motion does at the end.
   ========================================================================== */

/* --- heading rises out of a mask ---------------------------------------- */
/* clip-path rather than an inner wrapper element, so the markup stays clean */
.rise { transform: translateY(26px); opacity: 0; }
.rise.in {
  transform: none; opacity: 1;
  transition: transform .8s cubic-bezier(.16,1,.3,1), opacity .6s ease;
}
.rise.d1.in { transition-delay: .10s; }
.rise.d2.in { transition-delay: .20s; }
.rise.d3.in { transition-delay: .30s; }

/* --- drifting light behind the hero -------------------------------------- */
.hero-light::before { animation: drift 22s ease-in-out infinite alternate; }
@keyframes drift {
  0%   { transform: translate3d(0,0,0) scale(1); }
  50%  { transform: translate3d(-2.5%, 1.8%, 0) scale(1.06); }
  100% { transform: translate3d(2%, -2%, 0) scale(1.02); }
}

/* a second, slower wash so the ground is never completely static */
.hero-light::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(34% 40% at 18% 22%, rgba(11,122,90,.09), transparent 70%);
  animation: drift2 28s ease-in-out infinite alternate;
}
@keyframes drift2 {
  0%   { transform: translate3d(0,0,0) scale(1); opacity: .8; }
  100% { transform: translate3d(6%, 4%, 0) scale(1.14); opacity: 1; }
}

/* --- scroll progress, hairline under the nav ----------------------------- */
.nav::after {
  content: ""; position: absolute; left: 0; bottom: -1px; height: 2px;
  width: var(--progress, 0%); background: var(--brand);
  transition: width .08s linear;
}

/* --- pillar cards: accent line draws in on hover ------------------------- */
.pillar { position: relative; overflow: hidden; }
.pillar::after {
  content: ""; position: absolute; left: 0; top: 0; height: 3px; width: 100%;
  background: var(--brand); transform: scaleX(0); transform-origin: left;
  transition: transform .42s cubic-bezier(.16,1,.3,1);
}
.pillar:hover::after, .pillar:focus-visible::after { transform: scaleX(1); }

/* --- capability columns lift very slightly ------------------------------- */
.cap-col { transition: background .3s ease; }
.cap-col:hover { background: var(--surface); }

/* --- buttons get a touch of travel --------------------------------------- */
.btn-brand, .btn-primary { position: relative; overflow: hidden; }
.btn svg { transition: transform .22s cubic-bezier(.16,1,.3,1); }
.btn:hover svg { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  .rise { transform: none; opacity: 1; }
  .hero-light::before, .hero-light::after { animation: none; }
  .nav::after { display: none; }
  .pillar::after { display: none; }
}

/* --- above-the-fold motion runs on CSS alone ----------------------------- */
/* .rise and .reveal need JavaScript to add .in. That is fine below the fold,
   but the hero must never depend on a script to become visible, so it animates
   with keyframes and fill-mode "both" instead: it always ends visible. */
.rise-load { animation: riseIn .9s cubic-bezier(.16,1,.3,1) both; }
.rise-load.d1 { animation-delay: .08s; }
.rise-load.d2 { animation-delay: .18s; }
.rise-load.d3 { animation-delay: .28s; }
@keyframes riseIn {
  from { transform: translateY(26px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .rise-load { animation: none; }
}

/* ==========================================================================
   Page headers and supporting devices.
   Every top-level page opens on the dark band so the site has one rhythm:
   dark header, light body, accent close.
   ========================================================================== */

.head-dark { position: relative; overflow: hidden; }
.head-dark > .wrap { position: relative; z-index: 2; }

/* --- dark bands: drifting aurora -----------------------------------------
   What used to sit here was a faint 72px lattice plus one pinned radial glow.
   The lattice gave the band shape, but it also drew those rectangles across
   every page header, and a static grid is the opposite of moving light. Both
   are gone. The glow is now the only thing giving the band form, so it runs
   brighter than the single radial it replaces, and it moves.

   These blend with screen, not the multiply used on the light half of the
   site. On a near-black ground light is additive: two overlapping mint glows
   should build toward white the way real light does. Multiply can only ever
   darken, so on black it would be invisible.

   Only transform is animated. The blur rasterises once and the motion stays
   on the compositor. */

.glowfield {
  position: absolute; inset: 0; z-index: 1;
  overflow: hidden; pointer-events: none;
  isolation: isolate;
}
.glow {
  position: absolute; border-radius: 50%;
  mix-blend-mode: screen;
  will-change: transform;
}

/* large and slow for the ambient wash, small and quick for life */
.g1 {
  width: 68vw; height: 44vw; min-width: 520px; min-height: 330px;
  left: 4%; top: -28%;
  background: radial-gradient(ellipse at 50% 50%,
    rgba(0,255,168,.22) 0%, rgba(0,255,168,.08) 45%, rgba(0,255,168,0) 72%);
  filter: blur(54px);
  animation: glow-a 61s ease-in-out infinite;
}
.g2 {
  width: 46vw; height: 34vw; min-width: 350px; min-height: 250px;
  right: -8%; top: 10%;
  background: radial-gradient(ellipse at 50% 50%,
    rgba(22,214,192,.19) 0%, rgba(22,214,192,.07) 46%, rgba(22,214,192,0) 72%);
  filter: blur(46px);
  animation: glow-b 43s ease-in-out infinite;
}
.g3 {
  width: 34vw; height: 26vw; min-width: 250px; min-height: 185px;
  left: 36%; bottom: -24%;
  background: radial-gradient(ellipse at 50% 50%,
    rgba(0,255,168,.17) 0%, rgba(0,255,168,.06) 48%, rgba(0,255,168,0) 74%);
  filter: blur(38px);
  animation: glow-c 29s ease-in-out infinite;
}

@keyframes glow-a {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  35%      { transform: translate3d(21%, 26%, 0) scale(1.18); }
  68%      { transform: translate3d(-14%, 12%, 0) scale(.9); }
}
@keyframes glow-b {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  32%      { transform: translate3d(-30%, 22%, 0) scale(.88); }
  70%      { transform: translate3d(-12%, -18%, 0) scale(1.2); }
}
@keyframes glow-c {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  40%      { transform: translate3d(26%, -30%, 0) scale(1.24); }
  74%      { transform: translate3d(-24%, -12%, 0) scale(.86); }
}

/* data-glow used to pin the old radial to a corner. It now offsets each page
   into a different part of the cycle with a negative delay, so the six inner
   headers stay related without any two looking alike on load. */
.head-dark[data-glow="left"]   .glow { animation-delay: -17s; }
.head-dark[data-glow="centre"] .glow { animation-delay: -38s; }
.head-dark[data-glow="wide"]   .glow { animation-delay: -53s; }

/* The homepage hero already has a light source: the 3D mark sits right behind
   the headline and throws its own mint. Measured, the aurora at full strength
   added another 0.06 luminance on top of that, which the headline text-shadow
   then had to absorb alone. Here it plays a supporting wash instead. The inner
   headers have no mark, so they keep the full strength. */
.hero-dark .glowfield { opacity: .45; }

/* Three drifting surfaces in one scroll risks busy. The closing band runs at
   roughly half the speed of the headers and lower intensity, so it reads as
   the page settling rather than as a third thing asking for attention. */
.contact-band .glowfield { opacity: .60; }
.contact-band .g1 { animation-duration: 97s; }
.contact-band .g2 { animation-duration: 79s; }
.contact-band .g3 { animation-duration: 67s; }

/* Opt-in, so the dark bands on other pages are untouched. Dimmer and slower
   again than the closing band, because this one sits behind body copy rather
   than a headline, and the body grey gets the same lift the headers needed. */
.thesis.has-glow { position: relative; overflow: hidden; }
.band.has-glow > .wrap,
.thesis.has-glow > .wrap { position: relative; z-index: 2; }
.band.has-glow .glowfield,
.thesis.has-glow .glowfield { opacity: .48; }
.band.has-glow .g1,
.thesis.has-glow .g1 { animation-duration: 83s; }
.band.has-glow .g2,
.thesis.has-glow .g2 { animation-duration: 71s; }
.band.has-glow .g3,
.thesis.has-glow .g3 { animation-duration: 59s; }
.band.has-glow .lede, .band.has-glow .eyebrow, .band.has-glow .ticks li,
.thesis.has-glow .lede, .thesis.has-glow .eyebrow,
.thesis.has-glow .num p { color: #bdcfc7; }

@media (max-width: 900px) {
  /* the quick one goes; two glows carry a header that is half the width */
  .g3 { display: none; }
  .g1 { filter: blur(38px); }
  .g2 { filter: blur(32px); }
}

/* --- claim pills ---------------------------------------------------------- */
.pills { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 30px; }
.pill {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: 500; letter-spacing: -0.005em;
  border: 1px solid var(--line); border-radius: 999px; padding: 8px 16px 8px 13px;
  background: var(--surface); color: var(--ink-2);
}
.pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--brand); flex: none; }
.head-dark .pill { background: rgba(255,255,255,.05); border-color: var(--dark-line); color: #d3e2db; }
.head-dark .pill::before { background: var(--mint); }

/* --- tinted panel, to break a page that is one flat colour ---------------- */
.tint {
  background: linear-gradient(180deg, #eef5f2 0%, #eaf3ef 100%);
  border: 1px solid #dbe8e2; border-radius: clamp(18px, 2.4vw, 28px);
  padding: clamp(32px, 4.6vw, 68px) clamp(22px, 3.4vw, 52px);
}
.tint .section-head { margin-bottom: clamp(28px, 3.4vw, 44px); }

@media (max-width: 720px) {
  .pills { margin-top: 22px; gap: 7px; }
  .pill { font-size: 13px; padding: 7px 13px 7px 11px; }
}

/* ==========================================================================
   Hero: dark band, mark behind the type.
   Behind-the-text failed on light because a hard-edged object sat against
   near-black text. On dark, blurred, the mark becomes a luminous form the way
   KORE's gradient does, and white type over it has enormous contrast.
   Spacing is tuned so headline, line, buttons and marquee all sit above the
   fold at 1440x900, which is what the earlier version got wrong.
   ========================================================================== */

.hero-dark {
  position: relative; overflow: hidden; background: var(--dark); color: #eef4f1;
  padding-block: clamp(58px, 6.5vw, 96px) clamp(52px, 5.5vw, 78px);
}
.hero-dark .wrap { position: relative; z-index: 2; }
/* the ink field canvas is inserted as the hero's first child at z-index 0 */
.hero-stack { text-align: center; display: flex; flex-direction: column; align-items: center; }

.hero-kicker {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--mono); font-size: 12px; font-weight: 500;
  letter-spacing: .17em; text-transform: uppercase; color: #cfe3da;
  background: rgba(255,255,255,.06); border: 1px solid var(--dark-line);
  border-radius: 999px; padding: 9px 18px 9px 14px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
/* "Web3 engineering and infrastructure" is six characters longer than the
   kicker this pill was sized for, and at full tracking it wrapped to two lines
   inside the pill on a phone. Tighter tracking keeps it on one line down to a
   360px screen without shortening the words. */
@media (max-width: 480px) {
  .hero-kicker { font-size: 11px; letter-spacing: .08em; }
}

.hero-kicker::before {
  content: ""; width: 7px; height: 7px; border-radius: 2px; background: var(--mint);
  transform: skewX(-20deg); flex: none;
}

/* sized so two lines clear the fold, not three at display scale */
.hero-dark h1 {
  color: #fff; margin-top: clamp(24px, 2.6vw, 34px);
  font-size: clamp(34px, 4.4vw, 62px); letter-spacing: -0.04em;
  /* 27ch fits "Engineering and infrastructure" on one line at every desktop
     width; 20ch was sized for a shorter headline and left one word stranded
     on a third line. Balance is the safety net if the copy changes again. */
  line-height: 1.04; max-width: 27ch; text-wrap: balance;
  text-shadow: 0 2px 26px rgba(0,0,0,.7);
}
.hero-dark .lede {
  color: #b6c9c1; margin-top: clamp(16px, 1.6vw, 22px);
  max-width: 54ch; font-size: clamp(16.5px, 1.25vw, 18.5px);
  text-shadow: 0 1px 18px rgba(0,0,0,.5);
}
.hero-dark .btn-row { justify-content: center; margin-top: clamp(26px, 2.6vw, 34px); }
.hero-dark .btn-primary { background: var(--mint); color: #04231a; }
.hero-dark .btn-primary:hover { background: #4dffc2; }
.hero-dark .btn-ghost { color: #fff; border-color: rgba(255,255,255,.24); background: rgba(255,255,255,.04); }
.hero-dark .btn-ghost:hover { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.36); }
.hero-dark :focus-visible { outline-color: var(--mint); }

/* --- ink field: pigment suspended in water --------------------------------
   One drifting colour field sits behind the entire light region, and every
   glass surface on top of it samples it through backdrop-filter. That is the
   whole trick: the blur is real, so each card shows a different part of the
   field and no two are the same colour at the same moment. A gradient painted
   onto each card individually cannot do that, which is why the old flat green
   read as static no matter how it was tinted.

   The blobs blend with multiply, not screen. Multiply is subtractive, the way
   pigment actually behaves suspended in water. Screen is additive, the way
   light behaves, and additive blending over a light ground is exactly the neon
   glow this replaces.

   Only transform is animated. The blur is rasterised once and the motion stays
   on the compositor; animating the filter itself would re-rasterise every
   frame and drop the page to single digits on a phone. */

.ink-band { position: relative; isolation: isolate; }

.inkfield {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden;
  background: var(--ground);
  /* isolate so the blobs mix with each other and this ground, and never with
     whatever the page happens to paint behind the band */
  isolation: isolate;
  pointer-events: none;
}

.ink {
  position: absolute;
  border-radius: 50%;
  mix-blend-mode: multiply;
  will-change: transform;
}

/* Depth comes from pairing blur radius with speed: the near blobs are less
   blurred and travel further, the far ones are softer and slower. Durations
   are all primes so the composition never visibly returns to its start. */
.ink-1 {                                        /* emerald, the brand anchor */
  width: 62vw; height: 62vw; min-width: 440px; min-height: 440px;
  left: -12%; top: -20%;
  background: radial-gradient(circle at 50% 50%,
    rgba(11,122,90,.60) 0%, rgba(11,122,90,.26) 44%, rgba(11,122,90,0) 70%);
  filter: blur(90px);
  animation: ink-a 71s ease-in-out infinite;
}
.ink-2 {                                                     /* ocean blue */
  width: 54vw; height: 54vw; min-width: 390px; min-height: 390px;
  right: -14%; top: 2%;
  background: radial-gradient(circle at 50% 50%,
    rgba(47,107,224,.50) 0%, rgba(47,107,224,.21) 46%, rgba(47,107,224,0) 70%);
  filter: blur(76px);
  animation: ink-b 59s ease-in-out infinite;
}
.ink-3 {                              /* mint, nearest: sharpest and fastest */
  width: 40vw; height: 40vw; min-width: 290px; min-height: 290px;
  left: 27%; top: 33%;
  background: radial-gradient(circle at 50% 50%,
    rgba(0,255,168,.44) 0%, rgba(0,255,168,.18) 48%, rgba(0,255,168,0) 70%);
  filter: blur(56px);
  animation: ink-c 43s ease-in-out infinite;
}
.ink-4 {                                                          /* cyan */
  width: 46vw; height: 46vw; min-width: 330px; min-height: 330px;
  right: 6%; bottom: -14%;
  background: radial-gradient(circle at 50% 50%,
    rgba(34,211,238,.42) 0%, rgba(34,211,238,.17) 47%, rgba(34,211,238,0) 70%);
  filter: blur(70px);
  animation: ink-d 53s ease-in-out infinite;
}
.ink-5 {                                /* violet, furthest: heaviest blur */
  width: 50vw; height: 50vw; min-width: 350px; min-height: 350px;
  left: 2%; bottom: -22%;
  background: radial-gradient(circle at 50% 50%,
    rgba(109,90,230,.40) 0%, rgba(109,90,230,.16) 48%, rgba(109,90,230,0) 70%);
  filter: blur(104px);
  animation: ink-e 89s ease-in-out infinite;
}

/* A wide, flat sweeper confined to the top of the band. It runs horizontally
   under the marquee so the colour moves counter to the scrolling text; the two
   opposing motions are what keep the pill from reading as a static strip. */
.ink-6 {
  width: 78vw; height: 26vw; min-width: 560px; min-height: 190px;
  left: -20%; top: -4%;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 50%,
    rgba(24,160,150,.40) 0%, rgba(24,160,150,.16) 46%, rgba(24,160,150,0) 72%);
  filter: blur(64px);
  animation: ink-f 37s ease-in-out infinite;
}

@keyframes ink-f {
  0%, 100% { transform: translate3d(0, 0, 0) scaleX(1); }
  50%      { transform: translate3d(62%, 6%, 0) scaleX(1.15); }
}

@keyframes ink-a {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  34%      { transform: translate3d(16%, 14%, 0) scale(1.16); }
  67%      { transform: translate3d(27%, -9%, 0) scale(.92); }
}
@keyframes ink-b {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  30%      { transform: translate3d(-22%, 18%, 0) scale(.88); }
  65%      { transform: translate3d(-9%, 33%, 0) scale(1.18); }
}
@keyframes ink-c {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  28%      { transform: translate3d(-27%, -17%, 0) scale(1.22); }
  61%      { transform: translate3d(19%, 24%, 0) scale(.86); }
}
@keyframes ink-d {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  37%      { transform: translate3d(-19%, -26%, 0) scale(1.13); }
  72%      { transform: translate3d(-33%, 7%, 0) scale(.9); }
}
@keyframes ink-e {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  41%      { transform: translate3d(24%, -21%, 0) scale(.9); }
  76%      { transform: translate3d(6%, -34%, 0) scale(1.2); }
}

/* the sections themselves are transparent so the field shows through */
.ink-band > .marquee-wrap,
.ink-band > .cap,
.ink-band > .section,
.ink-band > .section-sm { position: relative; z-index: 1; background: transparent; }

/* --- glass ----------------------------------------------------------------
   Cool near-white over the field. The edge is two-part on purpose: a cool
   outer hairline so the card has a visible outline, plus an inset white top
   highlight and a darker inset bottom edge to give it thickness. One flat
   translucent fill reads as a rectangle; those three together read as glass. */
.marquee, .cap-col, .pillar, .teaser,
.card, .role, .form, .cell, .step, .product {
  position: relative;
  overflow: hidden;
  background: linear-gradient(165deg, rgba(255,255,255,.80) 0%, rgba(232,240,251,.66) 100%);
  border: 1px solid rgba(120,150,196,.34);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.92),
    inset 0 -1px 0 rgba(28,52,92,.07),
    0 12px 34px -14px rgba(24,48,92,.20);
}

/* The backdrop blur is separated out because it only earns its cost where a
   drifting field actually sits behind the surface. On the inner pages the
   ground is a flat colour, so blurring it would buy a compositor pass and show
   nothing. Those cards get the glass edge and fill, not the sampling. */
.ink-band .marquee, .ink-band .cap-col,
.ink-band .pillar, .ink-band .teaser {
  -webkit-backdrop-filter: blur(22px) saturate(185%);
  backdrop-filter: blur(22px) saturate(185%);
}

/* dark bands keep the dark card; the light insets above must not leak in */
.band .card { box-shadow: none; }

/* The specular sweep: a single travelling highlight, off-frame for most of
   the cycle so it reads as a glint rather than a loop. It lives on ::before
   because .pillar::after is already the accent line that draws in on hover. */
.marquee::before, .cap-col::before, .pillar::before, .teaser::before {
  content: "";
  position: absolute; top: -60%; bottom: -60%; left: 0; width: 38%;
  background: linear-gradient(100deg,
    rgba(255,255,255,0) 0%, rgba(255,255,255,.62) 50%, rgba(255,255,255,0) 100%);
  transform: translateX(-170%) skewX(-14deg);
  animation: sheen 9s ease-in-out infinite;
  pointer-events: none;
  /* behind the content, not over it. At z-index 3 the highlight washed across
     the type as it passed and briefly dropped the text contrast; a glint on
     the glass is worth having, a glint on the words is not. */
  z-index: 1;
}
@keyframes sheen {
  0%, 66% { transform: translateX(-170%) skewX(-14deg); }
  100%    { transform: translateX(390%)  skewX(-14deg); }
}
/* staggered so the three cards never glint together */
.cap-col:nth-child(2)::before, .pillar:nth-child(2)::before { animation-delay: 3s; }
.cap-col:nth-child(3)::before, .pillar:nth-child(3)::before { animation-delay: 6s; }
.teaser::before { animation-delay: 4.5s; }

.marquee:hover, .cap-col:hover, .pillar:hover, .teaser:hover,
.card:hover, .role:hover, .cell:hover, .step:hover {
  border-color: rgba(84,120,178,.52);
}
.cap-col:hover, .pillar:hover, .card:hover, .role:hover {
  transform: translateY(-3px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    inset 0 -1px 0 rgba(28,52,92,.07),
    0 20px 44px -16px rgba(24,48,92,.28);
}

/* --- marquee -------------------------------------------------------------- */
.marquee-wrap { padding: clamp(26px, 3vw, 40px) var(--pad) clamp(30px, 3.4vw, 46px); }
.marquee { width: min(var(--max), 100%); margin-inline: auto; border-radius: 999px; }

/* Fade the text, not the bar. The mask lives on an inner element because a
   mask on .marquee erases its own border and rounded ends, and the pill shape
   disappears at both edges. */
.marquee-mask {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%);
}
.marquee-track { display: flex; width: max-content; animation: marquee 46s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
@keyframes marquee { to { transform: translateX(-50%); } }
.marquee-group { display: flex; align-items: center; flex: none; }
.marquee-item {
  display: inline-flex; align-items: center; gap: 11px;
  padding: 15px 30px; font-size: 15px; font-weight: 600; color: var(--ink);
  white-space: nowrap; letter-spacing: -0.01em;
}
.marquee-item::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--brand);
  box-shadow: 0 0 0 3px rgba(11,122,90,.16); flex: none;
}

/* --- cards ---------------------------------------------------------------- */
.cap { border: 0; padding-block: 0 clamp(10px, 1.5vw, 20px); }
.cap-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
.cap-col {
  border-radius: var(--r-lg);
  padding: clamp(26px, 2.8vw, 36px) clamp(22px, 2.4vw, 30px);
  transition: transform .22s ease, border-color .22s ease, box-shadow .22s ease;
}
.cap-col .ico {
  background: linear-gradient(165deg, rgba(255,255,255,.9), rgba(214,230,248,.75));
  border: 1px solid rgba(120,150,196,.3);
  color: var(--brand-dark);
}
.pillar { transition: transform .22s ease, border-color .22s ease, box-shadow .22s ease; }
.pillar li { color: #46566f; }

/* content sits above the sheen */
.cap-col > *, .pillar > *, .teaser > *, .marquee-mask { position: relative; z-index: 2; }

@media (max-width: 900px) {
  /* Fewer, cheaper blobs and a lighter backdrop blur. Large-radius blur over
     many stacked glass surfaces is the expensive part on a phone, and on a
     stacked layout there are eight of them in a column. */
  .ink-4, .ink-5, .ink-6 { display: none; }
  .ink-1 { filter: blur(58px); }
  .ink-2 { filter: blur(50px); }
  .ink-3 { filter: blur(38px); }
  .marquee, .cap-col, .pillar, .teaser, .card, .role {
    background: linear-gradient(165deg, rgba(255,255,255,.86) 0%, rgba(232,240,251,.76) 100%);
  }
  .ink-band .marquee, .ink-band .cap-col,
  .ink-band .pillar, .ink-band .teaser {
    -webkit-backdrop-filter: blur(14px) saturate(165%);
    backdrop-filter: blur(14px) saturate(165%);
  }
}

@media (max-width: 720px) {
  .hero-dark h1 { max-width: none; }
  .marquee-item { padding: 13px 20px; font-size: 13.5px; }
  .marquee { border-radius: 22px; }
  .marquee-track { animation-duration: 32s; }
}

@media (prefers-reduced-motion: reduce) {
  /* freeze the field at its authored composition rather than removing it */
  .ink { animation: none; }
  .marquee::before, .cap-col::before, .pillar::before, .teaser::before {
    animation: none; opacity: 0;
  }
  .marquee-track { animation: none; }
  .glow { animation: none; }
}

/* --- overlay nav: transparent over a dark header, glass once scrolled -----
   Carried by body.navover, which every page with a dark opening section sets.
   It used to be body.landing, i.e. the homepage alone, and the result was that
   inner pages met their dark header with a light bar and a hard edge at the
   bar's exact height: the same seam this treatment was written to remove.
   The class is separate from .landing because .landing also drives the
   homepage-only mobile layout further down, which no other page wants. */
/* Fallback for a bar that is still in flow: `transparent` would show the body
   behind it, not the dark band, so paint it dark. */
.navover .nav:not(.is-stuck) {
  background: var(--dark); backdrop-filter: none; -webkit-backdrop-filter: none;
}
.navover .nav:not(.is-stuck) .nav-links a { color: #cfe0d8; }
.navover .nav:not(.is-stuck) .nav-links a:hover { color: #fff; background: rgba(255,255,255,.08); }
.navover .nav:not(.is-stuck) .btn-primary { background: var(--mint); color: #04231a; }
.navover .nav:not(.is-stuck) .btn-primary:hover { background: #4dffc2; }
.navover .nav:not(.is-stuck) .nav-toggle { border-color: var(--dark-line); }
.navover .nav:not(.is-stuck) .nav-toggle span,
.navover .nav:not(.is-stuck) .nav-toggle span::before,
.navover .nav:not(.is-stuck) .nav-toggle span::after { background: #fff; }
/* two lockups, the right one shown for the ground behind it */
.nav-logo .on-dark { display: none; }
.navover .nav:not(.is-stuck) .nav-logo .on-light { display: none; }
.navover .nav:not(.is-stuck) .nav-logo .on-dark { display: block; }

/* Responsive overrides must come after the base rules they override: media
   queries carry no extra specificity, so source order decides. The greened
   .cap-grid was declared later than the stacking rule and was winning on
   mobile, holding three columns at 390px. */
@media (max-width: 900px) {
  .cap-grid { grid-template-columns: minmax(0, 1fr); }
}


/* --- the bar sits over the dark header, not on top of it ------------------
   The bar and the header are the same near-black, but only the header carries
   the aurora, so the flat bar ended in a hard step at exactly its own height:
   measured down the centre of the page the colour held at rgb(7,12,10) to
   y=74 and jumped to rgb(6,20,14) immediately below. That edge read as a
   separate black container sitting on the hero.

   Rather than try to continue the glow through a second element and keep two
   surfaces aligned, the dark header now starts at the top of the page and the
   bar floats over it. One surface, nothing to match.

   Scroll behaviour is untouched. The moment the page moves, .is-stuck still
   swaps in the light glass bar, and that rule already outranks this one. */
.navover .nav:not(.is-stuck) {
  background: transparent;
}
/* --nav-h is the bar's content height; it also carries a 1px bottom border,
   so what it actually occupies is one pixel more. Pulling up by --nav-h alone
   left that pixel of light page background showing through the transparent
   bar as a white hairline across the very top. */
.navover main { margin-top: calc((var(--nav-h) + 1px) * -1); }
/* The homepage opens on .hero-dark, every other page on .head-dark. Both need
   the bar's height back as padding so the first line clears the floating bar;
   :first-child keeps it to the section that actually sits under it.

   They no longer take the same gap on top of it. The inner page headers keep
   the tightened spacing; the landing hero is back to the depth it had before,
   because on a page whose first screen is only a claim and two buttons, the
   air above the claim is the composition rather than waste. */
.navover main > .head-dark:first-child { padding-top: calc(var(--nav-h) + 1px + clamp(34px, 4vw, 60px)); }
.navover main > .hero-dark:first-child { padding-top: calc(var(--nav-h) + 1px + clamp(58px, 6.5vw, 96px)); }

/* the open dropdown needs an opaque bar behind it again, or the panel appears
   to float off a transparent strip */
@media (max-width: 900px) {
  .navover .nav:not(.is-stuck).open { background: rgba(242, 246, 255, .94); }
}

/* --- mobile menu ---------------------------------------------------------
   One state, not two. The landing nav is dark at the top of the page and light
   once scrolled, and driving the dropdown off that same flag let the panel and
   its links disagree: a light panel inheriting the dark nav's pale link
   colour, i.e. invisible options until you scrolled. So the open menu always
   renders light, at any scroll position, on every page. The whole bar comes
   with it (ground, lockup, burger) so the nav never reads as half-dark.

   Every selector is written twice, plain and landing-scoped. The landing rules
   above are four-class selectors, so a plain `.nav.open ...` cannot outrank
   them; adding `.open` to the landing form takes it to five and it wins in
   both directions.

   The breakpoint is 900px, matching the one that creates the panel. The
   earlier attempt used 720px and left the 721-900 band with no override. */
@media (max-width: 900px) {
  .nav.open,
  .navover .nav:not(.is-stuck).open {
    background: rgba(242, 246, 255, .94);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
  }

  .nav.open .nav-links,
  .navover .nav:not(.is-stuck).open .nav-links {
    background: var(--ground);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 18px 40px -24px rgba(10, 14, 20, .35);
  }

  .nav.open .nav-links a,
  .navover .nav:not(.is-stuck).open .nav-links a { color: var(--ink); }

  .nav.open .nav-links a:hover,
  .navover .nav:not(.is-stuck).open .nav-links a:hover {
    color: var(--ink); background: rgba(10, 14, 20, .05);
  }

  /* burger and lockup follow the bar back to light */
  .nav.open .nav-toggle,
  .navover .nav:not(.is-stuck).open .nav-toggle { border-color: var(--line); }

  .nav.open .nav-toggle span,
  .nav.open .nav-toggle span::before,
  .nav.open .nav-toggle span::after,
  .navover .nav:not(.is-stuck).open .nav-toggle span,
  .navover .nav:not(.is-stuck).open .nav-toggle span::before,
  .navover .nav:not(.is-stuck).open .nav-toggle span::after { background: var(--ink); }

  .navover .nav:not(.is-stuck).open .nav-logo .on-dark  { display: none; }
  .navover .nav:not(.is-stuck).open .nav-logo .on-light { display: block; }

  /* The primary CTA is hidden on mobile, so it belongs inside the open menu.
     It is an <a> inside .nav-links, so it needs the same selector depth as the
     link-colour rule above or that rule repaints its text. */
  .nav-cta-m {
    display: block; margin-top: 12px; text-align: center;
    padding: 13px 18px; border-radius: 11px;
    font-size: 15.5px; font-weight: 600; text-decoration: none;
  }
  .nav.open .nav-links a.nav-cta-m,
  .navover .nav:not(.is-stuck).open .nav-links a.nav-cta-m {
    background: var(--ink); color: #fff;
  }
  .nav.open .nav-links a.nav-cta-m:hover,
  .navover .nav:not(.is-stuck).open .nav-links a.nav-cta-m:hover {
    background: #1b2330; color: #fff;
  }
}
@media (min-width: 901px) { .nav-cta-m { display: none; } }

/* --- homepage on a phone --------------------------------------------------
   The same page, edited down rather than rebuilt. A phone visitor gets the
   claim and the link; the supporting argument stays in the markup for search
   engines and for anyone who widens the window, so there is still one source
   of truth and no second page to keep in sync.

   Scoped to .landing, which only index.html carries, so no other page is
   touched. Everything here is last in the file on purpose: media queries carry
   no extra specificity, so a later block would otherwise win.

   Trade-off worth knowing: display:none also removes content from the
   accessibility tree, so a phone screen-reader user does not hear the hidden
   detail either. It is acceptable here only because every hidden item is
   repeated in full on the page its card links to. */
@media (max-width: 720px) {

  /* A stack, inset from both edges. Two columns left an orphan third card,
     and full-bleed blocks read as banded sections rather than as cards. Each
     they sit centred at the same width so the column reads as an even stack,
     with the ink field visible down both sides. */
  .landing .cap-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .landing .cap-col {
    width: 86%;
    display: flex; flex-direction: row; align-items: center; gap: 14px;
    padding: 15px 18px;
    border-radius: 15px;
  }
  .landing .cap-col { margin-inline: auto; }

  .landing .cap-col p,
  .landing .cap-col .cap-more { display: none; }
  /* the read-more cue goes with the body copy, so the card needs some other
     signal that it is tappable. ::before is the specular sweep, ::after is free. */
  .landing .cap-col::after {
    content: "";
    margin-left: auto; flex: none;
    width: 7px; height: 7px;
    border-top: 2px solid var(--ink-3);
    border-right: 2px solid var(--ink-3);
    transform: rotate(45deg);
  }
  .landing .cap-col h3 {
    font-size: 16px; line-height: 1.3; letter-spacing: -0.018em; margin: 0;
  }
  .landing .cap-col .ico {
    width: 36px; height: 36px; border-radius: 10px; margin: 0;
  }
  .landing .cap-col .ico svg { width: 18px; height: 18px; }

  /* the discipline cards keep the claim and the link and drop the specifics,
     all of which are repeated on the page each one links to */
  .landing .pillar ul { display: none; }
  .landing .pillar { padding: 22px 20px 20px; gap: 9px; }
  .landing .pillar h3 { font-size: 22px; }
  .landing .pillar p { font-size: 15px; line-height: 1.5; }
  .landing .pillar .arrow-link { padding-top: 6px; font-size: 15px; }

  /* tighter rhythm so the edited page does not read as gaps */
  .landing .cap { padding-block: 0 4px; }
  .landing .section { padding-block: 46px; }
  .landing .section-head { margin-bottom: 26px; }
}

/* The landing hero holds its original depth on a phone too, but the bar under
   it is now 64px rather than the 74px this composition was set against, so the
   gap has to absorb that difference: 64 + 1 + 68 puts the first line back on
   the same 133px it always sat on. A flat value, not a clamp, because below
   900px the old clamp was pinned to its 58px floor at every width anyway. */
@media (max-width: 900px) {
  .navover main > .hero-dark:first-child { padding-top: calc(var(--nav-h) + 1px + 68px); }
}

/* Phones get a further trim: the inner page headers with roughly a third less
   air above the first line, which is most of a thumb-scroll on a small screen. */
@media (max-width: 720px) {
  .head-dark { padding-block: clamp(26px, 7vw, 40px) clamp(26px, 5vw, 44px); }
  .navover main > .head-dark:first-child { padding-top: calc(var(--nav-h) + 1px + clamp(22px, 6vw, 36px)); }
}

/* --- footer social links ---------------------------------------------------
   Two marks, mail and LinkedIn, holding the right end of the copyright row.
   Labelled, they read as more links among equals in a row of legal text and
   cost the width that keeps the row on one line; as marks they are the two
   ways out of the page and nothing else. The mail one is a plain envelope
   rather than the Gmail mark: that glyph is Google's, and the address is not a
   Gmail address, so it would be wrong twice over. */
.foot-social {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px;
  color: var(--ink-2);
  transition: color .16s ease, background .16s ease;
}
.foot-social svg { width: 17px; height: 17px; display: block; flex: none; }
.foot-social:hover { color: var(--brand); background: rgba(11, 122, 90, .09); }
/* The 30px hit area carries about 6px of padding around a 17px glyph, so the
   last mark needs that pulled back for its ink, not its box, to sit on the
   same gutter as the columns above. */
.foot-base nav .foot-social:last-child { margin-right: -6px; }

/* nowrap is what holds the marks on the copyright's line; min-width lets the
   copyright shrink into what is left rather than push them onto a row of
   their own, which cost about forty pixels of empty footer before. */
@media (max-width: 900px) {
  .foot-base        { flex-wrap: nowrap; gap: 10px; }
  .foot-base > span { min-width: 0; }
  .foot-base nav    { width: auto; flex: none; }
}

@media (max-width: 720px) {
  .site-footer { padding-top: 18px; }
  .foot-grid   { gap: 18px 24px; padding-bottom: 14px; }
  .foot-base   { padding-block: 8px 12px; }
}
