/* =============================================================================
   CONCEPT PAGE KIT  (kit.css)  -- MECHANICS ONLY, NOT DESIGN
   -----------------------------------------------------------------------------
   This file is COPIED VERBATIM into every concept build. It solves the boring,
   invisible plumbing that must be correct on EVERY good site and that the verify
   floors check for: 44px tap targets, >=16px body / >=14px fine print, no
   horizontal overflow, a sticky call bar with a tel link, a legible logo, an
   accessible tab widget and lightbox, and a working sample form.

   IT DOES NOT DEFINE THE DESIGN. It carries NO real colours, NO real fonts, NO
   hero, NO section layouts and NO gallery. Everything visual is read from the
   design tokens below, which EACH CONCEPT OVERRIDES with its own palette and
   type, and every concept still draws its own hero, rhythm and gallery per the
   design draw. If two concepts built on this kit look alike, the kit is being
   MISUSED: push the difference into the concept's own styles.css, never in here.

   Class prefix: k-  (so concept classes never collide with kit classes).
   ============================================================================= */

:root{
  /* ---- token contract: a concept OVERRIDES these in its own styles.css ---- */
  --k-head-h:80px;                 /* sticky header height (drives scroll-margin) */
  --k-ink:#191919;                 /* primary dark / text on light backgrounds */
  --k-on-ink:#f5f2ec;              /* text on dark backgrounds */
  --k-paper:#f5f0e8;               /* page background */
  --k-card:#ffffff;                /* card / form surface */
  --k-muted:#6b6b6b;               /* secondary text on light */
  --k-line:rgba(20,20,20,.13);     /* hairline on light */
  --k-line-on-dark:rgba(255,255,255,.15);
  --k-accent:#2f5044;              /* THE reserved action colour (buttons) */
  --k-accent-ink:#ffffff;          /* text on accent buttons */
  --k-radius:8px;
  --k-font-display:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --k-font-body:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --k-shadow:0 20px 48px -24px rgba(20,18,14,.44);
  --k-wrap:1180px;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0; background:var(--k-paper); color:var(--k-ink);
  font-family:var(--k-font-body); font-size:17px; line-height:1.65;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility}
img{max-width:100%; display:block}
a{color:inherit; text-decoration:none}
p{margin:0}
h1,h2,h3,h4{font-family:var(--k-font-display); margin:0; line-height:1.06}
/* Every element with an id is a potential in-page anchor: keep the sticky header
   from covering the heading it jumps to. */
[id]{scroll-margin-top:calc(var(--k-head-h) + 12px)}

/* Container */
.k-wrap{width:100%; max-width:var(--k-wrap); margin:0 auto; padding:0 24px}

/* Eyebrow / kicker / badge: ALWAYS a <div> or <span>, NEVER a <p>. A <p> here
   drags the measured paragraph size below the mobile floor. This class is the
   reminder as much as the style. */
.k-eyebrow{font-family:var(--k-font-body); font-weight:600; text-transform:uppercase;
  letter-spacing:.2em; font-size:.76rem; margin:0 0 14px}

/* Fine print: clamped so it can never fall under the 14px hard floor. */
.k-fine{font-size:max(14px,.9rem); line-height:1.55}

/* Long unbreakable strings (emails, urls) must wrap, or they force overflow. */
.k-break{min-width:0; overflow-wrap:anywhere}

/* ---- buttons ---- */
.k-btn{display:inline-flex; align-items:center; justify-content:center; gap:.5em;
  min-height:50px; padding:0 24px; border-radius:var(--k-radius); font-family:var(--k-font-display);
  font-weight:600; font-size:1rem; letter-spacing:.01em; cursor:pointer;
  border:2px solid transparent; transition:transform .16s ease, background .16s, color .16s, border-color .16s}
.k-btn--solid{background:var(--k-accent); color:var(--k-accent-ink); border-color:var(--k-accent)}
.k-btn--solid:hover{filter:brightness(.92); transform:translateY(-2px)}
.k-btn--ghost{background:transparent; color:var(--k-on-ink); border-color:color-mix(in srgb, var(--k-on-ink) 45%, transparent)}
.k-btn--ghost:hover{border-color:var(--k-on-ink); background:color-mix(in srgb, var(--k-on-ink) 8%, transparent)}
.k-btn--outline-ink{background:transparent; color:var(--k-ink); border-color:var(--k-line)}
.k-btn--outline-ink:hover{border-color:var(--k-ink); transform:translateY(-2px)}
.k-btn--block{width:100%}
@media (prefers-reduced-motion:reduce){.k-btn:hover{transform:none}}
/* Stacked button pairs match widths on a phone instead of reading as an accident. */
.k-actions{display:flex; gap:12px; flex-wrap:wrap}
@media (max-width:600px){
  .k-actions{flex-direction:column; align-items:stretch}
  .k-actions .k-btn{width:100%}
}

