/* ==========================================================================
   Eminent Concepts Technology Limited — design system, 2026 rebuild
   --------------------------------------------------------------------------
   Palette is derived from the ECT mark itself: the brush ring runs violet to
   coral, and the wordmark/leaf is sage. The legacy site used a flat #d73c00
   that appears nowhere in the logo, so the accents here are the brand's own.
   Sage is reserved as a SEMANTIC colour — it means "live / still running" and
   is never used decoratively.
   No framework: this file owns every visual decision on the site.
   ========================================================================== */

:root {
  /* ground + surfaces (violet-biased neutrals, chosen not inherited) */
  --ink:        #12101A;
  --ink-2:      #1A1724;
  --ink-3:      #221D2E;
  --line:       #2C2639;
  --line-soft:  #221D2E;

  /* accents, straight off the mark */
  --coral:      #E8734A;
  --coral-deep: #D2542A;
  --violet:     #8B5CB8;
  --violet-dim: #6E469A;
  --sage:       #93D6A8;   /* semantic: live / operating / still running */

  --text:       #F4F2F7;
  --muted:      #A9A3B8;
  --muted-dim:  #7C7590;

  --radius:     14px;
  --radius-lg:  22px;

  --font-display: 'Outfit', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body:    'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --shell: 1180px;
  --pad-y: clamp(64px, 8vw, 108px);
}

/* --------------------------------------------------------------- base ---- */

* { box-sizing: border-box; }

/* ⛔ THE TYPE SCALE IS ANCHORED HERE, NOT ON <body>.
   Every size below is in rem, and rem resolves against the ROOT element — so
   an override on body would have left all of them pinned to the browser
   default of 16px while only unstyled text moved. Stepping the root is what
   actually scales the whole page, and it keeps the ratios between headings,
   body, chips and mono labels fixed at every width.
   17.5 / 18 / 19px replaces a flat 16px root: roughly +10% on phones and
   +19% on large screens, which is what lifts the small mono labels out of
   the "why is this so tiny" range. */
html {
  font-size: 17.5px;
  scroll-behavior: smooth;
}
@media (min-width: 640px)  { html { font-size: 18px; } }
@media (min-width: 1280px) { html { font-size: 19px; } }

body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0 0 0.5em;
  color: var(--text);
}

/* Upper bounds are pulled in as the root grows, so the headings gain size
   with everything else instead of outrunning it. */
h1 { font-size: clamp(2.25rem, 4.6vw, 3.5rem); font-weight: 800; }
h2 { font-size: clamp(1.75rem, 2.9vw, 2.5rem); }
h3 { font-size: clamp(1.2rem, 1.6vw, 1.42rem); }

p { margin: 0 0 1.1em; color: var(--muted); }
p.lede { font-size: clamp(1.08rem, 1.4vw, 1.24rem); color: #CFC9DC; max-width: 62ch; }

a { color: var(--coral); text-decoration: none; transition: color .18s ease; }
a:hover { color: #F28E6B; }

img { max-width: 100%; height: auto; }

:focus-visible {
  outline: 2px solid var(--coral);
  outline-offset: 3px;
  border-radius: 4px;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: 22px;
}

section { padding-block: var(--pad-y); position: relative; }

/* alternating grounds give rhythm without borders everywhere */
.band-2 { background: var(--ink-2); }
.band-2::before, .band-2::after {
  content: ""; position: absolute; left: 0; right: 0; height: 1px;
  background: var(--line-soft);
}
.band-2::before { top: 0; } .band-2::after { bottom: 0; }

/* ------------------------------------------------------------ eyebrows --- */

.eyebrow {
  font-family: var(--font-mono);
  font-size: .82rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--coral);
  display: inline-flex;
  align-items: flex-start;
  gap: .6rem;
  margin-bottom: 1rem;
}
.eyebrow::before {
  content: ""; width: 26px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--violet), var(--coral));
  flex: none; margin-top: .72em;
}

.sec-head { max-width: 720px; margin-bottom: clamp(38px, 5vw, 62px); }
.sec-head p { margin-bottom: 0; }
.sec-head .lede { margin-top: 1.1rem; }

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

.ec-nav {
  position: fixed; inset: 0 0 auto 0; z-index: 1000;
  background: rgba(18, 16, 26, 0);
  border-bottom: 1px solid transparent;
  transition: background .3s ease, border-color .3s ease, padding .3s ease;
  padding-block: 18px;
}
.ec-nav.is-stuck {
  background: rgba(18, 16, 26, .92);
  backdrop-filter: saturate(150%) blur(14px);
  -webkit-backdrop-filter: saturate(150%) blur(14px);
  border-bottom-color: var(--line);
  padding-block: 10px;
}
.ec-nav .shell { display: flex; align-items: center; justify-content: space-between; gap: 20px; }

