/* ==========================================================================
   Rideware Technologies — ridewaretech.com
   Premium dark theme, 2026.

   Written against the class names the generator already emits, so the markup
   in site-src/lib.js and site-src/build.js is untouched: every page, URL and
   piece of structured data survives the redesign intact.

   The look
     - near-black canvas lit by two slow aurora fields, so the page has depth
       without a single decorative image to download
     - glass surfaces: 4% white, a 1px translucent edge, blurred backdrop
     - one accent gradient — cyan into indigo into violet — used on the things
       that matter and nowhere else
     - a hairline grid behind the hero, masked to fade out, so the panel reads
       as engineered rather than empty

   Everything degrades: no backdrop-filter, no mask, no colour — it still reads.
   ========================================================================== */

/* ---------- tokens ---------- */

:root {
  /* canvas */
  --bg:          #05070c;
  --bg-2:        #080c14;
  --bg-3:        #0b111c;

  /* glass */
  --glass:       rgba(255, 255, 255, .04);
  --glass-2:     rgba(255, 255, 255, .06);
  --edge:        rgba(255, 255, 255, .09);
  --edge-2:      rgba(255, 255, 255, .16);

  /* ink — brightened across the board. Body copy went 11.6:1 -> 15.8:1 against
     the canvas, and --faint went 4.2:1 -> 7.5:1, which was the only token
     sitting near the WCAG AA floor of 4.5:1. */
  --ink:         #f8fbff;
  --ink-2:       #dae5f4;
  --muted:       #c6d5e8;
  --faint:       #a6b9d0;

  /* accent */
  --cyan:        #22d3ee;
  --indigo:      #6366f1;
  --violet:      #a855f7;
  --brand:       #38bdf8;
  --brand-dark:  #0ea5e9;
  --wa:          #25d366;

  --accent-grad: linear-gradient(100deg, var(--cyan) 0%, var(--indigo) 55%, var(--violet) 100%);

  /* type */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, "Noto Sans", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --step--1: clamp(.82rem, .79rem + .12vw, .89rem);
  --step-0:  clamp(1rem, .96rem + .18vw, 1.08rem);
  --step-1:  clamp(1.16rem, 1.08rem + .36vw, 1.36rem);
  --step-2:  clamp(1.4rem, 1.26rem + .7vw, 1.9rem);
  --step-3:  clamp(1.75rem, 1.45rem + 1.4vw, 2.75rem);
  --step-4:  clamp(2.15rem, 1.5rem + 2.8vw, 4.1rem);

  /* space, radius, depth */
  --gap:      clamp(1rem, .8rem + .8vw, 1.55rem);
  --section:  clamp(3.75rem, 2.6rem + 4.4vw, 7rem);
  --radius:   16px;
  --radius-s: 11px;

  --glow:     0 0 0 1px rgba(56, 189, 248, .28), 0 8px 30px rgba(56, 189, 248, .22);
  --lift:     0 1px 0 rgba(255, 255, 255, .05) inset, 0 18px 44px rgba(0, 0, 0, .55);
  --ring:     0 0 0 3px rgba(56, 189, 248, .38);
}

/* ---------- reset ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; background: var(--bg); }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--step-0);
  line-height: 1.68;
  color: var(--ink-2);
  /* The canvas colour lives on <html>, not here. A background on <body> paints
     in the block-background layer, which is *above* every negative z-index
     child — it was burying both the aurora and the network. */
  background: transparent;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Two aurora fields, fixed, so scrolling moves the content across the light. */
body::before {
  content: "";
  position: fixed;
  inset: -20vh -10vw auto -10vw;
  height: 120vh;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(46rem 30rem at 8% 2%,  rgba(34, 211, 238, .16), transparent 62%),
    radial-gradient(42rem 28rem at 92% 12%, rgba(99, 102, 241, .18), transparent 64%),
    radial-gradient(38rem 26rem at 60% 88%, rgba(168, 85, 247, .10), transparent 66%);
}

