/* ══ KOVA — the layout system ══════════════════════════════════════════════
   The site read as machine-made for one measurable reason: nobody ever decided
   where the page's spine was, so every decision got made locally and centred.
   Measured in index.html before this file: 24 text-align:center + 26 margin:0
   auto = 50 centring declarations, NINE different content widths down the
   scroll (1320/1280/1000/980/900/860/820/760/720/680/660/620/440), 71 distinct
   font-size values, and 10 of 10 sections opening with the identical
   eyebrow -> h2 -> p unit. That is not a grid. It is a stack of boxes.

   The model for the rebuild was already in the codebase: .terms-band, whose own
   comment reads "cards would make these read as marketing claims. They are
   terms." Flat hairline rows, left-aligned, no cards, hierarchy from a bold
   lead-in and a rule. That instinct is the whole redesign.                   */

@font-face{
  font-family:'Archivo';
  src:url('/assets/fonts/archivo.woff2?v=59215ddd51') format('woff2');
  font-weight:100 900; font-display:swap;
}

:root{
  --spine: clamp(20px, 6vw, 96px);   /* the single left edge, everywhere */
  --measure: 68ch;                    /* one reading width, enforced */
  --wide: 1240px;                     /* ONE content width, not nine */
  --sans:'Archivo', system-ui, sans-serif;
  --serif:'Archivo', system-ui, sans-serif;   /* Fraunces is retired */
  --serif-italic:'Archivo', system-ui, sans-serif;
}

/* ── ONE FACE. Archivo, 100-900, subset to the site's own character set:
      18.4KB replacing 85.2KB of Fraunces x2 + Jost, and it is a geometric
      grotesque that relates to the KOVA wordmark instead of fighting it. */
body, h1,h2,h3,h4,h5,h6, p, li, a, button, input, select, textarea, .lead{
  font-family:var(--sans) !important;
}
.italic, em, i, .gradient-text{ font-style:normal !important; }

/* ── THE SPINE. Everything starts at the same left edge. */
main > section, main > div, header, footer{ padding-inline:var(--spine) !important; }
main > section > *, .section-head, .hero-inner, .container, .wrap{
  max-width:var(--wide) !important; margin-inline:0 !important; text-align:left !important;
}
.section-head{ margin-left:0 !important; margin-right:0 !important; max-width:var(--measure) !important; }
.section-head, .hero-inner, .industry, .proc-step, .stat, .cta-section,
[style*="text-align:center"], [style*="text-align: center"]{
  text-align:left !important;
}
main p, main li{ max-width:var(--measure); }

/* ── TYPE. Ten steps, ratio ~1.25, hard floor 13px. The old file had 71 sizes
      and agc-space.css had already given up and pinned them back with 38
      !important rules — so most of the type in index.html was dead code. */
h1{ font-size:clamp(44px,7vw,96px); font-weight:800; letter-spacing:-.035em; line-height:.98; }
h2{ font-size:clamp(30px,4vw,52px);  font-weight:800; letter-spacing:-.028em; line-height:1.04; }
h3{ font-size:clamp(22px,2.4vw,30px);font-weight:700; letter-spacing:-.02em;  line-height:1.14; }
h4{ font-size:22px; font-weight:700; letter-spacing:-.012em; line-height:1.2; }
.lead, p.lead{ font-size:clamp(18px,1.5vw,21px); font-weight:400; line-height:1.55; color:var(--cream); }
/* The scale sets p and li to 17px but never set BODY, so every unstyled element
   fell back to the browser's 16px default — two body sizes 6% apart, which is
   what the hook kept flagging as a flat hierarchy. Setting body removes the
   phantom 16px step entirely: 34 / 20 / 17 / 14 / 11, with no adjacent pair
   under 1.17. */
body{ font-size:17px; line-height:1.62; }
p, li{ font-size:17px; line-height:1.62; }
.h-eyebrow, .eyebrow{
  font-size:14px !important; font-weight:600; letter-spacing:.08em !important;
  text-transform:uppercase; color:var(--gray) !important;
}

/* ── STRUCTURE, NOT BOXES. The terms-band model applied everywhere: a hairline
      between rows, a bold lead-in, no container. */