.ec-brand { display: flex; align-items: center; gap: 12px; }
.ec-brand img { width: 44px; height: 44px; transition: width .3s ease, height .3s ease; }
.is-stuck .ec-brand img { width: 38px; height: 38px; }
.ec-brand span {
  font-family: var(--font-display); font-weight: 700; font-size: 1.02rem;
  letter-spacing: -.01em; line-height: 1.15; color: var(--text);
}
.ec-brand span small {
  display: block; font-family: var(--font-mono); font-weight: 400;
  font-size: .64rem; letter-spacing: .13em; color: var(--muted-dim);
  text-transform: uppercase;
}

.ec-links { display: flex; align-items: center; gap: 26px; list-style: none; margin: 0; padding: 0; }

/* ⛔ SCOPED WITH :not(.btn-ec) ON PURPOSE — DO NOT DROP IT.
   `.ec-links a` is specificity (0,1,1); `.btn-ec` is (0,1,0). Written
   unscoped, the generic nav rule silently beat the button on every property
   they share: the CTA lost its white text to var(--muted) and became
   unreadable on the gradient, and inside the mobile menu it lost its
   horizontal padding to `padding: 13px 0` and the label ran to the edges.
   Excluding the button removes the collision instead of escalating
   specificity to out-shout it. */
.ec-links a:not(.btn-ec) {
  color: var(--muted); font-size: .97rem; font-weight: 500; position: relative;
  padding-block: 4px;
}
.ec-links a:not(.btn-ec)::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 0; height: 2px;
  background: linear-gradient(90deg, var(--violet), var(--coral));
  transition: right .25s ease;
}
.ec-links a:not(.btn-ec):hover { color: var(--text); }
.ec-links a:not(.btn-ec):hover::after { right: 0; }

/* the header CTA is the same button as the hero CTA — same white label */
.ec-links .btn-ec { padding: 11px 22px; font-size: .93rem; }

.ec-burger {
  display: none; background: none; border: 1px solid var(--line);
  border-radius: 10px; padding: 9px 11px; cursor: pointer;
}
.ec-burger span {
  display: block; width: 19px; height: 2px; border-radius: 2px;
  background: var(--text); margin: 4px 0; transition: transform .25s ease, opacity .2s ease;
}

/* Breakpoint sits at 1040px, not 900px: the larger type makes the six-item
   row plus the CTA wider than the shell below roughly 1000px. */
@media (max-width: 1040px) {
  .ec-burger { display: block; }
  .ec-links {
    position: absolute; inset: 100% 0 auto 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: rgba(18,16,26,.98);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line);
    padding: 8px 22px 22px;
    display: none;
  }
  .ec-links.is-open { display: flex; }
  /* display:block, or the anchor stays inline and its border-bottom spans only
     the width of the label — five separators of five different lengths. */
  .ec-links a:not(.btn-ec) { display: block; padding: 14px 0; border-bottom: 1px solid var(--line-soft); font-size: 1.02rem; }
  .ec-links a:not(.btn-ec)::after { display: none; }
  .ec-links li:nth-last-child(2) a { border-bottom: none; }
  /* the CTA becomes a full-width pill, and keeps its own padding */
  .ec-links li:last-child { margin-top: 16px; }
  .ec-links .btn-ec { display: flex; justify-content: center; width: 100%; padding: 15px 26px; font-size: 1rem; }
}

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

.hero {
  position: relative;
  min-height: min(92vh, 880px);
  display: flex; align-items: center;
  padding-block: clamp(130px, 17vw, 190px) var(--pad-y);
  overflow: hidden;
}

/* the mark's brush ring, abstracted into an ambient field */
.hero-ring {
  position: absolute; pointer-events: none;
  width: min(155vw, 1250px); aspect-ratio: 1;
  right: -26%; top: 50%; translate: 0 -50%;
  background:
    conic-gradient(from 200deg,
      rgba(139,92,184,.30) 0deg,
      rgba(232,115,74,.34) 110deg,
      rgba(147,214,168,.14) 205deg,
      rgba(139,92,184,.30) 360deg);
  border-radius: 50%;
  filter: blur(84px);
  opacity: .82;
  animation: ring-turn 46s linear infinite;
}
@keyframes ring-turn { to { rotate: 360deg; } }

