/* ==========================================================================
   TicApp — stylesheet
   --------------------------------------------------------------------------
   Rewritten from scratch. The previous file had grown to 46 appended patch
   sections, 4 competing :root blocks, 3 definitions of .pad and 9 conflicting
   border-radius overrides. Every fix was individually correct and the result
   was incoherent, which is exactly what it looked like.

   The values below are measured from appmaker.xyz and its inner feature page
   using the same headless script that measures this site, so the two can be
   compared by number rather than by impression:

       page background    #ffffff
       dark sections      #000000        (a true black, not a dark grey)
       accent panel       #f3ece3        used sparingly
       text               #141414        near-black, not a slate
       body               16px / 1.5
       H1 home            ~56px / 500 / near-normal tracking
       H1 inner page      44px  / 500
       radius             16px panels, 10px small, 24px large surfaces
       section padding    96px
       content column     1216px, 32px gutter

   Structure of this file:
       1  tokens          6  header         11 calculator
       2  reset           7  hero           12 gallery + cases
       3  layout          8  sections       13 pages
       4  type            9  cards          14 footer
       5  buttons        10  phone UI       15 motion + responsive
   ========================================================================== */


/* ── 1. Tokens ─────────────────────────────────────────────────────────── */
:root {
  /* Ground */
  --paper:   #ffffff;
  --cream:   #f3ece3;
  --cream-2: #ece9e2;
  --lilac:   #f2f3ff;
  --black:   #000000;
  --black-2: #111111;

  /* Ink */
  --ink:     #141414;
  --text:    #141414;
  --text-2:  #4a4a4a;
  --text-3:  #767676;
  --on-dark:    #e6e6e6;
  --on-dark-2:  #a8a8a8;

  /* Brand — the logo green, sampled from the file */
  --brand:     #6ebd44;
  --brand-600: #57a12f;
  --brand-t:   #38701f;   /* the only green with enough contrast on light */
  --brand-50:  #eef7e6;

  /* Secondary, used once or twice a page at most */
  --warm:    #f97b2c;
  --warm-50: #fef0e8;

  /* Lines */
  --line:      #e8e5e0;
  --line-soft: #f2f0ec;

  /* Geometry */
  --w:      1216px;
  --w-text: 760px;
  --gutter: 32px;
  --r-sm:   10px;
  --r:      16px;
  --r-lg:   24px;
  --r-pill: 999px;

  /* Depth — light, because the reference barely uses shadow */
  --shadow-sm: 0 1px 2px rgba(0,0,0,.04);
  --shadow:    0 2px 8px rgba(0,0,0,.06);
  --shadow-lg: 0 12px 32px rgba(0,0,0,.10);
  --shadow-xl: 0 24px 64px rgba(0,0,0,.20);

  --ease: cubic-bezier(.22, 1, .36, 1);
  --sans: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}


/* ── 2. Reset ──────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font: 400 16px/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
h1, h2, h3, h4 { margin: 0; color: var(--ink); font-weight: 500; line-height: 1.2; letter-spacing: -.01em; }
h3, h4 { font-weight: 600; }
p, figure { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
:focus-visible { outline: 3px solid var(--brand); outline-offset: 3px; border-radius: 4px; }
/* Icons carry no width or height, so they need a default — without one they
   expand to fill their box and push the label out of a button.
   Article covers are also width-less SVGs, and this rule shrank all fifty of
   them to 18 pixels: present in the markup, labelled correctly, and invisible
   on screen. The exclusion is what makes both work. */
