/* ============================================================================
   Docolect - marketing site styles.css
   Landing, pricing, contact and terms. Sold to Portuguese contabilistas
   certificados. No build step, runs from file:// and from a static host.

   Rules this file keeps, carried from the product stylesheet:
   - Ring first (box-shadow: 0 0 0 1px var(--line)). On this site a real
     shadow exists in exactly two places: the hero screenshot frame and the
     sticky nav once it has scrolled. Nowhere else.
   - --accent is fill / wash / focus. Never white text on it (2.55:1, it
     fails). Primary buttons use --accent-deep.
   - The status spine, a 3px leading-edge bar, is the signature element. Here
     it appears only on the six benefit blocks and the three how-it-works
     steps, where it carries meaning. It is not decoration.
   - Bricolage Grotesque only at large sizes: hero title, section titles, the
     closing title, the step numerals and the price floor. Never body copy.
   - Containers do not carry the page rhythm. Only .sec sets vertical padding,
     so .sec and a content block can never fight over the same box.
   - No decorative animation, no gradient hero, no preloader, no carousel,
     no tabs. The motion budget is hover states, the sticky nav, and one
     optional reveal on the benefit blocks.

   Hooks this file expects from site.js (states, not new block names):
   - .nav.is-stuck or .nav[data-stuck]      nav has scrolled
   - html[data-reveal] + .benefit.is-in     optional benefit reveal. Without
     the html-level flag nothing is ever hidden, so no-JS is safe.
   - [aria-pressed="true"] / [aria-current] inside .nav__lang and .toc
   - [hidden] on .faq__a for the disclosure. Never a max-height collapse,
     because an overflow:hidden collapse clips the focus outline.

   Terms pages: the .legal__h heading strings in i18n.js carry their own number
   ("1. Definicoes"), which is also what the contents list renders, so the CSS
   counter that used to draw one here was removed. Do not add it back without
   stripping the numbers from i18n.
   ========================================================================== */


/* === TOKENS ============================================================== */

/* Copied verbatim from conferido-prototype/styles.css. The site and the
   product must be recognisably one thing, so this block does not drift. */

:root{
  /* core six, all lifted from uniplaces.com */
  --ink:#224251;          /* text, table numbers */
  --slate:#5A6B77;        /* labels, secondary text. Uniplaces ships #647A85, which is
                             exactly 4.50 on pure white and fails on every ground this app
                             actually uses (canvas 4.15, field 4.28, ok-wash 4.02).
                             Darkened one step, same hue family: 5.09 / 5.15 / 4.92. */
  --line:#BCC6CA;         /* hairlines and rings */
  --accent:#00ADEF;       /* fills, progress, focus ring, washes. WHITE-LABEL VARIABLE */
  --accent-deep:#005879;  /* accent text, primary buttons */
  --wash:#ECF7FC;         /* selected and active surfaces */

  /* surfaces */
  --paper:#FFFFFF;
  --canvas:#F4F6F7;       /* accountant canvas, cool */
  --field:#F0FBFF;        /* client portal field, pale cyan. NEVER cream */

  /* status */
  --ok:#16785F;      --ok-wash:#E8F5EF;    /* matched, complete */
  --soon:#8F5410;    --soon-wash:#FBF0E0;  /* deadline approaching, needs review.
                             Was #B4553A, a red-orange only dE 15 from --late, so overdue
                             and approaching read as one colour in a 3px spine. Moved to
                             amber so red means overdue and nothing else. 5.9 on white. */
  --late:#B3352C;    --late-wash:#FBE9E7;  /* genuinely overdue only */
  /* "missing" has NO colour. hollow spine in --line. this is deliberate. */

  /* shape */
  --r-chip:4px; --r-ctl:8px; --r-card:12px; --r-soft:18px; --r-pill:999px;

  /* elevation. ring first, shadow is a whisper */
  --ring:0 0 0 1px var(--line);
  --lift:0 3px 10px rgba(34,66,81,.10);
  --lift-lg:0 10px 34px rgba(34,66,81,.16);

  /* type scale */
  --t-xs:11px; --t-sm:12.5px; --t-base:14px; --t-md:15px;
  --t-lg:18px; --t-xl:23px; --t-2xl:30px; --t-3xl:44px;

  /* rhythm, 4px base, 20/30 from their --gap */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:30px; --s7:44px;
}

/* Non-colour helpers. Not part of the spec token set. Same two font stacks
   and the same easing as the product; the widths and the larger type steps
   are the marketing scale, which is allowed to be bigger than the app. */
:root{
  --f-display:'Bricolage Grotesque', 'Instrument Sans', system-ui, sans-serif;
  --f-body:'Instrument Sans', system-ui, -apple-system, sans-serif;
  --f-mono:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --ease-out:cubic-bezier(.22,1,.36,1);
  /* room for a 2.5px outline at 2px offset inside a scroll container */
  --focus-pad:6px;

  /* layout */
  --w-page:1120px;        /* content column, padding included */
  --w-prose:680px;        /* running text, lands near 65 characters */
  --pad-x:clamp(20px, 5vw, 40px);
  --sec-y:clamp(48px, 6.5vw, 88px);
  --nav-h:64px;

  /* marketing type steps, above the app scale */
  --t-4xl:clamp(30px, 3.4vw, 40px);   /* section titles */
  --t-5xl:clamp(33px, 5.4vw, 58px);   /* hero title */
  --s8:64px; --s9:88px;

  /* Hero screenshot. The image is rendered at a FIXED css width at every
     viewport, so the app text keeps one constant, legible size and the
     frame simply crops tighter as the window narrows. 1240px across a
     1440pt-wide app capture = 0.86 scale, so a 16pt client name renders
     at about 14px on any screen. Do not change this to a percentage. */
  --shot-w:1240px;
}


