/* ============================================================================
   VerityIQ - marketing site stylesheet
   Shared by /, /privacy/, /terms/.

   GOVERNING RULE
   A token that also exists in src/mmm_portfolio/app/assets/app.css keeps that
   file's NAME and VALUE. A token that exists only on marketing surfaces gets a
   name that does not appear in app.css at all.

   NOT SHARED WITH THE APP: the app's .eyebrow is an icon-mask section label and
   its .pill is a verdict chip. Both names mean something else here.

   RECORDED DEVIATION (owner-approved 2026-09-03): colors.md disallows gradients
   and DESIGN.md bars a second shadow. Those govern the report app; _DECISIONS.md
   2026-08-31 puts the marketing site outside that system. The hero wash and the
   layered lift scale are a deliberate marketing-surface exception.
   ============================================================================ */

:root {
    /* --- palette: adopted from app.css, name and value --- */
    --ink: #15181B;
    --bone: #F5F1E8;
    --bone-deep: #EDE9DF;
    --paper: #FCFBF8;
    --gray: #6B6760;
    --line: #E2DDD0;
    --hair: #D8D3C7;
    --fill: #EDE9DF;
    --green: #00BF6F;          /* fill / mark only - never small text */
    --green-text: #067946;     /* the ONLY green allowed as text */
    --green-band: rgba(0,191,111,.14);
    --blue: #1E50C8;           /* "what the platform claims" - rationed */
    --blue-text: #2B52BF;
    --blue-hard: #173FA8;
    --pill-soft-bg: #E7ECFB;
    --pill-hard-bg: #D9E1F6;

    /* --- site-only: names absent from app.css --- */
    --slate: #343D3F;
    --white: #FFFFFF;
    --green-tint: #DFF5E9;
    --green-tint-line: #BFE8D2;

    --font-sans: 'Geist', 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
    --font-mono: 'Geist Mono', ui-monospace, 'SF Mono', 'Cascadia Code', Menlo, Consolas, monospace;

    /* --- motion: identity/motion.md --- */
    --dur-fast: 120ms; --dur-base: 200ms; --dur-slow: 360ms;
    --ease: cubic-bezier(.2,.8,.2,1);
    --ease-standard: cubic-bezier(.2,.8,.2,1);

    /* --- geometry --- */
    --r-ctl: 8px;
    --r-card: 12px;
    --r-pill: 999px;
    --bw: 1px;
    /* Layered, not one flat token - depth is what "looks designed" is made of. */
    --lift-1: 0 1px 2px rgba(21,24,27,.05);
    --lift-2: 0 1px 2px rgba(21,24,27,.05), 0 6px 16px rgba(21,24,27,.05);
    --lift-3: 0 1px 2px rgba(21,24,27,.05), 0 10px 28px rgba(21,24,27,.07), 0 40px 80px rgba(21,24,27,.09);
    --shadow: var(--lift-2);

    /* --- rhythm: three tiers, so some sections are allowed to matter more --- */
    --flow-hero: 120px;
    --flow-section: 96px;
    --flow-tight: 60px;
}

/* ---------------------------------------------------------------- base --- */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
    margin: 0; background: var(--paper); color: var(--slate);
    font-family: var(--font-sans); font-size: 16px; line-height: 1.6;
    -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
a { color: var(--green-text); text-decoration: none; }
a:hover { text-decoration: underline; }
p { margin: 0 0 1rem; }
.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }

/* Visually hidden, still announced. NOT .hp - that is the form honeypot,
   deliberately hostile to assistive tech. Two opposite intents, two names. */
.viq-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
          overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ------------------------------------------------------- frame + measure --- */
/* Vertical rules run the page's full height, framing the content column. */
.frame { max-width: 1230px; margin: 0 auto; position: relative; }
.frame::before, .frame::after {
    content: ""; position: absolute; top: 0; bottom: 0; width: 1px;
    background: var(--line); pointer-events: none; z-index: 2;
}
.frame::before { left: 0; } .frame::after { right: 0; }
.wrap { max-width: 1100px; margin: 0 auto; padding: 0 28px; }
.measure { max-width: 760px; margin: 0 auto; }

section { padding: var(--flow-section) 0; }
section.tight { padding: var(--flow-tight) 0; }
/* Alternating ground. Uses the brand's own bone rather than a new tint -
   there was no reason to invent a colour for this. */
section.tinted { background: linear-gradient(180deg, var(--paper) 0%, var(--bone) 55%, var(--paper) 100%); }

/* ---------------------------------------------------------------- type --- */
h1, h2, h3 { font-family: var(--font-sans); margin: 0; color: var(--ink); }
h1, h2 { font-weight: 500; letter-spacing: -0.028em; line-height: 1.08; }
/* 500, not 600. The reference runs its 56px headline at 400 - the lighter
   weight is most of why it reads refined rather than shouty. */