.hero::after {   /* keeps text legible over the field */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(72% 66% at 6% 48%, var(--ink) 30%, rgba(18,16,26,.52) 66%, transparent 100%);
}
.hero .shell { position: relative; z-index: 2; }

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(34px, 4.5vw, 62px);
  align-items: center;
}
.hero-copy { max-width: 660px; }
.hero-copy .eyebrow { font-size: .76rem; letter-spacing: .12em; }

.hero h1 span.grad {
  background: linear-gradient(100deg, var(--violet) 8%, var(--coral) 62%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}

.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }

/* ---------------------------------------- hero illustration: the stack --- */
/*
   The thesis of the page rendered as a graphic. The headline claims the work
   "ships, scales and stays running", and the differentiator on this whole
   site is that the company OPERATES what it builds — so the hero shows a
   running production stack rather than a decorative shape: four real layers,
   a signal travelling down the spine, and a build → ship → run track beneath.

   ⛔ Deliberately carries NO metrics. Invented uptime percentages or client
      counts would be exactly the vanity numbers this rebuild removed, and a
      fabricated figure on the hero is a claim, not a decoration.

   Built entirely from CSS — no new image asset, nothing to download.
*/
.hero-art { position: relative; display: grid; place-items: center; }

/* brand halo — the logo's own conic sweep, sitting behind the card */
.hero-art::before {
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  width: 118%; aspect-ratio: 1; border-radius: 50%;
  background: conic-gradient(from 140deg,
    rgba(139,92,184,.40), rgba(232,115,74,.42) 120deg,
    rgba(147,214,168,.16) 220deg, rgba(139,92,184,.40) 360deg);
  filter: blur(58px); opacity: .55;
  animation: ring-turn 34s linear infinite reverse;
}

.stack-card {
  position: relative; z-index: 1; width: 100%; max-width: 430px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background:
    linear-gradient(180deg, rgba(139,92,184,.12), transparent 46%),
    rgba(26,23,36,.78);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  padding: 18px 20px 20px;
  box-shadow: 0 44px 96px -44px rgba(0,0,0,.96), inset 0 1px 0 rgba(255,255,255,.07);
  animation: card-float 9s ease-in-out infinite;
}
@keyframes card-float { 50% { translate: 0 -9px; } }

.sc-top {
  display: flex; align-items: center; gap: .55rem;
  padding-bottom: 14px; border-bottom: 1px solid var(--line-soft);
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .13em;
  text-transform: uppercase;
}
.sc-top .sc-dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--sage); flex: none;
  box-shadow: 0 0 0 0 rgba(147,214,168,.6);
  animation: live-pulse 2.4s ease-out infinite;
}
.sc-top .sc-env { color: var(--sage); }
.sc-top .sc-id  { margin-left: auto; color: var(--muted-dim); letter-spacing: .1em; }

.sc-layers { list-style: none; margin: 0; padding: 4px 0 0; position: relative; }

/* the spine the signal travels down */
.sc-layers::before {
  content: ""; position: absolute; left: 6px; top: 18px; bottom: 18px; width: 2px;
  border-radius: 2px; opacity: .55;
  background: linear-gradient(180deg, var(--violet), var(--coral));
}
.sc-layers::after {
  content: ""; position: absolute; left: 2px; width: 10px; height: 10px;
  border-radius: 50%; background: var(--coral);
  box-shadow: 0 0 16px 4px rgba(232,115,74,.5);
  animation: sc-travel 4.8s cubic-bezier(.7,0,.3,1) infinite;
}
@keyframes sc-travel {
  0%        { top: 12px; opacity: 0; }
  10%, 82%  { opacity: 1; }
  100%      { top: calc(100% - 22px); opacity: 0; }
}

.sc-layer { display: grid; grid-template-columns: 14px 1fr; gap: 0 14px; padding: 13px 0; }
.sc-layer + .sc-layer { border-top: 1px solid var(--line-soft); }
.sc-layer .sc-node {
  width: 10px; height: 10px; margin: 6px 0 0 1px; border-radius: 3px;
  background: var(--ink-2); border: 2px solid var(--violet); position: relative; z-index: 1;
}
.sc-layer b {
  display: block; font-family: var(--font-display); font-weight: 600;
  font-size: .98rem; color: var(--text); line-height: 1.3;
}
.sc-layer em {
  display: block; font-family: var(--font-mono); font-style: normal;
  font-size: .74rem; color: var(--muted-dim); letter-spacing: .03em; margin-top: 4px;
}