/* === RESET AND BASE ====================================================== */

*,*::before,*::after{box-sizing:border-box;}

html{-webkit-text-size-adjust:100%; scroll-behavior:smooth; scroll-padding-top:calc(var(--nav-h) + 24px);}

body{
  margin:0;
  background:var(--canvas);
  color:var(--ink);
  font-family:var(--f-body);
  font-size:var(--t-md);
  line-height:1.55;
  font-variant-numeric:tabular-nums;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;   /* nothing may bleed sideways; the hero crop is clipped by its frame */
}

[hidden]{display:none !important;}

img,svg{max-width:100%;}
svg{display:block;}

button,input,select,textarea{font-family:inherit; color:inherit;}
button{cursor:pointer;}

a{color:var(--accent-deep); text-decoration-thickness:1px; text-underline-offset:2px;}
a:hover{text-decoration-thickness:2px;}

ul,ol{margin:0; padding:0; list-style:none;}
p,h1,h2,h3,h4,dl,dd,figure,blockquote{margin:0;}

/* Focus is always visible. The only overflow:hidden box on this site is
   .hero__shotframe, and it contains an image, never a focusable element. */
/* --accent-deep, not --accent: a focus indicator is non-text content and needs
   3:1 (WCAG 1.4.11). --accent is 2.55:1 on paper and 2.34:1 on wash, so it
   failed on the two grounds this site actually uses. --accent-deep is 7.86:1. */
:focus-visible{outline:2.5px solid var(--accent-deep); outline-offset:2px;}
:focus:not(:focus-visible){outline:none;}

::selection{background:var(--wash); color:var(--accent-deep);}

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


/* === TYPOGRAPHY ========================================================== */

/* Bricolage Grotesque only at large sizes. Never body copy, never a table. */
.hero__title,
.sec__title,
.close__title,
.problem__quote,
.step__num,
.price__floor{
  font-family:var(--f-display);
  font-weight:650;
  letter-spacing:-.02em;
  text-wrap:balance;
}

.hero__title{font-size:var(--t-5xl); font-weight:700; letter-spacing:-.03em; line-height:1.04;}
.sec__title{font-size:var(--t-4xl); line-height:1.1;}
.close__title{font-size:var(--t-4xl); line-height:1.1;}

/* Every numeric surface is explicitly tabular. */
.step__num,.price__floor,.price__driver,.foot__legal,
.trust__fact,.legal__h,.legal__p,.hero__micro,.faq__a{
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;
}

.sec__eyebrow{
  font-size:var(--t-xs); font-weight:700;
  letter-spacing:.12em; text-transform:uppercase;
  color:var(--slate);
}

.sec__lede{
  max-width:var(--w-prose);
  font-size:var(--t-lg);
  line-height:1.6;
  color:var(--slate);
  text-wrap:pretty;
}


/* === SHARED COMPONENTS =================================================== */

/* ---- page bands and the content column ---------------------------------- */

.sec{
  padding-block:var(--sec-y);
}

.sec__inner,
.hero__inner,
.nav__inner,
.foot__inner{
  width:100%;
  max-width:var(--w-page);
  margin-inline:auto;
  padding-inline:var(--pad-x);
}

.sec__inner{
  display:flex; flex-direction:column;
  gap:var(--s6);
}

/* ---- buttons ------------------------------------------------------------
   One dominant treatment on the whole site: .btn--primary. .btn--ghost is a
   quiet utility control (back to top, a contents toggle). It carries no ring
   and no fill on purpose, so it can never read as a second call to action
   standing next to the primary one. There is no secondary button. */

.btn{
  display:inline-flex; align-items:center; justify-content:center;
  gap:var(--s2);
  font:inherit; font-size:var(--t-md); font-weight:600; line-height:1.2;
  padding:11px 20px;
  border:0; border-radius:var(--r-ctl);
  background:var(--paper); color:var(--ink);
  box-shadow:var(--ring);
  text-decoration:none; white-space:nowrap;
  -webkit-appearance:none; appearance:none;
  transition:background .18s ease, color .18s ease, box-shadow .18s ease,
             filter .18s ease, transform .12s ease;
}
.btn:hover{background:var(--wash); color:var(--accent-deep);}
.btn:active{transform:translateY(1px);}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.45; pointer-events:none;}
.btn svg{width:16px; height:16px; flex:none;}

.btn--primary{background:var(--accent-deep); color:var(--paper); box-shadow:none;}
.btn--primary:hover{background:var(--accent-deep); color:var(--paper); filter:brightness(1.16);}

.btn--ghost{
  background:transparent; color:var(--slate);
  font-weight:500; box-shadow:none;
  padding-inline:var(--s3);
  text-decoration:underline; text-decoration-color:var(--line);
}
.btn--ghost:hover{background:transparent; color:var(--accent-deep); text-decoration-color:currentColor;}

.btn--sm{padding:7px 13px; font-size:var(--t-sm); gap:6px;}
.btn--sm svg{width:14px; height:14px;}

/* ---- RGPD badge, small and monochrome ----------------------------------- */

