/* ============================================================================
   Lucky Cat AI Solutions — site system
   ----------------------------------------------------------------------------
   Follows the existing luckycat.ie: same tokens, same fonts, same rhythm of
   alternating light and dark bands, gold as the accent that carries emphasis.
   Green is the brand, not the wallpaper.
   ========================================================================= */

:root {
  /* tokens carried over from the live site, unchanged */
  --green:   #3db54a; --green-l:#52c960; --green-d:#2a9e37; --green-xl:#e6f7e8;
  /* --green-d was inherited as "the dark green" and used for green TEXT on light
     bands, where it is 3,31:1 on --cream and 3,08:1 on --off — under AA in both.
     It stays correct as a fill and on the dark bands (5,37:1 on --forest-2).
     --green-read is the one to use when the green IS the text on a light band:
     5,22:1 on cream, 4,86:1 on --off. Same value the Tillr app ships as
     --action, so the two surfaces agree. */
  --green-read: #1f7a2a;
  --orange:  #f5a01e; --orange-d:#e08c0a;
  --forest:  #111f0c; --forest-2:#0d1708; --forest-3:#1a2f13;
  --gold:    #d4a843; --gold-l:#e8c975; --gold-xl:rgba(212,168,67,.12);
  --ink:     #1a1206; --white:#ffffff; --cream:#fdf9f4; --off:#f4f1ec;
  --muted:   #7a6a52; --border:#e4dcd2;

  /* on dark bands */
  --d-ink:   #f6f3ec; --d-muted:#b9b0a0; --d-faint:#8d8577; --d-line:#25361d;

  /* per-product colourways, taken from each product's own brand kit */
  --ownly-deep:  #14342b;  --ownly-gold: #e0a458;
  --tillr-orange:#c96b10;  --tillr-cream:#fdf6ec;
  --pp-green:    #3db54a;
  --nock-deep:   #0d3a63;  --nock-flag: #cc5217;   /* blue fixed by Nock's identity spec */
  /* Synergy had no token anywhere in the codebase, which is why its dashboard card
     could not be branded from code while every other product's could. These are the
     signal colours from synergy/brand/tokens.css, which is the source; this is a
     serving copy in the same sense as the marks under site/assets/. assistant and app
     are the only two: the owner dropped the violet "meet" colour on 2026-09-24, so the
     mark's own blue and coral carry everything. */
  --syn-assistant: #2d4ad9;  --syn-app: #c9452e;

  --fd: "Bricolage Grotesque", system-ui, sans-serif;
  --fb: "DM Sans", system-ui, sans-serif;

  --gut: clamp(1.25rem, 4vw, 2.5rem);
  /* O piso mandava em tudo abaixo de ~711px: 9vw a 390px da 35px, menor que os
     4rem, entao um telefone de 390px e um tablet de 700px recebiam o MESMO
     respiro de secao. Baixar o piso muda so o estreito -- acima de 445px o
     termo fluido ja ultrapassa 2,5rem e a renderizacao larga fica identica. */
  --sec: clamp(2.5rem, 9vw, 7rem);
  --max: 78rem;
  --z-sticky: 50;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0; background: var(--cream); color: var(--ink);
  font-family: var(--fb); font-size: 1.0625rem; line-height: 1.65;
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
:focus-visible { outline: 3px solid var(--green-d); outline-offset: 3px; border-radius: 4px; }
::selection { background: var(--gold); color: var(--ink); }

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gut); }
.sec { padding-block: var(--sec); }
.tnum { font-variant-numeric: tabular-nums; }

.skip { position: absolute; left: -9999px; top: 0; z-index: 100; background: var(--gold); color: var(--ink); padding: 12px 20px; font-family: var(--fd); font-weight: 700; }
.skip:focus { left: 0; }

h1, h2, h3 { margin: 0; font-family: var(--fd); font-weight: 800; letter-spacing: -0.035em; line-height: 1.02; text-wrap: balance; }
h1 { font-size: clamp(2.5rem, 7vw, 4.5rem); }
h2 { font-size: clamp(1.9rem, 4.6vw, 3.1rem); }
h3 { font-size: clamp(1.15rem, 2vw, 1.4rem); letter-spacing: -0.025em; line-height: 1.15; }
p  { margin: 0; text-wrap: pretty; }
.lead { font-size: clamp(1.075rem, 1.7vw, 1.25rem); line-height: 1.6; color: var(--muted); max-width: 56ch; }

/* --- bands ---------------------------------------------------------------- */
/* The live site alternates light and dark. Keeping that rhythm is most of why
   it reads as the same site. */
.band-dark { background: var(--forest-2); color: var(--d-ink); }
.band-dark h1, .band-dark h2, .band-dark h3 { color: #fff; }
.band-dark .lead { color: var(--d-muted); }
.band-off  { background: var(--off); }
.band-cream{ background: var(--cream); }

/* --- pill kicker (the site's own device, used once per band) -------------- */
.pill {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--gold-xl); color: var(--gold); border: 1px solid rgba(212,168,67,.3);
  font-family: var(--fd); font-weight: 700; font-size: 0.78rem; letter-spacing: 0.06em;
  text-transform: uppercase; padding: 6px 14px; border-radius: 999px;
}
.band-off .pill, .band-cream .pill { color: #5c4610; background: rgba(212,168,67,.24); border-color: rgba(212,168,67,.5); }

/* --- header --------------------------------------------------------------- */
.nav { position: sticky; top: 0; z-index: var(--z-sticky); background: rgba(253,249,244,.88); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); border-bottom: 1px solid var(--border); }
.nav-in { display: flex; align-items: center; justify-content: space-between; gap: 12px; height: 68px; }
.lockup { display: flex; align-items: center; gap: 11px; min-width: 0; }
.lockup img { height: 32px; width: auto; flex-shrink: 0; }
.lockup .rule { width: 1px; height: 24px; background: var(--border); flex-shrink: 0; }
/* opsz 24 trava a forma do wordmark: sem isso o eixo optico do Bricolage muda
   as proporcoes com o tamanho e o header deixa de casar com o material impresso. */
.lockup .word { font-family: var(--fd); font-weight: 800; font-size: 1.2rem; letter-spacing: -0.01em; white-space: nowrap;
                font-variation-settings: "opsz" 24; font-optical-sizing: none;
                /* alinha a marca ao centro OTICO do wordmark (meio entre cap-top e
                   baseline), nao ao centro da caixa de linha: desc/2 = 0.1em. */
                transform: translateY(0.1em); }
.nav-links { display: flex; align-items: center; gap: clamp(14px, 2.2vw, 28px); }
.nav-links .nl { font-family: var(--fd); font-weight: 600; font-size: 0.92rem; color: var(--ink); opacity: .78; }
.nav-links .nl:hover { opacity: 1; color: var(--green-read); }
@media (max-width: 860px) { .nav-links .nl { display: none; } }

/* Um salto de ancora aterrissava debaixo do header fixo, cortando o titulo da
   secao que a pessoa acabou de pedir. */
[id] { scroll-margin-top: calc(68px + 12px); }

/* --- o header no telefone -------------------------------------------------
   A barra creme a 88% sobre uma faixa escura nao lia como vidro: lia como uma
   laje que corta o texto na metade da letra. No telefone ela some ao rolar
   para baixo e volta ao rolar para cima -- 68px de 664 e 10% da tela devolvidos
   a quem chegou pelo QR, e o corte deixa de existir enquanto se le. */
@media (max-width: 860px) {
  .nav { transition: transform .28s cubic-bezier(.22,1,.36,1); will-change: transform; }
  .nav.is-away { transform: translateY(-100%); }
  /* Vidro de verdade: menos tinta, mais desfoque, e uma borda que nao vira
     risco branco sobre o escuro. */
  .nav { background: rgba(253,249,244,.72); backdrop-filter: blur(20px) saturate(1.4); -webkit-backdrop-filter: blur(20px) saturate(1.4); }
  .nav-in { height: 60px; }
  .nav .btn-dark { min-height: 42px; padding: 9px 18px; font-size: 0.92rem; }
  [id] { scroll-margin-top: 74px; }
}
@media (prefers-reduced-motion: reduce) { .nav { transition: none; } }