.sc-pipe {
  margin-top: 6px; padding-top: 15px; border-top: 1px solid var(--line-soft);
  display: flex; justify-content: space-between;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted-dim);
}
.sc-track { height: 3px; margin-top: 9px; border-radius: 3px; background: var(--line); overflow: hidden; }
.sc-track i {
  display: block; height: 100%; width: 40%; border-radius: 3px;
  background: linear-gradient(90deg, var(--violet), var(--coral));
  animation: sc-run 4.2s ease-in-out infinite;
}
/* the bar is 40% of the track, so ±100%/250% of ITS OWN width is exactly one
   full pass edge to edge */
@keyframes sc-run {
  0%        { transform: translateX(-100%); }
  70%, 100% { transform: translateX(250%); }
}

@media (max-width: 1040px) {
  .hero-grid { grid-template-columns: 1fr; gap: 46px; }
  .hero-copy { max-width: 680px; }
  .hero-art { margin-inline: auto; width: 100%; max-width: 430px; }
  .hero { min-height: 0; }
}

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

.btn-ec, .btn-ghost {
  display: inline-flex; align-items: center; gap: .6rem;
  font-family: var(--font-display); font-weight: 600; font-size: 1rem;
  padding: 15px 28px; border-radius: 999px; border: 1px solid transparent;
  cursor: pointer; transition: transform .16s ease, box-shadow .16s ease,
                              background .2s ease, border-color .2s ease, color .2s ease;
  text-decoration: none; line-height: 1;
}
.btn-ec {
  background: linear-gradient(100deg, var(--violet-dim), var(--coral));
  color: #fff;
  box-shadow: 0 8px 24px -10px rgba(232,115,74,.75);
}
.btn-ec:hover { transform: translateY(-2px); color: #fff; box-shadow: 0 14px 30px -10px rgba(232,115,74,.85); }
.btn-ec[disabled] { opacity: .62; cursor: not-allowed; transform: none; }
.btn-ghost { background: transparent; border-color: var(--line); color: var(--text); }
.btn-ghost:hover { transform: translateY(-2px); border-color: var(--violet); color: var(--text); background: rgba(139,92,184,.10); }
.btn-ec:active, .btn-ghost:active { transform: translateY(0); }

/* ------------------------------------------------- capability / facts ---- */

.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 1px; background: var(--line-soft); border: 1px solid var(--line-soft); border-radius: var(--radius); overflow: hidden; }
.fact { background: var(--ink); padding: 26px 24px; }
.fact dt { font-family: var(--font-mono); font-size: .74rem; letter-spacing: .15em; text-transform: uppercase; color: var(--muted-dim); margin-bottom: .55rem; }
.fact dd { margin: 0; font-family: var(--font-display); font-size: 1.12rem; font-weight: 600; color: var(--text); line-height: 1.35; }
.fact dd small { display: block; font-family: var(--font-body); font-size: .9rem; font-weight: 400; color: var(--muted); margin-top: .35rem; letter-spacing: 0; }

/* ---------------------------------------------------- technology stack --- */

.stack { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 26px; }
.stack-group h4 {
  font-family: var(--font-mono); font-size: .78rem; font-weight: 500;
  letter-spacing: .15em; text-transform: uppercase; color: var(--coral);
  margin: 0 0 .9rem; padding-bottom: .6rem; border-bottom: 1px solid var(--line);
}
.chips { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0; padding: 0; }
.chips li {
  font-family: var(--font-mono); font-size: .84rem; color: #C6C0D4;
  background: var(--ink-2); border: 1px solid var(--line-soft);
  padding: 6px 11px; border-radius: 7px; transition: border-color .18s ease, color .18s ease;
}
.chips li:hover { border-color: var(--violet); color: var(--text); }
.band-2 .chips li { background: var(--ink); }

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

.grid-4 { display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); gap: 20px; }
.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; }