.badge{
  display:inline-flex; align-items:center; gap:7px;
  padding:5px 11px 5px 8px;
  border-radius:var(--r-pill);
  background:transparent; color:var(--slate);
  box-shadow:var(--ring);
  font-size:var(--t-sm); font-weight:600; line-height:1.4;
  text-decoration:none; white-space:nowrap;
  transition:color .18s ease, box-shadow .18s ease;
}
a.badge:hover{color:var(--ink); box-shadow:0 0 0 1px var(--slate);}

.badge__mark{
  flex:none;
  width:15px; height:15px;
  display:inline-grid; place-items:center;
  color:currentColor;
}
.badge__mark svg{width:100%; height:100%;}

.badge__text{letter-spacing:.01em;}

/* ---- supporting screenshots ---------------------------------------------
   One rule serves both shapes. A landscape app capture fills the column up
   to its cap; the 1170x2532 client-portal capture is height-limited, so it
   lands at phone width instead of being blown up. */

.shot{
  display:flex; flex-direction:column; align-items:center;
  gap:var(--s3);
  min-width:0;
}

.shot__img{
  display:block;
  width:auto; height:auto;
  max-width:100%; max-height:620px;
  margin-inline:auto;
  border-radius:var(--r-card);
  box-shadow:var(--ring);
  background:var(--paper);
}

.shot__cap{
  max-width:52ch;
  font-size:var(--t-sm);
  line-height:1.5;
  color:var(--slate);
  text-align:center;
}

/* ---- fields and forms --------------------------------------------------- */

.field{display:flex; flex-direction:column; gap:6px; min-width:0;}

.field__label{
  font-size:var(--t-xs); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--slate);
}

.input,.select,.textarea{
  width:100%; min-width:0;
  font:inherit; font-size:var(--t-md); line-height:1.4;
  color:var(--ink); background:var(--paper);
  border:0; border-radius:var(--r-ctl);
  box-shadow:var(--ring);
  padding:10px 12px;
  transition:box-shadow .16s ease, background .16s ease;
}
.input:hover,.select:hover,.textarea:hover{box-shadow:0 0 0 1px var(--slate);}
/* No opacity here: .8 dropped --slate to 3.61:1. */
.input::placeholder,.textarea::placeholder{color:var(--slate); opacity:1;}
.textarea{min-height:110px; resize:vertical; line-height:1.55;}
.select{padding-block:9px;}

.form{
  display:flex; flex-direction:column;
  gap:var(--s5);
  width:100%;
  max-width:var(--w-prose);
  padding:var(--s6);
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
}

.form__row{
  display:flex; flex-wrap:wrap;
  gap:var(--s4);
}
.form__row > .field{flex:1 1 220px;}

.form__foot{
  display:flex; align-items:center; justify-content:flex-start;
  flex-wrap:wrap; gap:var(--s4);
  padding-top:var(--s2);
}
.form__foot p{font-size:var(--t-sm); color:var(--slate); line-height:1.5; max-width:44ch;}


/* === NAV =================================================================
   The wordmark outranks everything on the bar, including any badge. One
   button. The links are links. */

.nav{
  position:sticky; top:0; z-index:50;
  background:var(--canvas);
  transition:background .2s ease, box-shadow .2s ease;
}

/* The one permitted shadow, number two of two: the bar once it has scrolled. */
.nav.is-stuck,
.nav[data-stuck]{
  background:var(--paper);
  box-shadow:0 1px 0 0 var(--line), var(--lift);
}

.nav__inner{
  display:flex; align-items:center;
  gap:var(--s5);
  min-height:var(--nav-h);
}

.nav__brand{
  flex:none;
  margin-right:auto;
  font-family:var(--f-display);
  font-size:var(--t-xl);
  font-weight:700;
  letter-spacing:-.03em;
  line-height:1;
  color:var(--ink);
  text-decoration:none;
}
.nav__brand:hover{color:var(--accent-deep);}

.nav__links{
  display:flex; align-items:center;
  gap:var(--s5);
  min-width:0;
}

.nav__link{
  font-size:var(--t-base); font-weight:500;
  color:var(--slate);
  text-decoration:none;
  white-space:nowrap;
  transition:color .16s ease;
}
.nav__link:hover{color:var(--ink);}
.nav__link[aria-current]{color:var(--ink); font-weight:600;}

/* Language switch. A real control, not the product's dev toggle. */
.nav__lang{
  flex:none;
  display:inline-flex; align-items:center;
  gap:2px;
  padding:2px;
  border-radius:var(--r-pill);
  background:var(--paper);
  box-shadow:var(--ring);
}
.nav__lang button,
.nav__lang a{
  border:0; border-radius:var(--r-pill);
  padding:4px 10px;
  background:transparent; color:var(--slate);
  font:inherit; font-size:var(--t-sm); font-weight:600; line-height:1.4;
  letter-spacing:.04em; text-transform:uppercase; text-decoration:none;
  -webkit-appearance:none; appearance:none;
  transition:background .16s ease, color .16s ease;
}
.nav__lang button:hover,
.nav__lang a:hover{color:var(--ink);}
.nav__lang [aria-pressed="true"],
.nav__lang [aria-current]{background:var(--wash); color:var(--accent-deep);}

.nav__cta{flex:none;}
a.nav__cta,button.nav__cta{padding:9px 17px; font-size:var(--t-base);}