/* --- buttons -------------------------------------------------------------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 9px; font-family: var(--fd); font-weight: 700; font-size: 0.97rem; min-height: 46px; padding: 12px 22px; border-radius: 999px; border: 1.5px solid transparent; cursor: pointer; white-space: nowrap; transition: transform .18s cubic-bezier(.22,1,.36,1), background-color .18s, border-color .18s, color .18s; }
.btn-gold  { background: var(--gold); color: var(--ink); }
.btn-gold:hover { background: var(--gold-l); transform: translateY(-2px); }
.btn-dark  { background: var(--forest-2); color: #fff; }
.btn-dark:hover { background: var(--forest); transform: translateY(-2px); }
.btn-line  { border-color: var(--border); color: var(--ink); background: #fff; }
.btn-line:hover { border-color: var(--ink); transform: translateY(-2px); }
.btn-line-d { border-color: rgba(255,255,255,.3); color: #fff; }
.btn-line-d:hover { border-color: #fff; transform: translateY(-2px); }
.btn-lg { font-size: 1.05rem; padding: 15px 28px; min-height: 54px; }
@media (prefers-reduced-motion: reduce) { .btn:hover { transform: none; } }

/* --- toque -----------------------------------------------------------------
   Todo estado interativo da pagina era :hover. Num telefone isso falha de duas
   formas ao mesmo tempo: ou o estado nunca acontece, ou -- no iOS -- ele GRUDA
   no elemento tocado ate o proximo toque em outro lugar, e o botao fica
   levantado depois que o dedo ja saiu, o que le como bug. Aqui o hover e
   desarmado onde nao ha ponteiro, e o toque ganha a unica resposta que faz
   sentido nele: a propria pressao. 90ms para entrar, a saida usa a transicao
   normal -- rapido o bastante para ler como o aparelho respondendo, nao como
   animacao. */
@media (hover: none) {
  .btn:hover, .pcard:hover, .pcard-pair:hover { transform: none; }
  .btn:active { transform: scale(.975); transition-duration: .09s; }
  .pcard:active, .pcard-pair:active { transform: scale(.988); transition-duration: .09s; }
}
@media (prefers-reduced-motion: reduce) {
  .btn:active, .pcard:active, .pcard-pair:active { transform: none; }
}

/* --- centred hero --------------------------------------------------------- */
.hero-mid { text-align: center; display: grid; justify-items: center; gap: 0; }
.hero-mid h1 { margin-inline: auto; }
.hero-mid .lead { margin-inline: auto; max-width: 58ch; }
.hero-mid .cta { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }

/* --- hero stage: the products themselves, not a description of them -------
   A studio's strongest opening argument is the work. The ownly window sits
   centre, the customer-facing apps lean in from the sides. Dotted field and a
   soft glow behind, both from the live site's own vocabulary. */
.hero-band { position: relative; overflow: hidden; }
.hero-band::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: radial-gradient(rgba(212,168,67,.16) 1px, transparent 1px);
  background-size: 26px 26px;
  mask-image: radial-gradient(ellipse 75% 55% at 50% 0%, #000 35%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 75% 55% at 50% 0%, #000 35%, transparent 78%);
}
.hero-band > * { position: relative; }

.stage { position: relative; width: 100%; max-width: 46rem; margin: clamp(2.5rem,5vw,4rem) auto 0; }
.stage-glow {
  position: absolute; left: 50%; top: 8%; translate: -50% 0;
  width: 70%; aspect-ratio: 2 / 1; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(212,168,67,.28), transparent 70%);
  filter: blur(30px); pointer-events: none;
}
/* ownly is a tablet product on the counter, so it gets a tablet, not a browser
   window. Even bezel all round, no chrome, one small camera dot. */
.stage-tablet {
  position: relative; border-radius: 26px; padding: 13px;
  background: #12170f; border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 40px 90px -35px rgba(0,0,0,.85);
}
.stage-tablet img { width: 100%; display: block; border-radius: 14px; }
.stage-tablet::before {
  content: ""; position: absolute; top: 5px; left: 50%; translate: -50% 0;
  width: 5px; height: 5px; border-radius: 50%; background: rgba(255,255,255,.22);
}

.stage-phone {
  position: absolute; bottom: -7%; width: 26%; max-width: 158px;
  border-radius: 20px; padding: 5px; background: #0b1207;
  border: 1px solid rgba(255,255,255,.16);
  box-shadow: 0 28px 55px -22px rgba(0,0,0,.9);
}
.stage-phone img { width: 100%; border-radius: 15px; display: block; aspect-ratio: 250/430; object-fit: cover; object-position: top center; }
.stage-phone.is-left  { left: -11%; rotate: -6deg; }
.stage-phone.is-right { right: -11%; rotate: 6deg; }
/* Retrato inverte a composicao, e de proposito.
   No desktop o tablet lidera porque ha largura; num telefone quem lidera e um
   telefone -- o visitante esta segurando exatamente o aparelho em que o tillr
   roda. Os tres continuam na cena: o tablet vira fundo, os dois telefones vem
   a frente. Esconde-los, como se fazia abaixo de 860px, resolvia o corte mas
   entregava um unico print de dashboard ilegivel como argumento de abertura.
   O palco sangra ate a borda porque cada por-cento de largura aqui e tamanho
   de aparelho -- o texto do hero mantem a goteira, a cena nao. */
@media (max-width: 720px) {
  .stage {
    max-width: none;
    width: calc(100% + var(--gut) * 2);
    margin-inline: calc(var(--gut) * -1);
    margin-top: clamp(2rem, 7vw, 3rem);
    margin-bottom: 0;
    aspect-ratio: 1 / 0.98;
  }
  .stage-glow { top: 2%; width: 86%; }

  .stage-tablet {
    position: absolute; top: 0; left: 8%; width: 84%;
    rotate: -3.5deg; padding: 8px; border-radius: 18px;
    box-shadow: 0 26px 60px -26px rgba(0,0,0,.9);
  }
  .stage-tablet img { border-radius: 10px; }
  .stage-tablet::before { width: 4px; height: 4px; top: 3px; }

  /* Os dois telefones voltam. Larguras diferentes e sobreposicao dao a
     profundidade que a fileira simetrica do desktop dava com espaco. */
  .stage-phone { display: block; max-width: none; bottom: auto; padding: 4px; border-radius: 17px; }
  .stage-phone img { border-radius: 13px; }
  .stage-phone.is-left  { left: 3%;  bottom: 0;  width: 45%; rotate: -6.5deg; z-index: 2; }
  .stage-phone.is-right { right: 2%; bottom: 9%; width: 39%; rotate: 7deg;    z-index: 1; }
}

/* Entre 720 e 860 ainda cabe a fileira do desktop, so mais apertada. Era esta
   a faixa que o display:none tratava junto com o telefone, sem precisar. */
@media (min-width: 721px) and (max-width: 860px) {
  .stage-phone { width: 23%; }
  .stage-phone.is-left  { left: -6%; }
  .stage-phone.is-right { right: -6%; }
}
@media (prefers-reduced-motion: reduce) { .stage-phone { rotate: none; } }