svg:not([width]):not([height]):not([role="img"]) { width: 1.15em; height: 1.15em; flex: none; }
svg[role="img"] { width: 100%; height: auto; display: block; }
.screen-reader-text { position: absolute !important; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: absolute; left: -9999px; }
.skip:focus { left: 12px; top: 12px; z-index: 9999; padding: 12px 20px; border-radius: 8px;
  background: #fff; color: #000; font-weight: 600; }


/* ── 3. Layout ─────────────────────────────────────────────────────────── */
.wrap   { width: 100%; max-width: var(--w); margin-inline: auto; padding-inline: var(--gutter); }
.narrow { max-width: var(--w-text); margin-inline: auto; }
.center { text-align: center; }
section { position: relative; }

.pad    { padding-block: 96px; }
.pad-sm { padding-block: 64px; }

/* Blocks: the page is white and a section opts into colour. */
section.blk        { margin: 16px; border-radius: var(--r-lg); overflow: hidden; }
section.blk-white  { background: var(--paper); }
section.blk-cream.is-accent { background: var(--cream); }
section.blk-lilac.is-accent { background: var(--lilac); }
/* One name for "this section is on black".
   The stylesheet previously carried two — .dark and .blk-dark — and every
   rule had to remember both. It did not: /features/ and /pricing/ shipped
   with body copy at 2.37:1 on black because their sections used .blk-dark
   and the colour rules were written against .dark. Aliasing them here means
   a rule can never again apply to one and miss the other. */
.dark, section.blk-dark { background: var(--black); color: var(--on-dark); }
.dark h1, section.blk-dark h1, .dark h2, section.blk-dark h2, .dark h3, section.blk-dark h3, .dark h4, section.blk-dark h4, section.blk-dark h1, section.blk-dark h2, section.blk-dark h3, section.blk-dark h4{ color: #fff; }
.hero.blk { margin-top: 0; border-radius: 0 0 var(--r-lg) var(--r-lg); }

.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.split  { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
.split.wide-l { grid-template-columns: 1.05fr .95fr; }
.split.is-flipped > *:first-child { order: 2; }


/* ── 4. Type ───────────────────────────────────────────────────────────── */
.h-xl { font-size: clamp(2.15rem, 4vw, 3.4rem);  line-height: 1.14; letter-spacing: -.014em; }
.h-lg { font-size: clamp(1.7rem, 2.7vw, 2.25rem); line-height: 1.22; letter-spacing: -.012em; }
.h-md { font-size: clamp(1.3rem, 1.9vw, 1.6rem);  line-height: 1.3; }
.h-sm { font-size: 1.1rem; }

.lede  { font-size: clamp(1rem, 1.35vw, 1.125rem); line-height: 1.6; color: var(--text-2); }
.muted { color: var(--text-2); }
.dark .lede, section.blk-dark .lede, .dark .muted, section.blk-dark .muted, .dark .cta-note, section.blk-dark .cta-note, .dark p, section.blk-dark p, .dark .card p, section.blk-dark .card p, .dark .stat p, section.blk-dark .stat p, .dark li, section.blk-dark li{ color: var(--on-dark-2); }
.dark .case-says, section.blk-dark .case-says, .dark .sync-visual, section.blk-dark .sync-visual, .dark .steps li, section.blk-dark .steps li, .dark .loop li, section.blk-dark .loop li, .dark .card, section.blk-dark .card, .dark .stat, section.blk-dark .stat{ color: var(--text); }
.dark .case-says p, section.blk-dark .case-says p, .dark .sync-visual p, section.blk-dark .sync-visual p, .dark .steps li p, section.blk-dark .steps li p, .dark .loop li p, section.blk-dark .loop li p, .dark .card p, section.blk-dark .card p, .dark .stat p, section.blk-dark .stat p{ color: var(--text-2); }

.eyebrow {
  display: inline-flex; align-items: center; gap: 8px; margin-bottom: 16px;
  font-size: 12px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--brand-t);
}
.eyebrow::before { content: ""; width: 20px; height: 2px; border-radius: 2px; background: var(--brand); }
.dark .eyebrow, section.blk-dark .eyebrow{ color: var(--brand); }

.grad { background: linear-gradient(96deg, var(--brand) 0%, #a8e07a 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent; }

.sec-head { margin-bottom: 48px; }
.sec-head.center { max-width: 660px; margin-inline: auto; }
.sec-head .lede { margin-top: 16px; }


/* ── 5. Buttons ────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 13px 24px; border-radius: var(--r-pill);
  font-size: 15px; font-weight: 500; white-space: nowrap;
  transition: background .18s, color .18s, border-color .18s, transform .18s var(--ease);
}
.btn:hover { transform: translateY(-1px); }
.btn svg { width: 17px; height: 17px; flex: none; }
.btn .arw { transition: transform .2s var(--ease); }
.btn:hover .arw { transform: translateX(3px); }
.btn-lg { padding: 16px 30px; font-size: 16px; }

.btn-accent  { background: var(--brand); color: #08210a; font-weight: 600; }
.btn-accent:hover { background: var(--brand-600); color: #fff; }
.btn-primary { background: var(--ink); color: #fff; }
.btn-primary:hover { background: #000; }
.btn-white   { background: #fff; color: var(--ink); font-weight: 600; }
.btn-white:hover { background: #ececec; }
.btn-ghost   { background: transparent; color: var(--ink); border: 1px solid var(--line); }
.btn-ghost:hover { border-color: var(--ink); }
.dark .btn-ghost, section.blk-dark .btn-ghost{ color: #fff; border-color: rgba(255,255,255,.28); }
.dark .btn-ghost:hover, section.blk-dark .btn-ghost:hover{ border-color: #fff; background: rgba(255,255,255,.07); }

.cta-row { display: flex; flex-wrap: wrap; gap: 12px; }
.cta-row.center { justify-content: center; }
.cta-note { margin-top: 16px; font-size: 13.5px; color: var(--text-3); }


/* ── 6. Header ─────────────────────────────────────────────────────────── */
/* Light, on white. The reference site's navigation sits on the white page —
   this was a dark bar for twelve rounds of review because the palette was
   matched from measurements taken of the page BODY and the header was never
   looked at. */
.hdr {
  position: sticky; top: 0; z-index: 900;
  background: rgba(255,255,255,.88);
  backdrop-filter: saturate(160%) blur(16px);
  -webkit-backdrop-filter: saturate(160%) blur(16px);
  border-bottom: 1px solid var(--line-soft);
}
.hdr.is-scrolled { background: rgba(255,255,255,.97); border-bottom-color: var(--line); }
.hdr-in { display: flex; align-items: center; gap: 32px; height: 98px; }
.logo { display: inline-flex; align-items: center; gap: 8px; }
.logo-mark { width: auto; height: 68px; flex: none; }


.nav { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.nav > a, .nav-top {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 8px 13px; border-radius: 8px;
  font-size: 14.5px; font-weight: 400; color: var(--text-2);
  transition: color .16s, background .16s;
}
.nav > a:hover, .nav-top:hover, .nav-group:hover .nav-top { color: var(--ink); background: var(--cream); }
.nav-top svg { transition: transform .2s var(--ease); }
.nav-group { position: relative; }
.nav-group:hover .nav-top svg { transform: rotate(180deg); }
.nav-drop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 20; min-width: 208px;
  padding: 6px; border-radius: 14px; background: #fff;
  border: 1px solid var(--line); box-shadow: var(--shadow-lg);
  opacity: 0; visibility: hidden; transform: translateY(-4px); transition: .18s var(--ease);
}
.nav-group:hover .nav-drop, .nav-group:focus-within .nav-drop { opacity: 1; visibility: visible; transform: none; }
.nav-drop a { display: block; padding: 9px 13px; border-radius: 8px; font-size: 14.5px;
  color: var(--text); white-space: nowrap; }
.nav-drop a:hover { background: var(--cream); }
.nav a[aria-current="page"] { color: var(--brand-t); font-weight: 500; }
.nav-drop a[aria-current="page"] { color: var(--brand-t); font-weight: 600; }
.hdr-cta .btn { padding: 10px 20px; font-size: 14.5px; }

.burger { display: none; width: 40px; height: 40px; margin-left: auto; border-radius: 10px;
  align-items: center; justify-content: center; }
.burger span, .burger span::before, .burger span::after {
  display: block; width: 18px; height: 2px; border-radius: 2px; background: var(--ink);
  transition: .22s var(--ease); }
.burger span { position: relative; }
.burger span::before, .burger span::after { content: ""; position: absolute; left: 0; }
.burger span::before { top: -6px; } .burger span::after { top: 6px; }
body.menu-open .burger span { background: transparent; }
body.menu-open .burger span::before { top: 0; transform: rotate(45deg); }
body.menu-open .burger span::after  { top: 0; transform: rotate(-45deg); }

.mobile-nav {
  position: fixed; inset: 98px 0 auto 0; z-index: 890;
  padding: 12px 20px 24px; background: #fff; border-bottom: 1px solid var(--line);
  transform: translateY(-10px); opacity: 0; visibility: hidden; transition: .24s var(--ease);
}
body.menu-open .mobile-nav { transform: none; opacity: 1; visibility: visible; }
.mobile-nav a { display: block; padding: 13px 2px; font-size: 16px; color: var(--ink);
  border-bottom: 1px solid var(--line-soft); }
.mobile-nav .mnav-sub { padding-left: 14px; font-size: 15px; color: var(--text-2); }
.mnav-label { padding: 14px 2px 4px; font-size: 11px; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-3); }
.mobile-nav .btn { width: 100%; margin-top: 18px; }

/* ── 7. Hero ───────────────────────────────────────────────────────────── */
/* On white, continuous with the header.
   The reference site's H1 is near-black on the white page — measured at
   oklch(0.145). This was a black band under a white header for most of the
   build, which cut the page in two at the very top and made the header look
   bolted on. */
.hero { background: var(--paper); color: var(--text); overflow: hidden; padding-block: 76px 88px; }
.hero::before {
  content: ""; position: absolute; inset: -30% -20% auto 30%; height: 620px; pointer-events: none;
  background: radial-gradient(38% 44% at 70% 30%, rgba(110,189,68,.13), transparent 70%);
  filter: blur(20px);
}
.hero-grid { position: relative; display: grid; grid-template-columns: 1.04fr .96fr;
  gap: 64px; align-items: center; }
.hero h1 { color: var(--ink); font-size: clamp(1.85rem, 3.3vw, 2.85rem); line-height: 1.14; letter-spacing: -.014em; }
.hero .cta-note { color: var(--text-3); }
.pill em { padding: 3px 9px; border-radius: var(--r-pill); background: var(--brand);
  color: #08210a; font-size: 11px; font-weight: 600; font-style: normal;
  letter-spacing: .04em; text-transform: uppercase; }

.phone-stage { position: relative; display: flex; justify-content: center; align-items: center; }
.hero-phone { position: relative; z-index: 2; width: 272px; padding: 9px;
  border-radius: 40px; background: linear-gradient(160deg,#3a3a3a,#0a0a0a 60%);
  box-shadow: var(--shadow-xl), inset 0 0 0 1px rgba(255,255,255,.14); }

/* A phone shows one screen, not the whole scrollable page.
   The Figma home export is 700x3146 — a 1:4.5 artboard. Rendered whole it
   came out 1150px tall and pushed the hero to 1333px, which is what made the
   section look broken. The frame is now a real device aspect ratio and the
   image is anchored to the top, exactly as it would be on the phone before
   anybody scrolls. */
.hero-phone .shot { position: relative; aspect-ratio: 9 / 19.5; border-radius: 32px;
  overflow: hidden; background: #fff; }
.hero-phone img { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: top center; border-radius: 0; }
/* the fold shading, so a cropped screen reads as "continues below" rather
   than "ends here" */
.hero-phone .shot::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 56px; pointer-events: none;
  background: linear-gradient(to top, rgba(255,255,255,.92), transparent); }

.push-card {
  position: absolute; z-index: 8; width: 250px; display: flex; gap: 10px; align-items: flex-start;
  padding: 12px 14px; border-radius: 16px; background: #fff;
  border: 1px solid var(--line); box-shadow: var(--shadow-lg); color: var(--ink);
}
.push-card i { width: 30px; height: 30px; border-radius: 9px; flex: none; display: grid;
  place-items: center; background: var(--black); }
.push-card i svg { width: 16px; height: 16px; color: var(--brand); }
.push-card b { display: block; font-size: 12.5px; font-weight: 600; }
.push-card p { margin-top: 2px; font-size: 12px; line-height: 1.4; color: var(--text-2); }
.push-card time { position: absolute; top: 12px; right: 14px; font-size: 10.5px; color: var(--text-3); }
/* Clear of the wordmark.
   The hero phone now shows a real client's app, and the strongest thing in it
   is the Arabic wordmark sitting beside the Latin one at the very top — which
   is precisely what this card was covering. It says "Arab, Gulf, Dubai"
   without a sentence, and it was behind a notification. Moved down past the
   logo strip and further left so the phone's own header reads clean. */
.push-a { top: 96px; left: -34px; animation: float 6s ease-in-out infinite; }
.push-b { bottom: 54px; right: -22px; width: 224px; animation: float 6s ease-in-out infinite 1.4s; }
@keyframes float { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }

/* ── 8. Sections ───────────────────────────────────────────────────────── */
.strip { padding-block: 30px; border-block: 1px solid var(--line-soft); }
.strip p { margin-bottom: 18px; font-size: 11.5px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-3); text-align: center; }
.strip ul { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 14px 44px; }
.strip li a { font-size: 17px; font-weight: 500; color: var(--text-2); transition: color .18s; }
.strip li a:hover { color: var(--ink); }

.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.stat { padding: 32px 28px; border-radius: var(--r); border: 1px solid var(--line); background: var(--paper); }
.stat .n { font-size: clamp(2.2rem, 3.4vw, 2.9rem); font-weight: 600; line-height: 1; letter-spacing: -.03em; color: var(--ink); }
.stat h3 { margin: 14px 0 6px; font-size: 1.02rem; }
.stat p { font-size: 14.5px; color: var(--text-2); line-height: 1.55; }
.n-plus { font-size: .48em; vertical-align: middle; margin: 0 .1em; opacity: .5; }

.prob-list { display: grid; gap: 12px; margin-top: 26px; }
.prob-list li { display: flex; gap: 12px; align-items: flex-start; font-size: 15.5px; }
.prob-list svg { width: 19px; height: 19px; flex: none; margin-top: 3px; color: var(--brand-t); }
.dark .prob-list svg, section.blk-dark .prob-list svg{ color: var(--brand); }

.tick-list { display: grid; gap: 11px; }
.tick-list li { display: flex; gap: 12px; align-items: flex-start; font-size: 15.5px; }
.tick-list svg { width: 18px; height: 18px; flex: none; margin-top: 3px; color: var(--brand-t); }

.quote-lg { margin: 44px auto 0; max-width: 24ch; text-align: center;
  font-size: clamp(1.4rem, 2.4vw, 1.9rem); font-weight: 500; line-height: 1.3; letter-spacing: -.012em; color: var(--ink); }
.quote-lg span { color: var(--brand-t); }
.dark .quote-lg, section.blk-dark .quote-lg{ color: #fff; }
.dark .quote-lg span, section.blk-dark .quote-lg span{ color: var(--brand); }

/* The leak diagram */
.leak { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.leak-col { padding: 20px 18px; border-radius: var(--r); background: var(--cream); }
.leak-col.is-app { background: var(--brand-50); }
.dark .leak-col, section.blk-dark .leak-col{ background: rgba(255,255,255,.05); }
.dark .leak-col.is-app, section.blk-dark .leak-col.is-app{ background: rgba(110,189,68,.14); }
.leak-h { margin-bottom: 14px; font-size: 11.5px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3); }
.leak-col.is-app .leak-h { color: var(--brand-t); }
.leak-steps { display: grid; gap: 6px; }
.leak-steps li { padding: 12px 13px; border-radius: var(--r-sm); background: rgba(255,255,255,.72); }
.leak-steps b { display: block; font-size: 14.5px; font-weight: 600; color: var(--ink); }
.leak-steps span { display: block; margin-top: 1px; font-size: 12.5px; color: var(--text-2); }
.leak-steps .bad  { background: #fdeceb; }
.leak-steps .bad b  { color: #b3261e; }
.leak-steps .good { background: #e8f6e4; }
.leak-steps .good b { color: #2b6b18; }

.loop { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; counter-reset: s; }
.loop li::before { content: counter(s); display: grid; place-items: center; width: 30px; height: 30px;
  margin-bottom: 14px; border-radius: 9px; background: var(--brand); color: #08210a;
  font-size: 14px; font-weight: 600; }
.loop b { display: block; margin-bottom: 5px; font-size: 15px; font-weight: 600; color: var(--ink); }
.loop p { font-size: 13.5px; color: var(--text-2); line-height: 1.5; }

.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; counter-reset: t; }
.steps li { counter-increment: t; position: relative; overflow: hidden; padding: 30px 26px;
  border-radius: var(--r); border: 1px solid var(--line); background: var(--paper); color: var(--text); }
.steps li::after { content: "0" counter(t); position: absolute; top: 14px; right: 20px; z-index: 0;
  font-size: 54px; font-weight: 600; line-height: 1; letter-spacing: -.04em; color: var(--cream-2); }
.steps li > * { position: relative; z-index: 1; }
.steps h3 { margin-bottom: 8px; font-size: 1.08rem; color: var(--ink); }
.steps p { font-size: 14.5px; color: var(--text-2); line-height: 1.55; }
.steps-lg { grid-template-columns: 1fr; gap: 14px; }
.steps-lg li { padding: 30px 32px; }
.steps-lg li::after { top: 16px; right: 26px; font-size: 66px; }
.steps-lg p { max-width: 70ch; font-size: 15px; color: var(--text); }
.step-when { margin-bottom: 7px; font-size: 12px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--brand-t); }
.step-you { display: inline-flex; align-items: center; gap: 8px; margin-top: 14px;
  padding: 7px 13px; border-radius: var(--r-pill); background: var(--cream);
  font-size: 13px; font-weight: 500; color: var(--ink); }
.step-you svg { color: var(--brand-t); }

.why { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 36px; }
.why li { display: flex; align-items: center; gap: 11px; padding: 13px 0;
  border-bottom: 1px solid rgba(255,255,255,.1); font-size: 15.5px; }
.why svg { width: 18px; height: 18px; flex: none; color: var(--brand); }

.sync-visual { padding: 26px 28px; border-radius: var(--r); background: var(--paper);
  border: 1px solid var(--line); color: var(--text); }
.sync-row { display: flex; align-items: center; gap: 14px; padding: 13px 0; border-bottom: 1px solid var(--line-soft); }
.sync-row:last-child { border-bottom: 0; }
.sync-row .tick { display: grid; place-items: center; width: 24px; height: 24px; flex: none;
  border-radius: 50%; background: var(--brand-50); color: var(--brand-t); }
.sync-row .tick svg { width: 13px; height: 13px; }
.sync-row b { font-size: 15px; font-weight: 500; color: var(--ink); }
.sync-row em { display: inline-flex; align-items: center; gap: 6px; margin-left: auto;
  font-size: 11.5px; font-weight: 600; font-style: normal; letter-spacing: .04em;
  text-transform: uppercase; color: var(--brand-t); }
.sync-row em::before { content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--brand); animation: pulse 2s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }

.reel-points { display: grid; grid-template-columns: 1fr 1fr; gap: 11px 26px; margin-top: 28px; }
.reel-points li { display: flex; align-items: center; gap: 10px; font-size: 15px; }
.reel-points svg { width: 17px; height: 17px; flex: none; color: var(--brand); }

.feat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); gap: 10px; }
.feat { display: flex; align-items: center; gap: 12px; padding: 15px 17px; border-radius: var(--r-sm);
  border: 1px solid var(--line); font-size: 14.5px; font-weight: 500; transition: border-color .18s; }
.feat:hover { border-color: var(--ink); }
.feat svg { width: 18px; height: 18px; flex: none; color: var(--brand-t); }
.feat-group { margin-bottom: 40px; }
.feat-group:last-child { margin-bottom: 0; }
.feat-group-h { margin-bottom: 16px; font-size: 12px; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-3); }
.feat-why { display: flex; gap: 10px; align-items: flex-start; margin-top: 22px;
  padding: 14px 16px; border-radius: var(--r-sm); background: var(--brand-50);
  font-size: 14.5px; font-weight: 500; color: var(--ink); }
.feat-why svg { color: var(--brand-t); margin-top: 2px; }


/* ── 9. Cards ──────────────────────────────────────────────────────────── */
.card { padding: 26px; border-radius: var(--r); border: 1px solid var(--line); background: var(--paper);
  color: var(--text); transition: border-color .2s, transform .2s var(--ease); }
.card:hover { border-color: var(--ink); transform: translateY(-2px); }
.card h3 { margin-bottom: 8px; font-size: 1.05rem; }
.card p { font-size: 14.5px; line-height: 1.55; color: var(--text-2); }
.card p strong { color: var(--brand-t); font-weight: 600; }
.ic { display: grid; place-items: center; width: 40px; height: 40px; margin-bottom: 16px;
  border-radius: var(--r-sm); background: var(--brand-50); color: var(--brand-t); }
.ic svg { width: 20px; height: 20px; }


/* ── 10. Phone UI (the drawn mock in the reels block) ──────────────────── */
.phone { position: relative; width: 274px; flex: none; padding: 9px; border-radius: 40px;
  background: linear-gradient(160deg,#3a3a3a,#0a0a0a 60%);
  box-shadow: var(--shadow-xl), inset 0 0 0 1px rgba(255,255,255,.14); }
.phone-screen { position: relative; display: flex; flex-direction: column; height: 560px;
  border-radius: 32px; overflow: hidden; background: #fff; color: var(--ink); font-size: 12px; }
.phone-notch { position: absolute; top: 9px; left: 50%; transform: translateX(-50%);
  width: 98px; height: 24px; border-radius: 0 0 14px 14px; background: #0a0a0a; z-index: 6; }
.ap-reel { position: relative; height: 100%; padding: 16px; display: flex; flex-direction: column;
  justify-content: flex-end; color: #fff; background: linear-gradient(170deg,#3a2f3d,#1a1520 70%); }
.ap-reel .rail { position: absolute; right: 14px; bottom: 110px; display: flex; flex-direction: column;
  gap: 16px; align-items: center; }
.ap-reel .rail svg { width: 21px; height: 21px; }
.ap-reel .buy { display: flex; align-items: center; gap: 9px; padding: 9px; border-radius: 11px;
  background: rgba(255,255,255,.15); backdrop-filter: blur(8px); border: 1px solid rgba(255,255,255,.2); }
.ap-reel .buy i { width: 36px; height: 36px; flex: none; border-radius: 8px;
  background: linear-gradient(150deg,#e8ddd4,#c9b6a6); }
.ap-reel .buy b { display: block; font-size: 10px; font-weight: 600; }
.ap-reel .buy small { font-size: 9px; opacity: .8; }
.ap-reel .buy span { margin-left: auto; padding: 6px 12px; border-radius: var(--r-pill);
  background: #fff; color: var(--ink); font-size: 9px; font-weight: 600; }


/* ── 11. Calculator ────────────────────────────────────────────────────── */
.calc { display: grid; grid-template-columns: 1fr 1fr; border-radius: var(--r);
  overflow: hidden; background: var(--paper); border: 1px solid var(--line); }
.calc-in  { padding: 34px 32px; }
.calc-out { padding: 34px 32px; background: var(--black); color: #cfcfcf; display: flex; flex-direction: column; }
.calc-in h3 { margin-bottom: 16px; font-size: 12px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3); }

.fld { display: block; margin-bottom: 18px; }
.fld-l { display: block; margin-bottom: 7px; font-size: 14px; font-weight: 500; color: var(--ink); }
.fld-hint { display: block; margin-top: 1px; font-size: 12px; font-weight: 400; color: var(--text-3); }
.fld-w { display: flex; align-items: center; gap: 11px; }
.fld-u { flex: none; font-size: 12.5px; font-weight: 600; color: var(--text-3); }
.fld-help { margin-bottom: 14px; font-size: 13px; line-height: 1.5; color: var(--text-2); }

.calc input[type="number"] {
  flex: 1; width: 100%; padding: 11px 13px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--cream);
  font: 500 15.5px var(--sans); color: var(--ink);
}
.calc input[type="number"]:focus { outline: none; border-color: var(--brand); background: #fff; }
.calc input[type="range"] { flex: 1; -webkit-appearance: none; appearance: none;
  height: 4px; border-radius: 4px; background: var(--cream-2); cursor: pointer; }
.calc input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none;
  width: 19px; height: 19px; border-radius: 50%; background: var(--brand); border: 3px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.25); }
.calc input[type="range"]::-moz-range-thumb { width: 19px; height: 19px; border-radius: 50%;
  background: var(--brand); border: 3px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.25); }
.calc output { flex: none; min-width: 48px; text-align: right; font-size: 14.5px;
  font-weight: 600; color: var(--brand-t); font-variant-numeric: tabular-nums; }

.calc-lab { font-size: 11.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: #8a8a8a; }
.calc-big { margin: 8px 0 22px; font-size: clamp(2rem, 3.6vw, 2.8rem); font-weight: 600;
  line-height: 1.05; letter-spacing: -.03em; color: #fff; font-variant-numeric: tabular-nums; }
.calc-big span { color: var(--brand); }
.calc-rows { margin: 0 0 auto; display: grid; }
.calc-rows > div { display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
  padding: 12px 0; border-bottom: 1px solid rgba(255,255,255,.11); }
.calc-rows dt { font-size: 13.5px; color: #a0a0a0; }
.calc-rows dd { margin: 0; font-size: 15px; font-weight: 600; color: #fff;
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.calc-rows dd small { display: block; margin-top: 1px; font-size: 11px; font-weight: 400;
  color: var(--brand); text-align: right; }
.calc-rows .is-free dd { color: var(--brand); }
.calc-fine { margin-top: 20px; font-size: 12.5px; line-height: 1.55; color: #8a8a8a; }


/* ── 12. Gallery and case studies ──────────────────────────────────────── */
.gallery { display: flex; gap: 20px; padding: 8px var(--gutter) 28px; overflow-x: auto;
  scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; }
.gallery::-webkit-scrollbar { height: 6px; }
.gallery::-webkit-scrollbar-track { background: var(--line-soft); border-radius: 6px; }
.gallery::-webkit-scrollbar-thumb { background: var(--line); border-radius: 6px; }
.gal { flex: none; width: 222px; scroll-snap-align: center; text-align: center; }
.gal-frame { padding: 7px; border-radius: 30px; background: var(--black);
  box-shadow: var(--shadow-lg); transition: transform .3s var(--ease); }
.gal-frame img { width: 100%; height: auto; border-radius: 24px; }
.gal:hover .gal-frame { transform: translateY(-6px); }
.gal figcaption { margin-top: 12px; font-size: 13px; font-weight: 500; color: var(--text-2); }

.shot-frame { display: inline-block; max-width: 288px; padding: 8px; border-radius: 34px;
  background: var(--black); box-shadow: var(--shadow-lg); }
.shot-frame img { width: 100%; height: auto; border-radius: 27px; }

.case-screens { display: flex; gap: 12px; align-items: flex-start; }
.case-screens .case-shot { flex: 1 1 0; min-width: 0; border-radius: 20px; overflow: hidden;
  background: var(--cream); box-shadow: var(--shadow-lg); }
.case-screens .case-shot img { width: 100%; height: auto; }
.case-screens .case-shot:nth-child(2) { margin-top: 22px; }
.case-screens .case-shot:nth-child(3) { margin-top: 44px; }
.case-screens .case-shot:nth-child(n+4) { display: none; }
.case-live { margin-top: 5px; font-size: 13px; font-weight: 500; color: var(--brand-t); }
.case-says { margin: 22px 0 0; padding: 16px 18px; border-radius: var(--r-sm);
  background: var(--cream); border-left: 3px solid var(--brand);
  font-size: 14.5px; line-height: 1.55; font-style: italic; color: var(--ink); }
.case-says cite { display: block; margin-top: 8px; font-size: 12px; font-style: normal;
  font-weight: 500; color: var(--text-3); }

.cases { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.case { display: flex; flex-direction: column; gap: 14px; padding: 26px;
  border-radius: var(--r); border: 1px solid var(--line); }
.case-head { display: flex; align-items: center; gap: 13px; }
.case-logo { display: grid; place-items: center; width: 46px; height: 46px; flex: none;
  border-radius: 13px; color: #fff; font-size: 16px; font-weight: 600; }
.case .dom { font-size: 13px; color: var(--text-3); }

.stores { display: flex; flex-wrap: wrap; gap: 9px; margin-top: auto; }
.store { display: inline-flex; align-items: center; gap: 7px; padding: 9px 15px; border-radius: var(--r-sm);
  background: var(--ink); color: #fff; font-size: 13px; font-weight: 500; transition: background .18s; }
.store:hover { background: #000; }
.store svg { width: 15px; height: 15px; flex: none; }
.store.alt { background: var(--cream); color: var(--ink); }
.store.alt:hover { background: var(--cream-2); }


/* ── 13. Pages ─────────────────────────────────────────────────────────── */
.crumbs { padding-top: 20px; font-size: 13px; color: var(--text-3); }
.crumbs .wrap { display: flex; gap: 8px; align-items: center; }
.crumbs a:hover { color: var(--brand-t); }
.crumbs span[aria-current] { color: var(--ink); }
.page-head { padding-block: 64px 56px; }
.page-head .cta-row { margin-top: 28px; }

.call-steps { counter-reset: c; display: grid; gap: 15px; }
.call-steps li { counter-increment: c; display: grid; grid-template-columns: 30px 1fr; gap: 13px; align-items: start; }
.call-steps li::before { content: counter(c); display: grid; place-items: center; width: 28px; height: 28px;
  border-radius: 8px; background: var(--ink); color: #fff; font-size: 13px; font-weight: 600; }
/* The li is a two-column grid holding THREE items — ::before, <b> and
   <span>. Auto-placement dropped the span into row two of the 30px column,
   where its text wrapped one character per line and the item grew to 300px.
   Three of them made the section 1,331px tall for six lines of copy.
   Pinning both text elements to column two is the whole fix. */
.call-steps b, .call-steps span { grid-column: 2; }
.call-steps b { display: block; font-size: 15.5px; font-weight: 600; color: var(--ink); }
.call-steps span { display: block; margin-top: 1px; font-size: 14px; color: var(--text-2); }
.contact-direct { margin-top: 30px; padding-top: 24px; border-top: 1px solid var(--line); }
.form-card { padding: 30px; border-radius: var(--r); background: #fff; box-shadow: var(--shadow-lg); }
.form-note { display: flex; gap: 9px; align-items: flex-start; margin-top: 18px; padding: 13px 15px;
  border-radius: var(--r-sm); background: var(--warm-50); font-size: 13px; line-height: 1.5; color: #8a4a12; }
.form-slot:empty { display: none; }
.form-slot input[type="text"], .form-slot input[type="email"], .form-slot input[type="tel"],
.form-slot textarea, .form-slot select {
  width: 100%; margin-bottom: 12px; padding: 12px 14px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--cream); font: 400 15.5px var(--sans); color: var(--ink); }
.form-slot input:focus, .form-slot textarea:focus { outline: none; border-color: var(--brand); background: #fff; }
.form-slot input[type="submit"] { width: auto; padding: 13px 28px; border: 0; border-radius: var(--r-pill);
  background: var(--brand); color: #08210a; font-weight: 600; cursor: pointer; }

.faq { max-width: 800px; margin-inline: auto; }
.qa { border-bottom: 1px solid var(--line); }
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after { content: "+"; flex: none; font-size: 22px; font-weight: 300; line-height: 1;
  color: var(--text-3); transition: transform .22s var(--ease); }
.qa[open] summary::after { content: "−"; }
.qa[open] summary { color: var(--brand-t); }
.qa .ans { padding: 0 48px 22px 0; font-size: 15.5px; line-height: 1.62; color: var(--text-2); }

.final { background: var(--black); }
.final .cta-row { margin-top: 28px; }

.prose { font-size: 17px; line-height: 1.7; color: var(--text); }
.prose > * + * { margin-top: 1.1em; }
.prose h2 { margin-top: 1.8em; font-size: 1.6rem; }
.prose h3 { margin-top: 1.6em; font-size: 1.24rem; }
.prose a { color: var(--brand-t); text-decoration: underline; text-underline-offset: 3px; }
.prose ul li { list-style: disc; margin-left: 1.2em; margin-bottom: .4em; }
.prose ol li { list-style: decimal; margin-left: 1.2em; margin-bottom: .4em; }
.prose img { border-radius: var(--r); }
.prose blockquote { margin-left: 0; padding-left: 22px; border-left: 3px solid var(--brand);
  font-size: 1.12em; font-style: italic; }
.post-thumb { display: block; margin: -26px -26px 18px; overflow: hidden; }
.post-thumb img { width: 100%; height: 180px; object-fit: cover; }
.post-meta { margin-bottom: 7px; font-size: 12px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-3); }
.post-more { display: inline-flex; align-items: center; gap: 6px; font-size: 14.5px;
  font-weight: 500; color: var(--brand-t); }
.post-more svg { width: 16px; height: 16px; transition: transform .2s var(--ease); }
.post-more:hover svg { transform: translateX(3px); }
.page-hero { margin-bottom: 32px; border-radius: var(--r); overflow: hidden; }
.post-foot { margin-top: 40px; padding-top: 24px; border-top: 1px solid var(--line); }
.post-nav { display: flex; justify-content: space-between; gap: 18px; margin-top: 18px;
  font-size: 14.5px; font-weight: 500; }
.post-nav a { color: var(--brand-t); }
.pager { display: flex; justify-content: center; margin-top: 40px; }
.pager .page-numbers { display: inline-grid; place-items: center; min-width: 40px; height: 40px;
  margin: 0 3px; padding: 0 11px; border-radius: var(--r-sm); border: 1px solid var(--line);
  font-size: 14.5px; font-weight: 500; color: var(--text-2); }
.pager .page-numbers.current { background: var(--ink); border-color: var(--ink); color: #fff; }
.searchform { display: flex; gap: 9px; }
.searchform input[type="search"] { flex: 1; padding: 12px 15px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--cream); font: 400 15.5px var(--sans); }


/* ── 14. Footer + WhatsApp ─────────────────────────────────────────────── */
.ftr { padding-block: 56px 28px; background: var(--black); color: #8a8a8a; font-size: 14.5px; }
.ftr-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 40px;
  padding-bottom: 38px; border-bottom: 1px solid rgba(255,255,255,.1); }
.ftr .logo { margin-bottom: 16px; }
.ftr .logo-mark { height: 60px; }
.ftr p { max-width: 34ch; line-height: 1.6; }
.ftr .ftr-h { margin-bottom: 16px; font-size: 12px; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: #fff; }
.ftr li { margin-bottom: 10px; }
.ftr a:hover { color: #fff; }
.ftr-btm { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px;
  padding-top: 22px; font-size: 13px; }

.wa { position: fixed; right: 20px; bottom: 20px; z-index: 800; display: inline-flex;
  align-items: center; gap: 9px; padding: 12px 18px 12px 14px; border-radius: var(--r-pill);
  background: #25d366; color: #06340f; font-size: 14px; font-weight: 600;
  box-shadow: 0 6px 22px rgba(37,211,102,.4); transition: transform .18s var(--ease); }
.wa:hover { transform: translateY(-2px); }
.wa svg { width: 20px; height: 20px; fill: currentColor; }


/* ── 15. Motion + responsive ───────────────────────────────────────────── */
.rv { opacity: 0; transform: translateY(16px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
.rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
  html { scroll-behavior: auto; }
  .rv { opacity: 1; transform: none; }
}

@media (max-width: 1080px) {
  .hero-grid { grid-template-columns: 1fr; gap: 48px; }
  .loop, .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .ftr-grid { grid-template-columns: 1fr 1fr; gap: 32px; }
}
@media (max-width: 860px) {
  :root { --gutter: 20px; }
  .nav, .hdr-cta { display: none; }
  .burger { display: flex; }
  .pad { padding-block: 56px; } .pad-sm { padding-block: 40px; }
  section.blk { margin: 10px; }
  .split, .split.wide-l, .grid-2, .grid-3, .stats, .steps, .cases, .why, .reel-points, .leak, .calc { grid-template-columns: 1fr; }
  .split { gap: 40px; }
  .split.is-flipped > *:first-child { order: 0; }
  .page-head { padding-block: 40px 34px; }
  .case-screens .case-shot:nth-child(2), .case-screens .case-shot:nth-child(3) { margin-top: 0; }
  .case-screens .case-shot:nth-child(n+3) { display: none; }
  .qa .ans { padding-right: 0; }
  .push-a { left: -6px; top: 16px; width: 216px; }
  .push-b { right: -6px; bottom: 40px; width: 200px; }
  .steps-lg li { padding: 24px 20px; }
}
@media (max-width: 520px) {
  .btn { width: 100%; }
  .cta-row { flex-direction: column; }
  .loop, .grid-4, .feat-grid { grid-template-columns: 1fr; }
  .gal { width: 190px; }
  .stores { flex-direction: column; }
  .store { justify-content: center; }
}

@media print {
  .hdr, .mobile-nav, .wa, .final, .btn, .phone-stage { display: none !important; }
  body, .dark, .hero { background: #fff !important; color: #000 !important; }
}

/* Timeline + plain list, used on the About page */
.timeline { display: grid; gap: 0; max-width: 780px; margin-inline: auto; }
.timeline li { display: grid; grid-template-columns: 92px 1fr; gap: 20px;
  padding: 22px 0; border-bottom: 1px solid var(--line); }
.timeline li:last-child { border-bottom: 0; }
.tl-year { font-size: 20px; font-weight: 600; color: var(--brand-t); letter-spacing: -.02em; }
.timeline b { display: block; margin-bottom: 5px; font-size: 16px; font-weight: 600; color: var(--ink); }
.timeline p { font-size: 14.5px; line-height: 1.55; color: var(--text-2); }
.plain-list { display: grid; gap: 22px; margin-top: 26px; }
.plain-list b { display: block; margin-bottom: 6px; font-size: 16.5px; font-weight: 600; }
.plain-list p { font-size: 15px; line-height: 1.6; }
@media (max-width: 640px) { .timeline li { grid-template-columns: 1fr; gap: 6px; } }

/* The strip is a block like everything else, so the page rhythm does not
   break in the one place a visitor first looks for proof. */
.strip.blk { padding-block: 28px; border: 0; }
.final.blk { margin-bottom: 16px; }
/* The footer closes the page, so it keeps its top corners and loses the rest. */
.ftr { margin: 16px 16px 0; border-radius: var(--r-lg) var(--r-lg) 0 0; }
@media (max-width: 860px) { .ftr { margin: 10px 10px 0; } }

/* Feature groups follow the purchase, so the heading carries its number. */
.feat-group-h { display: flex; align-items: center; gap: 10px; font-size: 13px;
  letter-spacing: .04em; text-transform: none; color: var(--ink); font-weight: 600; }
.feat-group-h::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* ── Customization: one screen, several ways ──────────────────────────── */
.opt-head { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: end; margin-bottom: 40px; }
.opt-row { display: flex; gap: 16px; overflow-x: auto; padding-bottom: 20px; scroll-snap-type: x mandatory; }
.opt-row::-webkit-scrollbar { height: 6px; }
.opt-row::-webkit-scrollbar-track { background: rgba(0,0,0,.05); border-radius: 6px; }
.opt-row::-webkit-scrollbar-thumb { background: rgba(0,0,0,.18); border-radius: 6px; }
.opt { flex: none; width: 208px; scroll-snap-align: start; text-align: center; }
.opt-frame { border-radius: 22px; overflow: hidden; background: #fff;
  border: 1px solid var(--line); box-shadow: var(--shadow); transition: transform .28s var(--ease); }
.opt-frame img { width: 100%; height: auto; display: block; }
.opt:hover .opt-frame { transform: translateY(-5px); box-shadow: var(--shadow-lg); }
.opt figcaption { margin-top: 11px; font-size: 13px; font-weight: 500; color: var(--text-2); }
@media (max-width: 860px) {
  .opt-head { grid-template-columns: 1fr; gap: 18px; margin-bottom: 28px; }
  .opt { width: 168px; }
}

/* ── Typographic balance ───────────────────────────────────────────────
   Three faults were making the copy read as unbalanced:

   1. Headings were broken with hard <br> at the point that looked right on
      one screen width and wrong on every other. Removed from the markup;
      the browser now balances the lines itself, per viewport.
   2. No measure was set, so a paragraph in a full-width block ran to about
      120 characters — roughly twice the length an eye tracks comfortably.
   3. Nothing prevented a one-word last line, and a heading ending in a
      single orphaned word is the thing that reads as "unfinished".         */

h1, h2, h3, .h-xl, .h-lg, .h-md, .quote-lg {
  text-wrap: balance;          /* the browser evens the lines */
  max-width: 20ch;
}
.h-md, h3 { max-width: 28ch; }
.sec-head.center h2 { margin-inline: auto; max-width: 22ch; }

p, li { text-wrap: pretty; }   /* no single-word last lines */
.lede { max-width: 62ch; }
.sec-head.center .lede { margin-inline: auto; }
.card p, .stat p, .steps p, .loop p { max-width: 46ch; }
.prose p, .qa .ans { max-width: 72ch; }

/* One vertical scale, so spacing is a decision rather than an accident. */
.sec-head { margin-bottom: 44px; }
.sec-head .eyebrow { margin-bottom: 14px; }
.sec-head h2 + .lede { margin-top: 16px; }
.split > div > .lede { margin-top: 18px; }
.split > div > .cta-row { margin-top: 26px; }
.page-head .h-xl { max-width: 19ch; }
.page-lede { margin-top: 18px; }

/* Optical alignment: uppercase eyebrows sit slightly low against a cap-height
   heading, and the rule beside them needs to sit on the x-height. */
.eyebrow { line-height: 1; }
.eyebrow::before { position: relative; top: -1px; }

/* Numerals in figures should not jump as they change. */
.stat .n, .calc-big, .calc-rows dd, .tl-year, output { font-variant-numeric: tabular-nums; }

/* ── Terms & conditions ───────────────────────────────────────────────── */
.tldr h2 { text-align: center; margin-inline: auto; }
.tldr .card a { color: var(--brand-t); text-decoration: underline; text-underline-offset: 2px; }
.terms-layout { display: grid; grid-template-columns: 232px 1fr; gap: 56px; align-items: start; }
.terms-toc { position: sticky; top: 116px; }
.terms-toc-h { margin-bottom: 12px; font-size: 12px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3); }
.terms-toc ol { display: grid; gap: 1px; }
.terms-toc a { display: grid; grid-template-columns: 26px 1fr; gap: 6px; padding: 7px 8px;
  border-radius: 8px; font-size: 13.5px; color: var(--text-2); line-height: 1.35; }
.terms-toc a span { color: var(--text-3); font-variant-numeric: tabular-nums; }
.terms-toc a:hover { background: var(--cream); color: var(--ink); }
.terms-body { max-width: 720px; }
.clause { padding-bottom: 40px; margin-bottom: 40px; border-bottom: 1px solid var(--line); scroll-margin-top: 102px; }
.clause:last-of-type { border-bottom: 0; }
.clause h2 { display: grid; grid-template-columns: 44px 1fr; gap: 10px; align-items: baseline; max-width: none; }
.clause-n { font-size: 15px; font-weight: 600; color: var(--brand-t); font-variant-numeric: tabular-nums; }
.clause-lead { margin-top: 14px; font-size: 16px; line-height: 1.6; color: var(--text); }
.clause-list { margin-top: 16px; }
.clause-list li { font-size: 15px; }
.clause-note { margin-top: 16px; padding: 14px 16px; border-radius: var(--r-sm);
  background: var(--cream); font-size: 14.5px; line-height: 1.6; color: var(--text); }
.clause-two { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 18px; }
.clause-two > div { padding: 18px 20px; border-radius: var(--r-sm); }
.clause-two .is-yes { background: var(--brand-50); }
.clause-two .is-no  { background: var(--cream); }
.clause-two h3 { margin-bottom: 10px; font-size: 13px; letter-spacing: .05em; text-transform: uppercase; }
.clause-two .is-yes h3 { color: var(--brand-t); }
.clause-two .is-no h3  { color: var(--text-3); }
.clause-two li { padding: 4px 0 4px 16px; position: relative; font-size: 14.5px; line-height: 1.5; }
.clause-two li::before { content: ""; position: absolute; left: 0; top: 12px;
  width: 6px; height: 1.5px; background: currentColor; opacity: .4; }
.clause-subs { margin-top: 22px; display: grid; gap: 20px; }
.sub { padding: 20px 22px; border-radius: var(--r-sm); border: 1px solid var(--line); }
.sub h3 { display: grid; grid-template-columns: 52px 1fr; gap: 8px; align-items: baseline;
  margin-bottom: 10px; font-size: 15.5px; max-width: none; }
.sub h3 span { font-size: 13px; color: var(--brand-t); font-variant-numeric: tabular-nums; }
.sub li { padding: 4px 0 4px 16px; position: relative; font-size: 14.5px; line-height: 1.55; color: var(--text-2); }
.sub li::before { content: ""; position: absolute; left: 0; top: 12px; width: 6px; height: 1.5px;
  background: var(--text-3); }
.sub-note { margin-top: 10px; font-size: 13.5px; font-style: italic; color: var(--text-3); }
.terms-foot { margin-top: 8px; font-size: 14px; color: var(--text-3); }
@media (max-width: 900px) {
  .terms-layout { grid-template-columns: 1fr; gap: 32px; }
  .terms-toc { position: static; }
  .terms-toc ol { display: flex; flex-wrap: wrap; gap: 6px; }
  .terms-toc a { padding: 6px 11px; border: 1px solid var(--line); }
  .clause-two { grid-template-columns: 1fr; }
}

/* ── Features page: named groups, list rows ───────────────────────────── */
.feat-nav { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }

.fgroup { display: grid; grid-template-columns: 330px 1fr; gap: 64px; align-items: start; }
.fgroup-n { font-size: 13px; font-weight: 600; color: var(--brand-t);
  font-variant-numeric: tabular-nums; margin-bottom: 10px; }
.fgroup-head h2 { max-width: 14ch; }
.fgroup-head .lede { margin-top: 14px; font-size: 15px; }

.fitems { display: grid; gap: 2px; }
.fitems li { display: grid; grid-template-columns: 44px 1fr; gap: 16px;
  padding: 22px 20px; border-radius: var(--r); transition: background .18s; }
.fitems li:hover { background: var(--cream); }
.fitem-ic { display: grid; place-items: center; width: 38px; height: 38px;
  border-radius: var(--r-sm); background: var(--brand-50); color: var(--brand-t); }
.fitem-ic svg { width: 19px; height: 19px; }
.fitems h3 { display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin-bottom: 6px; font-size: 16.5px; max-width: none; }
.fitems p { font-size: 14.5px; line-height: 1.6; color: var(--text-2); max-width: 62ch; }
.fitem-seen { padding: 3px 9px; border-radius: var(--r-pill); background: var(--brand-50);
  font-size: 11.5px; font-weight: 600; color: var(--brand-t); white-space: nowrap; }
.fitem-seen:hover { background: var(--brand); color: #08210a; }

@media (max-width: 960px) {
  .fgroup { grid-template-columns: 1fr; gap: 26px; }
  .fgroup-head { position: static; }
  .fgroup-head h2 { max-width: none; }
  .fitems li { padding: 18px 14px; grid-template-columns: 38px 1fr; gap: 13px; }
}

/* ── Home: client logo row ────────────────────────────────────────────── */
.logos { padding-block: 34px; border-bottom: 1px solid var(--line-soft); }
.logos-lab { margin-bottom: 20px; text-align: center; font-size: 11.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.logos-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 44px; }
.logos-row a { display: block; text-align: center; padding: 6px 4px; }
.logos-name { display: block; font-size: 17px; font-weight: 600; color: var(--text-2);
  letter-spacing: -.015em; transition: color .16s; }
.logos-row a:hover .logos-name { color: var(--ink); }
.logos-sec { display: block; margin-top: 2px; font-size: 11.5px; color: var(--text-3); }

/* ── Home: hero standfirst ────────────────────────────────────────────── */
.hero-sub { margin-top: 18px; font-size: clamp(1.05rem, 1.5vw, 1.25rem); font-weight: 500;
  color: var(--ink); max-width: 34ch; }

/* ── Website vs app ───────────────────────────────────────────────────── */
.vs { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.vs-col { padding: 22px 20px; border-radius: var(--r); background: var(--cream); }
.vs-col.is-app { background: var(--brand-50); }
.vs-col h3 { font-size: 15px; margin-bottom: 4px; }
.vs-col.is-app .vs-role { color: var(--brand-t); }
.vs-col ul { display: grid; gap: 9px; }
.vs-col li { position: relative; padding-left: 15px; font-size: 14px; line-height: 1.5; color: var(--text-2); }
.vs-col li::before { content: ""; position: absolute; left: 0; top: 9px; width: 6px; height: 1.5px;
  background: var(--text-3); }
.vs-col .is-cost { color: #a3271f; font-weight: 500; }
.vs-col .is-free { color: var(--brand-t); font-weight: 600; }

/* ── Small tick lists inside cards ────────────────────────────────────── */
.mini-ticks { margin-top: 14px; display: grid; gap: 7px; }
.mini-ticks li { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--text-2); }
.mini-ticks svg { width: 14px; height: 14px; flex: none; color: var(--brand-t); }

/* ── Growth loop: single-line steps ───────────────────────────────────── */
.loop li b { font-size: 14.5px; line-height: 1.4; }
.loop li { padding: 20px 18px; }

/* ── Why TicApp grid ──────────────────────────────────────────────────── */
.why-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 24px; }
.why-grid li { display: flex; align-items: center; gap: 10px; padding: 12px 0;
  border-bottom: 1px solid var(--line-soft); font-size: 14.5px; font-weight: 500; }
.why-grid svg { width: 17px; height: 17px; flex: none; color: var(--brand-t); }

/* ── Closing points ───────────────────────────────────────────────────── */
.closing-points { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 26px; margin-top: 24px; }
.closing-points li { display: flex; align-items: center; gap: 8px; font-size: 14.5px; color: #d4d4d4; }
.closing-points svg { width: 16px; height: 16px; flex: none; color: var(--brand); }

/* ── Notes under a stats band ─────────────────────────────────────────── */
.stats-src { margin-top: 26px; text-align: center; font-size: 13.5px; color: var(--text-3);
  max-width: 60ch; margin-inline: auto; }

/* A design export is a flat artboard, not a device photo — no black bezel. */
.gal-frame.is-design { padding: 0; background: #fff; border: 1px solid var(--line); }
.gal-frame.is-design img { border-radius: 26px; }

@media (max-width: 860px) {
  .vs, .why-grid { grid-template-columns: 1fr; }
  .logos-row { gap: 8px 26px; }
  .logos-name { font-size: 15px; }
}

/* --text-3 is a 3.88:1 grey on the cream block — fine on white, not on cream. */
.blk-cream .vs-role, .blk-cream .stats-src,
.blk-lilac .vs-role, .blk-lilac .stats-src,
.blk-cream .gal figcaption, .blk-cream .logos-sec { color: var(--text-2); }
.vs-role { color: var(--text-2); }

/* ── Sticky in-page navigation ────────────────────────────────────────
   A jump list that scrolls away is only usable from the top of the page,
   which is the one place a reader does not need it. It sticks under the
   header instead, and the current group highlights itself as you pass it. */
.feat-nav-wrap {
  position: sticky; top: 98px; z-index: 500;
  background: rgba(255,255,255,.92);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--line);
  margin: 0 16px; border-radius: 0;
}
.feat-nav { display: flex; gap: 6px; padding: 12px 0; overflow-x: auto;
  justify-content: flex-start; scrollbar-width: none; }
.feat-nav::-webkit-scrollbar { display: none; }
.feat-nav a { flex: none; padding: 8px 15px; border-radius: var(--r-pill);
  background: transparent; border: 1px solid var(--line);
  font-size: 13.5px; font-weight: 500; color: var(--text-2); white-space: nowrap;
  transition: border-color .16s, color .16s, background .16s; }
.feat-nav a:hover { border-color: var(--ink); color: var(--ink); }
.feat-nav a[aria-current="true"] { background: var(--ink); border-color: var(--ink); color: #fff; }

/* Each group must clear the two sticky bars when jumped to. */
section[id^="g-"] { scroll-margin-top: 156px; }
.fgroup-head { top: 164px; }

@media (max-width: 860px) {
  .feat-nav-wrap { top: 68px; margin: 0 10px; }
  .feat-nav { padding: 10px 0; }
  section[id^="g-"] { scroll-margin-top: 116px; }
}
.contact-lab { color: var(--text-2); }

/* Footer credential line */
.ftr-badge { display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px;
  border-radius: var(--r-pill); background: rgba(110,189,68,.14);
  font-size: 13px; font-weight: 500; color: var(--brand); }
.ftr-badge svg { width: 15px; height: 15px; flex: none; }

/* ── Hero rhythm ──────────────────────────────────────────────────────
   Three stacked paragraphs at three sizes read as a wall. The promise is
   the H1, the standfirst is one line at reading weight, and the body sits
   quieter beneath it — a clear first, second, third rather than three
   things competing at once. */
.hero-copy { max-width: 30rem; }
.hero h1 { max-width: 22ch; }
.hero-sub { margin-top: 16px; font-size: 1.12rem; font-weight: 500;
  line-height: 1.45; color: var(--ink); max-width: 30ch; }
.hero .lede { margin-top: 12px; font-size: 1rem; line-height: 1.62;
  color: var(--text-2); max-width: 42ch; }
.hero .cta-row { margin-top: 28px; }
.hero .cta-note { margin-top: 16px; }
.pill { margin-bottom: 22px; }

@media (min-width: 1081px) {
  .hero-grid { gap: 72px; }
  .hero { padding-block: 68px 84px; }
}

/* ── Feature group screenshots ────────────────────────────────────────
   A features page of pure text reads as unfinished, and every reference
   site puts a visual beside each group.

   These sat in a 190px strip inside a 1,152px row because .fgroup is a
   two-column grid and this was its third child — the same auto-placement
   trap that put the feature list in the sticky heading column. Spanning
   the full width is the fix in both cases. */
.fgroup > .fshots { grid-column: 1 / -1; }
.fshots { display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 18px; margin-top: 34px; padding-top: 30px;
  border-top: 1px solid var(--line-soft); }
.fshots::-webkit-scrollbar { display: none; }
.fshot { text-align: center; }
.fshot-frame { position: relative; aspect-ratio: 9 / 16; border-radius: 22px;
  overflow: hidden; background: var(--black); padding: 6px;
  box-shadow: var(--shadow); transition: transform .28s var(--ease), box-shadow .28s var(--ease); }
.fshot-frame img { width: 100%; height: 100%; object-fit: cover; object-position: top center;
  border-radius: 17px; }
.fshot:hover .fshot-frame { transform: translateY(-5px); box-shadow: var(--shadow-lg); }
.fshot.is-design .fshot-frame { background: #fff; border: 1px solid var(--line); padding: 0; }
.fshot.is-design .fshot-frame img { border-radius: 21px; }
.fshot figcaption { margin-top: 10px; font-size: 12.5px; font-weight: 500; color: var(--text-2); }
@media (max-width: 1080px) { .fshots { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 760px)  { .fshots { grid-template-columns: repeat(2, 1fr); gap: 12px; margin-top: 26px; } }
.contact-fine { margin-top: 14px; font-size: 13.5px; color: var(--text-2); }

/* ── Demo request form ────────────────────────────────────────────────── */
.form-intro { font-size: 14.5px; margin: 8px 0 22px; }
.tform { display: grid; gap: 14px; }
.tf-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.tf { display: block; }
.tf > span { display: flex; align-items: center; gap: 7px; margin-bottom: 6px;
  font-size: 13.5px; font-weight: 500; color: var(--ink); }
.tf > span em { font-style: normal; font-size: 11px; font-weight: 500; color: var(--text-3); }
.tf input, .tf select, .tf textarea {
  width: 100%; padding: 11px 13px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--cream);
  font: 400 15px var(--sans); color: var(--ink); }
.tf textarea { resize: vertical; min-height: 62px; }
.tf input:focus, .tf select:focus, .tf textarea:focus {
  outline: none; border-color: var(--brand); background: #fff;
  box-shadow: 0 0 0 3px rgba(110,189,68,.15); }
.tf small { display: block; margin-top: 5px; font-size: 12.5px; color: var(--text-3); }
.tf-send { width: 100%; margin-top: 4px; }
.tf-fine { font-size: 12.5px; line-height: 1.5; color: var(--text-3); text-align: center; }
.tf-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-err { display: flex; gap: 9px; align-items: flex-start; margin-bottom: 18px;
  padding: 13px 15px; border-radius: var(--r-sm); background: #fdeceb;
  font-size: 13.5px; line-height: 1.5; color: #8c1d18; }
.form-err svg { flex: none; margin-top: 2px; }
.form-err a { text-decoration: underline; }

.form-done { text-align: center; padding: 12px 0; }
.form-done-ic { display: grid; place-items: center; width: 52px; height: 52px;
  margin: 0 auto 18px; border-radius: 50%; background: var(--brand-50); color: var(--brand-t); }
.form-done-ic svg { width: 26px; height: 26px; }
.form-done p { font-size: 15px; line-height: 1.6; color: var(--text-2); max-width: 42ch; margin-inline: auto; }

@media (max-width: 640px) { .tf-row { grid-template-columns: 1fr; } }

/* ── Blog: masonry index ──────────────────────────────────────────────
   CSS columns rather than a masonry library — no dependency, no reflow
   while a script measures, and it collapses to one column by itself. */
.masonry { columns: 3; column-gap: 20px; }
.mcard { break-inside: avoid; margin-bottom: 20px; }
.mcard-link { display: block; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--line); background: var(--paper);
  transition: border-color .2s, transform .24s var(--ease), box-shadow .24s var(--ease); }
.mcard-link:hover { border-color: var(--ink); transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.mcard-cover { position: relative; display: block; }
.mcard-cover svg { width: 100%; height: auto; display: block; }
.mcard-flag { position: absolute; top: 12px; left: 12px; padding: 4px 11px; border-radius: var(--r-pill);
  background: #fff; font-size: 11px; font-weight: 600; font-style: normal; color: var(--ink); }
.mcard-body { display: block; padding: 20px 22px 22px; }
.mcard-meta { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.mcard-cat { font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--brand-t); }
.mcard-time { font-size: 11.5px; color: var(--text-3); }
.mcard-time::before { content: "· "; }
.mcard-title { display: block; font-size: 1.12rem; font-weight: 600; line-height: 1.32;
  letter-spacing: -.012em; color: var(--ink); }
.mcard-ex { display: block; margin-top: 9px; font-size: 14px; line-height: 1.55; color: var(--text-2); }
.mcard-more { display: inline-flex; align-items: center; gap: 6px; margin-top: 14px;
  font-size: 13.5px; font-weight: 500; color: var(--brand-t); }
.mcard-more svg { width: 15px; height: 15px; transition: transform .2s var(--ease); }
.mcard-link:hover .mcard-more svg { transform: translateX(3px); }

/* The pillar of each cluster gets a taller cover so the eye finds it. */
.mcard.is-pillar .mcard-title { font-size: 1.26rem; }
.mcard.is-pillar .mcard-link { border-color: var(--brand); }

/* Article page */
.post-cover-full { border-radius: var(--r); overflow: hidden; margin-bottom: 34px; }
.post-cover-full svg { width: 100%; height: auto; display: block; }
.post-lead { font-size: 1.14rem; line-height: 1.6; font-weight: 500; color: var(--ink);
  padding-bottom: 22px; margin-bottom: 8px; border-bottom: 1px solid var(--line); }
.post-tax { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 14px; }
.post-tax a { padding: 5px 13px; border-radius: var(--r-pill); background: var(--brand-50);
  font-size: 12px; font-weight: 600; color: var(--brand-t); }
.post-tax time { font-size: 13px; color: var(--text-3); }

.related { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.related .mcard { margin-bottom: 0; }

@media (max-width: 1080px) { .masonry { columns: 2; } .related { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 700px)  { .masonry { columns: 1; } .related { grid-template-columns: 1fr; } }

/* ── The customization journey ────────────────────────────────────────
   Four numbered decisions in the order they are actually made, identity
   first. A list of options says "you can change things"; a sequence says
   "here is what we will ask you, and here are the answers available". */
.journey { display: grid; gap: 14px; margin-bottom: 34px; counter-reset: j; }
.jstep { padding: 26px 28px; border-radius: var(--r); background: var(--cream); }
.blk-cream .jstep { background: #fff; }
.jstep-head { display: grid; grid-template-columns: 52px 1fr; gap: 16px; align-items: start; }
.jstep-n { display: grid; place-items: center; width: 42px; height: 42px; border-radius: 12px;
  background: var(--ink); color: #fff; font-size: 14px; font-weight: 600;
  font-variant-numeric: tabular-nums; }
.jstep h3 { margin-bottom: 7px; font-size: 1.1rem; max-width: none; }
.jstep p { font-size: 14.5px; line-height: 1.6; color: var(--text-2); max-width: 66ch; }
.jopts { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.jopts li { display: inline-flex; align-items: center; gap: 7px; padding: 6px 13px;
  border-radius: var(--r-pill); background: #fff; border: 1px solid var(--line);
  font-size: 13px; font-weight: 500; color: var(--ink); }
.blk-cream .jopts li { background: var(--cream); }
.jopts svg { width: 14px; height: 14px; color: var(--brand-t); }

/* The design options are the proof of this whole page, and they were sitting
   in a 168px strip with the rest of the row empty. They now fill the width —
   a grid that gives each option an equal share instead of a scroller that
   hides half of them off the right edge. */
.jshots { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 18px; margin: 26px 0 0; }
.jshot { border-radius: 18px; overflow: hidden; background: #fff;
  border: 1px solid var(--line);
  transition: transform .24s var(--ease), box-shadow .24s var(--ease), border-color .24s; }
.jshot img { width: 100%; aspect-ratio: 9 / 15; object-fit: cover;
  object-position: top center; display: block; height: auto; }
.jshot:hover { transform: translateY(-4px); border-color: var(--brand); box-shadow: var(--shadow-lg); }

/* Step one has no screen — it has a palette. */
/* The note is a sentence, not a swatch. It was a <span> inside the same flex
   row, so it inherited the 42x42 sizing meant for the colour chips and the
   whole sentence was crushed into one square on top of them. */
.jswatch { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin: 24px 0 0;
  padding: 18px 20px; border-radius: var(--r); background: #fff; border: 1px solid var(--line); }
.jswatch > span:not(.jswatch-note) { width: 52px; height: 52px; flex: none;
  border-radius: 12px; border: 1px solid rgba(0,0,0,.08); }
.jswatch-type { display: grid !important; place-items: center; width: 52px; height: 52px;
  border-radius: 12px; background: var(--cream); font-size: 19px; font-weight: 600; color: var(--ink); }

@media (max-width: 860px) {
  .jstep { padding: 20px 18px; }
  .jstep-head { grid-template-columns: 38px 1fr; gap: 12px; }
  .jstep-n { width: 34px; height: 34px; font-size: 13px; }
  .jshots { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; }
}

/* Header WhatsApp button — the brand green is already taken by the primary
   action, so this one carries WhatsApp's own colour and reads as a channel
   rather than a second competing CTA. */
.btn-wa { background: #25d366; color: #06340f; font-weight: 600; }
.btn-wa:hover { background: #1eb85a; }
.hdr-cta { display: flex; align-items: center; gap: 8px; }
.hdr-cta .btn-wa { padding: 10px 16px; }
@media (max-width: 1180px) { .hdr-cta .btn-wa span { display: none; } .hdr-cta .btn-wa { padding: 10px 13px; } }

/* Journey — full-page variant, where each step is the subject rather than
   one group among eight. */
.journey.is-full { gap: 20px; }
.journey.is-full .jstep { padding: 34px 36px; }
.jstep-lead { font-size: 15.5px; font-weight: 500; color: var(--ink); margin-bottom: 8px; }
.jshot figcaption { padding: 11px 12px 13px; font-size: 13px; font-weight: 500;
  color: var(--text); text-align: center; border-top: 1px solid var(--line-soft); }

.jswatch { flex-wrap: wrap; }
.jswatch-note { flex: 1 1 240px; min-width: 200px; width: auto !important; height: auto !important;
  margin-left: 6px; font-size: 13.5px; line-height: 1.5; color: var(--text-2); border: 0 !important; }
@media (max-width: 860px) { .journey.is-full .jstep { padding: 22px 20px; } }

/* ── Growth loop ──────────────────────────────────────────────────────
   Five equal boxes in a row read as a list of five unrelated things. A
   loop has to look like one: a numbered sequence down the left, what it
   compounds into on the right, and a line that closes the circle. */
.loop-wrap { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; }
.loop-seq { position: relative; display: grid; gap: 0; }
.loop-seq li { position: relative; display: grid; grid-template-columns: 40px 1fr;
  gap: 16px; align-items: center; padding: 15px 0; }
.loop-seq li:not(:last-child)::after {
  content: ""; position: absolute; left: 19px; top: 50px; bottom: -6px;
  width: 2px; background: linear-gradient(var(--brand), rgba(110,189,68,.25)); }
.loop-n { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
  background: #fff; border: 2px solid var(--brand); color: var(--brand-t);
  font-size: 15px; font-weight: 600; z-index: 1; }
.loop-t { font-size: 16px; font-weight: 500; color: var(--ink); line-height: 1.4; }
.loop-back { grid-template-columns: 40px 1fr !important; margin-top: 4px;
  padding-top: 18px !important; border-top: 1px dashed var(--line); }
.loop-back svg { width: 20px; height: 20px; color: var(--brand-t); justify-self: center; }
.loop-back span { font-size: 14px; font-style: italic; color: var(--text-2); }

.loop-impact { padding: 30px 32px; border-radius: var(--r); background: #fff;
  border: 1px solid var(--line); }
.loop-impact-h { margin-bottom: 18px; font-size: 12px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3); }
.loop-imp { display: grid; grid-template-columns: 36px 1fr; gap: 14px; align-items: start;
  padding: 14px 0; border-bottom: 1px solid var(--line-soft); }
.loop-imp:last-child { border-bottom: 0; padding-bottom: 0; }
.loop-imp-ic { display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 10px; background: var(--brand-50); color: var(--brand-t); }
.loop-imp-ic svg { width: 17px; height: 17px; }
.loop-imp b { display: block; margin-bottom: 3px; font-size: 15px; font-weight: 600; color: var(--ink); }
.loop-imp p { font-size: 13.5px; line-height: 1.5; color: var(--text-2); }

/* Client results — renders only when there is something to show. */
.res-metrics { display: flex; flex-wrap: wrap; gap: 26px; margin-top: 22px; }
.res-metric { min-width: 120px; }
.res-n { display: block; font-size: 2rem; font-weight: 600; letter-spacing: -.03em; color: var(--brand-t); }
.res-l { display: block; margin-top: 3px; font-size: 13.5px; line-height: 1.45; color: var(--text-2); max-width: 22ch; }
.res-quote { margin: 22px 0 0; padding: 18px 20px; border-radius: var(--r-sm);
  background: var(--brand-50); border-left: 3px solid var(--brand);
  font-size: 15.5px; line-height: 1.6; font-style: italic; color: var(--ink); }
.res-quote cite { display: block; margin-top: 9px; font-size: 12.5px; font-style: normal;
  font-weight: 600; color: var(--brand-t); }
.res-facts { display: grid; gap: 9px; margin-top: 20px; }
.res-facts li { display: flex; gap: 10px; align-items: flex-start; font-size: 14.5px; color: var(--text-2); }
.res-facts svg { width: 17px; height: 17px; flex: none; margin-top: 3px; color: var(--brand-t); }

@media (max-width: 900px) { .loop-wrap { grid-template-columns: 1fr; gap: 32px; } }

/* Inside the features page the journey shares the column with a text rail,
   so the options need a smaller minimum before they wrap. */
.fgroup .jshots { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
.fgroup .jshot img { aspect-ratio: 9 / 16; }

/* ── Journey, wide layout ─────────────────────────────────────────────
   A paragraph is capped at 66 characters because that is where a line
   stops being comfortable to read — widening it does not use the space,
   it just makes the text worse. The space is used by moving the options
   alongside the copy instead of beneath it. */
@media (min-width: 1000px) {
  /* The viewer holds a 300px phone. Giving it the wider track left ~300px
     of empty space around the frame — the gap. The text takes the surplus
     instead, and the viewer column is sized to what it actually contains. */
  .journey.is-full .jstep {
    display: grid;
    grid-template-columns: 1fr 412px;
    gap: 48px;
    align-items: start;
  }
  .journey.is-full .jstep-head { grid-column: 1; }
  .journey.is-full .jshots,
  .journey.is-full .jswatch { grid-column: 2; margin-top: 0; }
  /* Two columns, not auto-fit. auto-fit computed three across 596px while
     every step has four options, so the second row sat two-thirds empty and
     the images shrank to fit a column they did not need to. */
  .journey.is-full .jshots { grid-template-columns: repeat(2, 1fr); gap: 20px; }
  /* An odd last item takes the full width rather than leaving a hole. */
  .journey.is-full .jshots > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  .journey.is-full .jshots > :last-child:nth-child(odd) img { aspect-ratio: 16 / 9; object-position: top center; }
  .journey.is-full .jstep p { max-width: 60ch; }
  .journey.is-full .jopts { max-width: 56ch; }
  /* the identity step has no screens, so its swatch panel can be calmer */
  .journey.is-full .jswatch { align-content: start; }
}

/* .fgroup is a two-column grid: a sticky heading on the left, content on the
   right. Adding the journey gave the studio group THREE children, so auto
   placement dropped the feature list into row two column ONE — 330px wide,
   with the whole right-hand column beside it empty. That is the large gap.
   Anything after the first content block spans the full width. */
.fgroup > .fitems { grid-column: 1 / -1; }
.fgroup > .journey { grid-column: 2; }

.fitems { grid-template-columns: 1fr; }
.fgroup > .fitems,
.fitems:has(> :nth-child(3):last-child) {
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 14px;
}
.fgroup > .fitems li,
.fitems:has(> :nth-child(3):last-child) li {
  grid-template-columns: 1fr;
  gap: 12px;
  padding: 22px 20px;
  border: 1px solid var(--line);
}
.fgroup > .fitems li:hover,
.fitems:has(> :nth-child(3):last-child) li:hover { background: #fff; border-color: var(--ink); }
.fgroup > .fitems h3,
.fitems:has(> :nth-child(3):last-child) h3 { font-size: 15.5px; }
.fgroup > .fitems p,
.fitems:has(> :nth-child(3):last-child) p { font-size: 14px; }
@media (max-width: 960px) {
  .fgroup > .fitems, .fgroup > .journey { grid-column: 1; }
  .fitems:has(> :nth-child(3):last-child) { grid-template-columns: 1fr; }
}

/* A grid that flows. Five items in a fixed three-column grid leaves two
   visible holes; auto-fit fills the row and wraps what is left. */
.grid-auto { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px; }


/* ── Space corrections, found by measuring each section ───────────────
   Five faults, all of them invisible in the markup:

   1. The home gallery sits outside .wrap so it can bleed to the edges,
      which left a 606px vertical gap between the heading and the cards.
   2. The FAQ reserved 890px at 5% density — the answers are collapsed,
      so the section was mostly reserved air.
   3. Art Dei Marmi has no screenshots, so its case ran 640px of text
      with an empty column beside it.
   4. Closing sections held 375px for ten words.
*/

/* 1. the bleed gallery */
#work .gallery, #design .gallery { margin-top: -22px; }
#work .sec-head, #design .sec-head { margin-bottom: 26px; }

/* 2. a collapsed accordion should not reserve the height of an open one */
#faq { padding-block: 72px; }
#faq .sec-head { margin-bottom: 30px; }
.qa summary { padding: 18px 0; }

/* 3. a case with no screenshots becomes a single readable column rather
      than half a two-column layout */
.case-noshots .split { grid-template-columns: 1fr; max-width: 760px; }
.case-noshots .case-screens { display: none; }

/* 4. closing bands are an ask, not a chapter */
.final { padding-block: 72px; }
.final .h-lg { margin-inline: auto; }

/* ── Layout viewer ────────────────────────────────────────────────────
   One layout at a time, large enough to judge. Four side by side made each
   187px wide — too small to tell one design direction from another, which
   is the only reason to show four. */
.jviewer { display: grid; gap: 18px; }
.jview { position: relative; display: grid; place-items: center;
  padding: 22px 20px; border-radius: 20px; background: var(--cream);
  min-height: 0; }
.blk-cream .jview { background: #fff; }
.jslide { display: none; margin: 0; text-align: center; }
.jslide.is-on { display: block; animation: jfade .32s var(--ease); }
@keyframes jfade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* A Figma artboard is 700x3146 — a 1:4.5 ratio. Capping its HEIGHT at 500px
   made it 113px wide, a sliver nobody can read. The frame is a phone instead:
   a real width, a device-shaped window, and the full design scrolls inside it
   exactly as it would on the handset. */
.jslide { width: 340px; }
.jframe { position: relative; width: 340px; height: 470px; margin-inline: auto;
  border-radius: 34px; overflow: hidden; background: #fff;
  border: 1px solid var(--line); box-shadow: var(--shadow-lg); }
.jframe-scroll { position: absolute; inset: 0; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: none; scroll-behavior: smooth; }
.jframe-scroll::-webkit-scrollbar { display: none; }
.jslide img { display: block; width: 100%; height: auto; border-radius: 0; border: 0; box-shadow: none; }
/* the hint that there is more below the fold */
.jframe::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 54px;
  pointer-events: none; background: linear-gradient(to top, rgba(255,255,255,.96), transparent); }
.jscroll-note { position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%);
  z-index: 3; padding: 5px 12px; border-radius: var(--r-pill);
  background: rgba(20,20,20,.82); color: #fff; font-size: 11px; font-weight: 500;
  pointer-events: none; transition: opacity .25s; }
.jframe-scroll.is-scrolled + .jscroll-note { opacity: 0; }
.jslide figcaption { margin-top: 14px; font-size: 14px; font-weight: 500; color: var(--text); }

.jnav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
  background: #fff; border: 1px solid var(--line); color: var(--ink);
  box-shadow: var(--shadow); transition: background .16s, border-color .16s, transform .16s; }
.jnav:hover { background: var(--ink); border-color: var(--ink); color: #fff; }
.jnav:active { transform: translateY(-50%) scale(.94); }
.jnav.is-prev { left: -14px; }
.jnav.is-next { right: -14px; }

.jdots { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.jdot { padding: 8px 16px; border-radius: var(--r-pill);
  background: transparent; border: 1px solid var(--line);
  font-size: 13px; font-weight: 500; color: var(--text-2);
  transition: background .16s, border-color .16s, color .16s; }
.jdot:hover { border-color: var(--ink); color: var(--ink); }
.jdot.is-on { background: var(--ink); border-color: var(--ink); color: #fff; }

@media (max-width: 860px) {
  .jview { min-height: 0; padding: 14px; }
  .jslide, .jframe { width: 260px; }
  .jframe { height: 380px; }
  .jnav { width: 38px; height: 38px; }
  .jnav.is-prev { left: 4px; } .jnav.is-next { right: 4px; }
  .jdot { padding: 7px 12px; font-size: 12px; }
}

/* ── What the merchant does NOT decide ─────────────────────────────────────
   On /customization/. The bag, the account and search ship with every app, and
   saying so stops a visitor counting screens and concluding there is no basket. */

.jstandard {
  margin-top: 56px;
  padding-top: 40px;
  border-top: 1px solid rgba(0, 0, 0, .09);
}
.jstandard-h { font-size: 22px; margin: 0 0 10px; letter-spacing: -.015em; }
.jstandard-p {
  font-size: 15px;
  line-height: 1.62;
  color: var(--text-2, #4a4a4a);
  max-width: 62ch;
  margin: 0 0 28px;
  text-wrap: pretty;
}
.jstandard-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
}
.jstandard-fig { margin: 0; }
.jstandard-fig img {
  width: 100%;
  height: 260px;
  object-fit: cover;
  object-position: top;
  display: block;
  border: 1px solid rgba(0, 0, 0, .1);
  border-radius: 14px;
  background: #fff;
}
.jstandard-fig figcaption {
  font-size: 12.5px;
  color: var(--text-3, #767676);
  margin-top: 9px;
  text-align: center;
}
@media (max-width: 760px) {
  .jstandard-row { grid-template-columns: 1fr 1fr; gap: 14px; }
  .jstandard-fig img { height: 210px; }
}

/* ── What TicApp built, inside an article ──────────────────────────────────
   On every article: two or three true lines about what we have made on that
   subject, one of our own screens, and a way onward. Our screen rather than
   stock photography — a design we made is evidence; a person at a laptop is
   decoration. */

.acta {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 26px;
  align-items: center;
  background: var(--cream, #f3ece3);
  border-radius: var(--r-lg, 24px);
  padding: 26px 30px;
  margin: 44px 0 8px;
}

.acta-shot img {
  width: 100%;
  height: 230px;
  object-fit: cover;
  object-position: top;
  display: block;
  border-radius: 14px;
  border: 1px solid rgba(0, 0, 0, .09);
  background: #fff;
}

.acta-eyebrow {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--brand-t, #38701f);
  margin: 0 0 8px;
}

.acta-line {
  font-size: 15.5px;
  line-height: 1.62;
  color: var(--text, #141414);
  margin: 0 0 18px;
  max-width: 58ch;
  text-wrap: pretty;
}

.acta-cta { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

.acta-btn {
  display: inline-block;
  padding: 12px 22px;
  border-radius: 999px;
  background: var(--black, #000);
  color: #fff;
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
  transition: transform .12s;
}
.acta-btn:hover { transform: translateY(-1px); color: #fff; }

.acta-alt {
  font-size: 13.5px;
  color: var(--text-2, #4a4a4a);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.acta-small {
  font-size: 11.5px;
  color: var(--text-3, #767676);
  margin: 12px 0 0;
}

@media (max-width: 760px) {
  .acta { grid-template-columns: 1fr; gap: 18px; padding: 22px; }
  .acta-shot img { height: 180px; }
}

/* ── Topics ──────────────────────────────────────────────────────────────
   The second axis of the blog. Categories say what kind of piece an article
   is; these say what it is about, and an article carries both. Styled quieter
   than the category nav on purpose — the categories are the structure and
   these are the cross-references, and giving them equal weight made the header
   read as two menus arguing. */
.feat-tags { display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  padding: 0 0 14px; }
.feat-tags-label, .post-tags-label { font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
  margin-right: 4px; }
.feat-tag { display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px;
  font-size: 12px; color: var(--ink); text-decoration: none; background: #fff;
  transition: border-color .15s, color .15s; }
.feat-tag:hover, .feat-tag:focus-visible { border-color: var(--accent);
  color: var(--accent); }
.feat-tag[aria-current] { border-color: var(--accent); color: var(--accent);
  font-weight: 600; }
.feat-tag-n { font-size: 10px; color: var(--muted); font-variant-numeric: tabular-nums; }
.feat-tag:hover .feat-tag-n, .feat-tag[aria-current] .feat-tag-n { color: inherit; }

.post-tags { display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin: 30px 0 0; padding-top: 22px; border-top: 1px solid var(--line); }

/* ── Category and market rows ────────────────────────────────────────────
   Used by /who-its-for/ and /shopify-mobile-app-middle-east/, where the page
   is a series of short arguments rather than a grid of equal cards. A grid
   would force every category into the same length and the honest length
   varies — pet care needs three sentences and electronics needs two. */
.who-row { padding: 22px 0; border-bottom: 1px solid var(--line); }
.who-row:last-child { border-bottom: none; }
.who-h { font-size: 19px; margin-bottom: 8px; }
.who-row p { max-width: 74ch; }
.who-proof { margin-top: 10px; font-size: 14px; color: var(--muted); }
.who-proof a { color: var(--accent); }

/* ── The calculator's two answers ────────────────────────────────────────
   A merchant weighing an app asks two things and they are not the same
   question: how much more will I sell, and how much will I stop spending.
   The arithmetic already produced both; only one of them was announced. */
.calc-two { display: grid; grid-template-columns: 1fr 1fr; gap: 18px;
  margin-bottom: 22px; }
.calc-headline { padding: 18px 20px; border-radius: 14px; background: #fff;
  border: 1px solid var(--line); }
.calc-headline.is-saving { background: #f6fbf4; border-color: #d6ecd0; }
.calc-headline .calc-lab { margin: 0 0 6px; font-size: 12px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.calc-headline .calc-big { margin: 0; }
.calc-note { margin: 8px 0 0; font-size: 13px; line-height: 1.45;
  color: var(--muted); }
@media (max-width: 700px) { .calc-two { grid-template-columns: 1fr; } }

/* The office address. `<address>` is italic by default in every browser, which
   reads as an aside rather than as a fact somebody may need to write down. */
.contact-addr { font-style: normal; line-height: 1.7; margin: 0 0 10px;
  font-size: 15px; color: var(--ink); }

/* ── 404 ─────────────────────────────────────────────────────────────────
   A dead end is still a visitor, and increasingly an agent following a link
   that moved. Search first, because somebody who hit a wrong URL usually knows
   what they wanted and can type it faster than they can browse. */
.four-search { display: flex; gap: 10px; margin: 26px 0 34px; max-width: 520px; }
.four-search input { flex: 1; padding: 12px 16px; border: 1px solid var(--line);
  border-radius: 10px; font: inherit; font-size: 15px; }
.four-search input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.four-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.four-card { display: block; padding: 16px 18px; border: 1px solid var(--line);
  border-radius: 12px; text-decoration: none; background: #fff;
  transition: border-color .15s; }
.four-card:hover, .four-card:focus-visible { border-color: var(--accent); }
.four-card strong { display: block; color: var(--ink); font-size: 15px; margin-bottom: 4px; }
.four-card span { display: block; color: var(--muted); font-size: 13px; line-height: 1.5; }
.four-lab { margin: 34px 0 10px; font-size: 12px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); }
.four-list { margin: 0; padding-left: 18px; }
.four-list li { margin: 5px 0; font-size: 14px; }
@media (max-width: 860px) { .four-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .four-grid { grid-template-columns: 1fr; }
  .four-search { flex-direction: column; } }

/* Where we are, under the hero's buttons. Quieter than the note above it —
   it is a fact rather than a claim, and it sits beside a phone that already
   shows a Gulf client's app, so it confirms rather than argues. */
.hero-where { display: inline-flex; align-items: center; gap: 7px; margin-top: 8px;
  font-size: 13.5px; color: var(--muted); }
.hero-where svg { width: 15px; height: 15px; flex: none; color: var(--brand); }

/* The licence line. Quieter than the copyright above it — it is there for the
   reader who is checking rather than the one who is skimming, and that reader
   will find it. */
.ftr-licence { margin-top: 6px; font-size: 12.5px; line-height: 1.6;
  color: var(--muted); opacity: .85; }

/* ── Dubai, behind the footer ────────────────────────────────────────────
   Texture at a glance, a skyline if you look. Very low opacity because the
   footer's job is the links and the licence — a background that competes with
   them has forgotten what it is for.

   `pointer-events: none` so it can never swallow a click meant for a link, and
   it is placed rather than floated so it cannot affect the layout of anything
   above it. */
.ftr { position: relative; overflow: hidden; }
.ftr .ftr-skyline { position: absolute; left: 0; right: 0; bottom: 0;
  width: 100%; height: 190px; color: #fff; opacity: .09;
  pointer-events: none; user-select: none; }
.ftr > .wrap { position: relative; z-index: 1; }

/* Smaller screens get a shorter band, so the buildings do not crowd the text
   they sit behind. */
@media (max-width: 860px) {
  .ftr .ftr-skyline { height: 120px; opacity: .075; }
}

/* Somebody who has asked for less motion has usually also asked for less
   visual noise. This is not animated, but it is ornament, and honouring the
   preference costs nothing. */
@media (prefers-reduced-motion: reduce) {
  .ftr .ftr-skyline { opacity: .06; }
}