.card-ec {
  background: var(--ink-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 30px 27px;
  position: relative;
  transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.band-2 .card-ec { background: var(--ink); }
.card-ec:hover {
  transform: translateY(-4px);
  border-color: var(--line);
  box-shadow: 0 20px 44px -26px rgba(0,0,0,.9);
}
.card-ec h3 { margin-bottom: .6rem; }
.card-ec p { margin-bottom: 0; font-size: 1rem; }

.card-ec .ic {
  width: 46px; height: 46px; border-radius: 12px; margin-bottom: 18px;
  display: grid; place-items: center;
  background: linear-gradient(135deg, rgba(139,92,184,.22), rgba(232,115,74,.22));
  border: 1px solid var(--line);
}
.card-ec .ic svg { width: 22px; height: 22px; stroke: var(--coral); fill: none; stroke-width: 1.7; }

/* engagement stages — numbered because the order is real, not decorative */
/* The three stages carry different numbers of bullets, so the CTA is pushed
   to the bottom of the card rather than sitting wherever the list happens to
   end. Three buttons on one baseline read as one row of choices; three at
   different heights read as three unrelated blocks. */
.card-ec.stage { display: flex; flex-direction: column; }
.card-ec.stage .cta-row { margin-top: auto; padding-top: 26px; margin-bottom: 0; }
.stage .no {
  font-family: var(--font-mono); font-size: .78rem; letter-spacing: .14em;
  color: var(--muted-dim); display: block; margin-bottom: 12px;
}
.stage ul { list-style: none; margin: 16px 0 0; padding: 0; }
.stage ul li {
  font-size: .98rem; color: var(--muted); padding-left: 20px; position: relative;
  margin-bottom: .45rem;
}
.stage ul li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: 7px; height: 7px; border-radius: 50%;
  background: linear-gradient(135deg, var(--violet), var(--coral));
}

/* --------------------------------------------------------- case studies -- */

.work { display: grid; gap: 22px; }

.case {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 150% at 88% 8%, rgba(139,92,184,.13), transparent 58%),
    var(--ink-2);
  overflow: hidden;
  position: relative;
}
.band-2 .case { background: radial-gradient(120% 150% at 88% 8%, rgba(139,92,184,.13), transparent 58%), var(--ink); }

.case-flag {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--font-mono); font-size: .74rem; font-weight: 500;
  letter-spacing: .15em; text-transform: uppercase;
  color: var(--sage);
  border: 1px solid rgba(147,214,168,.32);
  background: rgba(147,214,168,.07);
  padding: 6px 13px; border-radius: 999px;
  margin-bottom: 18px;
}
.case-flag i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--sage); flex: none;
  box-shadow: 0 0 0 0 rgba(147,214,168,.6);
  animation: live-pulse 2.4s ease-out infinite;
}
@keyframes live-pulse {
  70%  { box-shadow: 0 0 0 7px rgba(147,214,168,0); }
  100% { box-shadow: 0 0 0 0 rgba(147,214,168,0); }
}

.case-inner { display: grid; grid-template-columns: 1.15fr .85fr; gap: 46px; padding: clamp(30px, 4vw, 52px); align-items: center; }
.case-inner.solo { grid-template-columns: 1fr; }
@media (max-width: 940px) { .case-inner { grid-template-columns: 1fr; gap: 34px; } }

.case h3 {
  font-size: clamp(1.8rem, 3vw, 2.4rem); font-weight: 800; margin-bottom: .3rem;
}
.case .tag {
  font-family: var(--font-display); font-size: 1.1rem; font-weight: 500;
  color: var(--coral); margin-bottom: 1.1rem;
}
.case .meta {
  margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line);
  font-size: .94rem; color: var(--muted-dim);
  display: flex; flex-wrap: wrap; gap: 8px 20px; align-items: center;
}
.badge-18 {
  font-family: var(--font-mono); font-size: .76rem; font-weight: 500;
  border: 1px solid var(--line); border-radius: 6px; padding: 4px 9px; color: var(--muted);
}

.avail {
  background: var(--ink-3); border: 1px solid var(--line-soft);
  border-radius: var(--radius); padding: 18px 20px; margin: 22px 0 0;
  font-size: 1rem; color: #CFC9DC; line-height: 1.6;
}
.avail strong { color: var(--text); font-weight: 600; }

/* phone mockup — no new asset, real game tiles in a CSS frame */
/* ── Case-study screens ─────────────────────────────────────────────────────
   Three real Android screens, the middle one forward. A fan rather than a row
   because a row of three equal phones has no focal point — the eye has nowhere
   to land and reads it as a spec sheet. Raising and enlarging the centre makes
   it the subject and the other two context, which is also the honest hierarchy:
   the home screen is what a visitor recognises, the other two are evidence.

   ⛔ NO DEVICE BEZEL IS DRAWN, DELIBERATELY. A fake hardware frame around a
      real screenshot is the tell that gives away a mockup, and it dates the
      image to whatever handset was fashionable when it was drawn. A radius, a
      hairline and a shadow read as "a screen" without claiming to be a
      specific phone. */