/* === HERO ================================================================
   One centred column. Headline, subheadline, one CTA, then the screenshot at
   full content width. Two equal columns would tell the visitor both halves
   matter equally, so there is only one dominant element after the headline
   and it is the product. */

.hero{
  background:var(--paper);
  box-shadow:0 1px 0 0 var(--line);
  /* Tightened from clamp(44px,6.5vw,84px): at 1440x900 the old value pushed the
     product screenshot so far down that only the summary strip cleared the fold,
     and the client rows are the actual proof. */
  padding-block:clamp(32px, 4vw, 56px) 0;
}

.hero__inner{
  display:flex; flex-direction:column; align-items:center;
  gap:var(--s5);
  text-align:center;
}

.hero__title{
  max-width:24ch;   /* two lines on desktop, not three, buys ~62px of fold */
  color:var(--ink);
}

.hero__sub{
  max-width:60ch;
  font-size:clamp(16px, 1.4vw, 19px);
  line-height:1.6;
  color:var(--slate);
  text-wrap:pretty;
}
.hero__sub strong{color:var(--ink); font-weight:600;}

.hero__cta{
  display:inline-flex; align-items:center; justify-content:center;
  gap:var(--s4); flex-wrap:wrap;
  margin-top:var(--s2);
}
/* Works whether .hero__cta wraps the button or is the button itself. */
a.hero__cta,button.hero__cta,
.hero__cta > .btn{
  padding:15px 30px;
  font-size:var(--t-lg);
  border-radius:var(--r-ctl);
}

.hero__micro{
  max-width:56ch;
  font-size:var(--t-sm);
  line-height:1.55;
  color:var(--slate);
}

.hero__badge{
  margin-top:var(--s1);
}

/* ---- the screenshot frame -----------------------------------------------
   The one permitted shadow, number one of two.

   assets/app-clientes.png is 2880x1800, a 2x capture of a 1440x900 app. The
   image is laid in at a fixed --shot-w and translated so the frame opens on
   the top-left of the client list: the summary strip, the filter row, the
   column heads and the first five client rows, each with its status spine.
   Cropped tight, straight on, no browser chrome, no angle. Nothing is
   focusable inside, so the overflow:hidden cannot clip a focus outline. */

.hero__shotframe{
  position:relative;
  width:100%;
  margin-top:var(--s4);
  aspect-ratio:1120 / 645;
  overflow:hidden;
  border-radius:var(--r-card) var(--r-card) 0 0;
  background:var(--canvas);
  box-shadow:var(--lift-lg), var(--ring);
}

.hero__shot{
  position:absolute; top:0; left:0;
  display:block;
  width:var(--shot-w);
  max-width:none; height:auto;
  /* x: -16.11% of 1440 = 232pt, the right edge of the app rail, so the crop
     starts exactly on the content column and never mid-word.
     y: -150px drops the app's page title and the e-Fatura scope paragraph out
     of the crop. The rows are the proof; the paragraph is not. Tuned against a
     1280x800 laptop, not just 1440x900, because at -96px the smaller fold
     stopped at the column headers and showed no client row at all. */
  transform:translate(-16.11%, -150px);
}


/* === PROBLEM =============================================================
   Her month, in her words. Short. No spine here: the spine means state, and
   this block has none. */

.problem{
  display:flex; flex-direction:column;
  gap:var(--s6);
  max-width:var(--w-prose);
}

.problem__quote{
  font-size:clamp(21px, 2.5vw, 28px);
  font-weight:650;
  line-height:1.32;
  color:var(--ink);
  text-wrap:pretty;
}

.problem__list{
  display:flex; flex-direction:column;
  gap:var(--s3);
}

.problem__item{
  position:relative;
  padding-left:var(--s5);
  font-size:var(--t-md);
  line-height:1.6;
  color:var(--slate);
}
.problem__item::before{
  content:"";
  position:absolute;
  left:0; top:.62em;
  width:6px; height:6px;
  border-radius:var(--r-pill);
  background:var(--line);
}


/* === BENEFITS ============================================================
   Six outcomes, benefit first, mechanism underneath. Pillar 1 leads and is
   deliberately larger; the other five sit in a grid below it. Six identical
   cards would flatten the argument.

   The status spine appears here because each block is one state of her
   practice. The lead pillar carries the live accent; the five supporting
   pillars carry the neutral line and warm to the accent on hover. */

/* Six columns, so the five supporting pillars land three then two without
   an orphan hole in the last row. The count is fixed at six by the spec. */
.benefits{
  display:grid;
  grid-template-columns:repeat(6, minmax(0, 1fr));
  gap:var(--s5);
}

/* All placement lives here, at one specificity, so nothing below can win an
   argument with it by accident. */
.benefits > .benefit{grid-column:span 2;}
.benefits > .benefit--lead{grid-column:1 / -1;}
.benefits > .benefit:nth-last-of-type(-n+2){grid-column:span 3;}

.benefit{
  position:relative;
  display:flex; flex-direction:column;
  gap:var(--s2);
  padding:var(--s6) var(--s6) var(--s6) calc(var(--s6) + 3px);
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
  min-width:0;
  transition:box-shadow .2s ease, transform .2s ease;
}
.benefit::before{
  content:"";
  position:absolute;
  left:0; top:0; bottom:0;
  width:3px;
  border-radius:var(--r-card) 0 0 var(--r-card);
  background:var(--line);
  transition:background .25s ease;
}
.benefit:hover{box-shadow:0 0 0 1px var(--slate);}
.benefit:hover::before{background:var(--accent);}