/* ---- sample-concept marker (required on the page) ---- */
.k-samplebar{background:var(--k-ink); color:var(--k-on-ink); font-size:.82rem; line-height:1.4;
  padding:9px 24px; text-align:center; display:flex; gap:10px; justify-content:center; flex-wrap:wrap}
.k-samplebar strong{font-weight:600}

/* ---- sticky header ---- */
.k-head{position:sticky; top:0; z-index:60; background:color-mix(in srgb, var(--k-paper) 92%, transparent);
  backdrop-filter:blur(10px); border-bottom:1px solid var(--k-line)}
.k-head--dark{background:color-mix(in srgb, var(--k-ink) 92%, transparent); border-bottom:1px solid var(--k-line-on-dark)}
.k-head-inner{display:flex; align-items:center; gap:22px; height:var(--k-head-h)}
.k-brand{display:flex; align-items:center; gap:12px}
/* Logo legibility + collapse guard: never renders under 60px, never relies on
   aspect-ratio as a flex child. Concepts may raise the height via --k-logo-h. */
.k-brand img{height:var(--k-logo-h,60px); width:auto; flex:none; align-self:center; aspect-ratio:auto; border-radius:6px}
.k-nav{display:flex; gap:4px; margin-left:auto}
.k-nav a{font-family:var(--k-font-display); font-size:.95rem; font-weight:500;
  padding:10px 13px; border-radius:6px; min-height:44px; display:inline-flex; align-items:center}
.k-head-cta{display:flex; align-items:center; gap:16px; margin-left:6px}
.k-tel{display:inline-flex; align-items:center; gap:7px; font-family:var(--k-font-display);
  font-weight:600; font-size:.95rem; min-height:44px}

/* ---- tab / router widget (accessible; drives .k-panel) ---- */
.k-tabs{display:flex; flex-wrap:wrap}
.k-tab{flex:1 1 auto; font-family:var(--k-font-display); font-weight:500; font-size:.95rem;
  background:transparent; border:0; padding:15px 14px; min-height:54px; cursor:pointer; white-space:nowrap;
  transition:background .15s, color .15s}
.k-panel[hidden]{display:none}   /* beats a display rule that would show all panels */

/* ---- sample contact form ---- */
.k-form label{display:block; font-family:var(--k-font-display); font-weight:500; font-size:.9rem; margin-bottom:16px}
.k-form input,.k-form select,.k-form textarea{width:100%; margin-top:7px; font-family:var(--k-font-body);
  font-size:1rem; color:var(--k-ink); background:var(--k-paper); border:1px solid var(--k-line);
  border-radius:var(--k-radius); padding:12px 14px; min-height:48px}
.k-form textarea{min-height:86px; resize:vertical}
.k-form input:focus,.k-form select:focus,.k-form textarea:focus{outline:2px solid var(--k-accent); border-color:var(--k-accent)}
.k-form-status{margin-top:14px; font-family:var(--k-font-body); font-weight:600; min-height:1.2em}

/* ---- safe scroll reveal (opacity is ALWAYS 1: content is never hidden) ----
   Use data-k-reveal (optionally ="left"/"right"); kit.js adds .k-in to settle
   it. A missed observer or a static capture just leaves a 16px offset, never a
   blank section. NEVER hand-roll an opacity:0 reveal: it fails verify (the probe
   reads opacity:0 as invisible) and blanks out sections in a screenshot. */
@media (prefers-reduced-motion:no-preference){
  [data-k-reveal]{transform:translateY(16px); transition:transform .6s ease, opacity .6s ease; will-change:transform}
  [data-k-reveal="left"]{transform:translateX(-16px)}
  [data-k-reveal="right"]{transform:translateX(16px)}
  [data-k-reveal="zoom"]{transform:scale(.94)}   /* scroll-linked scale-in; content stays visible */
  [data-k-reveal].k-in{transform:none}
}

/* ---- parallax helper (transform-only; opt in with data-k-parallax) ----
   Layered-depth scroll: a background photo drifts slower than the foreground.
   Put data-k-parallax="0.15" (the drift speed) on the moving layer; kit.js does
   the rAF-throttled, reduced-motion-off transform. Wrap the layer in .k-parallax:
   it CLIPS and the layer is OVERSIZED (128% tall), so the drift never exposes a
   blank edge. Never parallax text a visitor must read, and keep the speed subtle
   (0.08 to 0.25). background-attachment:fixed is NOT used: it is janky and
   effectively disabled on iOS. */
.k-parallax{ position:relative; overflow:hidden; isolation:isolate; }
.k-parallax > [data-k-parallax]{ position:absolute; left:0; right:0; top:-20%; height:140%; }
.k-parallax > [data-k-parallax] img{ width:100%; height:100%; object-fit:cover; display:block; }
@media (prefers-reduced-motion:no-preference){ [data-k-parallax]{ will-change:transform; } }
/* no motion wanted: the layer just fills its box normally, no transform, no edge */
@media (prefers-reduced-motion:reduce){ .k-parallax > [data-k-parallax]{ top:0; height:100%; } }