img, svg, video { max-width: 100%; height: auto; display: block; }
img { border-radius: 12px; }

h1, h2, h3, h4 {
  margin: 0 0 .55em;
  color: var(--ink);
  line-height: 1.14;
  letter-spacing: -.024em;
  font-weight: 680;
  text-wrap: balance;
}
h1 { font-size: var(--step-4); letter-spacing: -.035em; font-weight: 720; }
h2 { font-size: var(--step-3); letter-spacing: -.03em; }
h3 { font-size: var(--step-1); }
h4 { font-size: var(--step-0); }

p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

a { color: var(--brand); text-decoration: none; transition: color .15s ease; }
a:hover { color: #7dd3fc; text-decoration: underline; text-underline-offset: 3px; }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-radius: 8px;
}

ul, ol { padding-left: 1.15rem; }
li { margin-bottom: .42em; }

hr { border: 0; border-top: 1px solid var(--edge); margin: var(--gap) 0; }

::selection { background: rgba(56, 189, 248, .32); color: #fff; }

/* ---------- layout ---------- */

.container { width: min(2100px, 100% - 4rem); margin-inline: auto; }

section, section.pad { padding-block: var(--section); position: relative; }

/* The alternate band is a lighter pane of glass, not a different colour. */
.section-alt {
  background: linear-gradient(180deg, rgba(255, 255, 255, .035), rgba(255, 255, 255, .015));
  border-block: 1px solid var(--edge);
}

.center { text-align: center; }
.center .lead { margin-inline: auto; }
.full { grid-column: 1 / -1; }

/* The enquiry forms carry a honeypot field named _honey: bots fill it, people
   never see it, and a filled one is dropped as spam. It must stay off-screen
   rather than merely transparent, or a real visitor can tab into it and have
   their enquiry silently binned. */
.hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

/* ---------- eyebrow, lead ---------- */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .32rem .8rem .32rem .62rem;
  margin-bottom: 1rem;
  font-family: var(--mono);
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #cffafe;
  background: var(--glass);
  border: 1px solid var(--edge);
  border-radius: 999px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.eyebrow::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 10px 2px rgba(34, 211, 238, .8);
}

.lead {
  font-size: var(--step-1);
  /* A section intro is reading text, not a caption - same weight of ink as
     body copy. It sat a step dimmer before. */
  color: var(--ink-2);
  max-width: 62ch;
  line-height: 1.62;
}

/* Now the shell is 1440 wide, a paragraph that owns the container would run
   past 150 characters a line. Anything that carries its own class keeps its own
   measure; these are the ones that had none. Declared here, above .cta-band p,
   so the centred bands still win. */
.hero > .container > p { max-width: 64ch; }
.container > p         { max-width: 78ch; }

/* ---------- grids ---------- */

.grid   { display: grid; gap: var(--gap); }
.grid-2 { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grid-3 { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(100%, 268px), 1fr)); }
.grid-4 { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(100%, 236px), 1fr)); }

/* Below this the grids auto-fit and find their own column count. Above it the
   count is fixed, so a wider screen makes each card bigger instead of squeezing
   an extra one into the row. Prose keeps its own measure regardless — .lead,
   .post and .hero h1 are all capped in ch. */
@media (min-width: 1100px) {
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-4 { grid-template-columns: repeat(4, 1fr); }
}