.service, .pack, .tier, .industry, .proc-step, .stat, [class*="card"], [class*="panel"]{
  background:none !important; border:0 !important; border-radius:0 !important;
  border-top:1px solid var(--black-4) !important;
  padding:26px 0 !important; box-shadow:none !important;
}
.tier{ border-top:2px solid var(--off-white) !important; }

/* ── DEAD FURNITURE. The honesty reset removed the testimonials, the results
      counters and the case-study bento, but left ~90 lines of CSS standing for
      components that have zero uses in any markup. */
.testimonial, .testimonials, .tcar, .metric-strip, .results-counter,
.case-bento, .logo-wall, .trusted-by{ display:none !important; }

/* ── NOTHING HIDES THE PAGE. There were THREE separate full-viewport curtains:
      #loader (a fake progress bar counting Math.random()*22+18 on a static page,
      (a leftover monogram), .page-veil, and
      html.agc-pt body{opacity:0}. The page paints on first byte now. */
#loader, .page-veil{ display:none !important; }
html.agc-pt body, body{ opacity:1 !important; }

/* ── THE WORDMARK. It exists, it is his, and it had never once been on the site. */
.nav-wordmark{ height:34px; width:auto; display:block; }
.nav-logo{ display:flex; align-items:center; gap:0; }
@media (max-width:760px){ .nav-wordmark{ height:26px; } }

/* ── THE SPINE, PROPERLY. The hero is a <header>, not a <section>, so the
      earlier `main > section > *` rule never touched it — its h1 was still
      centred by an auto margin-left of 247px and its lead by 300px. Target the
      actual centring mechanisms rather than a structural guess. */
.hero, .hero-inner{ text-align:left !important; }
.hero-inner{ max-width:var(--wide) !important; margin-inline:0 !important; padding-inline:0 !important; }
.hero h1, .hero .lead, .hero-ctas, .hero-price-line, .hero p{
  margin-left:0 !important; margin-right:0 !important; text-align:left !important;
}
.hero h1{ max-width:16ch !important; }
.hero .lead, .hero p{ max-width:var(--measure) !important; }
.hero-ctas{ justify-content:flex-start !important; }

/* The gradient rounded-square with a letter in it is the single most generic
   AI-startup primitive there is, and it was the ONLY mark on the page while six
   real Kova wordmark files sat unreferenced on disk. The wordmark is in the
   header now; the hero does not need a second logo. */
.hero-mark, .hero-mark-fallback{ display:none !important; }

/* Any remaining auto-centred block in the reading column goes to the spine. */
main > *, main section > *, main header > *{ margin-inline:0 !important; }
.section-head, .cta-section, .contact-form-section, .terms-band{
  text-align:left !important; margin-inline:0 !important;
}

/* ── FAIL-OPEN ON TEXT. The reveal system animates words from opacity:0 and
      relies on JS to bring them back; the marquee words were measured stuck at
      0 after the layout changed under them. Text is the product here, so it
      defaults to visible and animation may only ever be an enhancement. */
h1, h2, h3, h4, h5, h6{
  color:var(--off-white) !important;
  -webkit-text-fill-color:var(--off-white) !important;
  opacity:1 !important;
  -webkit-text-stroke:0 !important;
}
h1 .accent, h2 .accent, .gradient-text, .italic{
  color:var(--accent) !important; -webkit-text-fill-color:var(--accent) !important;
}
/* FAIL-OPEN, BUT ONLY WHERE IT CAN ACTUALLY FAIL. `.word` and [data-fx-reveal]
   children exist in the SOURCE HTML, so if a script dies they must still be
   visible — that guarantee stays. `.fxm-w` and `.fxr-i` do NOT: they are spans
   the script itself creates, so they cannot exist unless the script ran, and
   forcing them visible could only ever break the animation. It did.

   THE ATTRIBUTION SMUDGE, DIAGNOSED. The morph keyframes animate opacity AND
   filter:blur(14px). `opacity:1 !important` won the opacity but could not touch
   the filter, so all six words sat at full opacity, blurred up to 14px, stacked
   at the same x, under a gooey feColorMatrix alpha threshold — the grey blob
   over "ATTRIBUTION". `transform:none` also cancelled the translate(-50%,-50%)
   that centres each word, which is why the blob hung to the right of the text. */
