/* ==========================================================================
   Lalinx Technologies — design system
   Built from scratch. Replaces Bootstrap 4 + the Colorlib template CSS.

   Palette is derived from the logo. Change --brand and everything follows.
   ========================================================================== */

:root {
  /* --- Brand -------------------------------------------------------------
     Sampled from the LALINX logo and the banner/social collateral. That system
     is entirely blue: navy for headlines, royal blue for emphasis and CTAs,
     pale blue tints for surfaces. There is no orange in it, so the previous
     amber accent has been retired. */
  --brand:        #1B54D6;   /* logo royal blue */
  --brand-600:    #1745B4;   /* hover / mid */
  --brand-700:    #103390;   /* banner band */
  --brand-800:    #0B2468;   /* deep band, top bar */
  --brand-050:    #EEF3FE;   /* tint */
  --brand-100:    #D9E5FB;
  --sky:          #4D8DF7;   /* the glow blue in the network artwork */

  /* CTAs use the brand blue, matching the buttons in the collateral. Kept as
     --accent tokens so every call site stays put. */
  --accent:       #1B54D6;
  --accent-600:   #1745B4;
  --accent-050:   #EEF3FE;

  /* --- Neutrals --------------------------------------------------------- */
  --ink:          #0A1A3C;   /* headline navy */
  --body:         #41526E;
  --muted:        #6B7C9B;
  --line:         #DEE7F5;
  --surface:      #FFFFFF;
  --surface-alt:  #F5F8FE;
  /* Footer sits deeper than the top bar (--brand-800 #0B2468) so the page
     reads top-bar -> content -> footer. Derived from --brand, not a slate. */
  --footer-bg:    #081B4E;

  /* --- Type ------------------------------------------------------------- */
  --font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* --- Shape ------------------------------------------------------------ */
  --r-sm: 6px;
  --r:    10px;
  --r-lg: 16px;
  --shadow:    0 1px 2px rgba(11,31,46,.05), 0 4px 16px rgba(11,31,46,.06);
  --shadow-lg: 0 2px 4px rgba(11,31,46,.06), 0 12px 40px rgba(11,31,46,.10);

  --container: 1160px;
  --gutter: 24px;
}