.hero-proof {
  display: flex; flex-wrap: wrap; justify-content: center; gap: clamp(1rem, 3vw, 2.5rem);
  margin-top: clamp(3.5rem, 7vw, 5rem); color: var(--d-muted); font-size: 0.95rem;
}
.hero-proof b { color: #fff; font-family: var(--fd); font-weight: 800; }

/* --- product grid: side by side, each in its own colourway --------------- */
.pgrid { display: grid; gap: clamp(1rem, 2vw, 1.5rem); grid-template-columns: 1fr; }
@media (min-width: 760px)  { .pgrid { grid-template-columns: repeat(2, 1fr); } }

/* The restaurant platform is one product sold as two apps, so it gets one box
   split down the middle rather than two boxes pretending to be separate. */
.pcard-pair {
  grid-column: 1 / -1; display: grid; grid-template-columns: 1fr;
  border-radius: 22px; overflow: hidden; border: 1px solid var(--border);
  transition: transform .2s cubic-bezier(.22,1,.36,1), box-shadow .2s;
}
.pcard-pair:hover { transform: translateY(-3px); box-shadow: 0 18px 40px -22px rgba(26,18,6,.45); }
@media (prefers-reduced-motion: reduce) { .pcard-pair:hover { transform: none; } }
@media (min-width: 760px) { .pcard-pair { grid-template-columns: 1fr 1fr; } }
.pair-half { padding: clamp(1.5rem, 2.6vw, 2rem); display: flex; flex-direction: column; gap: 0.85rem; }
.pair-half p { font-size: 0.98rem; line-height: 1.6; opacity: .9; }
.pair-half ul { list-style: none; margin: 0.2rem 0 0; padding: 0; display: grid; gap: 9px; font-size: 0.94rem; }
.pair-half li { display: flex; gap: 10px; align-items: flex-start; opacity: .92; }
.pair-ownly { background: var(--ownly-deep); color: #eef2ec; }
.pair-tillr { background: var(--tillr-cream); color: var(--ink); border-top: 1px solid #ecdfc9; }
@media (min-width: 760px) { .pair-tillr { border-top: 0; border-left: 1px solid rgba(0,0,0,.08); } }
.pair-foot {
  grid-column: 1 / -1; background: var(--ink); color: #fff;
  padding: 14px clamp(1.5rem, 2.6vw, 2rem);
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  font-family: var(--fd); font-weight: 700; font-size: 0.95rem;
}
.pcard-pair:hover .arw { transform: translateX(5px); }

.pcard {
  border-radius: 22px; padding: clamp(1.5rem, 2.6vw, 2rem);
  display: flex; flex-direction: column; gap: 0.9rem;
  border: 1px solid transparent; position: relative; overflow: hidden;
  transition: transform .2s cubic-bezier(.22,1,.36,1), box-shadow .2s;
}
.pcard:hover { transform: translateY(-3px); box-shadow: 0 18px 40px -22px rgba(26,18,6,.45); }
@media (prefers-reduced-motion: reduce) { .pcard:hover { transform: none; } }

/* each card wears its product's own brand, not the site's */
.pcard-ownly { background: var(--ownly-deep); color: #eef2ec; }
.pcard-tillr { background: var(--tillr-cream); color: var(--ink); border-color: #ecdfc9; }
.pcard-nock  { background: var(--nock-deep); color: #e9f2ee; }
.pcard-pp    { background: #fff; color: var(--ink); border-color: var(--border); }
.pcard-open  { background: transparent; border: 1.5px dashed var(--border); color: var(--ink); }

/* ...including its typeface. Nock is set in Archivo and pitchpilot in Poppins
   over Hanken Grotesk, exactly as their own sites are. ownly and tillr
   already share the Lucky Cat faces, so they are left alone.
   Doubled-up selectors so these beat the generic `.pcard .go` rule that is
   declared further down the file. */
.pcard.pcard-nock,
.pcard.pcard-nock h3,
.pcard.pcard-nock .go,
.pcard.pcard-nock .wm-sub { font-family: Archivo, ui-sans-serif, system-ui, sans-serif; }
.pcard.pcard-nock h3 { letter-spacing: -0.03em; }

.pcard.pcard-pp,
.pcard.pcard-pp .wm-sub { font-family: "Hanken Grotesk", ui-sans-serif, system-ui, sans-serif; }
.pcard.pcard-pp h3,
.pcard.pcard-pp .go { font-family: Poppins, ui-sans-serif, system-ui, sans-serif; letter-spacing: -0.015em; }

/* Synergy wears its own identity (the Synergy brand tokens): warm
   paper, Newsreader, IBM Plex Mono for labels. Third card after the pair and
   the two halves, so it takes the whole row and reads as a wide band. */
.pcard-syn { grid-column: 1 / -1; background: #FAF8F3; color: #171614; border-color: #E6E1D7; }
.pcard.pcard-syn, .pcard.pcard-syn h3, .pcard.pcard-syn .wm { font-family: Newsreader, Georgia, serif; font-weight: 500; }
.pcard.pcard-syn .wm { font-size: 1.75rem; letter-spacing: -0.02em; }
.pcard.pcard-syn h3 { font-size: clamp(1.6rem, 3vw, 2.1rem); letter-spacing: -0.02em; }
.pcard.pcard-syn p { font-size: 1.08rem; max-width: 56ch; }
.pcard.pcard-syn .wm-sub, .pcard.pcard-syn .go, .pcard-syn .syn-tags { font-family: "IBM Plex Mono", ui-monospace, monospace; }
.pcard.pcard-syn .wm-sub { color: #565046; font-size: 0.78rem; }
.pcard.pcard-syn .go { color: var(--syn-assistant); font-weight: 500; }
.pcard-syn .syn-tags { display: flex; flex-wrap: wrap; gap: 8px; font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; }
.pcard-syn .syn-tags li { padding: 5px 9px; border: 1px solid #E6E1D7; background: #fff; color: #565046; opacity: 1; }
.pcard.pcard-syn { display: grid; gap: 1.5rem; align-items: center; box-shadow: 0 22px 50px -38px rgba(45, 74, 217, .45); }
.pcard-syn .syn-copy { display: flex; flex-direction: column; gap: 0.9rem; }
@media (min-width: 900px) { .pcard.pcard-syn { grid-template-columns: 1.1fr .9fr; padding: clamp(2rem, 3.2vw, 2.75rem); } .pcard.pcard-syn h3 { font-size: clamp(2rem, 3.4vw, 2.7rem); } }
.syn-demo { width: 100%; max-width: 360px; justify-self: center; overflow: visible; }
.sd-src rect { fill: #fff; stroke: #D9DEF7; }
.sd-src text { font-family: Newsreader, Georgia, serif; font-size: 16px; fill: #171614; text-anchor: middle; }
.sd-in { fill: none; stroke: var(--syn-assistant); stroke-width: 1.4; opacity: .7; }
.sd-out { fill: none; stroke: var(--syn-app); stroke-width: 1.4; opacity: .8; }
.sd-l, .sd-r { fill: none; stroke-width: 7.5; transform-box: fill-box; }
.sd-l { stroke: var(--syn-assistant); } .sd-r { stroke: var(--syn-app); }
.sd-halo { fill: none; stroke: var(--syn-assistant); stroke-width: 1; opacity: 0; transform-box: fill-box; transform-origin: center; }
.sd-app { fill: #FBF1EE; stroke: #F1D8D1; }
.sd-app-t { font-family: Newsreader, Georgia, serif; font-size: 17px; fill: #171614; text-anchor: middle; }
.sd-dot { opacity: 0; fill: var(--syn-assistant); }
.sd-d4 { fill: var(--syn-app); }
@media (prefers-reduced-motion: no-preference) {
  @supports (offset-path: path("M0 0")) {
    .sd-dot { offset-rotate: 0deg; animation: sd-travel 4.8s cubic-bezier(.65,0,.35,1) infinite; }
    .sd-d1 { offset-path: path("M48 40 C48 80 160 72 160 104"); }
    .sd-d2 { offset-path: path("M160 40 L160 104"); animation-delay: .45s; }
    .sd-d3 { offset-path: path("M272 40 C272 80 160 72 160 104"); animation-delay: .9s; }
    .sd-d4 { offset-path: path("M160 160 L160 192"); animation-name: sd-deliver; }
  }
  .sd-halo { animation: sd-halo 4.8s cubic-bezier(.16,1,.3,1) infinite; }
  .sd-l { animation: sd-close-l 4.8s cubic-bezier(.16,1,.3,1) infinite; }
  .sd-r { animation: sd-close-r 4.8s cubic-bezier(.16,1,.3,1) infinite; }
}
@keyframes sd-travel { 0% { offset-distance: 0%; opacity: 0; } 8% { opacity: 1; } 38% { offset-distance: 100%; opacity: 1; } 44%, 100% { offset-distance: 100%; opacity: 0; } }
@keyframes sd-deliver { 0%, 52% { offset-distance: 0%; opacity: 0; } 56% { opacity: 1; } 74% { offset-distance: 100%; opacity: 1; } 80%, 100% { offset-distance: 100%; opacity: 0; } }
@keyframes sd-halo { 0%, 38% { transform: scale(.7); opacity: 0; } 46% { transform: scale(1); opacity: .5; } 70%, 100% { transform: scale(1.35); opacity: 0; } }
@keyframes sd-close-l { 0%, 34% { transform: none; } 44% { transform: translateX(5px); } 58%, 100% { transform: none; } }
@keyframes sd-close-r { 0%, 34% { transform: none; } 44% { transform: translateX(-5px); } 58%, 100% { transform: none; } }

.pcard-head { display: flex; align-items: center; gap: 12px; min-height: 44px; }
.pcard-head img { height: 38px; width: auto; }
.pcard-for { font-family: var(--fd); font-weight: 800; font-size: 0.68rem; letter-spacing: 0.13em; text-transform: uppercase; opacity: .72; }
.pcard h3 { font-size: clamp(1.3rem, 2.2vw, 1.6rem); }
.pcard p { font-size: 0.98rem; line-height: 1.6; opacity: .88; }
.pcard ul { list-style: none; margin: 0.2rem 0 0; padding: 0; display: grid; gap: 8px; font-size: 0.94rem; }
.pcard li { display: flex; gap: 9px; align-items: flex-start; opacity: .9; }
.pcard .go { margin-top: auto; padding-top: 0.9rem; font-family: var(--fd); font-weight: 700; display: inline-flex; align-items: center; gap: 8px; }
.pcard:hover .arw { transform: translateX(5px); }
.arw { transition: transform .25s cubic-bezier(.22,1,.36,1); }
@media (prefers-reduced-motion: reduce) { .arw { transition: none; } }

/* wordmarks rendered in each product's own type, as the apps do */
.wm { font-family: Nunito, system-ui, sans-serif; font-weight: 900; letter-spacing: -0.03em; line-height: 1; font-size: 1.5rem; }
/* Bigger and at full opacity: at 10px and 70% these labels measured 2.6–4.0:1. */
.wm-sub { font-family: var(--fd); font-weight: 800; font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; opacity: 1; display: block; margin-top: 4px; }

/* --- feature rows --------------------------------------------------------- */
.frow { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.fitem h3 { margin-bottom: 0.5rem; }
.fitem p { color: var(--muted); font-size: 0.98rem; }
.band-dark .fitem p { color: var(--d-muted); }

/* --- numbered steps ------------------------------------------------------- */
/* A real sequence, so it is an <ol> and the numbers carry meaning. The rule on
   top of each step reads as one line across the row at desktop widths. */
.steps { list-style: none; margin: 0; padding: 0; display: grid;
  gap: clamp(1.5rem, 3vw, 2.25rem);
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); }
.steps li { border-top: 2px solid var(--border); padding-top: 1.15rem; }
.steps li:first-child { border-top-color: var(--gold); }
.step-n { display: block; font-family: var(--fd); font-weight: 800;
  font-size: 0.82rem; letter-spacing: 0.14em; color: var(--muted);
  margin-bottom: 0.6rem; }
.steps h3 { margin-bottom: 0.5rem; }
.steps p { color: var(--muted); font-size: 0.98rem; }

.evidence { list-style: none; margin: 0; padding: 0; display: grid;
  gap: clamp(1.5rem, 3vw, 2.25rem);
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.evidence li { border-top: 2px solid var(--gold); padding-top: 1.15rem; }
.evidence h2, .evidence h3 { margin: 0.55rem 0 0.5rem; }
.evidence p { color: var(--muted); font-size: 0.98rem; }
.evidence .ev-tag { display: block; margin-top: 0.75rem;
  font-family: var(--fd); font-weight: 700; font-size: 0.72rem;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted); }
.band-dark .evidence p { color: var(--d-muted); }
.band-dark .evidence .ev-tag { color: var(--gold-l); }
/* The disclaimer is the credibility of everything above it, so it gets a rule
   of its own rather than reading as a footnote to the last card. */
.ev-not { margin-top: clamp(2rem, 4vw, 3rem); padding-top: 1.4rem;
  border-top: 1px solid var(--d-line); max-width: 62ch; }
.ev-not b { color: #fff; font-weight: 700; }

/* --- contact facts -------------------------------------------------------- */
/* Label above value, four across. A <dl> because that is exactly what it is:
   four terms and their definitions. The label is the small caps line and the
   value is the thing somebody came to the page to copy, so the value is the
   one that gets the size. */
.facts { margin: 0; display: grid; gap: clamp(1.5rem, 3vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.facts dt { font-family: var(--fd); font-weight: 700; font-size: 0.75rem;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted); }
.facts dd { margin: 0.55rem 0 0; font-size: 1.2rem; line-height: 1.35; }
.facts dd a { color: var(--green-read); font-weight: 600; }
/* 600 is not bold, so 1,2rem here is NORMAL text for WCAG and needs 4,5:1. */
.band-dark .facts dd a { color: var(--green-l); }
/* .facts nasceu para banda clara: dt e --muted, que sobre --forest-2 da 3,55:1.
   O contato da /about foi para banda escura, entao o rotulo precisa do dourado
   claro (11,5:1). Os valores usam --green-d e ja passam. */
.band-dark .facts dt { color: var(--gold-l); }


/* --- product lineup ------------------------------------------------------- */
/* Four products and an open slot. The dashed chip is the whole argument for
   custom work, so it has to read as "next one", not as a fifth product. */
.lineup { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 12px 17px; border-radius: 13px;
  background: #fff; border: 1px solid var(--border);
  font-size: 1.05rem; line-height: 1;
}
.chip img { width: 22px; height: 22px; object-fit: contain; flex-shrink: 0; }
.chip-open {
  background: transparent; border-style: dashed; border-color: #cfc4b4;
  color: var(--muted);
}
.chip-open b { font-family: var(--fd); font-weight: 700; letter-spacing: -0.02em; }
.chip-plus {
  width: 22px; height: 22px; border-radius: 6px; flex-shrink: 0;
  display: grid; place-items: center;
  background: var(--off); color: var(--muted); border: 1px dashed #cfc4b4;
  font-family: var(--fd); font-weight: 800; font-size: 0.95rem;
}

/* --- tick list ------------------------------------------------------------ */
.ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: 11px; }
.ticks li { display: flex; gap: 11px; align-items: flex-start; }
.tk { color: var(--gold); font-family: var(--fd); font-weight: 800; flex-shrink: 0; }

/* --- footer --------------------------------------------------------------- */
.foot { background: var(--forest-2); color: var(--d-ink); padding-block: clamp(3rem, 6vw, 4.5rem); }
.foot-grid { display: flex; flex-wrap: wrap; gap: clamp(2rem, 6vw, 5rem); justify-content: space-between; }
.foot h2 { font-family: var(--fd); font-size: 0.74rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--d-faint); margin: 0 0 12px; }
.foot a { display: block; color: var(--d-muted); padding-block: 8px; font-size: 0.96rem; }
.foot a:hover { color: var(--gold-l); }
/* .foot a acima forca display:block em TODO <a> do rodape, o que quebrava o
   lockup em duas linhas. O lockup e uma linha por especificacao de marca. */
.foot .lockup { display: flex; padding-block: 0; }
.foot .word { color: var(--cream); }

@media (prefers-reduced-motion: no-preference) {
  .rise { animation: rise .8s cubic-bezier(.16,1,.3,1) backwards; }
  .rise-2 { animation-delay: .08s; } .rise-3 { animation-delay: .16s; } .rise-4 { animation-delay: .24s; }
  @keyframes rise { from { opacity: 0; transform: translateY(15px); } to { opacity: 1; transform: none; } }
}


/* --- o estreito: rodape e degraus ------------------------------------------
   Os dois gastavam altura repetindo estrutura em vez de conteudo. */
@media (max-width: 600px) {
  /* Tres blocos de 2-3 links empilhados viravam tres faixas quase identicas,
     uma sob a outra. Em duas colunas o rodape cai para perto da metade sem
     perder um unico link; o bloco da marca fica em largura cheia. */
  .foot { padding-block: 2.5rem; }
  .foot-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem 1.25rem; }
  .foot-grid > :first-child { grid-column: 1 / -1; }
  .foot a { padding-block: 10px; }   /* continua acima do alvo de 44px com a linha */

  /* O numero do degrau ocupava uma linha inteira so para si. Sentado na linha
     do titulo diz a mesma coisa e devolve a altura. */
  .steps { gap: 1rem; }
  .steps li { padding-top: 0.7rem; display: grid; grid-template-columns: auto 1fr; column-gap: 10px; align-items: baseline; }
  .step-n { margin-bottom: 0; }
  .steps li h3 { margin-bottom: 0.35rem; }
  .steps li p { grid-column: 2; }
}

/* --- cards de produto no estreito -----------------------------------------
   A altura desta secao e conteudo, nao respiro: quatro produtos com paragrafo
   e checklist. Um carrossel horizontal cortaria ~1300px, e foi descartado pelo
   proprio titulo da secao -- "Pick the one that matches your business" so
   funciona se as opcoes forem visiveis; esconder tres atras de um gesto
   contradiz o que a secao existe para fazer. O que da para devolver e a
   gordura de moldura, e e so isso. */
@media (max-width: 600px) {
  .pcard, .pair-half { padding-block: 20px; }
  .pair-foot { padding-block: 11px; }
  .pcard ul li, .pair-half ul li { gap: 8px; }
  .go { padding-top: 11px; }
}

/* O lockup e um link, e media 32px de altura -- abaixo dos 44px que um dedo
   precisa. O chevron ao lado ja resolvia o seu por area estendida
   (brandmenu.css: ::after com inset -7px sob (hover: none)); este nao tinha
   nada. Cresce a area, nao o desenho. */
@media (hover: none) {
  .lockup { min-height: 44px; }
  .foot .lockup { min-height: 44px; align-items: center; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   COMPONENTES VISUAIS  ·  25/08/2026

   POR QUE ESTES EXISTEM

   Revisando /about e /ai, o Augusto disse: "sinto uma falta enorme na parte
   visual", "muito texto e pouco conteudo visual pra quem eh leigo entender".
   A causa era estrutural: TODA secao das duas paginas tinha a mesma forma -
   pilula, H2, paragrafo, quatro cards de texto. Cinco vezes seguidas. O site
   nao tinha vocabulario para fazer outra coisa.

   Na segunda rodada ele foi mais fundo: "eu gostaria que as imagens dos apps
   estivessem na tela de um computador e num celular, assim fica so o app
   flutuante. a pessoa precisa enxergar que isso estara nos dispositivos que ela
   pode ter a sua disposicao." E: "quando o nome dos apps aparecer, ou o
   wordmark ou a logo ou os dois juntos deveriam acompanhar."

   O QUE ENTRA
     .device    moldura de aparelho de verdade: laptop, tablet, celular
     .lockup    marca + wordmark de um produto, na tipografia dele
     .split     secao de duas colunas: texto de um lado, aparelho do outro
     .swap      par "como e hoje" -> "como fica", com seta no meio

   Sobre o .swap: o padrao nao e invencao minha, ja existe e funciona na pagina
   do Nock (.transform / .tarrow no nock.css) - chamada perdida de um lado, job
   card do outro. E o unico bloco do site inteiro que um leigo entende em dois
   segundos sem ler. Aqui vira componente do sistema.
   ═════════════════════════════════════════════════════════════════════════ */

/* ---------------------------------------------------------------------------
   .device — o produto dentro de um aparelho
   ---------------------------------------------------------------------------
   A versao anterior era uma barra de navegador com tres bolinhas. Funcionava
   como "isto e um programa", mas nao como "isto roda no aparelho que voce ja
   tem" - que e a pergunta que o dono de negocio realmente faz antes de comprar
   (a Lucky Cat nao vende hardware; o argumento inteiro depende disso ficar
   obvio). Moldura de aparelho responde a pergunta sem uma linha de texto.

   O corpo e cinza quente (#1c1b18) e nao preto puro: preto puro sobre a banda
   creme abre um buraco na pagina, e sobre a banda escura some.
   ------------------------------------------------------------------------- */
.device { position: relative; margin: 0; }
.device-screen {
  position: relative;
  background: #1c1b18;
  overflow: hidden;
}
.device-screen img { display: block; width: 100%; height: auto; }

/* --- laptop --------------------------------------------------------------- */
.device--laptop .device-screen {
  border-radius: 12px 12px 3px 3px;
  padding: 13px 13px 15px;
  box-shadow: 0 26px 50px -26px rgba(12, 20, 10, 0.6);
}
.device--laptop .device-screen img { border-radius: 3px; }
/* A camera. Sem ela a moldura lê como televisao, e televisao ninguem tem na
   cozinha. */
.device--laptop .device-screen::before {
  content: "";
  position: absolute;
  top: 5px; left: 50%; translate: -50% 0;
  width: 5px; height: 5px; border-radius: 50%;
  background: #3d3a33;
}
/* A base, em trapezio: e ela que faz o objeto virar laptop e nao monitor. */
.device--laptop .device-foot {
  /* 100% e nao 116%: a versao anterior sobrava 8% para cada lado e punha a
     pagina inteira para rolar de lado em todos os aparelhos medidos. O
     trapezio vem do clip-path abaixo, entao o efeito fica e o estouro sai. */
  width: 100%;
  margin-left: 0;
  height: 13px;
  background: linear-gradient(180deg, #d4cec3 0%, #aaa398 52%, #8a8377 100%);
  border-radius: 0 0 11px 11px;
  clip-path: polygon(5% 0, 95% 0, 100% 100%, 0 100%);
}
/* O recorte do trackpad, na frente da base. */
.device--laptop .device-foot::after {
  content: "";
  display: block;
  width: 86px; height: 4px;
  margin: 0 auto;
  border-radius: 0 0 4px 4px;
  background: rgba(0, 0, 0, 0.16);
}

/* --- tablet --------------------------------------------------------------- */
.device--tablet .device-screen {
  border-radius: 22px;
  padding: 16px 13px;
  box-shadow: 0 26px 50px -26px rgba(12, 20, 10, 0.6);
}
.device--tablet .device-screen img { border-radius: 8px; }
.device--tablet .device-screen::before {
  content: "";
  position: absolute;
  top: 6px; left: 50%; translate: -50% 0;
  width: 6px; height: 6px; border-radius: 50%;
  background: #3d3a33;
}

/* --- celular -------------------------------------------------------------- */
/* .device--sm: o mesmo telefone com as proporcoes de moldura refeitas para
   larguras de ~120px. As medidas fixas (10px de moldura, raio 34) sao corretas
   a 300px e grosseiras a 120: a moldura fica com 8% da largura do aparelho e o
   canto arredonda mais que o vidro real. Usado dentro do trilho do "how it
   works", onde o telefone e um item de uma sequencia, nao o assunto. */
.device--phone.device--sm .device-screen { border-radius: 21px; padding: 5px; }
.device--phone.device--sm .device-screen img { border-radius: 17px; }
.device--phone.device--sm .device-screen::before { top: 9px; width: 30px; height: 3px; }

.device--phone .device-screen {
  border-radius: 34px;
  padding: 10px;
  box-shadow: 0 26px 46px -22px rgba(12, 20, 10, 0.66);
}
.device--phone .device-screen img { border-radius: 25px; }
/* O alto-falante. Dois pixels que decidem se o objeto e um telefone. */
.device--phone .device-screen::before {
  content: "";
  position: absolute;
  top: 17px; left: 50%; translate: -50% 0;
  width: 52px; height: 4px; border-radius: 4px;
  background: rgba(255, 255, 255, 0.2);
  z-index: 2;
}

/* --- legenda -------------------------------------------------------------- */
.device figcaption {
  margin-top: 0.85rem;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--muted);
}
.band-dark .device figcaption { color: var(--d-muted); }

/* --- laptop com celular encostado ----------------------------------------
   Os dois aparelhos juntos sao o argumento: a mesma coisa no computador do
   balcao e no telefone do bolso. Separados, viram duas ilustracoes. */
.device-stack { position: relative; padding-bottom: clamp(1.5rem, 4vw, 2.5rem); }
.device-stack .device--phone {
  position: absolute;
  right: -3%;
  bottom: 0;
  width: 27%;
  max-width: 178px;
  rotate: 3deg;
}
/* A legenda do laptop corre por baixo do telefone encostado, e o telefone
   ocupa 27% da direita: sem este limite as duas ultimas palavras da legenda
   ficam atras do aparelho. Nao e o telefone que sai -- e o texto que para. */
.device-stack .device--laptop figcaption { max-width: 68%; }
@media (max-width: 680px) {
  .device-stack { padding-bottom: 0; }
  .device-stack .device--phone {
    position: static; width: 58%; margin: 1.4rem auto 0; rotate: 0deg;
  }
  /* Empilhado, nao ha nada a direita da legenda para evitar. */
  .device-stack .device--laptop figcaption { max-width: none; }
}

/* ---------------------------------------------------------------------------
   .lockup — o nome de um produto nunca aparece sozinho
   ---------------------------------------------------------------------------
   Pedido do Augusto: "quando o nome dos apps aparecer, ou o wordmark ou a logo
   ou os dois juntos deveriam acompanhar, e isso sempre, independente dos sites,
   a nao ser que seja texto corrido."

   Cada produto tem tipografia propria e ela e respeitada aqui. O Nock sai de
   proposito SEM marca: a identidade dele e wordmark puro, decidida em 25/08.

   Tudo dimensionado em `em` para o lockup herdar o tamanho de onde estiver -
   serve num H3 e numa legenda sem ajuste. */
.lockup {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  line-height: 1;
  white-space: nowrap;
}
.lockup img { width: 1.15em; height: 1.15em; object-fit: contain; flex: none; }
.lockup b { font-weight: 900; letter-spacing: -0.03em; }
.lockup--ownly b { font-family: Nunito, system-ui, sans-serif; }
.lockup--tillr b { font-family: Nunito, system-ui, sans-serif; }
.lockup--tillr img { border-radius: 0.22em; }
.lockup--nock  b { font-family: Archivo, system-ui, sans-serif; font-weight: 700; letter-spacing: 0; }
.lockup--pitch b { font-family: Poppins, system-ui, sans-serif; font-weight: 700; letter-spacing: -0.02em; }
.lockup--syn   b { font-family: Newsreader, Georgia, serif; font-weight: 500; letter-spacing: -0.02em; }

/* ---------------------------------------------------------------------------
   .split — texto de um lado, aparelho do outro
   ------------------------------------------------------------------------- */
.split {
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1.18fr); }
  .split--flip .split-media { order: -1; }
}
.split-copy > * + * { margin-top: 1.15rem; }

/* ---------------------------------------------------------------------------
   .swap — como e hoje  ->  como fica
   ------------------------------------------------------------------------- */
.swap {
  display: grid;
  gap: clamp(0.9rem, 2.2vw, 1.6rem);
  grid-template-columns: 1fr;
  align-items: stretch;
}
@media (min-width: 860px) {
  .swap { grid-template-columns: 1fr auto 1.14fr; align-items: center; }
}
.swap-arrow {
  display: grid;
  place-items: center;
  color: var(--gold);
  font-size: 1.7rem;
  font-weight: 800;
  line-height: 1;
}
@media (max-width: 859px) { .swap-arrow { rotate: 90deg; padding-block: 2px; } }

.swap-card {
  border-radius: 16px;
  padding: clamp(1.05rem, 2.3vw, 1.45rem);
  border: 1px solid var(--border);
  background: var(--off);
}
/* O lado esquerdo e o problema que a pessoa ja tem. Tracejado e cor apagada
   porque ele precisa parecer inacabado: e o estado que ela quer deixar. */
.swap-card--now { border-style: dashed; border-color: #cfc4b4; background: transparent; }
.swap-card--now .swap-line { color: var(--muted); }
/* O lado direito e o resultado. Fundo solido e sombra: e a coisa terminada. */
.swap-card--after { background: #fff; border-color: var(--border);
  box-shadow: 0 24px 48px -30px rgba(12, 20, 10, 0.45); }

.swap-label {
  font-family: var(--fd); font-weight: 700; font-size: 0.7rem;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted);
}
.swap-title { font-family: var(--fd); font-weight: 800; letter-spacing: -0.02em;
  font-size: clamp(1.05rem, 2.2vw, 1.3rem); margin: 0.5rem 0 0; }
.swap-line { margin: 0.55rem 0 0; font-size: 0.95rem; line-height: 1.55; color: var(--muted); }
.swap-card--after .swap-line { color: var(--ink); }

.band-dark .swap-card { border-color: var(--d-line); }
.band-dark .swap-card--now { border-color: #35492b; }
.band-dark .swap-card--now .swap-line,
.band-dark .swap-label { color: var(--d-faint); }
.band-dark .swap-card--after { background: rgba(255, 255, 255, 0.05); border-color: rgba(255,255,255,.13); }
.band-dark .swap-title { color: #fff; }
.band-dark .swap-card--after .swap-line { color: var(--d-ink); }

/* ---------------------------------------------------------------------------
   .gain — o que a pessoa GANHA, em unidades que ela sente
   ---------------------------------------------------------------------------
   Pedido do Augusto: a pagina tem de deixar claro que o resultado e mais tempo,
   mais produtividade, mais qualidade de vida e, por consequencia, mais lucro.
   Isso nao cabe num card de texto igual aos outros: precisa de peso proprio.
   Numero grande em cima, o que ele significa embaixo. */
.gains {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: clamp(1.25rem, 3vw, 2rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}
.gain-fig {
  font-family: var(--fd); font-weight: 800; letter-spacing: -0.035em;
  font-size: clamp(2rem, 4.6vw, 2.9rem); line-height: 1;
  color: var(--gold);
}
.band-off .gain-fig, .band-cream .gain-fig { color: var(--green-d); }
.gain h3 { margin: 0.6rem 0 0.35rem; font-size: 1.05rem; }
.gain p { margin: 0; color: var(--muted); font-size: 0.95rem; line-height: 1.55; }
.band-dark .gain p { color: var(--d-muted); }

/* ---------------------------------------------------------------------------
   MOTION — extensoes do sistema que ja existe em assets/motion.css
   ---------------------------------------------------------------------------
   Tudo continua atras de `html.motion`, que so entra quando ha JavaScript e o
   sistema NAO pede movimento reduzido. Sem essa classe a pagina fica visivel e
   parada: nenhum conteudo depende de uma animacao que pode nao rodar.
   ------------------------------------------------------------------------- */

/* O par antes->depois ENCENA a transformacao em vez de so aparecer: o estado de
   hoje entra primeiro, a seta acende, e o resultado chega por ultimo, vindo da
   esquerda. A ordem e o conteudo. */
html.motion .swap[data-reveal] .swap-card--now { opacity: 0; transform: translateY(14px); }
html.motion .swap[data-reveal] .swap-arrow     { opacity: 0; transform: scale(.6); }
html.motion .swap[data-reveal] .swap-card--after { opacity: 0; transform: translate(-18px, 14px); }
html.motion .swap[data-reveal].is-in .swap-card--now,
html.motion .swap[data-reveal].is-in .swap-arrow,
html.motion .swap[data-reveal].is-in .swap-card--after {
  opacity: 1; transform: none;
  transition: opacity .6s var(--e-out), transform .6s var(--e-out);
}
html.motion .swap[data-reveal].is-in .swap-arrow      { transition-delay: .18s; }
html.motion .swap[data-reveal].is-in .swap-card--after { transition-delay: .3s; }

/* O aparelho nao sobe junto com o texto: ele se aproxima. Escala leve, sem
   overshoot, para nao virar apresentacao de slide. */
html.motion .device[data-reveal] { opacity: 0; transform: translateY(20px) scale(.985); }
html.motion .device[data-reveal].is-in {
  opacity: 1; transform: none;
  transition: opacity .8s var(--e-out), transform .8s var(--e-out);
}


/* ═══════════════════════════════════════════════════════════════════════════
   VISUAL COMPONENTS  ·  v3  ·  26/08/2026

   WHY THIS ROUND EXISTS

   Two things were still wrong after v2.

   1. /about and /ai asked for `.shot`, `.shot--browser` and `.shot-pair` —
      classes that were never written. Those images were rendering as bare app
      screenshots on a coloured band, which is exactly the complaint ("os apps
      ficam flutuando"). Everything on those pages now uses `.device`, which
      does exist, and the dead class names are gone from the markup.

   2. Every section still resolved to the same silhouette: kicker, heading,
      paragraph, row of equal boxes. A page cannot get more visual by writing
      more text into the same box. So this round adds SHAPES that carry meaning
      on their own — paper, a clock strip, a rail, an artefact panel — and each
      one is used ONCE per page, so no two sections repeat a silhouette.

   Everything below is additive. No existing selector is redefined.
   ═════════════════════════════════════════════════════════════════════════ */

/* ---------------------------------------------------------------------------
   .device--tablet-land — a tablet held sideways
   ---------------------------------------------------------------------------
   The ordering app screenshot is landscape, and a landscape screen in an even
   bezel reads as a television. Two changes fix it: wider bezel on the short
   edges (that is how a tablet is actually built, so it is where your hands go)
   and the camera moved to the middle of the LEFT edge. Those two details are
   the whole difference between "a telly" and "the tablet on my counter".
   ------------------------------------------------------------------------- */
.device--tablet-land .device-screen { border-radius: 20px; padding: 12px 20px; }
.device--tablet-land .device-screen::before {
  top: 50%; left: 8px; translate: 0 -50%;
  width: 6px; height: 6px;
}

/* ---------------------------------------------------------------------------
   .paper-stack — the "before" that needs no caption
   ---------------------------------------------------------------------------
   Drawn in CSS rather than photographed: what has to read is the OBJECT, and
   ruled sheets at slightly wrong angles say "paper" faster than any sentence
   about digitalisation. The angles are deliberately uneven — a tidy stack
   reads as stationery for sale, a crooked one reads as Tuesday.
   ------------------------------------------------------------------------- */
.paper-stack { position: relative; aspect-ratio: 5 / 4; }
.sheet {
  position: absolute;
  width: 58%; aspect-ratio: 1 / 1.3;
  background: #fffdf8;
  border: 1px solid #e6ddcd;
  border-radius: 2px;
  box-shadow: 0 12px 26px -16px rgba(26, 18, 6, .5);
  /* Ruled lines. 15px is close enough to the pitch of a real refill pad that
     the eye stops asking what the texture is. */
  background-image: repeating-linear-gradient(#fffdf8 0 14px, #ece3d2 14px 15px);
  background-position: 0 18px;
}
.sheet:nth-child(1) { left:  2%; top: 10%; rotate: -8deg; }
.sheet:nth-child(2) { left: 16%; top:  4%; rotate:  4.5deg; }
.sheet:nth-child(3) { left: 30%; top: 13%; rotate: -2deg; }
/* The top sheet carries the only human mark: a red margin rule. It is what
   makes the stack a docket book instead of three grey rectangles. */
.sheet:nth-child(3)::before {
  content: ""; position: absolute; inset: 0 auto 0 14%;
  width: 1px; background: rgba(180, 60, 40, .45);
}
@media (prefers-reduced-motion: reduce) { .sheet { rotate: none; } }
@media (max-width: 520px) {
  /* Three sheets at three angles need width to read as a stack. Narrow, the
     fan closes up and the top sheet does the work on its own. */
  .sheet:nth-child(1) { left: 6%; rotate: -5deg; }
  .sheet:nth-child(2) { left: 18%; rotate: 3deg; }
  .sheet:nth-child(3) { left: 30%; rotate: -1deg; }
}

/* ---------------------------------------------------------------------------
   .daystrip — the same two hours, twice
   ---------------------------------------------------------------------------
   The strongest thing this studio sells is time, and time has an obvious
   graphic form: an axis. Above the line, the jobs a person does by hand, one
   block each. Below it, the one block that runs on its own — and the empty
   track beside it IS the argument. Nothing here is a claim about how much time
   is saved; it is the shape of a morning, which the reader can check against
   their own.
   ------------------------------------------------------------------------- */
.daystrip {
  border: 1px solid var(--border); border-radius: 20px; background: #fff;
  padding: clamp(1.1rem, 2.6vw, 1.75rem);
  box-shadow: 0 28px 56px -38px rgba(12, 20, 10, .5);
}
.drow { display: grid; grid-template-columns: 1fr; gap: 8px; }
.drow + .drow { margin-top: 1.1rem; }
@media (min-width: 720px) { .drow { grid-template-columns: 7.5rem 1fr; gap: 14px; align-items: center; } }
.dlabel {
  font-family: var(--fd); font-weight: 700; font-size: .74rem;
  letter-spacing: .11em; text-transform: uppercase; color: var(--muted);
}
.dtrack { display: flex; gap: 6px; padding: 6px; border-radius: 12px; background: var(--off); min-height: 56px; }
.dchip {
  flex: 1 1 0; min-width: 0; border-radius: 8px; padding: 7px 9px;
  background: #eae0cd; color: #5c4d33;
  font-size: .74rem; line-height: 1.25; display: grid; align-content: center;
}
/* The automated block keeps the width of the job it replaced, so the gap to
   its right is measurable by eye rather than described in a sentence. */
.dchip--auto {
  background: var(--green-xl); color: #1d6b26;
  border: 1px solid rgba(42, 158, 55, .4); font-weight: 600;
}
.dchip--free { background: transparent; color: var(--muted); border: 1px dashed #d8ccb8; flex-grow: 4; }
.dscale { display: flex; justify-content: space-between; margin-top: 10px; font-size: .74rem; color: var(--muted); }

/* Abaixo de 400px a fileira de chips nao tem mais para onde encolher e empurra
   a pagina para fora da tela (medido: 39px num iPhone SE). Aqui ela quebra em
   duas linhas, que e o unico jeito de caber sem encolher o texto ate o
   ilegivel. */
@media (max-width: 400px) {
  .dtrack { flex-wrap: wrap; min-height: 0; }
  .dtrack .dchip { flex: 1 1 46%; }
  .dchip--free { flex-basis: 100%; }
}

/* ---------------------------------------------------------------------------
   .jobs — ordinary work, set as type instead of in cards
   ---------------------------------------------------------------------------
   These are examples of WORK, never quotes and never attributed to anybody:
   there is no customer to quote, and a sentence in inverted commas beside a
   trade name would read as a testimonial. Hairlines and display type do the
   separating, which is also how this section avoids being another card row.
   ------------------------------------------------------------------------- */
.jobs {
  list-style: none; margin: 0; padding: 0; text-align: left;
  display: grid; grid-template-columns: 1fr;
  border-top: 1px solid var(--border);
}
@media (min-width: 760px) { .jobs { grid-template-columns: 1fr 1fr; column-gap: clamp(2rem, 5vw, 4rem); } }
.jobs li {
  border-bottom: 1px solid var(--border);
  padding: clamp(.9rem, 2vw, 1.25rem) 0;
  display: grid; grid-template-columns: auto 1fr; gap: 14px; align-items: baseline;
}
.jobs b {
  font-family: var(--fd); font-weight: 800; letter-spacing: -.02em;
  font-size: clamp(1.02rem, 1.8vw, 1.2rem); line-height: 1.3;
}
/* A 7px gold square, the smallest possible marker. It exists to give the
   column a left edge; anything more decorative would compete with the words. */
.jobs .mk {
  width: 8px; height: 8px; border-radius: 2px; background: var(--gold);
  translate: 0 -.35em;
}

/* ---------------------------------------------------------------------------
   .pull — one sentence at heading weight, no heading role
   ---------------------------------------------------------------------------
   Used where a section needs a beat of emphasis without another H2 in the
   outline. Set in the display face at a size between .lead and h2.
   ------------------------------------------------------------------------- */
.pull {
  font-family: var(--fd); font-weight: 800; letter-spacing: -.03em;
  font-size: clamp(1.35rem, 2.9vw, 2rem); line-height: 1.18;
  text-wrap: balance; max-width: 34ch;
}
.pull em { font-style: normal; color: var(--gold); }
.band-off .pull em, .band-cream .pull em { color: var(--green-d); }

/* ---------------------------------------------------------------------------
   .shapes — what the answer can be
   ---------------------------------------------------------------------------
   The positioning says the solution is sometimes small: a website, an app, one
   automation, something that answers. Four words would be abstract; four
   objects are not. Each glyph is built from borders — a rectangle with a fat
   top edge is a web page, a tall rounded rectangle is a phone — because that
   is the level of drawing a reader decodes instantly and a designer cannot get
   precious about.
   ------------------------------------------------------------------------- */
.shapes {
  display: grid; gap: clamp(.7rem, 1.6vw, 1rem); text-align: left;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
}
.shape {
  display: grid; gap: 10px; align-content: start;
  padding: clamp(.9rem, 1.8vw, 1.15rem);
  border-radius: 16px; border: 1px solid var(--border); background: #fff;
}
.band-dark .shape { background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .14); }
.shape-art { height: 52px; display: grid; place-items: center; }
.shape b { font-family: var(--fd); font-weight: 800; font-size: 1.02rem; letter-spacing: -.02em; }
.shape span { font-size: .88rem; line-height: 1.45; color: var(--muted); }
.band-dark .shape span { color: var(--d-muted); }

/* the glyphs — simple geometry only, in gold on both bands */
.gl { display: block; border: 2px solid var(--gold); }
.gl-page  { width: 62px; height: 40px; border-radius: 4px; border-top-width: 9px; }
.gl-phone { width: 26px; height: 46px; border-radius: 7px; border-top-width: 7px; border-bottom-width: 7px; }
/* Two things joined, with the join doing the work: dot, line, dot. */
.gl-auto  { width: 62px; height: 0; border: 0; border-top: 2px solid var(--gold); position: relative; }
.gl-auto::before, .gl-auto::after {
  content: ""; position: absolute; top: 50%; width: 12px; height: 12px;
  border-radius: 50%; translate: 0 -50%; background: var(--gold);
}
.gl-auto::before { left: -2px; }
.gl-auto::after  { right: -2px; background: var(--green); }
/* Two speech bubbles, one answering the other. */
.gl-talk { width: 54px; height: 40px; border: 0; position: relative; }
.gl-talk::before, .gl-talk::after {
  content: ""; position: absolute; border: 2px solid var(--gold); border-radius: 9px 9px 9px 2px;
  width: 34px; height: 18px;
}
.gl-talk::before { top: 0; left: 0; }
.gl-talk::after  { bottom: 0; right: 0; border-radius: 9px 9px 2px 9px; border-color: var(--green); }

/* ---------------------------------------------------------------------------
   .frag — a fragment of the finished thing
   ---------------------------------------------------------------------------
   For the places where a full screenshot is too much and a sentence is too
   little: the two or three rows of interface that carry the point. Real words
   only. Greeked grey bars would put the abstraction straight back.
   ------------------------------------------------------------------------- */
.frag {
  border-radius: 14px; border: 1px solid var(--border); background: #fff;
  padding: clamp(.85rem, 1.8vw, 1.1rem); display: grid; gap: 9px;
  box-shadow: 0 24px 48px -34px rgba(12, 20, 10, .45);
}
.band-dark .frag { background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .14); box-shadow: none; }
.frag-head {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--fd); font-weight: 700; font-size: .72rem;
  letter-spacing: .11em; text-transform: uppercase; color: var(--muted);
}
.band-dark .frag-head { color: var(--d-faint); }
.frag-head .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green); flex: none; }
.frag-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 11px; border-radius: 10px; background: var(--off); font-size: .93rem; line-height: 1.35;
}
.band-dark .frag-row { background: rgba(255, 255, 255, .06); }
.frag-row b { font-family: var(--fd); font-weight: 700; }
.frag-row .tick { color: var(--green-read); font-weight: 800; flex: none; }
.band-dark .frag-row .tick { color: var(--green-l); }
.frag-note { font-size: .86rem; line-height: 1.5; color: var(--muted); }
.band-dark .frag-note { color: var(--d-muted); }

/* the message thread variant — a question arriving and being answered */
.thread { display: grid; gap: 8px; }
.bub { max-width: 88%; padding: 9px 12px; border-radius: 15px; font-size: .92rem; line-height: 1.45; }
.bub-cust { justify-self: start; background: var(--off); color: var(--ink); border-bottom-left-radius: 4px; }
.bub-nock { justify-self: end; background: var(--forest-2); color: var(--d-ink); border-bottom-right-radius: 4px; }
.band-dark .bub-cust { background: rgba(255, 255, 255, .1); color: var(--d-ink); }
.band-dark .bub-nock { background: var(--gold); color: var(--ink); }

/* ---------------------------------------------------------------------------
   .plates — /ai's own section shape
   ---------------------------------------------------------------------------
   /about explains the change with a dashed card becoming a solid one. /ai has
   to do something else, or the two pages are the same page. So here each item
   is a PLATE: a numbered line, a plain-English sentence, and beside it the
   artefact — the actual rows of the actual thing. Sides alternate, which is
   what stops four plates reading as a list.
   ------------------------------------------------------------------------- */
.plates { list-style: none; margin: 0; padding: 0; display: grid; gap: clamp(2.25rem, 5vw, 3.5rem); }
.plate { display: grid; gap: clamp(1.1rem, 3vw, 2.25rem); grid-template-columns: 1fr; align-items: center; border-top: 2px solid var(--border); padding-top: clamp(1.1rem, 2.4vw, 1.6rem); }
.plate:first-child { border-top-color: var(--gold); }
@media (min-width: 900px) {
  .plate { grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr); }
  .plate:nth-child(even) .plate-art { order: -1; }
}
.plate-n { font-family: var(--fd); font-weight: 800; font-size: .8rem; letter-spacing: .14em; color: var(--muted); }
.band-dark .plate-n { color: var(--gold-l); }
.plate h3 { margin: .55rem 0 .55rem; font-size: clamp(1.3rem, 2.5vw, 1.75rem); }
.plate p { color: var(--muted); font-size: 1rem; }
.band-dark .plate p { color: var(--d-muted); }

/* ---------------------------------------------------------------------------
   .flow — the workflow as a rail, not four boxes
   ---------------------------------------------------------------------------
   This section is a sequence, so the graphic is a line with stops on it and
   each stop shows the thing that changes hands at that point. The rail is a
   pseudo-element on the list so motion.css can draw it left to right; without
   motion it is simply a drawn line, which is what it has to be.
   ------------------------------------------------------------------------- */
.flow { list-style: none; margin: 0; padding: 0; position: relative; display: grid; gap: clamp(1.5rem, 3vw, 2rem); grid-template-columns: 1fr; }
@media (min-width: 940px) { .flow { grid-template-columns: repeat(4, 1fr); column-gap: clamp(1rem, 2.2vw, 1.75rem); } }
.flow-stop { display: grid; gap: .7rem; align-content: start; position: relative; }
.flow-art { min-height: 150px; display: grid; align-content: end; }
/* The stop marker sits on the rail: number in the display face, a dot under
   it. Both stay put when the rail is not drawn. */
.flow-mark { display: flex; align-items: center; gap: 10px; border-top: 2px solid var(--border); padding-top: .9rem; }
.flow-stop:first-child .flow-mark { border-top-color: var(--gold); }
.flow-n { font-family: var(--fd); font-weight: 800; font-size: .8rem; letter-spacing: .14em; color: var(--muted); }
.flow-stop h3 { font-size: clamp(1.08rem, 1.7vw, 1.25rem); }
.flow-stop p { color: var(--muted); font-size: .95rem; }

/* ---------------------------------------------------------------------------
   lockups, everywhere
   ---------------------------------------------------------------------------
   House rule: a product name is never set as plain text. These are the bits
   the v2 component was missing to make that hold on every band and in the
   footer.
   ------------------------------------------------------------------------- */
/* The one coloured letter in tillr. #c96b10 is the official mark colour on
   light. On the dark bands it drops to a muddy brown, so there it swaps to the
   amber that was rejected for cream (1.97:1 there, 8.6:1 here). */
.lockup--tillr b i { font-style: normal; color: var(--tillr-orange); }
.lockup--ownly b { color: var(--ownly-deep); }
.lockup--nock  b { color: var(--nock-deep); }
/* The footer is dark but does NOT carry .band-dark — it is styled by .foot. That
   gap made `ownly` render at #14342b on #0d1708 (1,36:1) and `Nock` at #0d3a63
   (1,58:1): six navigation links, on three pages, effectively invisible. The
   symptom was already known and patched by hand once, with a style="color:#fff"
   on one lockup in ai.html. This is the same rule, applied where it belongs. */
.band-dark .lockup b, .foot .lockup b { color: #fff; }
/* ...but a LIGHT-filled button inside a dark band is not a dark ground. `ownly` in
   a .btn-gold on ai.html was inheriting the white above and measuring 2,21:1 on
   #d4a843 -- and brandRules already says gold is a fill that takes ink on top.
   The button's own colour wins over the band's. */
.band-dark .btn-gold .lockup b, .band-dark .btn-line .lockup b,
.foot .btn-gold .lockup b,      .foot .btn-line .lockup b { color: var(--ink); }
.band-dark .btn-gold .lockup--tillr b i, .band-dark .btn-line .lockup--tillr b i
  { color: var(--tillr-orange); }
.band-dark .lockup--tillr b i, .foot .lockup--tillr b i { color: var(--orange); }
/* `.foot a` forces display:block and `.foot .lockup` zeroes the padding for the
   Lucky Cat lockup in the corner. A product lockup in the footer is both at
   once, so it needs its own rule or it lands under the 44px touch target. */
.foot a.lockup--ownly, .foot a.lockup--tillr,
.foot a.lockup--nock,  .foot a.lockup--pitch, .foot a.lockup--syn {
  display: flex; align-items: center; min-height: 44px; padding-block: 8px;
}

.demo-note{font-size:.875rem;line-height:1.5;color:var(--muted);margin-top:1rem}
.band-dark .demo-note{color:var(--d-muted)}
/* Two products sold as one platform: the ampersand belongs to the pair, not to
   either lockup, so it is set outside both. */
.lockup-pair { display: inline-flex; align-items: center; gap: .45em; flex-wrap: wrap; }
.lockup-pair .amp { color: var(--muted); font-weight: 600; }
.band-dark .lockup-pair .amp, .foot .lockup-pair .amp { color: var(--d-faint); }

/* ---------------------------------------------------------------------------
   .hero-mark — the Lucky Cat, in the hero, where it was missing entirely
   ---------------------------------------------------------------------------
   The home page opened with a text pill and no mark: the one page a stranger
   arrives on had nothing on it to remember. The cat sits above the pill at a
   size that survives a phone, with the same gold field the band already uses
   pooling behind it.
   ------------------------------------------------------------------------- */
.hero-mark { position: relative; display: grid; place-items: center; width: clamp(72px, 11vw, 104px); aspect-ratio: 1; }
.hero-mark img { width: 100%; height: auto; position: relative; }
.hero-mark::before {
  content: ""; position: absolute; inset: -22%;
  background: radial-gradient(closest-side, rgba(212, 168, 67, .3), transparent 72%);
}

/* ---------------------------------------------------------------------------
   .proof — the four finished things, as lockups
   ---------------------------------------------------------------------------
   Replaces the bold-text row under the hero. Same job, but each name arrives
   with its mark and in its own typeface, and the trade sits under it in small
   caps so the row scans as "who each one is for".
   ------------------------------------------------------------------------- */
.proof { list-style: none; margin: clamp(3rem, 6vw, 4.5rem) 0 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: clamp(1rem, 3vw, 2.5rem); }
.proof li { display: grid; gap: 6px; justify-items: center; font-size: 1.12rem; }
.proof .for { font-family: var(--fd); font-weight: 700; font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--d-faint); }

/* --- .qa: perguntas e respostas ------------------------------------------
   Forma nova de proposito. O site ja tem grade de quatro cards, par
   antes-depois e coluna dividida; repetir uma delas aqui faria a secao
   desaparecer no meio da pagina. Uma pilha de perguntas com regua fina entre
   elas le como indice, que e exatamente o que esta secao e.

   Texto visivel e nao acordeao: o conteudo desta secao existe para ser lido e
   para ser EXTRAIDO por um assistente. Escondido atras de um clique ele
   continua no HTML, mas deixa de ser a primeira coisa que a pessoa ve quando
   chega procurando a resposta. */
.qa > h3 {
  font-size: clamp(1.05rem, 2.2vw, 1.25rem);
  max-width: 30ch;
}
.qa > h3 + p {
  margin-top: 0.7rem;
  color: var(--muted);
  max-width: 68ch;
  line-height: 1.65;
}
.qa > h3 ~ h3 {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  padding-top: clamp(1.75rem, 3.5vw, 2.5rem);
  border-top: 1px solid var(--border);
}
.band-dark .qa > h3 + p { color: var(--d-muted); }
.band-dark .qa > h3 ~ h3 { border-top-color: var(--d-line); }