.benefit--lead{
  gap:var(--s3);
  padding:var(--s7) clamp(var(--s6), 5vw, var(--s8));
  padding-left:calc(clamp(var(--s6), 5vw, var(--s8)) + 3px);
  background:var(--wash);
  box-shadow:0 0 0 1px var(--line);
}
.benefit--lead::before{background:var(--accent);}
.benefit--lead:hover{box-shadow:0 0 0 1px var(--accent);}

.benefit__title{
  font-size:var(--t-lg);
  font-weight:650;
  letter-spacing:-.01em;
  line-height:1.3;
  color:var(--ink);
  text-wrap:balance;
}
.benefit--lead .benefit__title{
  font-family:var(--f-display);
  font-size:clamp(23px, 2.6vw, 31px);
  font-weight:650;
  letter-spacing:-.02em;
  line-height:1.15;
  max-width:22ch;
}

.benefit__body{
  font-size:var(--t-base);
  line-height:1.6;
  color:var(--slate);
}
.benefit--lead .benefit__body{
  font-size:var(--t-lg);
  line-height:1.6;
  color:var(--ink);
  max-width:56ch;
}

/* The mechanism, one line, always subordinate to the outcome above it. */
.benefit__how{
  margin-top:var(--s2);
  padding-top:var(--s3);
  border-top:1px solid var(--line);
  font-size:var(--t-sm);
  line-height:1.5;
  color:var(--slate);
}
.benefit--lead .benefit__how{
  font-size:var(--t-base);
  border-top-color:color-mix(in srgb, var(--accent) 30%, transparent);
  max-width:60ch;
}

/* The whole motion budget for the page below the fold: one restrained
   reveal, and only if site.js opts in at the html level. */
[data-reveal] .benefit{
  opacity:0;
  transform:translateY(10px);
  transition:opacity .5s var(--ease-out), transform .5s var(--ease-out),
             box-shadow .2s ease;
}
[data-reveal] .benefit.is-in,
[data-reveal] .benefit[data-in]{
  opacity:1;
  transform:none;
}


/* === STEPS AND PROOF =====================================================
   Three steps, then the e-Fatura mechanism as the evidence underneath.

   The step spines are the only other place the signature bar appears, and
   they carry the product's own state vocabulary end to end: nothing yet,
   in progress, complete. That is what the three steps do to a client. */

.steps{
  display:grid;
  grid-template-columns:repeat(3, minmax(0, 1fr));
  gap:var(--s5);
}

.step{
  position:relative;
  display:flex; flex-direction:column;
  gap:var(--s2);
  padding:var(--s5) var(--s6) var(--s6) calc(var(--s6) + 3px);
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
  min-width:0;
}
.step::before{
  content:"";
  position:absolute;
  left:0; top:0; bottom:0;
  width:3px;
  border-radius:var(--r-card) 0 0 var(--r-card);
  background:var(--line);
}
.steps .step:nth-of-type(2)::before{background:var(--accent);}
.steps .step:nth-of-type(3)::before{background:var(--ok);}

/* These used to run --line / --accent / --ok to echo the product's state
   vocabulary, but a step number is not a state: nothing here is "complete".
   It also put a 1.74:1 numeral on white, which is invisible. One colour. */
.step__num{
  font-size:var(--t-2xl);
  font-weight:700;
  line-height:1;
  color:var(--slate);
}

.step__title{
  font-size:var(--t-lg);
  font-weight:650;
  letter-spacing:-.01em;
  line-height:1.3;
  color:var(--ink);
}

.step__body{
  font-size:var(--t-base);
  line-height:1.6;
  color:var(--slate);
}

.proof{
  display:flex; flex-direction:column;
  gap:var(--s6);
  padding:var(--s7) clamp(var(--s5), 4vw, var(--s7));
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
}

.proof > .shot{margin-inline:auto;}

.proof__note{
  max-width:var(--w-prose);
  margin-inline:auto;
  font-size:var(--t-md);
  line-height:1.65;
  color:var(--slate);
  text-align:center;
  text-wrap:pretty;
}
.proof__note strong{color:var(--ink); font-weight:600;}


/* === TRUST ===============================================================
   Facts, not seals. A short row of provable claims, then the controller and
   processor sentence, which is the one that matters to somebody bound by
   segredo profissional. */

.trust{
  display:flex; flex-direction:column;
  gap:var(--s5);
}

.trust__row{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(238px, 1fr));
  gap:var(--s4);
}

.trust__fact{
  display:flex; align-items:flex-start;
  gap:var(--s3);
  padding:var(--s5);
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
  font-size:var(--t-base);
  line-height:1.55;
  color:var(--ink);
  min-width:0;
}
.trust__fact strong{font-weight:650;}

/* Monochrome. No colour, no seal, no vendor logo. */
.trust__mark{
  flex:none;
  width:18px; height:18px;
  margin-top:2px;
  display:inline-grid; place-items:center;
  color:var(--slate);
}
.trust__mark svg{width:100%; height:100%;}

.trust__roles{
  max-width:var(--w-prose);
  padding:var(--s5) var(--s6);
  background:var(--wash);
  border-radius:var(--r-card);
  box-shadow:0 0 0 1px color-mix(in srgb, var(--accent) 34%, transparent);
  font-size:var(--t-md);
  line-height:1.6;
  color:var(--ink);
}
.trust__roles strong{font-weight:650;}

