/* ==========================================================================
   Shared styles for the SEO landing pages (/web-design-birmingham.html etc).

   These pages exist because the homepage cannot rank for four different things
   at once. Each one targets a real search, so each one needs real content — not
   a thin doorway page, which Google penalises and a human sees straight through.

   House system (AGENT.md §5): Plus Jakarta Sans + Space Grotesk, structured
   corners, generous whitespace, alternating section grounds, real scroll reveals.
   No emoji. No glassmorphism. No gradient blobs.
   ========================================================================== */

:root {
  --purple: #7C5CE0;
  --purple-dk: #5B3FC4;
  --teal: #2FB8AE;
  --grad: linear-gradient(135deg, #7C5CE0, #2FB8AE);
  --lav: #EFEAFC;
  --ink: #131B33;
  --ink-2: #4B5675;
  --ink-3: #7A85A0;
  --bg: #F6FBFA;
  --bg-2: #FFFFFF;
  --line: #E4E9F2;
  --sh: 0 30px 60px -30px rgba(30, 25, 90, .28);
  --sh-sm: 0 6px 18px -10px rgba(30, 25, 90, .22);
  --wrap: 1080px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg-2);
  color: var(--ink);
  font-family: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 22px; }

/* ---- ambient colour ----
   The homepage's warmth doesn't come from coloured section backgrounds — it comes
   from these: huge, heavily-blurred gradient orbs sitting behind everything. Without
   them a page reads as white boxes on white.

   Clipped inside a viewport-sized layer, NOT left loose: unclipped they hang off the
   right edge and drag the document wider than the phone screen, which is exactly what
   was making the homepage scroll sideways on mobile. */
.blobs { position: fixed; inset: 0; overflow: hidden; z-index: -1; pointer-events: none; }
.blob { position: absolute; border-radius: 50%; filter: blur(70px); opacity: .45; }
.blob.a { width: 520px; height: 520px; top: -170px; left: -130px; background: radial-gradient(circle, rgba(124, 92, 224, .45), transparent 68%); animation: drift1 18s ease-in-out infinite alternate; }
.blob.b { width: 480px; height: 480px; top: -80px; right: -150px; background: radial-gradient(circle, rgba(47, 184, 174, .45), transparent 68%); animation: drift2 22s ease-in-out infinite alternate; }
.blob.c { width: 560px; height: 560px; top: 55%; left: 40%; background: radial-gradient(circle, rgba(167, 139, 240, .3), transparent 70%); animation: drift1 26s ease-in-out infinite alternate; }
@keyframes drift1 { to { transform: translate(38px, 30px) scale(1.06); } }
@keyframes drift2 { to { transform: translate(-34px, 40px) scale(1.04); } }
@media (prefers-reduced-motion: reduce) { .blob { animation: none; } }

/* ---- header ----
   The gradient bar, same as the homepage. Without it these pages read as a
   different, cheaper website — which is the fastest way to lose someone who
   arrived from Google and is deciding in two seconds whether you're real. */