.split {
  display: grid;
  gap: clamp(1.6rem, 1rem + 3vw, 4rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  align-items: center;
}
.split img { box-shadow: var(--lift); border: 1px solid var(--edge); }

/* ---------- header ---------- */

.site-header {
  position: sticky;
  text-shadow: 0 1px 6px rgba(3, 6, 12, .85);
  top: 0;
  z-index: 60;
  background: rgba(5, 7, 12, .46);
  backdrop-filter: saturate(1.5) blur(5px);
  -webkit-backdrop-filter: saturate(1.5) blur(5px);
  transition: background .25s ease, backdrop-filter .25s ease;
}

/* Once real content is passing underneath, the bar has to become opaque glass
   or the page reads through it. Without JS it simply stays clear, which is the
   state it has at the top of the page anyway. */
.site-header.is-scrolled {
  background: rgba(5, 7, 12, .93);
  backdrop-filter: saturate(1.4) blur(16px);
  -webkit-backdrop-filter: saturate(1.4) blur(16px);
  border-bottom: 1px solid var(--edge);
}
.site-header > .container {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 74px;
}

.logo { display: flex; align-items: center; flex: 0 0 auto; }
.logo img { width: 168px; border-radius: 0; }

.nav { margin-left: auto; }
.nav > ul {
  display: flex; align-items: center; gap: .12rem;
  margin: 0; padding: 0; list-style: none;
}
.nav > ul > li { margin: 0; position: relative; }

.nav a, .nav .drop {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .55rem .82rem;
  border: 0; background: none; font: inherit;
  font-size: .94rem; font-weight: 550;
  color: var(--ink-2);
  border-radius: 9px;
  cursor: pointer; white-space: nowrap;
  transition: color .15s ease, background-color .15s ease;
}
.nav a:hover, .nav .drop:hover, .nav .drop[aria-expanded="true"] {
  color: #fff;
  background: var(--glass-2);
  text-decoration: none;
}

/* Services and Products are plain links to their hub pages. On a pointer
   device the sub-menu still drops on hover, so nothing became harder to reach;
   on touch, where hover does not exist, tapping goes to the hub page, which
   lists every child anyway. */
@media (hover: hover) and (min-width: 861px) {
  .nav li:hover > .dropdown,
  .nav li:focus-within > .dropdown { display: block; }
}

.dropdown {
  display: none;
  position: absolute;
  top: calc(100% + .5rem);
  left: 0;
  min-width: 274px;
  padding: .45rem;
  background: rgba(11, 17, 28, .96);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}
.dropdown.open { display: block; }
.dropdown ul { list-style: none; margin: 0; padding: 0; }
.dropdown li { margin: 0; }
.dropdown a { display: block; padding: .52rem .68rem; font-size: .92rem; font-weight: 480; border-radius: 8px; }

.header-cta { flex: 0 0 auto; }

.nav-toggle {
  display: none;
  margin-left: auto;
  padding: .45rem .72rem;
  font-size: 1.1rem; line-height: 1;
  color: var(--ink);
  background: var(--glass);
  border: 1px solid var(--edge);
  border-radius: 10px;
  cursor: pointer;
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .8rem 1.4rem;
  border: 1px solid transparent;
  border-radius: 11px;
  font-size: .96rem; font-weight: 620; line-height: 1.2;
  text-align: center; cursor: pointer;
  transition: transform .15s ease, box-shadow .2s ease, background .2s ease, border-color .2s ease;
}
.btn:hover { text-decoration: none; transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

/* The one gradient on the page that asks to be clicked. */
.btn-primary {
  position: relative;
  color: #04121c;
  background: var(--accent-grad);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .25) inset, 0 8px 26px rgba(56, 189, 248, .34);
}
.btn-primary:hover {
  color: #04121c;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .3) inset, 0 12px 34px rgba(99, 102, 241, .46);
}

.btn-outline,
.btn-outline-blue {
  background: var(--glass);
  border-color: var(--edge-2);
  color: var(--ink);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.btn-outline:hover,
.btn-outline-blue:hover {
  background: var(--glass-2);
  border-color: rgba(56, 189, 248, .55);
  color: #fff;
}

.btn-wa {
  background: rgba(37, 211, 102, .14);
  border-color: rgba(37, 211, 102, .45);
  color: #6ee7a5;
}
.btn-wa:hover {
  background: var(--wa);
  border-color: var(--wa);
  color: #04240f;
  box-shadow: 0 8px 24px rgba(37, 211, 102, .3);
}

.cta-row { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.7rem; }
.cta-row.center { justify-content: center; }

/* ---------- hero ---------- */

.hero {
  position: relative;
  isolation: isolate;
  /* The foot of the hero and the head of the next section both bring their own
     space; stacked at full width that reads as a hole, so the hero gives back
     most of its lower half. */
  padding-top: clamp(4rem, 2.4rem + 8vw, 8.5rem);
  padding-bottom: clamp(2rem, 1.4rem + 2.4vw, 3.4rem);
  overflow: hidden;
}
.hero + section,
.hero + .section-alt { padding-top: clamp(2.2rem, 1.6rem + 2.2vw, 3.6rem); }

/* ---------- the systems backdrop ----------
   Not an abstract neural net — the things Rideware actually installs and
   builds, wired together the way a site survey draws them: access points,
   switches and routers, servers and databases, controllers, scanners, locks
   and game systems, joined by right-angled traces like a rack diagram or a
   board layout. A pulse runs down a third of the traces so the network reads
   as live rather than printed.

   Fixed rather than scrolled, so content moves over a steady field. Dropped
   below 900px, where full-width cards cover it anyway, and in print. */

.site-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .55;
  /* No fade at the top any more — the schematic runs right up behind the
     header, which is translucent and blurred, so the equipment reads through
     the glass. Only the foot of the page fades out. */
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 80%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0%, #000 80%, transparent 100%);
}
/* On a phone the schematic stays, but lighter: half the traces stop pulsing so
   the paint cost drops, and it sits back a little further behind the content,
   which is full-width there and has less room to spare. */
@media (max-width: 900px) {
  .site-bg { opacity: .42; }
  .net-pulses .ln-pulse:nth-child(even) { display: none; }
  .net-packets .pkt:nth-child(odd) { display: none; }
  .scanline { display: none; }
}

.net { position: absolute; inset: 0; width: 100%; height: 100%; overflow: hidden; }

/* the cabling */
.ln-static { stroke: rgba(140, 190, 250, .26); stroke-width: 1.2; }

/* traffic on it */
.ln-pulse {
  stroke: url(#netFlow);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-dasharray: 26 320;
  animation: ln-flow var(--d, 4s) linear var(--t, 0s) infinite;
}
@keyframes ln-flow {
  from { stroke-dashoffset: 346; }
  to   { stroke-dashoffset: 0; }
}

/* the equipment */
.dev-box {
  fill: rgba(10, 16, 28, .82);
  stroke: rgba(150, 200, 255, .34);
  stroke-width: 1.2;
}
.dev-ico {
  stroke: #7dd3fc;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}
.dev {
  animation: dev-breathe 5.2s ease-in-out var(--t, 0s) infinite;
  transform-box: fill-box;
  transform-origin: center;
}
/* A packet physically travelling the cable, driven by the path itself so it
   turns every corner the wire turns. */
.pkt {
  fill: url(#pktCore);
  filter: drop-shadow(0 0 6px rgba(56, 189, 248, .95));
}

/* Each box gets a status light, blinking on its own offset. */
.dev-led {
  fill: rgba(74, 222, 128, .85);
  filter: drop-shadow(0 0 3px rgba(74, 222, 128, .6));
  animation: led-blink 2.6s steps(1, end) var(--t, 0s) infinite;
}
@keyframes led-blink {
  0%, 62%  { opacity: 1; }
  63%, 78% { opacity: .12; }
  79%      { opacity: 1; }
}

/* A survey sweep crossing the field every twelve seconds. */
.scanline {
  position: absolute;
  left: 0; right: 0;
  height: 26vh;
  top: -26vh;
  background: linear-gradient(180deg,
    transparent 0%,
    rgba(56, 189, 248, .02) 62%,
    rgba(125, 211, 252, .06) 92%,
    rgba(186, 230, 253, .13) 99%,
    transparent 100%);
  animation: sweep 16s cubic-bezier(.45, 0, .55, 1) infinite;
}
@keyframes sweep {
  0%        { transform: translateY(0); opacity: 0; }
  10%       { opacity: 1; }
  70%       { opacity: 1; }
  82%, 100% { transform: translateY(128vh); opacity: 0; }
}

@keyframes dev-breathe {
  0%, 100% { opacity: .62; }
  50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .ln-pulse, .dev, .dev-led, .scanline { animation: none; }
  .ln-pulse { stroke-dasharray: none; opacity: .3; }
  .scanline, .net-packets { display: none; }
}

/* Hairline grid, masked so it dissolves rather than stopping at an edge. */
.hero::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background-image:
    linear-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .045) 1px, transparent 1px);
  background-size: 72px 72px;
  mask-image: radial-gradient(120% 92% at 50% 34%, #000 42%, transparent 100%);
  -webkit-mask-image: radial-gradient(120% 92% at 50% 34%, #000 42%, transparent 100%);
}

.hero h1 { max-width: 19ch; }

/* The headline's last words carry the accent, so the gradient means something. */
.hero h1 em,
.hero h1 span {
  font-style: normal;
  background: var(--accent-grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero .lead { color: var(--ink-2); max-width: 58ch; }

.hero-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: var(--gap);
  margin-top: clamp(2.4rem, 1.6rem + 2.6vw, 4rem);
  padding-top: clamp(1.7rem, 1.1rem + 1.8vw, 2.6rem);
  border-top: 1px solid var(--edge);
}

.stat strong, .stat b, .stat .num {
  display: block;
  font-size: clamp(1.95rem, 1.4rem + 1.9vw, 3rem);
  font-weight: 700; line-height: 1; letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(180deg, #ffffff 30%, #9fd8f5 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.stat span, .stat small {
  display: block;
  margin-top: .5rem;
  font-size: var(--step--1);
  color: var(--faint);
  letter-spacing: .01em;
}

/* ---------- cards ---------- */

.card {
  position: relative;
  display: flex; flex-direction: column;
  padding: clamp(1.25rem, 1rem + .7vw, 1.75rem);
  background: var(--glass);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  overflow: hidden;
  transition: transform .18s ease, border-color .22s ease, background .22s ease;
}

/* A gradient hairline that only appears on approach. */
.card::before {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: var(--accent-grad);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  transition: opacity .25s ease;
  pointer-events: none;
}
.card:hover {
  transform: translateY(-4px);
  background: var(--glass-2);
  border-color: transparent;
}
.card:hover::before { opacity: .9; }

.card h3 { margin-bottom: .45rem; }
.card p { color: var(--ink-2); font-size: .96rem; }
.card .more, .card > a:last-child {
  margin-top: auto;
  padding-top: .95rem;
  font-weight: 620; font-size: .92rem;
  color: var(--brand);
}

.icon-dot {
  position: relative;
  display: grid; place-items: center;
  width: 46px; height: 46px;
  margin-bottom: 1rem;
  border-radius: 13px;
  color: #04121c;
  font-size: 1.05rem;
  font-family: var(--mono);
  font-weight: 700;
  background: var(--accent-grad);
  box-shadow: 0 6px 18px rgba(56, 189, 248, .3);
}

/* A soft bloom under the tile, so the icon reads as lit rather than printed. */
.icon-dot::after {
  content: "";
  position: absolute; inset: -35%;
  border-radius: inherit;
  background: radial-gradient(50% 50% at 50% 50%, rgba(56, 189, 248, .38), transparent 70%);
  filter: blur(12px);
  z-index: -1;
  opacity: 0;
  transition: opacity .28s ease;
}
.card:hover .icon-dot::after { opacity: 1; }

.ico { width: 23px; height: 23px; display: block; }

/* ---------- tick lists ---------- */

.checks { list-style: none; padding: 0; margin: 1.2rem 0 0; }

/* A check list that owns the full container runs two-up on wide screens —
   on its own it left half the row empty. Lists sitting inside a grid cell are
   already columned by the grid, so they are left alone. */
@media (min-width: 900px) {
  .container > .checks,
  .container > .lead + h2 + .checks {
    columns: 2;
    column-gap: 3rem;
  }
  .container > .checks li { break-inside: avoid; }
}
.checks li { position: relative; padding-left: 1.95rem; margin-bottom: .62rem; color: var(--ink-2); }
.checks li::before {
  content: "";
  position: absolute; left: 0; top: .38em;
  width: 1.2rem; height: 1.2rem; border-radius: 50%;
  background: rgba(56, 189, 248, .14);
  box-shadow: inset 0 0 0 1px rgba(56, 189, 248, .42);
}
.checks li::after {
  content: "";
  position: absolute; left: .4rem; top: .66em;
  width: .38rem; height: .2rem;
  border-left: 2px solid var(--cyan);
  border-bottom: 2px solid var(--cyan);
  transform: rotate(-45deg);
}

/* ---------- blog ---------- */

.post-card {
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--glass);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  transition: transform .18s ease, border-color .22s ease;
}
.post-card:hover { transform: translateY(-4px); border-color: var(--edge-2); }
/* The thumbnail is the top edge of the card, so the card gives up its own
   padding and the text block brings its own back. */
.post-card { padding: 0; }
.post-card > a:first-child { display: block; }
.post-card img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 0; }

.post-card > div, .post-card > .pad { padding: 1.15rem 1.3rem 1.4rem; }
.post-card h3 { font-size: var(--step-0); line-height: 1.36; }

.post-meta { font-family: var(--mono); font-size: .78rem; color: var(--faint); margin-bottom: .55rem; }

.post { max-width: 74ch; margin-inline: auto; position: relative; }

/* Long-form reading is the one place the network gets in the way — a wire
   passing behind a paragraph is fine for a heading, tiring for a thousand
   words. The article carries its own soft scrim so the backdrop stays visible
   around it but calms down under the text. */
.post::before {
  content: "";
  position: absolute;
  inset: -2rem clamp(-4rem, -3vw, -1.5rem);
  z-index: -1;
  pointer-events: none;
  border-radius: 28px;
  background: radial-gradient(66% 52% at 50% 42%, rgba(5, 7, 12, .88), rgba(5, 7, 12, .6) 72%, transparent 100%);
}
.post h2 { margin-top: 2.3rem; }
.post h3 { margin-top: 1.7rem; }
.post img { margin-block: 1.5rem; border: 1px solid var(--edge); }
.post blockquote {
  margin: 1.7rem 0;
  padding: .2rem 0 .2rem 1.25rem;
  border-left: 2px solid var(--cyan);
  color: var(--ink);
  font-size: var(--step-1);
}

.toc {
  padding: 1.15rem 1.35rem;
  background: var(--glass);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  margin-bottom: 2.1rem;
}
.toc ul { margin: .45rem 0 0; }

/* ---------- breadcrumbs ---------- */

.breadcrumbs {
  position: relative;
  background: rgba(5, 7, 12, .44);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  padding-block: .9rem;
  font-size: var(--step--1);
  color: var(--faint);
  border-bottom: 1px solid var(--edge);
}
.breadcrumbs a { color: var(--muted); }
.breadcrumbs a:hover { color: var(--brand); }
.breadcrumbs ol {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .2rem .5rem;
  list-style: none;
  margin: 0; padding: 0;
}
.breadcrumbs li { margin: 0; display: flex; align-items: center; gap: .5rem; }
.breadcrumbs li + li::before { content: "/"; color: var(--edge-2); }
.breadcrumbs [aria-current="page"] { color: var(--ink-2); }

/* ---------- FAQ ---------- */

.faq {
  background: var(--glass);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  margin-bottom: .7rem;
  overflow: hidden;
  transition: border-color .2s ease;
}
.faq:hover { border-color: var(--edge-2); }
.faq summary, .faq > h3 {
  margin: 0;
  padding: 1.1rem 1.3rem;
  font-weight: 620;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq[open] summary { color: var(--brand); }
.faq-a { padding: 0 1.3rem 1.2rem; color: var(--ink-2); }

/* ---------- forms ---------- */

.form-wrap {
  padding: clamp(1.35rem, 1rem + 1.1vw, 2.1rem);
  background: var(--glass);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: var(--lift);
}

.form-grid { display: grid; gap: .9rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }

.enquiry-form label, .form-wrap label {
  display: block;
  margin-bottom: .32rem;
  font-size: var(--step--1);
  font-weight: 620;
  color: var(--ink);
}

.enquiry-form input, .enquiry-form select, .enquiry-form textarea,
.form-wrap input, .form-wrap select, .form-wrap textarea {
  width: 100%;
  padding: .76rem .9rem;
  font: inherit; font-size: .95rem;
  color: var(--ink);
  background: rgba(255, 255, 255, .05);
  border: 1px solid var(--edge-2);
  border-radius: 11px;
  transition: border-color .16s ease, box-shadow .16s ease, background .16s ease;
}
.enquiry-form input:focus, .enquiry-form select:focus, .enquiry-form textarea:focus,
.form-wrap input:focus, .form-wrap textarea:focus {
  border-color: rgba(56, 189, 248, .7);
  background: rgba(255, 255, 255, .07);
  box-shadow: var(--ring);
  outline: none;
}
.enquiry-form textarea { min-height: 120px; resize: vertical; }
.enquiry-form button { width: 100%; margin-top: .35rem; }

.enquiry-form input::placeholder, .enquiry-form textarea::placeholder,
.form-wrap input::placeholder { color: var(--faint); }

/* Native select needs its own list colours, or the options come out white. */
.enquiry-form select option, .form-wrap select option { background: #0b111c; color: var(--ink); }

/* ---------- CTA band ---------- */

.cta-band {
  position: relative;
  isolation: isolate;
  padding-block: clamp(2.8rem, 2.2rem + 2.8vw, 5rem);
  text-align: center;
  border-block: 1px solid var(--edge);
  background:
    radial-gradient(38rem 20rem at 50% 0%, rgba(99, 102, 241, .28), transparent 68%),
    linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .015));
}
.cta-band p { color: var(--ink-2); max-width: 60ch; margin-inline: auto; }
.cta-band .cta-row { justify-content: center; }

/* ---------- sticky mobile bar ---------- */

.sticky-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
  display: none; gap: .55rem;
  padding: .6rem .8rem calc(.6rem + env(safe-area-inset-bottom));
  background: rgba(5, 7, 12, .9);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--edge);
}
.sticky-cta .btn { flex: 1; padding-block: .72rem; }

/* ---------- footer ---------- */

.site-footer {
  position: relative;
  padding-top: clamp(2.8rem, 2rem + 2.6vw, 4.4rem);
  color: var(--ink-2);
  background: linear-gradient(180deg, rgba(255, 255, 255, .02), transparent);
  border-top: 1px solid var(--edge);
}
/* A thin lit seam, instead of a solid brand bar. */
.site-footer::before {
  content: "";
  position: absolute; top: -1px; left: 0; right: 0; height: 1px;
  background: var(--accent-grad);
  opacity: .55;
}
.site-footer h4 {
  margin-bottom: .85rem;
  font-family: var(--mono);
  font-size: .76rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink);
}
.site-footer a { color: var(--muted); }
.site-footer a:hover { color: var(--ink); }
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: .45rem; font-size: .93rem; }