/* ---- typewriter (opt in with data-k-type) ----
   The FULL text lives in the element, so it shows with no JS, in a static capture
   and to screen readers. kit.js types it in ONCE, on scroll into view, only as
   enhancement: it reserves the final size first (a hidden ghost) so nothing
   reflows, keeps an sr-only copy for assistive tech, and is skipped entirely for
   reduced motion. Best on SHORT lines below the fold (a typed review, a tagline);
   wrap plain text only (no inner markup). */
.k-type-host{ position:relative; }
.k-type-ghost{ visibility:hidden; }
.k-type-run{ position:absolute; left:0; right:0; top:0; }
.k-type-run::after{ content:"|"; margin-left:2px; animation:k-caret 1s step-end infinite; }
.k-type-host.k-type-done .k-type-run::after{ display:none; }
@keyframes k-caret{ 50%{ opacity:0; } }
.k-sr-only{ position:absolute !important; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }

/* ---- comparison table / grid (mechanics only; the concept styles the cells) ----
   For product, plan/tier or service comparisons, and us-vs-alternatives grids.
   Put a REAL <table class="k-compare"> inside .k-compare-wrap so a wide matrix
   SCROLLS inside its own box instead of overflowing the page (the
   no-horizontal-overflow floor). Add tabindex="0" to the wrap so it is keyboard
   scrollable. Colours, the "recommended" column and check/cross marks are the
   concept's own styles.css. Compare on VERIFIED facts only, never invented data. */
.k-compare-wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; border-radius:var(--k-radius); }
.k-compare-wrap:focus-visible{ outline:2px solid var(--k-accent); outline-offset:2px; }
.k-compare{ width:100%; border-collapse:collapse; min-width:600px; }  /* min-width keeps columns legible; the wrap scrolls */
.k-compare th,.k-compare td{ text-align:left; padding:14px 18px; vertical-align:top; }
.k-compare thead th{ position:sticky; top:0; background:var(--k-card); }   /* header pins; override the bg to taste */
.k-compare tbody th{ position:sticky; left:0; background:var(--k-card); }  /* label column pins horizontally */
.k-compare th:first-child,.k-compare td:first-child{ min-width:150px; }

/* ---- gallery tile + lightbox (only used by photo-led concepts) ---- */
.k-tile{padding:0; border:0; margin:0; cursor:pointer; position:relative; overflow:hidden;
  border-radius:var(--k-radius); background:color-mix(in srgb, var(--k-ink) 12%, var(--k-paper))}
.k-tile img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transition:transform .5s ease}
.k-tile:hover img{transform:scale(1.05)}
.k-tile:focus-visible{outline:3px solid var(--k-accent); outline-offset:2px}
@media (prefers-reduced-motion:reduce){.k-tile img{transition:none} .k-tile:hover img{transform:none}}
.k-lightbox{position:fixed; inset:0; z-index:90; background:rgba(12,12,12,.92);
  display:none; align-items:center; justify-content:center; padding:24px}
.k-lightbox.k-open{display:flex}
.k-lb-inner{position:relative; max-width:1000px; width:100%; display:flex; align-items:center; gap:8px; justify-content:center}
.k-lb-figure{margin:0; max-width:860px}
.k-lb-figure img{width:100%; max-height:80vh; object-fit:contain; border-radius:var(--k-radius)}
.k-lb-figure figcaption{font-family:var(--k-font-body); color:#e6e0d4; text-align:center; margin-top:14px; font-size:.95rem}
.k-lb-close{position:absolute; top:-46px; right:0; background:none; border:0; color:#f2ece0;
  font-size:2.4rem; line-height:1; cursor:pointer; min-width:44px; min-height:44px}
.k-lb-nav{background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.25); color:#fff;
  font-size:2rem; width:52px; height:52px; border-radius:50%; cursor:pointer; flex:none;
  display:flex; align-items:center; justify-content:center}
.k-lb-nav:hover{background:rgba(255,255,255,.2)}

/* ---- footer skeleton ---- */
.k-foot-nav a,.k-foot-contact a{min-height:44px; display:flex; align-items:center}

/* ---- sticky mobile call bar (shown on phones; keeps a tel link reachable) ---- */
.k-callbar{position:fixed; left:0; right:0; bottom:0; z-index:70; display:none; gap:10px;
  padding:10px 14px calc(10px + env(safe-area-inset-bottom));
  background:color-mix(in srgb, var(--k-ink) 96%, transparent); backdrop-filter:blur(8px);
  border-top:1px solid var(--k-line-on-dark)}
.k-callbar .k-btn{flex:1}
@media (max-width:760px){
  body{font-size:16px}                 /* keep body text at the 16px floor on phones */
  .k-callbar{display:flex}
  main{padding-bottom:74px}            /* clear the fixed call bar */
  .k-nav{display:none}                 /* concept supplies its own compact header if needed */
  .k-head-cta .k-tel{display:none}
}