.case-shots {
  display: flex;
  align-items: center;
  justify-content: center;
  /* ⛔ NOT A NEGATIVE GAP. `gap` rejects negative values and the whole
     declaration is dropped without warning, which leaves three phones sitting
     flat in a row. The overlap comes from the flanking figures pulling
     themselves inward with a negative margin instead. */
  gap: 0;
  padding-block: 10px;
}
.shot { margin: 0; flex: 0 0 auto; }
.shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--bg-2, #0F0B18);
}
.shot-front {
  width: 216px;
  z-index: 2;
  border-radius: 18px;
  box-shadow: 0 26px 60px -18px rgba(0, 0, 0, .75);
}
.shot-front img { border-radius: 18px; border-color: var(--violet); }
/* ⚠️ The back pair are SMALLER AND DIMMED, not just lower in z-order. Same-size
   siblings peeking out from behind the centre look like a rendering mistake;
   scaled back and desaturated they read as depth. */
.shot-back { width: 190px; opacity: .62; filter: saturate(.85); }
.shot-back:first-child  { margin-right: -22px; transform: translateY(14px) rotate(-4deg); }
.shot-back:last-child   { margin-left:  -22px; transform: translateY(14px) rotate(4deg); }

@media (max-width: 760px) {
  /* ⛔ THE FAN COLLAPSES TO ONE SCREEN ON A PHONE. Three phone screenshots
     shown ON a phone are ~110px wide each — too small to read a single word
     of, so they stop being evidence and become texture. Showing one at a
     usable size says more than three that cannot be read. */
  .case-shots { gap: 0; }
  /* display:none also drops the negative margins above — nothing to unset. */
  .shot-back { display: none; }
  .shot-front { width: min(248px, 62vw); }
}

@media (prefers-reduced-motion: no-preference) {
  .shot { transition: transform .35s ease, opacity .35s ease; }
  .case-shots:hover .shot-back { opacity: .8; }
  .case-shots:hover .shot-back:first-child { transform: translateY(10px) rotate(-7deg); }
  .case-shots:hover .shot-back:last-child  { transform: translateY(10px) rotate(7deg); }
}

/* --------------------------------------------------------- training ----- */

.track ul { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 7px; }
.track ul li {
  font-family: var(--font-mono); font-size: .8rem; color: var(--muted);
  border: 1px solid var(--line-soft); border-radius: 6px; padding: 5px 10px;
}

/* --------------------------------------------------------- contact ------ */

.contact-grid { display: grid; grid-template-columns: 1.1fr .9fr; gap: 46px; }
@media (max-width: 940px) { .contact-grid { grid-template-columns: 1fr; gap: 34px; } }