.trust__note{
  max-width:var(--w-prose);
  font-size:var(--t-sm);
  line-height:1.55;
  color:var(--slate);
}


/* === NEW =================================================================
   The product is new and says so. Stated newness reads as honest; invented
   proof would contaminate every true claim on the page. */

.new{
  display:flex; flex-direction:column;
  gap:var(--s3);
  max-width:var(--w-prose);
  padding:var(--s6);
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
}

.new__title{
  font-size:var(--t-lg);
  font-weight:650;
  letter-spacing:-.01em;
  line-height:1.3;
  color:var(--ink);
}

.new__body{
  font-size:var(--t-md);
  line-height:1.65;
  color:var(--slate);
}


/* === FAQ =================================================================
   A disclosure list. site.js toggles [hidden] on .faq__a; there is no
   max-height collapse, because an overflow:hidden collapse would clip the
   focus outline of anything inside. Works as <details> too. */

.faq{
  display:flex; flex-direction:column;
  gap:var(--s3);
  max-width:820px;
}

.faq__item{
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
  overflow:visible;
}

.faq__q{
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--s4);
  width:100%;
  margin:0;
  padding:var(--s4) var(--s5);
  border:0; border-radius:var(--r-card);
  background:transparent;
  font:inherit; font-size:var(--t-md); font-weight:600; line-height:1.45;
  color:var(--ink);
  text-align:left;
  list-style:none;
  -webkit-appearance:none; appearance:none;
  transition:color .16s ease;
}
.faq__q::-webkit-details-marker{display:none;}
.faq__q::marker{content:"";}
.faq__q:hover{color:var(--accent-deep);}

/* The disclosure caret. Plain, and it does not spin. */
.faq__q::after{
  content:"";
  flex:none;
  width:9px; height:9px;
  margin-right:2px;
  border-right:2px solid var(--slate);
  border-bottom:2px solid var(--slate);
  transform:rotate(45deg) translate(-2px,-2px);
  transition:transform .2s ease;
}
.faq__q[aria-expanded="true"]::after,
.faq__item[open] .faq__q::after{
  transform:rotate(225deg) translate(-2px,-2px);
}

.faq__a{
  padding:0 var(--s5) var(--s5);
  font-size:var(--t-base);
  line-height:1.65;
  color:var(--slate);
  max-width:64ch;
}
.faq__a p + p{margin-top:var(--s3);}


/* === CLOSE ===============================================================
   The same single call to action, repeated. Never a second one. */

.close{
  display:flex; flex-direction:column; align-items:center;
  gap:var(--s5);
  padding:var(--s8) var(--pad-x);
  background:var(--wash);
  border-radius:var(--r-card);
  box-shadow:0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent);
  text-align:center;
}

.close__title{
  max-width:20ch;
  color:var(--ink);
}

.close__cta{
  display:inline-flex; align-items:center; justify-content:center;
  gap:var(--s4); flex-wrap:wrap;
}
a.close__cta,button.close__cta,
.close__cta > .btn{
  padding:15px 30px;
  font-size:var(--t-lg);
}


/* === FOOTER ==============================================================
   DL 7/2004 art. 10 and CSC art. 171 require firma, sede, conservatoria,
   matricula, NIPC, capital social and endereco electronico to be permanently
   accessible. It is a lot of small print, so it is set as a real block: one
   column of links per topic, then a ruled legal identity block with enough
   line height and a labelled structure. Not a grey mush. */

.foot{
  background:var(--paper);
  box-shadow:0 -1px 0 0 var(--line);
  padding-block:var(--s8) var(--s6);
}

.foot__inner{
  display:flex; flex-direction:column;
  gap:var(--s6);
}

.foot__cols{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(190px, 1fr));
  gap:var(--s6) var(--s5);
}

.foot__col{
  display:flex; flex-direction:column;
  gap:var(--s2);
  min-width:0;
  font-size:var(--t-base);
  line-height:1.6;
  color:var(--slate);
}
.foot__col h2,
.foot__col h3,
.foot__col strong{
  margin-bottom:var(--s1);
  font-size:var(--t-xs); font-weight:700;
  letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink);
}
.foot__col a{
  color:var(--slate);
  text-decoration:none;
}
.foot__col a:hover{color:var(--accent-deep); text-decoration:underline;}

/* Companion documents that do not exist yet are marked, not hidden. */
.foot__pending{
  display:inline-block;
  margin-left:6px;
  padding:1px 6px;
  border-radius:var(--r-chip);
  background:var(--canvas);
  box-shadow:var(--ring);
  font-size:var(--t-xs); font-weight:600;
  letter-spacing:.04em;
  color:var(--slate);
  white-space:nowrap;
  vertical-align:1px;
}

.foot__legal{
  display:flex; flex-direction:column;
  gap:var(--s2);
  padding-top:var(--s5);
  border-top:1px solid var(--line);
  font-size:var(--t-sm);
  line-height:1.7;
  color:var(--slate);
  max-width:92ch;
}
.foot__legal strong{color:var(--ink); font-weight:600;}

/* Identity block. Two offices side by side rather than a label/value list.
   The company name is the heading, so no row needs an "Entidade" label and
   the whole block collapses from eight lines to four. */