/* --- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.65;
  color: var(--body);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-700); }
h1, h2, h3, h4 { color: var(--ink); font-weight: 700; line-height: 1.2; margin: 0 0 .5em; letter-spacing: -.02em; }
h1 { font-size: clamp(2.1rem, 1.3rem + 3.2vw, 3.4rem); letter-spacing: -.032em; }
h2 { font-size: clamp(1.65rem, 1.15rem + 1.9vw, 2.35rem); letter-spacing: -.028em; }
h3 { font-size: 1.15rem; }
p  { margin: 0 0 1rem; }
ul, ol { margin: 0 0 1rem; padding-left: 1.15rem; }
li { margin-bottom: .35rem; }
strong { color: var(--ink); font-weight: 650; }
hr { border: 0; border-top: 1px solid var(--line); margin: 3rem 0; }

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

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  background: var(--brand); color: #fff; padding: 10px 16px;
  border-radius: 0 0 var(--r-sm) var(--r-sm); font-weight: 600;
  transition: top .15s;
}
.skip-link:focus { top: 0; color: #fff; }

/* --- Layout --------------------------------------------------------------- */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding: clamp(56px, 7vw, 96px) 0; }
.section--tint { background: var(--surface-alt); }
.section--brand { background: var(--brand); color: #DEE8FB; }
.section--brand h2, .section--brand h3 { color: #fff; }
.section--navy { background: var(--brand-700); color: #BCCDF2; }
.section--navy h2, .section--navy h3 { color: #fff; }

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

/* Between phone and desktop, auto-fit resolves to three columns and strands the
   fourth card alone on a second row. Force a 2x2 so the set always reads as a
   balanced block and each row's cards share a height. */
@media (min-width: 561px) and (max-width: 980px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
}

.section-head { max-width: 720px; margin-bottom: 44px; }
.section-head.center { margin-inline: auto; text-align: center; }
.section-head p { font-size: 1.06rem; color: var(--muted); margin-bottom: 0; }
.section--brand .section-head p, .section--navy .section-head p { color: #A9BEEA; }

.eyebrow {
  display: inline-block; font-size: .78rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent-600); margin-bottom: 12px;
}
.section--brand .eyebrow, .section--navy .eyebrow { color: var(--accent); }

/* --- Buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font: inherit; font-weight: 600; font-size: .97rem;
  padding: 13px 24px; border-radius: var(--r-sm); border: 1.5px solid transparent;
  cursor: pointer; transition: background .15s, color .15s, border-color .15s, transform .1s;
  text-align: center;
}
.btn:active { transform: translateY(1px); }
.btn--primary  { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn--primary:hover  { background: var(--accent-600); border-color: var(--accent-600); color: #fff; }
.btn--brand    { background: var(--brand); color: #fff; border-color: var(--brand); }
.btn--brand:hover    { background: var(--brand-700); border-color: var(--brand-700); color: #fff; }
.btn--outline  { background: transparent; color: var(--brand); border-color: var(--brand); }
.btn--outline:hover  { background: var(--brand); color: #fff; }
.btn--ghost-light { background: transparent; color: #fff; border-color: rgba(255,255,255,.5); }
.btn--ghost-light:hover { background: #fff; color: var(--brand-700); border-color: #fff; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }

/* When a .btn is an <a> inside .nav, `.nav a` (0-1-1) outranks `.btn--primary`
   (0-1-0) and the label inherits body grey instead of its own colour. That
   dropped the header "Get a quote" button to 3.15:1, below AA. Doubling the
   class raises specificity to 0-2-0 so the button always owns its label. */
.btn.btn--primary, .btn.btn--primary:hover { color: #fff; }
.btn.btn--brand,   .btn.btn--brand:hover   { color: #fff; }
.btn.btn--outline            { color: var(--brand); }
.btn.btn--outline:hover      { color: #fff; }
.btn.btn--ghost-light        { color: #fff; }
.btn.btn--ghost-light:hover  { color: var(--brand-700); }

/* --- Header --------------------------------------------------------------- */
.topbar {
  background: var(--brand-800); color: #9CB2E2;
  font-size: .84rem; padding: 8px 0;
}
.topbar a { color: #DEE8FB; }
.topbar a:hover { color: #fff; }
.topbar .container { display: flex; flex-wrap: wrap; gap: 6px 20px; align-items: center; justify-content: space-between; }
.topbar-contact { display: flex; flex-wrap: wrap; gap: 6px 18px; }

.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255,255,255,.94);
  backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--line);
}
.site-header .container { display: flex; align-items: center; gap: 20px; min-height: 78px; }

.brand { display: flex; align-items: center; gap: 10px; font-weight: 800; font-size: 1.32rem; letter-spacing: -.03em; color: var(--brand); }
.brand:hover { color: var(--brand); }
.brand-mark { width: 30px; height: 30px; flex: none; }

.nav { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.nav a {
  padding: 9px 14px; border-radius: var(--r-sm);
  font-size: .95rem; font-weight: 550; color: var(--body);
}
.nav a:hover { background: var(--brand-050); color: var(--brand-700); }
.nav a[aria-current="page"] { color: var(--brand); font-weight: 650; background: var(--brand-050); }
.nav .btn { margin-left: 10px; padding: 10px 20px; }

.nav-toggle {
  display: none; margin-left: auto; background: transparent; border: 1.5px solid var(--line);
  border-radius: var(--r-sm); padding: 8px 12px; cursor: pointer; color: var(--ink);
  font: inherit; font-size: .9rem; font-weight: 600; align-items: center; gap: 8px;
}
.nav-toggle svg { width: 18px; height: 18px; }

@media (max-width: 900px) {
  .nav-toggle { display: inline-flex; }
  /* Closed state is display:none, not an off-screen transform. A translated
     panel still contributes to document width and gave the page a horizontal
     scrollbar on mobile. */
  .nav {
    display: none;
    position: fixed; inset: 0; margin: 0;
    flex-direction: column; align-items: stretch; gap: 2px;
    background: #fff; padding: 80px 20px 28px;
    height: 100dvh; overflow-y: auto;
    box-shadow: var(--shadow-lg);
  }
  /* Opacity only — a transform here would push the panel past the viewport
     edge for the duration of the animation and reintroduce horizontal scroll. */
  .nav[data-open="true"] { display: flex; animation: navIn .18s ease; }
  @keyframes navIn { from { opacity: 0; } to { opacity: 1; } }
  .nav a { padding: 14px 12px; font-size: 1.05rem; border-bottom: 1px solid var(--line); border-radius: 0; }
  .nav .btn { margin: 16px 0 0; border-bottom: 0; }
  .nav-close {
    position: absolute; top: 18px; right: 18px; background: transparent;
    border: 0; font-size: 1.8rem; line-height: 1; cursor: pointer; color: var(--ink);
  }
}
@media (min-width: 901px) { .nav-close { display: none; } }

/* --- Hero ----------------------------------------------------------------- */
.hero {
  background: linear-gradient(180deg, var(--brand-800) 0%, var(--brand-700) 55%, var(--brand-600) 100%);
  color: #BCCDF2; position: relative; overflow: hidden;
}
.hero::after {
  content: ""; position: absolute; right: -180px; top: -180px;
  width: 620px; height: 620px; border-radius: 50%;
  background: radial-gradient(circle, rgba(77,141,247,.18) 0%, transparent 62%);
  pointer-events: none;
}
.hero .container { position: relative; z-index: 1; }
.hero-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: 56px; align-items: center; padding: clamp(56px, 7vw, 96px) 0; }
@media (max-width: 900px) { .hero-grid { grid-template-columns: 1fr; gap: 36px; } }
.hero h1 { color: #fff; margin-bottom: 18px; }
.hero-lead { font-size: 1.15rem; color: #B6CAF2; max-width: 560px; margin-bottom: 28px; }
.hero-points { list-style: none; padding: 0; margin: 28px 0 0; display: flex; flex-wrap: wrap; gap: 8px 22px; }
.hero-points li { display: flex; align-items: center; gap: 8px; font-size: .92rem; color: #9FB6E6; margin: 0; }
.hero-points .tick { color: var(--accent); font-weight: 700; }
.hero-media { border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-lg); }
.hero-media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

/* page hero (inner pages) */
.pagehead { background: var(--brand-700); color: #BCCDF2; padding: clamp(44px, 6vw, 72px) 0; }
.pagehead h1 { color: #fff; margin-bottom: 10px; }
.pagehead p { color: #A9BEEA; max-width: 640px; margin: 0; }
.crumbs { font-size: .85rem; color: #8CA3D6; margin-bottom: 14px; }
.crumbs a { color: #A9BEEA; }
.crumbs a:hover { color: #fff; }

/* --- Cards ---------------------------------------------------------------- */
.card {
  position: relative;
  background: linear-gradient(180deg, #FFFFFF 0%, #FAFCFE 100%);
  border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 30px 28px 28px; height: 100%;
  overflow: hidden;
  /* Column layout so the "Explore" link can be pushed to the bottom edge.
     Without this the link sits directly after whatever content precedes it,
     so links across a row landed at four different heights. */
  display: flex; flex-direction: column;
  transition: border-color .25s, box-shadow .3s, transform .3s cubic-bezier(.22,1,.36,1);
}
/* Gradient hairline along the top — hidden at rest, sweeps in on hover so the
   card answers the pointer instead of sitting inert. */
.card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg, var(--brand) 0%, var(--accent) 100%);
  transform: scaleX(0); transform-origin: left;
  transition: transform .38s cubic-bezier(.22,1,.36,1);
}
.card:hover::before, .card:focus-within::before { transform: scaleX(1); }
.card:hover {
  border-color: var(--brand-100);
  transform: translateY(-6px);
  box-shadow: 0 2px 6px rgba(11,31,46,.05), 0 26px 48px -18px rgba(27,84,214,.22);
}
.card h3 { margin-bottom: 8px; }
.card p:last-child { margin-bottom: 0; }
.card .icon {
  width: 52px; height: 52px; border-radius: 14px;
  background: linear-gradient(135deg, var(--brand-050) 0%, #FFFFFF 100%);
  border: 1px solid var(--brand-100);
  color: var(--brand);
  display: grid; place-items: center; margin-bottom: 18px;
  box-shadow: inset 0 1px 0 #fff, 0 1px 3px rgba(11,31,46,.06);
  transition: background .25s, color .25s, transform .3s cubic-bezier(.22,1,.36,1), border-color .25s;
}
.card .icon svg { width: 24px; height: 24px; }
.card:hover .icon {
  background: var(--brand); border-color: var(--brand); color: #fff;
  transform: scale(1.07) rotate(-4deg);
}
.card--accent .icon {
  background: linear-gradient(135deg, var(--accent-050) 0%, #FFFFFF 100%);
  border-color: #F3D9AC; color: var(--accent-600);
}
.card--accent:hover .icon { background: var(--accent); border-color: var(--accent); color: #fff; }

.card-list { list-style: none; padding: 0; margin: 16px 0 0; }
.card-list li { position: relative; padding-left: 26px; margin-bottom: 8px; font-size: .93rem; }
/* Tick, not square — reads as "included", which is what the list means. */
.card-list li::before {
  content: ""; position: absolute; left: 3px; top: .46em;
  width: 5px; height: 10px;
  border-right: 2.2px solid var(--accent); border-bottom: 2.2px solid var(--accent);
  transform: rotate(42deg);
}

/* "Explore" link at the foot of a linking card */
.card-link {
  display: inline-flex; align-items: center; gap: 7px;
  /* auto pushes the link to the bottom of the flex column, so every card in a
     row ends on the same baseline regardless of how much copy sits above it */
  margin-top: auto; padding-top: 18px;
  font-size: .92rem; font-weight: 650; color: var(--brand);
  align-self: flex-start; white-space: nowrap;
}
.card-link .arr { transition: transform .25s cubic-bezier(.22,1,.36,1); }
.card:hover .card-link .arr { transform: translateX(4px); }

/* In the four-across overview grid the columns are narrow enough that some
   titles run to two lines ("Server Security & Networking") while others do not
   ("Web Development"). Reserving two lines keeps the descriptions underneath
   starting on the same line across the row. */
@media (min-width: 981px) {
  .grid-4 .card h3 { min-height: 2.4em; }
}

/* numbered process steps */
.step { position: relative; padding-top: 6px; }
.step-num {
  font-size: .8rem; font-weight: 800; letter-spacing: .06em;
  color: var(--accent-600); background: var(--accent-050);
  display: inline-block; padding: 4px 10px; border-radius: 99px; margin-bottom: 14px;
}
.section--navy .step-num, .section--brand .step-num { color: var(--accent); background: rgba(77,141,247,.18); }

/* --- Stats ---------------------------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 28px; }
.stat b {
  display: block; font-size: clamp(2.1rem, 1.4rem + 2.4vw, 3rem);
  font-weight: 800; letter-spacing: -.04em; color: #fff; line-height: 1.05;
}
.stat span { font-size: .93rem; color: #A9BEEA; }

/* --- Split feature -------------------------------------------------------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 52px; align-items: center; }
@media (max-width: 860px) { .split { grid-template-columns: 1fr; gap: 32px; } }
.split-media { border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow); }
.split-media img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.split-media--stack { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; box-shadow: none; }
.split-media--stack img { border-radius: var(--r); box-shadow: var(--shadow); aspect-ratio: 1; }

/* --- Work tiles ----------------------------------------------------------- */
.tile {
  border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
  background: #fff; height: 100%; display: flex; flex-direction: column;
  transition: border-color .16s, box-shadow .16s, transform .16s;
}
.tile:hover { border-color: var(--brand-100); box-shadow: var(--shadow); transform: translateY(-2px); }
.tile img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
.tile-body { padding: 20px 20px 22px; }
.tile-body h3 { font-size: 1.05rem; margin-bottom: 6px; }
.tile-body p { font-size: .92rem; margin-bottom: 0; color: var(--muted); }

/* --- FAQ (native details) ------------------------------------------------- */
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer; list-style: none; padding: 20px 44px 20px 0; position: relative;
  font-weight: 620; color: var(--ink); font-size: 1.03rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 10px; top: 50%;
  width: 10px; height: 10px; margin-top: -7px;
  border-right: 2.5px solid var(--brand); border-bottom: 2.5px solid var(--brand);
  transform: rotate(45deg); transition: transform .18s;
}
.faq details[open] summary::after { transform: rotate(-135deg); margin-top: -3px; }
.faq details[open] summary { color: var(--brand); }
.faq .faq-body { padding: 0 12px 22px 0; color: var(--body); }
.faq .faq-body p:last-child { margin-bottom: 0; }

/* --- Callout -------------------------------------------------------------- */
.callout {
  background: var(--brand-050); border-left: 4px solid var(--brand);
  border-radius: var(--r); padding: 28px 30px;
}
.callout h3 { margin-bottom: 8px; }
.callout p:last-child { margin-bottom: 0; }
.callout--warn { background: var(--accent-050); border-left-color: var(--accent); }

/* --- CTA band ------------------------------------------------------------- */
.cta-band { background: var(--brand-700); color: #BCCDF2; border-radius: var(--r-lg); padding: clamp(32px, 5vw, 52px); }
.cta-band h2 { color: #fff; }
.cta-band p { color: #A9BEEA; max-width: 620px; }

/* --- Forms ---------------------------------------------------------------- */
.field { margin-bottom: 18px; }
.field label { display: block; font-size: .9rem; font-weight: 600; color: var(--ink); margin-bottom: 6px; }
.field .req { color: var(--accent-600); }
.input, .select, .textarea {
  width: 100%; font: inherit; font-size: .97rem; color: var(--ink);
  padding: 12px 14px; border: 1.5px solid var(--line); border-radius: var(--r-sm);
  background: #fff; transition: border-color .15s, box-shadow .15s;
}
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--brand); box-shadow: 0 0 0 3px rgba(27,84,214,.16); outline: none;
}
.textarea { min-height: 130px; resize: vertical; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
@media (max-width: 620px) { .form-grid { grid-template-columns: 1fr; } }
.form-card { background: #fff; border: 1px solid var(--line); border-radius: var(--r-lg); padding: clamp(24px, 4vw, 36px); box-shadow: var(--shadow); }
.hp { position: absolute; left: -9999px; }

/* contact detail rows */
.contact-list { list-style: none; padding: 0; margin: 0; }
.contact-list li { display: flex; gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--line); margin: 0; }
.contact-list li:last-child { border-bottom: 0; }
.contact-list .ic {
  width: 38px; height: 38px; flex: none; border-radius: var(--r-sm);
  background: var(--brand-050); color: var(--brand); display: grid; place-items: center;
}
.contact-list .ic svg { width: 18px; height: 18px; }
.contact-list dt { font-size: .8rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); font-weight: 650; }
.contact-list dd { margin: 2px 0 0; color: var(--ink); }

/* --- Prose (legal pages) -------------------------------------------------- */
.prose { max-width: 760px; }
.prose h2 { font-size: 1.3rem; margin-top: 2.4rem; }
.prose h3 { font-size: 1.08rem; margin-top: 1.9rem; }
.prose ul { padding-left: 1.25rem; }
.prose li { margin-bottom: .5rem; }

/* --- Footer --------------------------------------------------------------- */
.site-footer { background: var(--footer-bg); color: #AFC4EE; padding: 64px 0 0; font-size: .94rem; }
.site-footer h3 { color: #fff; font-size: .82rem; text-transform: uppercase; letter-spacing: .1em; margin-bottom: 18px; }
.site-footer a { color: #CBD9F6; }
.site-footer a:hover { color: #fff; }
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.5fr; gap: 40px; }
@media (max-width: 860px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: 32px; } }
@media (max-width: 520px) { .footer-grid { grid-template-columns: 1fr; } }
.footer-brand { display: flex; align-items: center; gap: 10px; font-weight: 800; font-size: 1.25rem; color: #fff; letter-spacing: -.03em; margin-bottom: 14px; }
.footer-list { list-style: none; padding: 0; margin: 0; }
.footer-list li { margin-bottom: 10px; }
.footer-bottom {
  margin-top: 52px; border-top: 1px solid rgba(255,255,255,.1); padding: 22px 0 26px;
  display: flex; flex-wrap: wrap; gap: 8px 24px; justify-content: space-between;
  font-size: .87rem; color: #93A8DA;
}
.social { display: flex; gap: 10px; margin-top: 18px; }
.social a {
  width: 38px; height: 38px; border-radius: var(--r-sm);
  background: rgba(255,255,255,.09); display: grid; place-items: center; color: #CBD9F6;
}
.social a:hover { background: var(--brand); color: #fff; }
.social svg { width: 18px; height: 18px; }

/* --- Cookie banner -------------------------------------------------------- */
.cookie {
  position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 150;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg); padding: 20px 22px; max-width: 620px; margin-inline: auto;
  display: none;
}
.cookie[data-show="true"] { display: block; }
.cookie p { font-size: .9rem; margin-bottom: 14px; }
.cookie .btn { padding: 9px 18px; font-size: .9rem; }

/* --- Motion ---------------------------------------------------------------
   FAIL-SAFE BY CONSTRUCTION.

   The previous template set `.ftco-animate { opacity:0; visibility:hidden }`
   in CSS and relied on a JS callback to reveal it. That callback never fired,
   so every visitor got invisible content — the single worst bug on the old
   site.

   So: CSS here NEVER hides anything. `.reveal` is an inert marker. Only JS
   adds `.pre-anim`, and only to elements already below the fold. If the
   script fails to load, errors, or the observer never fires, nothing was
   hidden in the first place and the page reads normally.
   -------------------------------------------------------------------------- */
.reveal { /* marker only — intentionally has no hiding styles */ }

/* Applied by JS only, and only to elements below the fold. Three directions:
   up (default), from the left, from the right. `.reveal-l` / `.reveal-r` on
   the element pick the direction; JS maps them to the matching pre/in pair. */
.pre-anim   { opacity: 0; transform: translateY(18px); }
.pre-anim-l { opacity: 0; transform: translateX(-30px); }
.pre-anim-r { opacity: 0; transform: translateX(30px); }

/* On reveal, JS REMOVES the pre-anim class and adds the matching anim-in.
   Note there is no animation-fill-mode: once the animation finishes (or if it
   never runs at all) the element falls back to its normal, fully visible
   styles. The resting state of every element on this site is "visible". */
.anim-in   { animation: lxFadeUp .6s cubic-bezier(.22,1,.36,1); }
.anim-in-l { animation: lxFadeL  .6s cubic-bezier(.22,1,.36,1); }
.anim-in-r { animation: lxFadeR  .6s cubic-bezier(.22,1,.36,1); }

/* A sideways entrance moves the element outside the container for the length
   of the animation, which lets the page be scrolled horizontally while it
   plays. Clipping the section contains it without affecting the sticky header
   (that lives outside <main>). `clip` rather than `hidden` so no new scroll
   container is created. */
.section, .hero, .pagehead { overflow-x: clip; }

/* On phones there is no room to give: drop the horizontal travel entirely and
   fall back to the vertical entrance. Guarantees no sideways scroll even in
   browsers without `overflow: clip`. */
@media (max-width: 720px) {
  .pre-anim-l, .pre-anim-r { transform: translateY(18px); }
  .anim-in-l,  .anim-in-r  { animation-name: lxFadeUp; }
}

@keyframes lxFadeUp {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@keyframes lxFadeL {
  from { opacity: 0; transform: translateX(-30px); }
  to   { opacity: 1; transform: none; }
}
@keyframes lxFadeR {
  from { opacity: 0; transform: translateX(30px); }
  to   { opacity: 1; transform: none; }
}

/* Ambient hero motion — two soft light orbs drifting very slowly. Decorative
   pseudo-elements only, so they cost nothing if animations are disabled. */
.hero::after { animation: lxDrift 16s ease-in-out infinite alternate; }
.hero::before {
  content: ""; position: absolute; left: -160px; bottom: -220px;
  width: 520px; height: 520px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,.07) 0%, transparent 60%);
  pointer-events: none;
  animation: lxDrift 20s ease-in-out infinite alternate-reverse;
}
@keyframes lxDrift {
  from { transform: translate(0, 0) scale(1); }
  to   { transform: translate(-36px, 24px) scale(1.08); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  .pre-anim, .pre-anim-l, .pre-anim-r { opacity: 1; transform: none; }
}

/* --- Utilities ------------------------------------------------------------ */
.center { text-align: center; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.mt-4 { margin-top: 2rem; }
.lead { font-size: 1.1rem; color: var(--muted); }

/* ==========================================================================
   Pricing tiers (/applications)
   ========================================================================== */
.tiers {
  display: grid; gap: 24px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  align-items: stretch;
}
.tier {
  position: relative; display: flex; flex-direction: column;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 32px 28px 30px;
  transition: border-color .25s, box-shadow .3s, transform .3s cubic-bezier(.22,1,.36,1);
}
.tier:hover { border-color: var(--brand-100); box-shadow: var(--shadow); transform: translateY(-3px); }
.tier--featured {
  border-color: var(--accent); box-shadow: 0 12px 40px rgba(27,84,214,.18);
}
.tier--featured:hover { border-color: var(--accent); }
.tier-badge {
  position: absolute; top: -12px; left: 28px;
  background: var(--brand); color: #fff;
  font-size: .72rem; font-weight: 750; letter-spacing: .06em; text-transform: uppercase;
  padding: 5px 12px; border-radius: 99px;
}
.tier h3 { font-size: 1.1rem; margin-bottom: 6px; }
.tier-price { margin: 0 0 20px; }
.tier-price strong {
  font-size: 2.6rem; font-weight: 800; letter-spacing: -.04em; color: var(--brand);
  line-height: 1;
}
.tier-price span { color: var(--muted); font-size: .9rem; }
.tier-list { list-style: none; padding: 0; margin: 0 0 26px; }
.tier-list li { position: relative; padding-left: 26px; margin-bottom: 10px; font-size: .94rem; }
.tier-list li::before {
  content: ""; position: absolute; left: 4px; top: .48em;
  width: 11px; height: 6px; border-left: 2.2px solid var(--accent);
  border-bottom: 2.2px solid var(--accent); transform: rotate(-45deg);
}
.tier .btn { margin-top: auto; }
.tier-price + .tier-note { margin: -12px 0 20px; font-size: .82rem; color: var(--muted); }
.tier-list li.tier-lead { padding-left: 0; font-weight: 650; color: var(--ink); }
.tier-list li.tier-lead::before { content: none; }
.tiers--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px; }
.tiers--4 .tier { padding: 30px 22px 26px; }
.tiers--4 .tier-price strong { font-size: 2.3rem; }
.tiers--4 .tier-price span { display: block; margin-top: 6px; }
.tiers--4 .tier-price + .tier-note { margin-top: -14px; min-height: 2.8em; }
@media (max-width: 620px) { .tiers--4 .tier-price + .tier-note { min-height: 0; } }
@media (max-width: 1080px) { .tiers--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 32px; } }
@media (max-width: 620px)  { .tiers--4 { grid-template-columns: 1fr; } }

/* Product page hero gets the hero gradient rather than the flat navy */
.pagehead--product {
  background: linear-gradient(180deg, var(--brand-800) 0%, var(--brand-700) 55%, var(--brand-600) 100%);
  position: relative; overflow: hidden;
}
.pagehead--product::after {
  content: ""; position: absolute; right: -160px; top: -160px;
  width: 560px; height: 560px; border-radius: 50%;
  background: radial-gradient(circle, rgba(77,141,247,.20) 0%, transparent 62%);
  pointer-events: none;
}
.pagehead--product .container { position: relative; z-index: 1; }
.pagehead--product h1 { max-width: 16ch; }
.pagehead--product p { max-width: 62ch; }

/* ==========================================================================
   Coverage band — where we work
   ========================================================================== */
.coverage { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 22px; }
.coverage-card {
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.14);
  border-radius: var(--r); padding: 24px 22px; backdrop-filter: blur(4px);
}
.coverage-card .flagline {
  display: flex; align-items: center; gap: 10px; margin-bottom: 12px;
}
.coverage-card .flag {
  font-size: 1.5rem; line-height: 1; filter: saturate(1.1);
}
.coverage-card h3 { color: #fff; font-size: 1.02rem; margin: 0; }
.coverage-card p { color: #A9BEEA; font-size: .9rem; margin: 0; }
.coverage-card .hours { color: var(--accent); font-weight: 650; font-size: .84rem; display: block; margin-top: 10px; }

/* ==========================================================================
   Client quotes — rendered only when real, attributed quotes exist.
   See build/testimonials.py. Nothing here is placeholder copy.
   ========================================================================== */
.quotes { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; }
.quote {
  display: flex; flex-direction: column;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 30px 28px; position: relative;
  transition: border-color .25s, box-shadow .3s, transform .3s cubic-bezier(.22,1,.36,1);
}
.quote:hover { border-color: var(--brand-100); box-shadow: var(--shadow); transform: translateY(-3px); }
.quote::before {
  content: "\201C"; position: absolute; top: 10px; right: 22px;
  font-size: 4.5rem; line-height: 1; color: var(--brand-050); font-family: Georgia, serif;
}
.quote blockquote { margin: 0 0 22px; font-size: 1rem; line-height: 1.6; color: var(--body); position: relative; z-index: 1; }
.quote-person { display: flex; align-items: center; gap: 14px; margin-top: auto; }
.quote-person img { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; flex: none; }
.quote-person .who { font-weight: 700; color: var(--ink); font-size: .95rem; line-height: 1.3; }
.quote-person .role { color: var(--muted); font-size: .85rem; }
.quote-stars { color: var(--accent); letter-spacing: 2px; margin-bottom: 14px; font-size: .95rem; }

/* ==========================================================================
   Product feature block (OPSORE teaser on the home page)
   ========================================================================== */
.section--product {
  background:
    radial-gradient(680px 380px at 88% 12%, rgba(77,141,247,.14), transparent 60%),
    radial-gradient(620px 420px at 5% 88%, rgba(27,84,214,.10), transparent 62%),
    var(--surface);
}
.pill-row { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; padding: 0; margin: 22px 0 0; }
.pill-row li {
  margin: 0; font-size: .84rem; font-weight: 600; color: var(--brand-700);
  background: var(--brand-050); border: 1px solid var(--brand-100);
  padding: 7px 14px; border-radius: 99px;
}

/* Browser-chrome framing so the screenshot reads as a product, not a stock photo */
.product-shot { position: relative; border-radius: var(--r-lg); overflow: visible; }
.product-shot img {
  width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  box-shadow: var(--shadow-lg);
}
.shot-chrome {
  display: flex; align-items: center; gap: 7px;
  background: #0B2468; padding: 11px 14px;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.shot-chrome span { width: 10px; height: 10px; border-radius: 50%; background: rgba(255,255,255,.28); }
.shot-chrome span:first-child { background: var(--sky); }
.shot-chrome em {
  margin-left: 10px; font-style: normal; font-size: .78rem; color: #B6CAF2;
  background: rgba(255,255,255,.08); padding: 3px 12px; border-radius: 99px;
}
.shot-badge {
  position: absolute; right: -14px; bottom: -18px;
  background: var(--brand); color: #fff;
  border-radius: var(--r); padding: 14px 18px;
  box-shadow: 0 10px 30px rgba(27,84,214,.32);
  display: flex; align-items: center; gap: 10px;
}
.shot-badge strong { font-size: 1.7rem; font-weight: 800; letter-spacing: -.03em; line-height: 1; }
.shot-badge span { font-size: .72rem; line-height: 1.25; font-weight: 600; }
@media (max-width: 640px) {
  .shot-badge { right: 8px; bottom: -14px; padding: 11px 14px; }
  .shot-badge strong { font-size: 1.35rem; }
}

/* ==========================================================================
   LALINX logo
   Drawn as SVG geometry (build/logo.py) rather than a raster: crisp at any
   size, ~1 KB, inherits currentColor, and each letter is separately animatable.
   ========================================================================== */
.lalinx-logo { display: block; height: 100%; width: auto; color: var(--brand); overflow: visible; }
.lx-tag { font-family: Inter, 'Segoe UI', Arial, sans-serif; }

.brand { gap: 0; }
.brand .lalinx-logo { height: 46px; }
/* 130px so the tagline lands at ~10px and is actually readable. In the sticky
   header the same lockup would put it at 4.1px, which is why the header shows
   the mark alone. */
.footer-brand .lalinx-logo { height: 130px; color: #fff; max-width: 100%; }
.footer-brand { display: block; margin-bottom: 18px; }
@media (max-width: 520px) { .footer-brand .lalinx-logo { height: 104px; } }

/* Declared AFTER the base rule on purpose. An identical-specificity override
   inside an earlier @media block loses to source order and silently does
   nothing - which is exactly what happened the first time. */
@media (max-width: 900px) {
  .brand .lalinx-logo { height: 38px; }
  .site-header .container { min-height: 68px; }
}

/* --- entrance -------------------------------------------------------------
   The bracket draws itself, then the letters rise in sequence. Runs once on
   load. Like every other animation on this site it is additive only: the
   resting state is the finished logo, so if the animation never runs (reduced
   motion, old browser, frozen clock) the logo is simply there. */
.lalinx-logo.is-anim .lx-bracket {
  stroke-dasharray: 620;
  animation: lxDraw 1.1s cubic-bezier(.65,0,.35,1) both;
}
.lalinx-logo.is-anim .lx-l {
  animation: lxLetter .5s cubic-bezier(.22,1,.36,1) both;
  animation-delay: calc(.34s + var(--i) * .075s);
}

@keyframes lxDraw {
  from { stroke-dashoffset: 620; }
  to   { stroke-dashoffset: 0; }
}
@keyframes lxLetter {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}
.lalinx-logo .lx-l { transform-box: fill-box; transform-origin: center; }

/* --- hover ----------------------------------------------------------------
   Pointing at the logo replays it: the bracket opens and the letters lift in
   sequence. Purely additive, so it cannot leave the mark in a broken state. */
.brand .lx-bracket { transition: transform .3s cubic-bezier(.22,1,.36,1); }
.brand:hover .lx-bracket,
.brand:focus-visible .lx-bracket { transform: translateX(-3px); }

.brand:hover .lalinx-logo .lx-l,
.brand:focus-visible .lalinx-logo .lx-l {
  animation: lxWave .52s cubic-bezier(.22,1,.36,1);
  animation-delay: calc(var(--i) * .045s);
}
@keyframes lxWave {
  0%   { transform: none; }
  38%  { transform: translateY(-6px); }
  100% { transform: none; }
}

.brand .lx-tag { transition: opacity .3s ease; }
.brand:hover .lx-tag { opacity: .72; }

@media (prefers-reduced-motion: reduce) {
  .lalinx-logo.is-anim .lx-bracket,
  .lalinx-logo.is-anim .lx-l { animation: none; }
  .brand .lx-bracket { transition: none; }
}

/* ==========================================================================
   About block — scannable version
   The original ran three separate claims into one long sentence. Split into
   labelled points so the eye can pick out what Lalinx actually does.
   ========================================================================== */
.lead-navy { font-size: 1.08rem; color: #C6D2F5; margin-bottom: 26px; }

.about-points { list-style: none; padding: 0; margin: 0 0 28px; }
.about-points li {
  position: relative; padding-left: 34px; margin-bottom: 20px;
  color: #A9BEEA; font-size: .97rem; line-height: 1.55;
}
.about-points strong {
  display: block; color: #fff; font-weight: 650;
  font-size: 1.02rem; margin-bottom: 3px;
}
/* tick marker */
.about-points li::before {
  content: ""; position: absolute; left: 0; top: 4px;
  width: 20px; height: 20px; border-radius: 50%;
  background: rgba(77,141,247,.22);
}
.about-points li::after {
  content: ""; position: absolute; left: 6px; top: 10px;
  width: 8px; height: 4px;
  border-left: 2px solid var(--sky); border-bottom: 2px solid var(--sky);
  transform: rotate(-45deg);
}
.about-close {
  color: #A9BEEA; font-size: .95rem; padding-top: 20px; margin-bottom: 26px;
  border-top: 1px solid rgba(255,255,255,.14);
}

/* --- stats, now with a timeframe ------------------------------------------ */
.stats-panel {
  background: rgba(255,255,255,.055);
  border: 1px solid rgba(255,255,255,.13);
  border-radius: var(--r-lg);
  padding: 30px 28px 26px;
}
.stats-label {
  font-size: .74rem; font-weight: 750; letter-spacing: .14em;
  text-transform: uppercase;
  /* --sky (#4D8DF7) is only 3.41:1 on the navy panel and this label is ~12px,
     so it needs 4.5:1. Lightened to clear AA. */
  color: #8FB8FB;
  margin: 0 0 22px; padding-bottom: 14px;
  border-bottom: 1px solid rgba(255,255,255,.13);
}
.stats-panel .stats { gap: 26px 24px; }
.stats-panel .stat b { font-size: clamp(2rem, 1.4rem + 1.9vw, 2.7rem); }

/* Inside the panel the minmax(150px) track resolves to a single column on a
   phone, giving four stacked rows and a very tall block. Force 2x2. */
@media (max-width: 560px) {
  .stats-panel { padding: 24px 20px 20px; }
  .stats-panel .stats { grid-template-columns: 1fr 1fr; gap: 22px 16px; }
  .stats-panel .stat b { font-size: 2rem; }
}