.field { margin-bottom: 16px; }
.field label {
  display: block; font-family: var(--font-mono); font-size: .74rem;
  letter-spacing: .13em; text-transform: uppercase; color: var(--muted-dim);
  margin-bottom: 7px;
}
.field input, .field textarea {
  width: 100%; background: var(--ink); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 14px 15px; font-family: var(--font-body); font-size: 1rem;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.band-2 .field input, .band-2 .field textarea { background: var(--ink-2); }
.field input::placeholder, .field textarea::placeholder { color: var(--muted-dim); }
.field input:focus, .field textarea:focus {
  outline: none; border-color: var(--violet);
  box-shadow: 0 0 0 3px rgba(139,92,184,.18);
}
.field textarea { resize: vertical; min-height: 128px; }
.field .err { display: block; margin-top: 6px; font-size: .88rem; color: #F08A6B; min-height: 1em; }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: #C95030; }

/* the submit button and its note are one group — the note is a caption for
   the button, so it is spaced off it rather than crowding it */
.form-submit { margin-top: 30px; }
.form-note { font-size: .9rem; color: var(--muted-dim); margin: 16px 0 0; }

#form-status { border-radius: 10px; padding: 14px 17px; margin-bottom: 18px; font-size: .97rem; display: none; }
#form-status.ok   { display: block; background: rgba(147,214,168,.09); border: 1px solid rgba(147,214,168,.35); color: var(--sage); }
#form-status.bad  { display: block; background: rgba(232,115,74,.09);  border: 1px solid rgba(232,115,74,.35);  color: #F08A6B; }

.contact-list { list-style: none; margin: 0; padding: 0; }
.contact-list li { padding: 17px 0; border-bottom: 1px solid var(--line-soft); }
.contact-list li:last-child { border-bottom: none; }
.contact-list dt {
  font-family: var(--font-mono); font-size: .74rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--muted-dim); margin-bottom: 5px;
}
.contact-list dd { margin: 0; font-size: 1.04rem; color: var(--text); }

/* ⛔ A LINK MUST NOT BE INDISTINGUISHABLE FROM THE TEXT AROUND IT.
   `.contact-list dd a` was `color: var(--text)` — the exact value the `dd`
   itself already carries — so the two email addresses and the phone number
   rendered identically to the postal address sitting directly above them,
   which is not a link and never will be. Nothing on screen said which three
   of those four blocks would do something when tapped, and hover is not an
   answer: it does not exist on a phone, which is where this section is read.

   ⛔ THE UNDERLINE IS THE POINT, NOT THE COLOUR. WCAG 1.4.1 is explicit that
      colour alone may not be the sole carrier of meaning, and "this word is
      clickable" is meaning. The underline is drawn dim and offset so it reads
      as a considered detail rather than a default-browser link, then firms up
      on hover and focus — but it is present at rest, which is what makes it
      work for a colour-blind visitor and on a touch screen. */
.contact-list dd a {
  color: var(--text);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  text-decoration-color: rgba(232, 115, 74, .55);
  transition: color .18s ease, text-decoration-color .18s ease;
}
.contact-list dd a:hover,
.contact-list dd a:focus-visible {
  color: var(--coral);
  text-decoration-color: var(--coral);
}

.socials { display: flex; gap: 9px; margin-top: 22px; }
.socials a {
  width: 42px; height: 42px; border-radius: 11px; display: grid; place-items: center;
  border: 1px solid var(--line); color: var(--muted);
  transition: border-color .18s ease, color .18s ease, transform .18s ease, background .18s ease;
}
.socials a:hover { border-color: var(--violet); color: var(--text); transform: translateY(-2px); background: rgba(139,92,184,.10); }
.socials svg { width: 18px; height: 18px; fill: currentColor; }

/* ---------------------------------------------------------- footer ------ */

.ec-foot { background: var(--ink-2); border-top: 1px solid var(--line); padding-block: clamp(48px, 6vw, 72px) 0; }
.foot-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 38px; }
@media (max-width: 900px) { .foot-grid { grid-template-columns: 1fr 1fr; gap: 30px; } }
@media (max-width: 560px) { .foot-grid { grid-template-columns: 1fr; } }

.ec-foot h5 {
  font-family: var(--font-mono); font-size: .75rem; letter-spacing: .15em;
  text-transform: uppercase; color: var(--muted-dim); margin-bottom: 1rem; font-weight: 500;
}
.ec-foot ul { list-style: none; margin: 0; padding: 0; }
.ec-foot ul li { margin-bottom: .6rem; }
/* Footer navigation. Every item in these lists IS a link, so the underline can
   arrive on hover rather than sitting under all sixteen of them at rest — the
   distinction that matters here is link vs. the NON-link copy in the same
   footer (the brand blurb, the RC line, the copyright row), and that is carried
   by weight and colour: links sit at --muted, prose at --muted-dim below. */
.ec-foot ul a {
  color: var(--muted);
  font-size: .98rem;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  /* Transparent at rest, so the underline is reserved space that fades in
     instead of a layout shift on hover. */
  text-decoration-color: transparent;
  transition: color .18s ease, text-decoration-color .18s ease;
}
.ec-foot ul a:hover,
.ec-foot ul a:focus-visible {
  color: var(--text);
  text-decoration-color: var(--coral);
}

/* ⛔ THE NON-LINK FOOTER TEXT IS DELIBERATELY DIMMER THAN THE LINKS.
   This is the other half of the same fix: making links stand out only works if
   the things that are not links step back. --muted-dim vs --muted is a small
   step, but combined with the hover underline it means a visitor can tell the
   two apart without touching anything. */
.ec-foot .foot-brand p { color: var(--muted-dim); }

/* Outbound links say so. `game4pay.com` and `fast-trac.co.uk` leave the site;
   the arrow is generated content so it needs no markup change and is hidden
   from screen readers, which announce the destination anyway. */
/* ⛔ FOOTER ONLY. The header nav's `a::after` is already spoken for — it draws
   the hover underline marker — so this must never be widened to `.ec-links`.
   Two rules writing `content` on the same pseudo-element is the collision that
   made the CTA unreadable once already. */