.foot__entity{
  display:flex; flex-direction:column;
  gap:var(--s3);
}
.foot__entity-name{font-size:var(--t-base);}
.foot__entity-cols{
  display:grid;
  grid-template-columns:repeat(2, minmax(0, 1fr));
  gap:var(--s4);
  max-width:52ch;
}
.foot__addr{
  display:flex; flex-direction:column;
  font-style:normal;
  line-height:1.6;
}
.foot__addr strong{
  margin-bottom:2px;
  font-size:var(--t-xs); font-weight:700;
  letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink);
}


/* === PRICING PAGE ========================================================
   Talk to sales, done confidently: the unit, what moves the price, a floor
   for a solo practice, and who it is for. No invented tiers. */

.price{
  display:flex; flex-direction:column;
  gap:var(--s6);
}

.price__unit{
  max-width:var(--w-prose);
  padding:var(--s6);
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
  font-size:var(--t-lg);
  line-height:1.55;
  color:var(--ink);
}
.price__unit strong{font-weight:650;}

.price__drivers{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(230px, 1fr));
  gap:var(--s4);
}

.price__driver{
  display:flex; flex-direction:column;
  gap:var(--s1);
  padding:var(--s5);
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
  font-size:var(--t-base);
  line-height:1.55;
  color:var(--slate);
  min-width:0;
}
.price__driver strong{
  display:block;
  font-size:var(--t-md); font-weight:650;
  color:var(--ink);
}

/* The floor. For a solo practitioner with 20 clients this is the single
   most valuable line on the page, so it is set like one. */
.price__floor{
  display:flex; flex-direction:column;
  gap:var(--s2);
  max-width:var(--w-prose);
  padding:var(--s6) var(--s7);
  background:var(--wash);
  border-radius:var(--r-card);
  box-shadow:0 0 0 1px color-mix(in srgb, var(--accent) 34%, transparent);
  font-size:clamp(24px, 3vw, 34px);
  line-height:1.18;
  color:var(--ink);
}
.price__floor small{
  font-family:var(--f-body);
  font-size:var(--t-md); font-weight:400;
  letter-spacing:0;
  line-height:1.6;
  color:var(--slate);
}

.price__fit{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(280px, 1fr));
  gap:var(--s5);
  font-size:var(--t-md);
  line-height:1.65;
  color:var(--slate);
}
.price__fit > *{
  padding:var(--s5) var(--s6);
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
  min-width:0;
}
.price__fit strong{
  display:block;
  margin-bottom:var(--s2);
  font-size:var(--t-md); font-weight:650;
  color:var(--ink);
}
.price__fit li{
  position:relative;
  padding-left:var(--s4);
}
.price__fit li + li{margin-top:6px;}
.price__fit li::before{
  content:"";
  position:absolute;
  left:0; top:.66em;
  width:5px; height:5px;
  border-radius:var(--r-pill);
  background:var(--line);
}


/* === CONTACT PAGE ========================================================
   Short single column. Real address, real email, routed paths, a response
   time, and the demo form. No map, no chat widget, no social icons.
   The routed paths and the entity block reuse .foot__col and .field. */

.sec__inner > .form{margin-inline:0;}


/* === TERMS PAGE ==========================================================
   Long-form legal reading layout. Sticky contents on wide screens, numbered
   sections, comfortable measure.

   .legal__h numbers itself with a counter. The heading strings in i18n.js
   must not carry their own number. */

.legal{
  counter-reset:legal;
  display:grid;
  grid-template-columns:minmax(0, 250px) minmax(0, var(--w-prose));
  gap:clamp(var(--s6), 5vw, var(--s8));
  align-items:start;
}

.toc{
  position:sticky;
  top:calc(var(--nav-h) + var(--s5));
  display:flex; flex-direction:column;
  gap:var(--s1);
  max-height:calc(100vh - var(--nav-h) - var(--s7));
  padding:var(--s5);
  background:var(--paper);
  border-radius:var(--r-card);
  box-shadow:var(--ring);
  /* Scrolls on short windows. Padded so a focus outline is never clipped. */
  overflow-y:auto;
  scrollbar-width:thin;
}

.toc__item{
  display:block;
  padding:5px var(--s2);
  border-radius:var(--r-chip);
  font-size:var(--t-sm);
  line-height:1.45;
  color:var(--slate);
  text-decoration:none;
  transition:background .16s ease, color .16s ease;
}
.toc__item:hover{background:var(--canvas); color:var(--ink);}
.toc__item[aria-current]{background:var(--wash); color:var(--accent-deep); font-weight:600;}

/* The notice at the top. It must read as a warning without being alarming,
   so it takes the soon palette, not the late one. */
.legal__notice{
  grid-column:1 / -1;
  display:flex; flex-direction:column;
  gap:var(--s2);
  padding:var(--s5) var(--s6);
  background:var(--soon-wash);
  border-radius:var(--r-card);
  box-shadow:0 0 0 1px color-mix(in srgb, var(--soon) 32%, transparent);
  font-size:var(--t-md);
  line-height:1.6;
  color:var(--ink);
  max-width:none;
}
.legal__notice strong{
  display:block;
  font-size:var(--t-base); font-weight:700;
  letter-spacing:.06em; text-transform:uppercase;
  color:var(--soon);
}