header {
  position: sticky; top: 0; z-index: 50;
  background: var(--grad);
  box-shadow: 0 10px 30px -16px rgba(90, 62, 198, .6);
}
.nav { max-width: var(--wrap); margin: 0 auto; padding: 14px 22px; display: flex; align-items: center; justify-content: space-between; gap: 20px; position: relative; }
.brand { display: flex; align-items: center; gap: 10px; font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: 18px; color: #fff; text-decoration: none; letter-spacing: -.01em; }
.brand img { width: 30px; height: 30px; border-radius: 8px; background: #fff; padding: 3px; }
.nav-right { display: flex; align-items: center; gap: 22px; }
.nav-links { display: flex; align-items: center; gap: 22px; }
.nav-links a.plain { color: rgba(255, 255, 255, .88); text-decoration: none; font-size: 14.5px; font-weight: 600; }
.nav-links a.plain:hover { color: #fff; }
.nav-right .btn { background: #fff; color: var(--purple-dk); white-space: nowrap; }
.nav-right .btn:hover { box-shadow: 0 12px 26px -12px rgba(0, 0, 0, .3); }
/* Hamburger — hidden on desktop, the mobile way into the page menu. */
.nav-toggle { display: none; width: 42px; height: 38px; padding: 0; border: 0; cursor: pointer; align-items: center; justify-content: center; background: rgba(255, 255, 255, .16); border-radius: 11px; -webkit-tap-highlight-color: transparent; }
.nav-toggle .bars { position: relative; display: block; width: 20px; height: 14px; }
.nav-toggle .bars span { position: absolute; left: 0; right: 0; height: 2.5px; border-radius: 2px; background: #fff; transition: transform .25s, opacity .18s; }
.nav-toggle .bars span:nth-child(1) { top: 0; }
.nav-toggle .bars span:nth-child(2) { top: 50%; transform: translateY(-50%); }
.nav-toggle .bars span:nth-child(3) { bottom: 0; }
.nav.open .nav-toggle .bars span:nth-child(1) { top: 50%; transform: translateY(-50%) rotate(45deg); }
.nav.open .nav-toggle .bars span:nth-child(2) { opacity: 0; }
.nav.open .nav-toggle .bars span:nth-child(3) { bottom: auto; top: 50%; transform: translateY(-50%) rotate(-45deg); }
@media (max-width: 860px) {
  .nav { padding: 12px 16px; }
  .brand { font-size: 16px; gap: 8px; }
  .brand img { width: 34px; height: 34px; }
  .nav-right { gap: 10px; }
  .nav-right .btn { padding: 9px 14px; font-size: 13px; }
  .nav-toggle { display: inline-flex; }
  .nav-links { position: absolute; top: 100%; left: 0; right: 0; flex-direction: column; align-items: stretch; gap: 0;
    background: var(--purple-dk); padding: 6px 16px 12px; border-top: 1px solid rgba(255, 255, 255, .14);
    box-shadow: 0 20px 34px -16px rgba(40, 20, 90, .6); display: none; }
  .nav.open .nav-links { display: flex; }
  .nav-links a.plain { display: block; color: #fff; font-size: 16px; padding: 14px 4px; border-top: 1px solid rgba(255, 255, 255, .13); }
  .nav-links a.plain:first-child { border-top: 0; }
}

.btn {
  display: inline-block;
  background: linear-gradient(135deg, var(--purple), var(--teal));
  color: #fff; text-decoration: none;
  padding: 12px 22px; border-radius: 10px;
  font-weight: 700; font-size: 15px;
  border: 0; cursor: pointer;
  transition: transform .16s ease, box-shadow .16s ease;
}
.btn:hover { transform: translateY(-1px); box-shadow: 0 12px 26px -12px rgba(124, 92, 224, .55); }
.btn.ghost { background: none; color: var(--purple-dk); border: 1.5px solid var(--line); }
.btn.ghost:hover { border-color: var(--purple); box-shadow: none; }
.btn.lg { padding: 15px 30px; font-size: 16px; }

/* ---- sections: alternating grounds, divided by a gradient hairline ----
   A 1px grey border between sections says "two divs". A gradient rule says the
   same brand runs all the way down the page. It's a small thing that stops a
   long page reading as a stack of unrelated blocks. */
section { padding: 78px 0; position: relative; }
section.tint { background: var(--bg); }
section.tint::before, section.tint::after {
  content: ""; position: absolute; left: 0; right: 0; height: 2px;
  background: var(--grad); opacity: .55;
}
section.tint::before { top: 0; }
section.tint::after { bottom: 0; }

.eyebrow {
  display: inline-block;
  font-family: "Space Grotesk", sans-serif;
  font-size: 12px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--purple-dk);
  background: rgba(124, 92, 224, .09);
  padding: 6px 11px; border-radius: 6px;
  margin-bottom: 16px;
}
h1 {
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(32px, 5vw, 50px);
  line-height: 1.1; letter-spacing: -.025em;
  margin: 0 0 18px; text-wrap: balance;
}
h2 {
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(25px, 3.4vw, 34px);
  line-height: 1.2; letter-spacing: -.02em;
  margin: 0 0 14px; text-wrap: balance;
}
h3 { font-family: "Space Grotesk", sans-serif; font-size: 19px; margin: 0 0 8px; letter-spacing: -.01em; }
.g { background: linear-gradient(135deg, var(--purple), var(--teal)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.lede { font-size: 18.5px; color: var(--ink-2); max-width: 62ch; margin: 0 0 28px; }
.sub { font-size: 16.5px; color: var(--ink-2); max-width: 60ch; margin: 0 0 34px; }
p { margin: 0 0 16px; }
p:last-child { margin-bottom: 0; }
a { color: var(--purple-dk); }

/* ---- hero ----
   Two columns. The right one is not decoration — it SHOWS the thing the page is
   selling: a search result on the web-design page, a conversation on the assistant
   page, a diary on the booking page. A hero that's all words is a hero that's
   asking to be believed instead of just demonstrating. */
.hero { padding: 62px 0 66px; background: linear-gradient(180deg, #FBFAFF 0%, #fff 100%); }
.hero .wrap { display: grid; grid-template-columns: 1.02fr .98fr; gap: 52px; align-items: center; }
.hero .cta-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 6px; }
.hero .note { font-size: 14px; color: var(--ink-3); margin-top: 16px; }
@media (max-width: 940px) {
  .hero .wrap { grid-template-columns: 1fr; gap: 44px; }
  .hero .mock { max-width: 460px; }
}

/* the floating mockup shell */
.mock { position: relative; animation: floaty 6s ease-in-out infinite; }
@keyframes floaty { 50% { transform: translateY(-11px); } }


/* ---- mockup: a Google result (web design page) ---- */
.serp { background: #fff; border-radius: 18px; box-shadow: var(--sh); border: 1px solid var(--line); overflow: hidden; }
.serp .sbar { display: flex; align-items: center; gap: 9px; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.serp .sbox {
  flex: 1; background: #F3F5F9; border: 1px solid var(--line); border-radius: 999px;
  padding: 9px 14px; font-size: 13px; color: var(--ink-2);
}
.serp .sres { padding: 18px 20px 22px; display: grid; gap: 16px; }
.serp .r { display: grid; gap: 5px; }
.serp .r .u { font-size: 11.5px; color: var(--ink-3); }
.serp .r .t { font-size: 15px; font-weight: 700; color: #1a3fa8; line-height: 1.3; }
.serp .r .d { font-size: 12.5px; color: var(--ink-2); line-height: 1.45; }
.serp .r.you {
  background: linear-gradient(135deg, rgba(124, 92, 224, .07), rgba(47, 184, 174, .07));
  border-left: 3px solid var(--purple); border-radius: 0 10px 10px 0;
  padding: 12px 14px; margin: -4px -4px -4px -6px;
}
.serp .r.you .t { color: var(--purple-dk); }
.serp .r.dim { opacity: .45; }
.serp .tag {
  /* justify-self, because the parent is a grid — inline-block alone still stretches. */
  justify-self: start;
  font-size: 10px; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--purple-dk); background: rgba(124, 92, 224, .13);
  padding: 3px 7px; border-radius: 5px; margin-bottom: 4px;
}

/* ---- mockup: a chat (assistant page) ---- */
.chatm { background: #fff; border-radius: 18px; box-shadow: var(--sh); border: 1px solid var(--line); overflow: hidden; max-width: 400px; margin: 0 auto; }
.chatm .ch { display: flex; align-items: center; gap: 10px; padding: 14px 16px; background: var(--grad); color: #fff; }
.chatm .ch .dot { width: 9px; height: 9px; border-radius: 50%; background: #7BE7A8; box-shadow: 0 0 0 3px rgba(123, 231, 168, .3); }
.chatm .ch b { font-size: 14.5px; display: block; }
.chatm .ch small { font-size: 11px; opacity: .9; }
.chatm .cb { padding: 16px; display: flex; flex-direction: column; gap: 10px; min-height: 310px; }
/* Messages start hidden and are popped in one by one by page.js — the conversation
   plays out in front of you rather than sitting there as a finished screenshot.
   That IS the product: watch it answer someone while you're asleep. */
.chatm .msg { font-size: 13px; padding: 10px 13px; border-radius: 13px; max-width: 86%; line-height: 1.45; opacity: 0; transform: translateY(8px); }
.chatm .msg.in { animation: pop .38s ease forwards; }
.chatm .msg.u { align-self: flex-end; background: var(--lav); color: var(--ink); border-bottom-right-radius: 4px; }
.chatm .msg.b { align-self: flex-start; background: #F1F4F9; color: var(--ink-2); border-bottom-left-radius: 4px; }
.chatm .time { text-align: center; font-size: 11px; color: var(--ink-3); }
@keyframes pop { to { opacity: 1; transform: none; } }

/* the three-dot "typing" bubble shown before each reply */
.chatm .typing { align-self: flex-start; background: #F1F4F9; padding: 12px 15px; border-radius: 13px; display: flex; gap: 4px; }
.chatm .typing i { width: 6px; height: 6px; border-radius: 50%; background: #B7C0D4; animation: blink 1.2s infinite; }
.chatm .typing i:nth-child(2) { animation-delay: .2s; }
.chatm .typing i:nth-child(3) { animation-delay: .4s; }
@keyframes blink { 0%, 60%, 100% { opacity: .3; } 30% { opacity: 1; } }


/* ---- mockup: a diary (booking page) ---- */
.calm { background: #fff; border-radius: 18px; box-shadow: var(--sh); border: 1px solid var(--line); overflow: hidden; max-width: 400px; margin: 0 auto; }
.calm .chd { padding: 15px 18px; background: var(--grad); color: #fff; display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.calm .chd b { font-size: 15px; display: block; }        /* block, or the date collides with the title */
.calm .chd small { font-size: 11.5px; opacity: .9; display: block; }
.calm .chd > small { text-align: right; flex: 0 0 auto; }
.calm .cbody { padding: 18px; }
.calm .lbl { font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 10px; }
.calm .slots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.calm .slot {
  border: 1px solid var(--line); border-radius: 9px; padding: 10px 6px;
  text-align: center; font-size: 13px; font-weight: 700; color: var(--ink-2);
}
.calm .slot.gone { color: var(--ink-3); background: #F5F7FA; text-decoration: line-through; opacity: .6; }
.calm .slot.on { background: var(--grad); color: #fff; border-color: transparent; }
.calm .invite {
  margin-top: 16px; border: 1px dashed var(--line); border-radius: 10px;
  padding: 12px 14px; display: flex; gap: 11px; align-items: center; background: #FBFCFE;
}
.calm .invite .ico { width: 34px; height: 34px; border-radius: 9px; background: var(--lav); display: grid; place-items: center; flex: 0 0 34px; }
.calm .invite b { font-size: 13px; display: block; color: var(--ink); }
.calm .invite small { font-size: 11.5px; color: var(--ink-3); }

/* ---- cards ---- */
.grid { display: grid; gap: 20px; }
/* Fixed column counts, not auto-fit. auto-fit was fitting THREE cards into the
   "c2" row and orphaning the fourth on a line of its own. */
.grid.c2 { grid-template-columns: repeat(2, 1fr); }
.grid.c3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .grid.c3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .grid.c2, .grid.c3 { grid-template-columns: 1fr; } }
/* Cards, matched to the homepage: generous padding, a gradient icon tile, and a
   real lift on hover. The old version (26px padding, no icon) is why these pages
   read as documents while the homepage reads as a product. */
.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 32px 30px;
  box-shadow: var(--sh-sm);
  transition: transform .22s ease, box-shadow .22s ease;
}
.card:hover { transform: translateY(-6px); box-shadow: var(--sh); }
.card p { color: var(--ink-2); font-size: 15.5px; margin: 0; }
.card h3 { font-size: 20px; margin: 0 0 10px; }

/* the icon tile — a soft gradient square, the homepage's signature card element */
.card .ic {
  width: 56px; height: 56px; border-radius: 16px;
  display: grid; place-items: center; margin-bottom: 20px;
  background: linear-gradient(135deg, rgba(124, 92, 224, .13), rgba(47, 184, 174, .16));
}
/* the little eyebrow above a card heading (YOUR CUSTOMER, 01, …) */
.card .n {
  font-family: "Space Grotesk", sans-serif;
  font-size: 12px; font-weight: 700;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
  margin-bottom: 8px; letter-spacing: .08em; text-transform: uppercase;
}

/* ---- checklist ---- */
ul.checks { list-style: none; padding: 0; margin: 0; display: grid; gap: 12px; }
ul.checks li { display: flex; gap: 11px; align-items: flex-start; font-size: 15.5px; color: var(--ink-2); }
ul.checks li b { color: var(--ink); font-weight: 700; }
ul.checks svg { flex: 0 0 20px; margin-top: 3px; }

/* ---- price strip ---- */
.prices { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.price {
  border: 1px solid var(--line); border-radius: 12px; padding: 24px 22px; background: #fff;
  transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}
.price:hover { transform: translateY(-3px); box-shadow: var(--sh-sm); border-color: var(--purple); }
.price .k { font-size: 13.5px; color: var(--ink-2); font-weight: 700; }
.price .v {
  font-family: "Space Grotesk", sans-serif; font-size: 30px; font-weight: 700;
  margin: 8px 0 3px; letter-spacing: -.025em;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.price .m { font-size: 13.5px; color: var(--ink-3); line-height: 1.45; }


/* ---- checklist rows get a hover too — they're the densest part of the page ---- */
ul.checks li { padding: 4px 0; transition: transform .18s ease; }
ul.checks li:hover { transform: translateX(3px); }


/* ---- faq ---- */
.faq { display: grid; gap: 10px; max-width: 800px; }
.qa {
  border: 1px solid var(--line); border-radius: 11px; background: #fff; overflow: hidden;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.qa:hover { border-color: #D3DAE8; }
.qa.open { border-color: var(--purple); box-shadow: var(--sh-sm); }
.qa button {
  width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  font: inherit; font-weight: 700; font-size: 16px; color: var(--ink);
  padding: 18px 20px; display: flex; justify-content: space-between; gap: 16px; align-items: center;
}
.qa button:focus-visible { outline: 2px solid var(--purple); outline-offset: -2px; }
.qa .ax { color: var(--purple); font-size: 21px; flex: 0 0 auto; transition: transform .24s ease; }
.qa.open .ax { transform: rotate(45deg); }
.qa .a { max-height: 0; overflow: hidden; transition: max-height .3s ease; }
.qa .a p { padding: 0 20px 19px; color: var(--ink-2); font-size: 15.5px; margin: 0; }


/* ---- live demo wrapper (the booking page mounts the REAL widget in here) ---- */
.live-demo {
  background: #fff; border: 1px solid var(--line); border-radius: 20px;
  padding: 26px; box-shadow: var(--sh); max-width: 720px;
}
@media (max-width: 620px) { .live-demo { padding: 16px; } }

/* ---- "ask it something" chips (the assistant page's own thing) ----
   Real questions a real customer asks. Clicking one OPENS THE LIVE ASSISTANT and
   asks it. You're not reading about the product — you're using it, and you can try
   to catch it out. That's a claim no paragraph can make. */
.asks { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
.ask {
  border: 1px solid var(--line); background: #fff; border-radius: 999px;
  padding: 11px 18px; font: inherit; font-size: 14.5px; font-weight: 600; color: var(--ink-2);
  cursor: pointer; box-shadow: var(--sh-sm);
  transition: transform .18s ease, border-color .18s ease, color .18s ease, box-shadow .18s ease;
}
.ask:hover { transform: translateY(-2px); border-color: var(--purple); color: var(--purple-dk); box-shadow: 0 10px 22px -12px rgba(124, 92, 224, .5); }
.ask:focus-visible { outline: 2px solid var(--purple); outline-offset: 2px; }
.ask::before { content: "\201C"; margin-right: 2px; color: var(--purple); font-weight: 800; }
.ask::after { content: "\201D"; margin-left: 2px; color: var(--purple); font-weight: 800; }


/* ---- real work: the web-design page's own thing ----
   Claims are cheap. Three sites you can click into and poke are not. This is the
   only section on any of these pages that shows finished work, and it's why the
   web-design page can't just be the same skeleton with different words. */
.work { display: grid; gap: 22px; grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .work { grid-template-columns: 1fr; } }
.job {
  border: 1px solid var(--line); border-radius: 18px; overflow: hidden; background: #fff;
  box-shadow: var(--sh-sm); text-decoration: none; color: inherit; display: block;
  transition: transform .24s ease, box-shadow .24s ease;
}
.job:hover { transform: translateY(-6px); box-shadow: var(--sh); }
.job .shot { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: #F3F5F9; border-bottom: 1px solid var(--line); }
.job .shot img {
  width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block;
  transition: transform 3.2s cubic-bezier(.2, .7, .2, 1);
}
.job:hover .shot img { transform: translateY(-14%); }   /* scrolls the site as you hover */
.job .meta { padding: 18px 20px 20px; }
.job .trade {
  font-family: "Space Grotesk", sans-serif; font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.job h3 { font-size: 17px; margin: 6px 0 5px; }
.job p { font-size: 13.5px; color: var(--ink-2); margin: 0; }
.job .go { margin-top: 12px; font-size: 13.5px; font-weight: 700; color: var(--purple-dk); }

/* ---- cta band ---- */
.band {
  background: var(--grad);
  color: #fff; border-radius: 18px; padding: 52px 40px; text-align: center;
  box-shadow: 0 30px 60px -30px rgba(90, 62, 198, .55);
  position: relative; overflow: hidden;
}
/* a soft light source in the corner, so a big flat gradient doesn't read as a
   coloured rectangle. Subtle enough that you notice it only if it's missing. */
.band::after {
  content: ""; position: absolute; top: -60%; right: -10%;
  width: 380px; height: 380px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, .18), transparent 65%);
  pointer-events: none;
}
.band h2 { color: #fff; position: relative; }
.band p { color: rgba(255, 255, 255, .92); max-width: 52ch; margin: 0 auto 26px; position: relative; font-size: 16.5px; }
.band .btn { background: #fff; color: var(--purple-dk); position: relative; }
.band .btn:hover { box-shadow: 0 14px 30px -12px rgba(0, 0, 0, .4); }

/* ---- footer ---- */
footer { border-top: 1px solid var(--line); padding: 34px 0; color: var(--ink-3); font-size: 14px; }
footer .row { display: flex; flex-wrap: wrap; gap: 18px; justify-content: space-between; align-items: center; }
footer a { color: var(--ink-2); text-decoration: none; margin-right: 16px; }
footer a:hover { color: var(--ink); }

/* ---- scroll reveal: things float in as you reach them ----
   Every rule below is gated on `.js`, which a one-liner in <head> adds. If JavaScript
   never runs — disabled, blocked by an extension, a CDN hiccup — the class is never
   set, these rules never match, and the page is simply VISIBLE.
   Without that gate, a page whose script fails renders as a blank white screen. */
.js .reveal   { opacity: 0; transform: translateY(28px);  transition: opacity .7s cubic-bezier(.2,.7,.2,1), transform .7s cubic-bezier(.2,.7,.2,1); }
.js .reveal-l { opacity: 0; transform: translateX(-48px); transition: opacity .8s cubic-bezier(.2,.7,.2,1), transform .8s cubic-bezier(.2,.7,.2,1); }
.js .reveal-r { opacity: 0; transform: translateX(48px);  transition: opacity .8s cubic-bezier(.2,.7,.2,1), transform .8s cubic-bezier(.2,.7,.2,1); }
.reveal.in, .reveal-l.in, .reveal-r.in { opacity: 1; transform: none; }

/* Stagger children so a row of cards deals itself out rather than snapping in as a block. */
.reveal.d1 { transition-delay: .08s; }
.reveal.d2 { transition-delay: .16s; }
.reveal.d3 { transition-delay: .24s; }

/* On a phone an element parked 48px to the RIGHT hangs off the screen and drags the
   whole document wider — that's what made the homepage scroll sideways. Columns are
   full-width here anyway, so the horizontal slide buys nothing: float them up instead. */
@media (max-width: 920px) {
  /* NOTE THE `.js` PREFIX. This override was written without it, so it lost to
     `.js .reveal-l` (0,2,0 beats 0,1,0) and never applied — the cards stayed
     parked 48px off-screen and the page scrolled sideways on every phone, which
     is exactly the bug this rule was added to prevent. */
  .js .reveal-l, .js .reveal-r { transform: translateY(28px); }
}

/* The scroll-reveal deliberately does NOT back off under prefers-reduced-motion.
   That matches the homepage, which slides everything in regardless — and the whole
   point of these pages is to feel like the same site. Only the ambient background
   drift is calmed, which is what the homepage does too.
   (Noted honestly: strictly, reduced-motion should suppress the slide. Ciaran's call,
   and consistency with the rest of the site won. If it's ever revisited, the accepted
   compromise is to fade in without translating.) */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