.ec-foot ul a[target="_blank"]::after {
  content: "↗";
  display: inline-block;
  margin-left: .32em;
  font-size: .82em;
  opacity: .6;
}
.foot-brand p { font-size: .98rem; max-width: 34ch; }
.foot-rc { font-family: var(--font-mono); font-size: .84rem; color: var(--muted-dim); }
.foot-bottom {
  margin-top: 46px; padding-block: 22px; border-top: 1px solid var(--line-soft);
  display: flex; flex-wrap: wrap; gap: 10px 22px; justify-content: space-between;
  font-size: .9rem; color: var(--muted-dim);
}

.to-top {
  position: fixed; right: 22px; bottom: 22px; z-index: 900;
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--ink-2); border: 1px solid var(--line); color: var(--text);
  opacity: 0; pointer-events: none; transition: opacity .25s ease, transform .18s ease;
}
.to-top.show { opacity: 1; pointer-events: auto; }
.to-top:hover { transform: translateY(-3px); border-color: var(--violet); color: var(--text); }

/* ------------------------------------------------ mobile text alignment -- */
/*
   Section HEADERS are centred on narrow screens; running text is not.
   A centred heading of one to three lines reads as composed on a narrow
   column, but centring paragraphs gives every line a different starting
   x-position, so the eye has to hunt for the start of each one — the cost
   grows with the length of the paragraph. Headings, eyebrows and the lede
   centre; body copy, card text, bullet lists, chips and the form stay left
   aligned, where the reader's eye can return to a fixed margin.
*/
@media (max-width: 760px) {
  .sec-head { text-align: center; margin-inline: auto; }
  .sec-head .eyebrow { justify-content: center; }
  .sec-head .lede { margin-inline: auto; }

  .hero-copy { text-align: center; margin-inline: auto; }
  .hero-copy .eyebrow { justify-content: center; }
  .hero-copy .lede { margin-inline: auto; }
  .hero .hero-actions { justify-content: center; }

  /* the eyebrow's leading dash reads as clutter once the line is centred and
     wraps to two lines */
  .sec-head .eyebrow::before, .hero-copy .eyebrow::before { display: none; }
}

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

/* ⛔ The hidden state is scoped to .js — set by an inline script in <head>.
   Without that guard a failed/blocked script leaves every .reveal element at
   opacity 0 forever, which hides the ENTIRE page from anyone whose JS did not
   run (and from crawlers that do not execute it). No-JS must render everything. */
.js .reveal { opacity: 0; translate: 0 22px; transition: opacity .62s cubic-bezier(.22,1,.36,1), translate .62s cubic-bezier(.22,1,.36,1); }
.js .reveal.is-revealed { opacity: 1; translate: 0 0; }
.reveal[data-d="1"] { transition-delay: .07s } .reveal[data-d="2"] { transition-delay: .14s }
.reveal[data-d="3"] { transition-delay: .21s } .reveal[data-d="4"] { transition-delay: .28s }

/* ⛔ non-negotiable: motion is opt-out for anyone who asked the OS to stop it */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1 !important; translate: none !important; }
  /* The case-study fan keeps its layout offsets (they are composition, not
     motion) but loses the hover transition. */
  .case-shots:hover .shot-back { transform: translateY(14px) rotate(0deg); opacity: .62; }
  .hero-ring, .hero-art::before, .stack-card { animation: none !important; }
  .sc-layers::after { display: none; }
  .sc-track i { transform: none; width: 100%; }
}

/* ------------------------------------------------- legal document page --- */

.doc-shell { padding-block: 150px var(--pad-y); }
.doc-paper {
  background: #fff; color: #2A2733;
  border-radius: var(--radius-lg);
  padding: clamp(26px, 4vw, 60px);
  box-shadow: 0 30px 70px -40px rgba(0,0,0,.9);
  overflow-x: auto;
}
.doc-paper [data-custom-class='body'] { max-width: 100% !important; padding: 0 !important; }
.doc-paper a { color: #6E469A !important; }
.doc-paper table { max-width: 100%; }
.doc-back {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-mono); font-size: .82rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 22px;
}
.doc-back:hover { color: var(--coral); }

/* -------------------------------------------------------------- 404 ----- */

.err-wrap { min-height: 74vh; display: grid; place-items: center; text-align: center; padding-block: 150px var(--pad-y); }
.err-code {
  font-family: var(--font-display); font-weight: 800; font-size: clamp(4.6rem, 15vw, 9rem);
  line-height: .9; letter-spacing: -.05em;
  background: linear-gradient(100deg, var(--violet), var(--coral));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  margin-bottom: .1em;
}

@media print {
  .hide_print, .ec-nav, .ec-foot, .to-top { display: none !important; }
  body { background: #fff; color: #000; }
  .doc-paper { box-shadow: none; padding: 0; }
}