.footer-grid {
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  padding-bottom: clamp(1.9rem, 1.4rem + 1.4vw, 2.8rem);
}

.footer-bottom {
  padding-block: 1.2rem;
  border-top: 1px solid var(--edge);
  font-size: var(--step--1);
  color: var(--faint);
  display: flex; flex-wrap: wrap; gap: .6rem 1.2rem;
  justify-content: space-between; align-items: center;
}

.social { display: flex; gap: .5rem; }
.social a {
  display: grid; place-items: center;
  width: 38px; height: 38px;
  border-radius: 11px;
  background: var(--glass);
  border: 1px solid var(--edge);
  color: var(--ink-2);
}
.social a:hover { background: var(--glass-2); border-color: rgba(56, 189, 248, .5); color: #fff; }

/* ---------- responsive ---------- */

@media (max-width: 960px) {
  .nav-toggle { display: inline-block; order: 3; }
  .header-cta { display: none; }

  .nav {
    order: 4; flex-basis: 100%; margin-left: 0;
    display: none; padding-bottom: .9rem;
  }
  .nav.open { display: block; }
  .nav > ul { flex-direction: column; align-items: stretch; gap: .1rem; }
  .nav a, .nav .drop { width: 100%; justify-content: space-between; padding: .72rem .8rem; }

  .dropdown {
    position: static; box-shadow: none; background: none;
    border: 0; border-left: 1px solid var(--edge);
    border-radius: 0; margin: .2rem 0 .45rem .85rem; padding: 0 0 0 .4rem;
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }

  .site-header > .container { flex-wrap: wrap; min-height: 64px; }
}

@media (max-width: 720px) {
  .sticky-cta { display: flex; }
  /* the mobile drawer must be solid - the nav list sits over page content */
  .nav.is-open { background: rgba(5, 7, 12, .97); }
  body { padding-bottom: 4.7rem; }
  .hero { padding-block: clamp(3rem, 2rem + 6vw, 4.5rem); }
  .hero-stats { text-align: center; }
}

/* ---------- embedded map ----------
   Google's embed ships a white tile canvas that would sit on this page like a
   lightbox. Inverting and rotating the hue turns it into a dark map without an
   API key or a custom style URL; saturation is pulled back so the road colours
   do not fight the accent. Hovering restores the true colours, because a map
   you are about to read should be the real one. */

.map-frame {
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: var(--bg-3);
  overflow: hidden;
  box-shadow: var(--lift);
}
.map-frame iframe {
  display: block;
  filter: invert(.92) hue-rotate(180deg) saturate(.72) contrast(.92) brightness(.95);
  transition: filter .35s ease;
}
.map-frame:hover iframe { filter: none; }

/* ---------- portrait in a card ----------
   The leadership photos arrive at different aspect ratios, which left one head
   sitting lower than the other. A fixed square crop anchored to the top of the
   frame lines them up. */

.card > img:first-child {
  width: 180px;
  height: 180px;
  object-fit: cover;
  object-position: 50% 20%;
  border-radius: 14px;
  border: 1px solid var(--edge);
}

/* ---------- article lead image ----------
   The image straight after the headline is the article's opening frame, so it
   runs the full measure at a fixed crop. Images further down keep their own
   size and simply centre. */

.post > h1 + img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius);
}
.post img { display: block; max-width: 100%; height: auto; margin-inline: auto; border-radius: var(--radius-s); }

/* Where the browser cannot blur, the glass becomes a solid panel rather than
   a washed-out one. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .site-header, .breadcrumbs { background: rgba(5, 7, 12, .97); }
  .card, .form-wrap, .dropdown { background: #0b111c; }
}

/* ---------- scroll reveal ----------
   main.js already tags these with .reveal and adds .in when they scroll into
   view, staggering siblings via inline transition-delay. It sets .reveal only
   when JS runs and IntersectionObserver exists, so with JS off nothing is ever
   hidden — these rules simply never match. */

.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .62s cubic-bezier(.22, .8, .3, 1),
              transform .62s cubic-bezier(.22, .8, .3, 1);
  will-change: opacity, transform;
}
.reveal.in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

@media print {
  html, body { background: #fff; color: #000; }
  body::before, .site-bg, .site-header, .sticky-cta, .cta-band, .site-footer, .nav-toggle { display: none !important; }
  h1, h2, h3, h4, .stat strong { color: #000 !important; background: none; -webkit-text-fill-color: #000; }
  a { color: #000; text-decoration: underline; }
}