.legal__h{
  margin-top:var(--s7);
  margin-bottom:var(--s3);
  font-size:var(--t-xl);
  font-weight:650;
  letter-spacing:-.01em;
  line-height:1.3;
  color:var(--ink);
  scroll-margin-top:calc(var(--nav-h) + var(--s5));
  counter-increment:legal;
}
/* The i18n strings already carry their own number ("1. Definicoes"), which is
   what the table of contents renders too, so the counter would double it.
   Kept incrementing above in case the strings are ever stripped. */
.legal__notice + .legal__h,
.legal__h:first-child{margin-top:0;}

.legal__p{
  margin-bottom:var(--s4);
  max-width:var(--w-prose);
  font-size:var(--t-md);
  line-height:1.75;
  color:var(--ink);
}
.legal__p strong{font-weight:650;}
.legal__p + .legal__p{margin-top:0;}


/* === RESPONSIVE ==========================================================
   Down to 360px with no horizontal body scroll. The hero screenshot keeps a
   constant render scale at every width; what changes is which part of the
   app the frame opens on. Below 980px it drops the summary strip and opens
   straight on the client rows, so the names and the coloured spines stay
   the point of the image. */

@media (max-width:1080px){
  .benefits{grid-template-columns:repeat(2, minmax(0, 1fr));}
  .benefits > .benefit,
  .benefits > .benefit:nth-last-of-type(-n+2){grid-column:auto;}
  .benefits > .benefit--lead{grid-column:1 / -1;}
}

@media (max-width:980px){
  .steps{grid-template-columns:1fr;}
  .step{padding-block:var(--s5);}

  .legal{grid-template-columns:minmax(0,1fr);}
  .legal__notice{order:-2;}
  .toc{
    position:static;
    max-height:none;
    order:-1;
  }

  /* Rows crop. x0 = 250pt (just left of the spines), y0 = 340pt (the column
     heads), so the frame is client names, progress and status, nothing else. */
  .hero__shotframe{aspect-ratio:16 / 10;}
  .hero__shot{transform:translate(-17.36%, -37.78%);}
}

@media (max-width:860px){
  /* The bar wraps onto three rows here, which as a sticky element ate 132px of a
     360px-tall phone screen and put every anchor jump underneath itself. Below
     this width it scrolls away with the page instead. The CTA is not lost: it
     repeats four times down the page, which is the single-CTA rule anyway. */
  .nav{position:static;}
  html{scroll-padding-top:24px;}

  .nav__inner{flex-wrap:wrap; gap:var(--s3) var(--s4); padding-block:var(--s3);}
  .nav__brand{font-size:var(--t-lg);}
  .nav__links{order:3; width:100%; gap:var(--s4); flex-wrap:wrap;}

  .hero__title{max-width:18ch;}
  .price__floor{padding:var(--s6);}
  .trust__roles{padding:var(--s5);}
}

@media (max-width:700px){
  .benefits{grid-template-columns:minmax(0, 1fr);}
  .benefit{padding:var(--s5) var(--s5) var(--s5) calc(var(--s5) + 3px);}
  .benefit--lead{
    padding:var(--s6) var(--s5);
    padding-left:calc(var(--s5) + 3px);
  }
  .benefit__how{margin-top:var(--s1);}

  .proof{padding:var(--s6) var(--s5);}
  .close{padding:var(--s7) var(--s5);}
  .form{padding:var(--s5);}
  .price__fit > *{padding:var(--s5);}

  /* Taller frame so the crop keeps eight or nine client rows on a phone. */
  .hero__shotframe{aspect-ratio:4 / 5;}
}

@media (max-width:520px){
  /* Row one keeps the two things that matter, the wordmark and the one
     button. The links and the language switch take row two. */
  .nav__links{order:3; width:auto; margin-right:auto;}
  .nav__lang{order:4;}
}

@media (max-width:560px){
  .sec__inner{gap:var(--s5);}
  .hero__inner{gap:var(--s4);}
  .hero__cta{width:100%;}
  a.hero__cta,button.hero__cta,
  .hero__cta > .btn{width:100%; padding-inline:var(--s4);}
  a.close__cta,button.close__cta,
  .close__cta > .btn{width:100%;}
  .close__cta{width:100%;}

  .trust__row{grid-template-columns:1fr;}
  .price__drivers{grid-template-columns:1fr;}
  .price__fit{grid-template-columns:1fr;}
  .foot__cols{gap:var(--s5);}
  .foot__entity-cols{grid-template-columns:1fr; gap:var(--s3);}
}

@media (max-width:400px){
  :root{--pad-x:16px;}
  .nav__links{gap:var(--s3);}
  .nav__link{font-size:var(--t-sm);}
  a.nav__cta,button.nav__cta{padding:8px 13px; font-size:var(--t-sm);}
  .faq__q{padding:var(--s3) var(--s4);}
  .faq__a{padding:0 var(--s4) var(--s4);}
  .legal__notice{padding:var(--s4);}
  .toc{padding:var(--s4);}
}


/* === REDUCED MOTION ====================================================== */

/* The contents box unpins below 980px. On a phone that put about 700px of the
   26 contents links between the notice and clause 1, so cap it and let it
   scroll. Lived in a page-scoped <style> in termos.html; moved here so the
   site has exactly one stylesheet. */
@media (max-width:980px){
  .toc{max-height:42vh; overflow-y:auto;}
}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    transition-delay:0ms !important;
    scroll-behavior:auto !important;
  }
  /* The reveal must never leave content invisible when motion is off. */
  [data-reveal] .benefit{opacity:1; transform:none;}
}