.h1 { font-size: clamp(38px, 4.4vw, 56px); }
.h2 { font-size: clamp(29px, 3.1vw, 40px); }
h3 { font-weight: 600; font-size: 17px; letter-spacing: -0.01em; }
.lead { font-size: 17px; line-height: 1.62; color: var(--gray); }

/* The eyebrow is used THREE times on the whole page, not on every section.
   A section that needs a label to say what it is has a headline problem. */
.eyebrow {
    display: inline-flex; align-items: center; gap: 9px;
    font-family: var(--font-mono); font-size: 11.5px; font-weight: 500;
    letter-spacing: .14em; text-transform: uppercase; color: var(--gray);
}
.eyebrow::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--green); flex: none; }

/* -------------------------------------------------------------- header --- */
.site-header { position: sticky; top: 0; z-index: 50; height: 76px;
    background: rgba(252,251,248,.9); backdrop-filter: saturate(150%) blur(10px);
    border-bottom: 1px solid var(--line); }
.site-header .inner { height: 76px; display: flex; align-items: center;
    justify-content: space-between; gap: 24px; padding: 0 32px; }
.brand { display: inline-flex; align-items: center; gap: 9px; color: var(--ink);
    font-weight: 600; font-size: 18px; letter-spacing: -.02em; flex: none; }
.brand:hover { text-decoration: none; }
.brand img { display: block; }
.nav { display: flex; gap: 30px; }
/* Negative margin cancels the padding, so the hit area grows to clear the
   WCAG 2.2 24x24 minimum without moving anything visually. */
.nav a { font-size: 14px; color: var(--gray); white-space: nowrap;
         padding: 11px 4px; margin: -11px -4px; }
.nav a:hover { color: var(--ink); text-decoration: none; }
.h-right { display: flex; align-items: center; gap: 10px; flex: none; }

/* ------------------------------------------------------------- buttons --- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    height: 48px; padding: 0 22px; border: 1px solid transparent; border-radius: var(--r-ctl);
    font-family: var(--font-sans); font-size: 14px; font-weight: 600;
    white-space: nowrap; cursor: pointer;
    transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
                box-shadow var(--dur-fast) var(--ease), transform 50ms var(--ease); }
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--green); color: var(--ink); box-shadow: var(--lift-1); }
.btn-primary:hover { background: #00D47B; }
.btn-ghost { background: var(--white); color: var(--ink); border-color: var(--line); box-shadow: var(--lift-1); }
.btn-ghost:hover { border-color: var(--hair); }
.btn-sm { height: 40px; padding: 0 16px; font-size: 13.5px; }
.btn .chev { width: 6px; height: 6px; flex: none;
    border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor;
    transform: rotate(45deg); margin-left: 1px;
    transition: transform var(--dur-fast) var(--ease); }
.btn:hover .chev { transform: rotate(45deg) translate(2px,-2px); }

/* Travelling border-beam, kept by owner decision. On ::before, never ::after -
   ::after is the chevron, and one pseudo-element cannot be both. */
@property --beam-angle { syntax: "<angle>"; initial-value: 0deg; inherits: false; }
.btn-primary:not(.btn-sm) { position: relative; }
html.motion .btn-primary:not(.btn-sm)::before {
    content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 2px;
    background: conic-gradient(from var(--beam-angle),
        transparent 0deg, transparent 235deg,
        rgba(21,184,106,0) 255deg, #15B86A 298deg, #EBFFF4 325deg, #15B86A 352deg,
        rgba(21,184,106,0) 360deg);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor; mask-composite: exclude;
    filter: drop-shadow(0 0 2px rgba(21,184,106,.55));
    pointer-events: none; animation: btn-beam 3.2s linear infinite;
}
@keyframes btn-beam { to { --beam-angle: 360deg; } }

/* ---------------------------------------------------- browser-chrome shot --- */
.chrome { border: 1px solid var(--line); border-radius: var(--r-card); overflow: hidden;
    background: var(--white); box-shadow: var(--lift-3); }
.chrome .bar2 { display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 14px;
    background: var(--bone); border-bottom: 1px solid var(--line); }
.chrome .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--hair); }
.chrome .url { margin: 0 auto; padding: 3px 14px; border-radius: 999px; background: var(--paper);
    border: 1px solid var(--line); font-family: var(--font-mono); font-size: 11px; color: var(--gray);
    transition: opacity .25s var(--ease); }