/* Nothing is force-shown here any more, and that is the point.

   Both of the things this rule used to flatten already fail open BY
   THEMSELVES, and better than a blanket override could:

     .fxr-i   carries `animation:fxrSafety 1ms linear 1.8s forwards`, so the
              text appears after 1.8s whatever happened to the observer — and
              if the script never runs at all, .fxr-i is never created and the
              heading is just a heading.
     .word    is a plain CSS keyframe with `forwards`. It needs no JavaScript,
              so there is no failure mode in which it stays hidden.

   What the rule DID do was switch off both animations site-wide. 43 reveal
   spans on the homepage and every one of the 278 `data-fx-reveal` headings
   were being built by the script and then flattened to opacity:1 by this line.
   The fail-open guarantee is kept where it is real — see the reduced-motion
   blocks in kova-nav.css — rather than by nailing every animated element open. */

/* The huge outlined decorative word behind sections — a dark-room flourish that
   on bone reads as a ghost of the real headline sitting on top of it. */
.ghost-word{ display:none !important; }

/* Section rhythm: the old file had five separate rules all declaring
   padding:120px 24px, which agc-space.css then flattened to 7rem for all ten.
   Ten identical slabs is the stack-of-boxes problem in vertical form. */
main > section{ padding-block:clamp(64px,7vw,104px) !important; }
main > section + section{ border-top:1px solid var(--black-4); }

/* ── PULLQUOTES were fixed AT SOURCE (the 3px accent bar became a 1px rule and
      the synthesised oblique was removed in each blog file), so the override
      that used to live here is gone rather than left to fight it. Keeping both
      would have been a fourth layer of !important on a codebase whose type was
      already the arithmetic residue of stylesheets overriding each other. */

/* ── CENTRED CLUSTERS. The spine applies to READING content — headlines,
      paragraphs, lists — because a shared left edge is what gives the eye a
      rail. It does not apply to small symmetrical clusters that are objects
      rather than text. The social row is one: it carries margin:0 auto and
      justify-content:center by design, and the blanket margin-inline:0 in the
      spine rules was cancelling the auto margin, pushing it off-centre. */
.social-bar{
  margin-inline:auto !important;
  justify-content:center !important;
  text-align:center !important;
}
.social-icons{
  display:flex; align-items:center; justify-content:center;
  gap:16px; flex-wrap:wrap;
}

/* ── SERVICE ICON TILES. The tile rotates -6deg on :hover and :focus-visible,
      and focus-visible fires on click — which is why Sayed saw the corner cut
      only when clicking. The rotation pushed the tile past the card's edge, and
      once the redesign removed the card's 32px horizontal padding there was no
      room left for it to rotate into, so the corner got clipped.
      The tilt goes rather than the padding coming back: a 6-degree hover tilt is
      the same ornament this redesign stripped everywhere else, and the tile is
      solid brand bronze now instead of a gradient. */
.service .service-icon, .service .ic,
.service:hover .service-icon, .service:focus-visible .service-icon,
.service:hover .ic, .service:focus-visible .ic{
  transform:none !important;
  background:var(--off-white) !important;
  color:var(--black) !important;
  border-radius:8px !important;
  box-shadow:none !important;
}
.service:hover, .service:focus-visible{
  transform:none !important;
  background:none !important;
  box-shadow:none !important;
  border-color:var(--black-5) !important;
}
/* the hover glow layer this card carried */
.service::before{ content:none !important; }

/* ── SOCIAL ROW. The bar holds a label AND the icon cluster in one flex row, so
      centring the ROW centres label+icons together and leaves the icons sitting
      right of the page centre. Centre the icon cluster itself instead: measured
      10px off at 1440px before this, 0px after. */
.social-bar{ flex-direction:column; gap:14px !important; }
.social-bar .social-bar-label{ text-align:center; width:100%; }
.social-bar .social-icons{ margin-inline:auto !important; }

/* ══ ONE CENTRED COLUMN, TWO TRACKS ════════════════════════════════════════
   THE BUG SAYED REPORTED, MEASURED. He said text "is moved to the right rather
   than centred" on desktop while mobile looked fine. At 1680px the probe read:

       nav wordmark   left  40px
       hero h1        left 316px      right gutter 679px
       lead           left 316px      right gutter 703px

   So the reading content was not centred and was not on the nav's rail either —
   it sat between the two, with a right gutter twice the left. That in-between
   position is the whole complaint. Mobile looked fine for a reason worth
   writing down: at 390px the 1240px column is wider than the viewport, so
   `margin-inline:auto` resolves to 0 and both rails collapse onto the same
   20px edge. The defect could only ever appear above 1240px.

   The previous pass centred the SECTION but left every line of prose flush to
   that section's left edge, which is what produced the lopsided gutter. The fix
   is to stop treating "the column" as one thing. There are two tracks, and both
   of them are centred:

       WIDE  (--wide, 1240px)  grids, card rows, tables, forms — objects
       READ  (--read,  680px)  every heading, paragraph and list item — prose

   Prose elements all share ONE width, so their left edges line up to the pixel;
   each is margin-inline:auto, so the block sits centred with equal gutters. At
   1680px that reads 500 / 500 for prose and 316 / 316 for grids — symmetrical
   at both scales, which is what "centred" actually means here. Text itself
   stays left-aligned; a centred RAG-RIGHT block is not the same thing as
   centred text, and the ragged left edge of centred text is what makes a page
   unreadable.                                                                */

:root{
  --read: 680px;      /* the reading track — one width for every line of prose */
}

/* ── The wide track. The section is the column; the spine is its padding. */
main > section,
main > header,
main > div.wrap,
main > .container,
main > .terms-band{
  max-width:var(--wide) !important;
  margin-inline:auto !important;
  padding-inline:var(--spine) !important;
  box-sizing:border-box;
}

/* ── Objects fill the wide track and centre in it. Anything that is not prose
      — a grid, a card row, a table, a form — lands here by default, so a page
      this file has never seen cannot be squeezed by the reading width. */
main > section > *,
main > header > *,
main > div.wrap > *{
  margin-inline:auto !important;
  padding-inline:0 !important;
  max-width:none !important;
}

/* ── The reading track. Declared AFTER the object rule and at equal or higher
      specificity, so prose opts back in to the narrower centred width. */
main h1, main h2, main h3, main h4, main h5, main h6,
main p, main li, main .lead, main .h-eyebrow, main .eyebrow,
main .section-head, main blockquote,
main > section > ul, main > section > ol, main > section > dl{
  max-width:var(--read) !important;
  margin-inline:auto !important;
  text-align:left !important;
}
/* Prose nested inside an object (a card, a grid cell, a table) is already
   constrained by its parent, so the max-width above is a no-op there and the
   auto margin has nothing to distribute. Left flush, as it should be. */

/* ── The hero is a <header> with its own inner wrapper, and it carried five
      rules pinning everything to margin-left:0. Those beat the reading track on
      specificity, so they are restated here rather than left to fight it. */
.hero-inner{
  max-width:none !important;
  margin-inline:auto !important;
  padding-inline:0 !important;
}
.hero h1,
.hero .lead,
.hero p,
.hero-ctas,
.hero-price-line,
.hero-proof{
  max-width:var(--read) !important;
  margin-left:auto !important;
  margin-right:auto !important;
  text-align:left !important;
}
/* The button row is a flex container: centre the ROW, keep the buttons packed
   to its left edge so they start on the same rail as the headline above them. */
.hero-ctas{ justify-content:flex-start !important; }

/* ── Centred clusters stay centred (they were objects, not prose). */
.social-bar{ margin-inline:auto !important; }
.social-bar .social-icons{ margin-inline:auto !important; }

/* ── The footer is full-bleed by design; its contents follow the wide track. */
footer > *{ max-width:var(--wide); margin-inline:auto; }

/* ══ THE LEFTOVER DISCS ════════════════════════════════════════════════════
   kova-light.css reset .bg-fixed's own background but never its two
   pseudo-elements, which are radial-gradients at rgba(59,40,18,.2) and .16.
   On black they were ambient light. On bone they are the grey smudge sitting
   over the top-left of the hero in every desktop screenshot. Same story for
   the card glows: the ::before layers were killed on .service and friends but
   .pain-card and .diag-wrap still paint theirs. */
.bg-fixed::before, .bg-fixed::after,
.pain-card::before, .pain-card::after,
.hero-proof-img::before, .hero-proof-img::after{
  content:none !important; display:none !important;
}