.chrome img { display: block; width: 100%; height: auto; }
.frames { position: relative; }
.fr { display: block; width: 100%; height: auto; opacity: 0; transition: opacity .7s var(--ease); }
.fr:first-child { position: relative; }        /* holds the height */
.fr:not(:first-child) { position: absolute; inset: 0; }
.fr.is-on { opacity: 1; }
.shotcap { margin: 0 0 16px; font-size: 12px; color: var(--gray); text-align: center; }

/* ---------------------------------------------------- range instrument --- */
/* Pure CSS - no SVG, no JS. The band is the range the data supports; the dashed
   ceiling is its top; the caret is what the platform claims. DELIBERATELY no
   estimate node inside the band: a point inside a credible range IS a point
   attribution, which PROJECT.md 12 forbids anywhere, in any output. */
.rangebar { position: relative; height: 16px; margin: 30px 0 4px; }
.rangebar::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--hair); }
.rangebar .band { position: absolute; top: 0; bottom: 0; background: var(--green-band);
    border-top: 1.5px solid var(--green); border-bottom: 1.5px solid var(--green); }
.rangebar .cap { position: absolute; top: -4px; bottom: -4px; width: 1.5px; background: var(--green-text); }
.rangebar .cap.ceiling { background: none; width: 0; border-left: 1.5px dashed var(--green-text); top: -10px; bottom: -10px; }
.rangebar .mark { position: absolute; top: -11px; width: 0; height: 0; margin-left: -5px;
    border: 5px solid transparent; border-top-color: var(--blue); }
.rangebar .mark::after { content: ""; position: absolute; left: -1px; top: -1px;
    width: 2px; height: 28px; background: var(--blue); opacity: .4; }
.rangebar-axis { position: relative; height: 5px; margin: 0 0 6px; }
.rangebar-axis i { position: absolute; top: 0; width: 1px; height: 4px; background: var(--hair); }
.range-row { display: flex; justify-content: space-between; gap: 16px; align-items: baseline; flex-wrap: wrap; }
.range-row b { color: var(--ink); font-weight: 600; font-size: 15px; }
.range-row .claim { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 13px; color: var(--gray); }
.rlab { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
    font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 12.5px; color: var(--gray); }
.rlab .v { font-family: var(--font-sans); font-weight: 600; letter-spacing: 0; color: var(--blue-hard); }
.rlab .v.ok { color: var(--green-text); }

/* The measurement is already true when the page arrives. The claim is the part
   being asserted, so the claim is the part that moves. */
@keyframes viq-claim { from { transform: translateY(-7px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
html.motion .rangebar .mark { opacity: 0; }
html.motion .reveal.is-in .rangebar .mark,
html.motion .stagger.is-in .rangebar .mark { animation: viq-claim var(--dur-slow) var(--ease) both; }

/* -------------------------------------------------------------- motion --- */
/* Scoped to html.motion, which the inline <head> bootstrap sets ONLY when
   IntersectionObserver exists AND prefers-reduced-motion is not "reduce".
   That coupling is load-bearing: .te-word rests at opacity:0, so if these ever
   applied without the JS that clears them, every headline would be permanently
   invisible. Do not simplify the scope away in favour of the block at the end. */
html.motion .reveal { opacity: 0; transform: translateY(6px); transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease); }
html.motion .reveal.is-in { opacity: 1; transform: none; }
html.motion .stagger > * { opacity: 0; transform: translateY(6px); transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease); }
html.motion .stagger.is-in > * { opacity: 1; transform: none; }
html.motion .te-word { display: inline-block; white-space: pre; opacity: 0; filter: blur(12px);
    transition: opacity var(--dur-slow) var(--ease), filter var(--dur-slow) var(--ease); will-change: opacity, filter; }
html.motion .te-word.in { opacity: 1; filter: blur(0); }

/* -------------------------------------------------------------- footer --- */
.site-footer { border-top: 1px solid var(--line); padding: 56px 0 0; overflow: hidden; }
.site-footer .brand { color: var(--ink); }
.site-footer a { color: var(--slate); }
.site-footer .credit { font-size: 13px; color: var(--gray); }
.site-footer .credit a { color: var(--slate); }

/* ------------------------------------------------------------- narrow --- */
@media (max-width: 880px) {
    :root { --flow-hero: 72px; --flow-section: 64px; --flow-tight: 44px; }
    .nav { display: none; }
    .h-right .btn-ghost { display: none; }   /* two header buttons will not fit */
    .site-header .inner { padding: 0 20px; }
}

/* ------------------------------------------------------------ reduced --- */
/* Must stay LAST. Property-whitelist form (app.css:1068) rather than a blanket
   duration kill, so any spatial transition added later is neutered without
   anyone having to remember this block exists. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    * { animation: none !important;
        transition-property: color, background-color, border-color, opacity !important; }
}
