/*
  rebuild/spine.css : the structural, responsive, accessibility, and motion
  framework for the SMPL flagship conversion spine. Layout primitives + the
  section skeletons. Reads design values ONLY through tokens.css custom
  properties; contains zero color/type/space literals of its own.

  What it is:
    The "how it is built" layer that sits under the section shells. It owns:
      - the mobile-first responsive framework (single breakpoint ladder)
      - the accessibility framework (skip link, landmarks, focus-visible, the
        reduced-motion contract)
      - the reveal/motion CONTRACT (the .reveal-item mount points Kai's motion
        layer attaches to, carried verbatim from /scan so both pages animate as
        one system)
      - the spine section layout primitives (container, section rhythm, the
        surface-ladder background hooks, the W+K case-study card grid)

  Why this shape (rationale):
    - Mobile-first, one breakpoint up at 720px, matching /scan exactly. SMPL sells
      mobile excellence; the spine is the proof, so it is sized from the small
      screen up and enhances, never the reverse.
    - Token-agnostic: every visual value is a var(). Swapping Sloane's palette or
      type scale touches tokens.css only. That is the whole point of the split.
    - Accessibility is baseline, not a layer added later. Skip link, semantic
      landmarks, visible focus, and reduced-motion parity are in the framework so
      the section shells inherit them for free.
    - Motion is deferred-by-default and IntersectionObserver-gated (the .reveal
      contract), NOT eager on mount. This is the Beecasso INP lesson: eager
      below-fold motion lands in the hydration burst and tanks INP. Kai's layer
      attaches here; the gate is already built so his motion passes CWV.

  Rejected alternative:
    Tailwind / utility classes (no build system in this repo, and the spine wants
    a small hand-authored surface, not a utility framework). Desktop-first media
    queries (more overrides, worse mobile default, contradicts the mobile-first
    posture). Eager GSAP-style mount animation (the documented INP regression).

  Refactor targets:
    - Breakpoint count may grow to two (tablet) if Sloane's layout needs it; the
      ladder is intentionally minimal now.
    - The card grid is a v1 primitive; richer case-study layouts attach here.
*/

@layer structure {

  /* ----- reset (scoped, matches /scan) ----- */
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

  html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

  body {
    font-family: var(--font-body);
    font-weight: var(--weight-light);
    font-feature-settings: var(--font-body-features);
    background: var(--surface-1);
    color: var(--color-ink);
    line-height: var(--leading-body);
    min-height: 100vh;
    overflow-x: hidden;
    position: relative;
  }

  /* ----- accessibility framework ----- */

  /* Skip link: first focusable element, visually hidden until focused. Every
     spine page gets one; the shell wires href="#main". */
  .skip-link {
    position: absolute;
    left: var(--space-3);
    top: -100%;
    z-index: 100;
    padding: var(--space-2) var(--space-4);
    background: var(--surface-4);
    color: var(--color-ink);
    border: 1px solid var(--color-hairline-2);
    border-radius: var(--radius-sm);
    text-decoration: none;
    transition: top var(--dur-fast) var(--ease-out);
  }
  .skip-link:focus { top: var(--space-3); }

  /* Visible focus for keyboard users only. Never remove the outline outright. */
  :focus-visible {
    outline: 2px solid var(--color-signal);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
  }

  /* Screen-reader-only utility for labels that must exist but not display. */
  .sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0);
    white-space: nowrap; border: 0;
  }

  /* ----- layout primitives ----- */

  .container {
    width: 100%;
    max-width: var(--measure-wide);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  .measure { max-width: var(--measure-read); }

  /* Every spine section is a landmark with consistent vertical rhythm and a
     surface-ladder background hook. data-surface picks the ladder stop. */
  .spine-section {
    position: relative;
    padding-block: var(--space-section);
  }
  .spine-section[data-surface="1"] { background: var(--surface-1); }
  .spine-section[data-surface="2"] { background: var(--surface-2); }
  .spine-section[data-surface="3"] { background: var(--surface-3); }
  .spine-section[data-surface="4"] { background: var(--surface-4); }

  .eyebrow {
    font-size: var(--type-eyebrow);
    letter-spacing: var(--tracking-eyebrow);
    text-transform: uppercase;
    color: var(--color-ink-faint);
    margin-bottom: var(--space-3);
  }

  /* Display headings use the locked display family + tight leading. */
  .display {
    font-family: var(--font-display);
    font-weight: var(--weight-regular);
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-display);
  }
  .display--hero { font-size: var(--type-hero); }
  .display--h2   { font-size: var(--type-h2); }

  /* Every metric carries tabular numerals so digits align. Tokenized so a
     number block reads as deliberate craft, not default. */
  .metric { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

  /* ----- the ONE signal: CTA + active nav ----- */

  /* Primary CTA. The lime lives here (one of its four sanctioned sites). Glow on
     hover only, never strobing (direction §7). */
  .cta-primary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    background: var(--color-signal);
    color: var(--surface-1);
    font-weight: var(--weight-semibold);
    border-radius: var(--radius-md);
    text-decoration: none;
    transition: box-shadow var(--dur-base) var(--ease-out),
                transform var(--dur-fast) var(--ease-out);
  }
  .cta-primary:hover { box-shadow: 0 0 20px var(--color-signal-soft); }
  .cta-primary:active { transform: translateY(1px); }

  /* Low-friction secondary entry. No fill, no lime. "Let's talk about your
     visibility" lives here, not a second primary. */
  .cta-secondary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    color: var(--color-ink);
    border: 1px solid var(--color-hairline-2);
    border-radius: var(--radius-md);
    text-decoration: none;
    transition: border-color var(--dur-base) var(--ease-out);
  }
  .cta-secondary:hover { border-color: var(--color-ink-muted); }

  /* ----- case-study card grid (W+K model: industry tag + short outcome) ----- */
  .case-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-4);
    margin-top: var(--space-5);
  }
  .case-card {
    background: var(--surface-4);
    border: 1px solid var(--color-hairline);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
  }
  .case-card__tag {
    font-size: var(--type-eyebrow);
    letter-spacing: var(--tracking-eyebrow);
    text-transform: uppercase;
    color: var(--color-ink-faint);
  }
  .case-card__outcome {
    font-family: var(--font-display);
    font-size: var(--type-h3);
    line-height: var(--leading-snug);
    margin-top: var(--space-2);
  }

  /* Honest empty-state for case studies (direction §3 / G6: no fabricated proof;
     the section carries the "test the tool yourself" framing until a REAL case
     study lands). Shown when the grid has no populated cards. */
  .case-empty {
    background: var(--surface-3);
    border: 1px dashed var(--color-hairline-2);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    text-align: center;
    color: var(--color-ink-muted);
  }

  /* ----- NAV bar ----- */
  header {
    position: sticky;
    top: 0;
    z-index: 40;
    background: var(--surface-1);
    border-bottom: 1px solid var(--color-hairline);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
  }
  header .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 3.5rem;
    gap: var(--space-4);
  }
  .nav-logo {
    font-family: var(--font-display);
    font-size: 1.5rem;
    letter-spacing: var(--tracking-eyebrow);
    color: var(--color-ink);
    text-decoration: none;
  }
  .nav-logo span { color: var(--color-signal); }
  .nav-links {
    display: none;
    list-style: none;
    gap: var(--space-5);
  }
  .nav-links a {
    font-size: var(--type-small);
    letter-spacing: var(--tracking-eyebrow);
    text-transform: uppercase;
    color: var(--color-ink-muted);
    text-decoration: none;
    transition: color var(--dur-fast) var(--ease-out);
  }
  .nav-links a:hover,
  .nav-links a[aria-current="page"] { color: var(--color-ink); }
  .nav-links a[aria-current="page"] { color: var(--color-signal); }  /* one of the four signal sites */

  /* ----- decorative atmosphere layers (matches /scan) ----- */
  .atmosphere {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 0;
    background:
      radial-gradient(ellipse 70% 40% at 15% 10%, rgba(194,255,0,0.04) 0%, transparent 70%),
      radial-gradient(ellipse 60% 50% at 85% 80%, rgba(194,255,0,0.025) 0%, transparent 70%);
  }
  .grain {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 1;
    opacity: 0.028;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
    background-size: 160px 160px;
  }
  main { position: relative; z-index: 2; }

  /* ----- hero sub-elements (homepage) ----- */
  .hero-sub {
    font-size: var(--type-h4);
    font-weight: var(--weight-light);
    color: var(--color-ink-muted);
    line-height: var(--leading-body);
    max-width: var(--measure-read);
    margin-top: var(--space-5);
  }
  .platform-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-3);
    list-style: none;
    margin-top: var(--space-4);
  }
  .platform-row li {
    font-size: var(--type-small);
    letter-spacing: var(--tracking-eyebrow);
    text-transform: uppercase;
    color: var(--color-ink-faint);
    background: var(--surface-4);
    border: 1px solid var(--color-hairline);
    border-radius: var(--radius-pill);
    padding: var(--space-1) var(--space-3);
  }
  .social-proof {
    margin-top: var(--space-4);
    font-size: var(--type-small);
    color: var(--color-ink-faint);
    letter-spacing: var(--tracking-body);
  }

  /* ----- AEO answer-first intro block ----- */
  /* The first 40-60 words of any AEO page MUST be a direct answer to the
     implied question. This block is visually set apart from the surrounding
     prose — it is the AI-citation target, not a marketing paragraph. */
  .answer-block {
    border-left: 2px solid var(--color-signal);
    padding-left: var(--space-4);
    margin-block: var(--space-5);
    max-width: var(--measure-answer);
  }
  .answer-block p {
    font-size: var(--type-h4);
    font-weight: var(--weight-regular);
    line-height: var(--leading-body);
    color: var(--color-ink);
  }

  /* ----- page hero (interior pages, smaller than homepage) ----- */
  .page-hero {
    padding-block: var(--space-7) var(--space-6);
    border-bottom: 1px solid var(--color-hairline);
  }
  .page-hero__eyebrow { margin-bottom: var(--space-3); }
  .page-hero__heading {
    font-family: var(--font-display);
    font-size: clamp(2.25rem, 6vw, 4.5rem);
    font-weight: var(--weight-regular);
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-display);
    max-width: 18ch;
  }
  .page-hero__sub {
    margin-top: var(--space-4);
    font-size: var(--type-h4);
    font-weight: var(--weight-light);
    color: var(--color-ink-muted);
    max-width: var(--measure-read);
    line-height: var(--leading-body);
  }

  /* ----- method steps (ordered) ----- */
  .method-steps {
    counter-reset: step;
    list-style: none;
    margin-top: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
  }
  .method-steps li {
    counter-increment: step;
    position: relative;
    display: block;
    padding-left: calc(2.5rem + var(--space-3));
  }
  .method-steps li::before {
    content: counter(step, decimal-leading-zero);
    position: absolute;
    left: 0;
    top: 0;
    font-family: var(--font-display);
    font-size: var(--type-h3);
    line-height: 1;
    color: var(--color-signal);
  }

  /* ----- honest caveat box ----- */
  .honest-caveat {
    margin-top: var(--space-6);
    padding: var(--space-4) var(--space-5);
    border: 1px solid var(--color-hairline-2);
    border-radius: var(--radius-md);
    background: var(--surface-3);
  }
  .honest-caveat p {
    font-size: var(--type-small);
    color: var(--color-ink-muted);
    line-height: var(--leading-loose);
  }
  .honest-caveat p + p { margin-top: var(--space-3); }

  /* ----- scan mount ----- */
  .scan-mount {
    margin-top: var(--space-5);
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--color-hairline);
  }
  .scan-mount iframe { display: block; }

  /* ----- FAQ block ----- */
  /* Every AEO interior page requires at least one FAQ block. The answer text
     inside each .faq-answer is the schema/citation target — keep it concise
     and standalone (Soren wires the FAQPage schema; the DOM IS the data). */
  .faq-list {
    margin-top: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: 1px;                         /* hairline between items via gap, not border-bottom */
    border: 1px solid var(--color-hairline);
    border-radius: var(--radius-lg);
    overflow: hidden;
  }
  .faq-item {
    background: var(--surface-2);
  }
  .faq-item + .faq-item { border-top: 1px solid var(--color-hairline); }
  .faq-question {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-5);
    background: transparent;
    border: 0;
    color: var(--color-ink);
    font-family: var(--font-body);
    font-size: var(--type-body);
    font-weight: var(--weight-medium);
    line-height: var(--leading-snug);
    text-align: left;
    cursor: pointer;
    transition: color var(--dur-fast) var(--ease-out);
  }
  .faq-question:hover { color: var(--color-ink); }
  .faq-question[aria-expanded="true"] { color: var(--color-signal); }
  .faq-question__icon {
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    color: var(--color-ink-faint);
    transition: transform var(--dur-base) var(--ease-out),
                color var(--dur-fast) var(--ease-out);
  }
  .faq-question[aria-expanded="true"] .faq-question__icon {
    transform: rotate(45deg);
    color: var(--color-signal);
  }
  .faq-answer {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--dur-base) var(--ease-out);
  }
  .faq-answer[aria-hidden="false"] { grid-template-rows: 1fr; }
  .faq-answer__inner {
    overflow: hidden;
    padding: 0 var(--space-5) 0;
    transition: padding var(--dur-base) var(--ease-out);
  }
  .faq-answer[aria-hidden="false"] .faq-answer__inner {
    padding: 0 var(--space-5) var(--space-4);
  }
  .faq-answer p {
    font-size: var(--type-body);
    color: var(--color-ink-muted);
    line-height: var(--leading-loose);
    max-width: var(--measure-read);
  }

  /* ----- feature list (icon + text, used in service/offer pages) ----- */
  .feature-list {
    list-style: none;
    margin-top: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }
  .feature-list li {
    position: relative;
    display: block;
    padding-left: calc(1.5rem + var(--space-3));
    font-size: var(--type-body);
    color: var(--color-ink-muted);
    line-height: var(--leading-body);
  }
  .feature-list li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.15em;
    width: 1.25rem;
    height: 1.25rem;
    background: var(--color-signal);
    clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
  }
  .feature-list li strong { color: var(--color-ink); font-weight: var(--weight-medium); }

  /* ----- comparison / pricing table ----- */
  /* Responsive: stacks on mobile, becomes a proper two-column comparison
     at 720px. Used on offer pages and /methodology. */
  .compare-table {
    margin-top: var(--space-5);
    width: 100%;
    border: 1px solid var(--color-hairline);
    border-radius: var(--radius-lg);
    overflow: hidden;
    border-collapse: collapse;
  }
  .compare-table thead tr {
    background: var(--surface-4);
    border-bottom: 1px solid var(--color-hairline-2);
  }
  .compare-table th,
  .compare-table td {
    padding: var(--space-3) var(--space-4);
    text-align: left;
    font-size: var(--type-small);
    vertical-align: top;
    border-right: 1px solid var(--color-hairline);
  }
  .compare-table th:last-child,
  .compare-table td:last-child { border-right: 0; }
  .compare-table th {
    font-size: var(--type-eyebrow);
    letter-spacing: var(--tracking-eyebrow);
    text-transform: uppercase;
    color: var(--color-ink-faint);
    font-weight: var(--weight-regular);
  }
  .compare-table th.col-highlight,
  .compare-table td.col-highlight {
    background: rgba(194, 255, 0, 0.04);
    color: var(--color-ink);
  }
  .compare-table th.col-highlight { color: var(--color-signal); }
  .compare-table td { color: var(--color-ink-muted); line-height: var(--leading-body); }
  .compare-table tbody tr:nth-child(even) td { background: var(--surface-2); }
  .compare-table tbody tr:nth-child(even) td.col-highlight {
    background: rgba(194, 255, 0, 0.06);
  }
  /* Check / dash symbols */
  .compare-table .check  { color: var(--color-signal); font-weight: var(--weight-semibold); }
  .compare-table .no     { color: var(--color-ink-faint); }

  /* ----- proof/press strip ----- */
  .proof-strip {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4) var(--space-5);
    align-items: center;
    justify-content: center;
    margin-top: var(--space-5);
    padding: var(--space-5);
    border: 1px solid var(--color-hairline);
    border-radius: var(--radius-lg);
    background: var(--surface-2);
  }
  .proof-strip__item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--type-small);
    letter-spacing: var(--tracking-eyebrow);
    text-transform: uppercase;
    color: var(--color-ink-faint);
  }
  .proof-strip__item img { height: 1.25rem; opacity: 0.6; filter: grayscale(1); }

  /* ----- tag pills ----- */
  .tag {
    display: inline-flex;
    align-items: center;
    font-size: var(--type-eyebrow);
    letter-spacing: var(--tracking-eyebrow);
    text-transform: uppercase;
    color: var(--color-ink-faint);
    background: var(--surface-4);
    border: 1px solid var(--color-hairline);
    border-radius: var(--radius-pill);
    padding: var(--space-1) var(--space-3);
  }
  .tag--signal {
    color: var(--color-signal);
    background: var(--color-signal-soft);
    border-color: transparent;
  }

  /* ----- full-width CTA block (section-level, before footer) ----- */
  .cta-block {
    text-align: center;
    padding-block: var(--space-section);
    border-top: 1px solid var(--color-hairline);
  }
  .cta-block .cta-row {
    justify-content: center;
    margin-top: var(--space-5);
  }

  /* ----- section divider / hairline rule ----- */
  .spine-divider {
    border: 0;
    border-top: 1px solid var(--color-hairline);
    margin-block: 0;
  }

  /* ----- two-column content split (image or metric + prose) ----- */
  .content-split {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
    align-items: start;
    margin-top: var(--space-5);
  }
  .content-split--metric .split-metric {
    font-family: var(--font-display);
    font-size: clamp(3rem, 8vw, 5rem);
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-display);
  }
  .content-split--metric .split-metric span { color: var(--color-signal); }

  /* ----- footer ----- */
  footer {
    background: var(--surface-2);
    border-top: 1px solid var(--color-hairline);
    padding-block: var(--space-6);
  }
  footer .container {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }
  .nap {
    font-size: var(--type-small);
    color: var(--color-ink-faint);
    line-height: var(--leading-body);
  }
  .footer-legal {
    font-size: var(--type-small);
    color: var(--color-ink-faint);
    display: flex;
    gap: var(--space-3);
  }
  .footer-legal a {
    color: var(--color-ink-faint);
    text-decoration: none;
    transition: color var(--dur-fast) var(--ease-out);
  }
  .footer-legal a:hover { color: var(--color-ink-muted); }

  /* ----- responsive: mobile-first, one step up ----- */
  @media (min-width: 720px) {
    .case-grid { grid-template-columns: repeat(3, 1fr); }
    .cta-row { display: flex; gap: var(--space-4); align-items: center; }
    .nav-links { display: flex; }
    .content-split { grid-template-columns: 1fr 1fr; }
    footer .container { flex-direction: row; justify-content: space-between; align-items: center; }
  }
}

/*
  ----- MOTION CONTRACT (Kai's mount surface) -----
  The .reveal-item / .is-shown pair is carried VERBATIM from /scan so the spine
  and the scan animate as one system. Default state is pre-reveal (hidden + risen);
  an IntersectionObserver adds .is-shown when the element enters the viewport.

  Kai attaches his motion layer to these hooks. The gate is already built:
    - elements opt in with class="reveal-item"
    - the observer is below-fold-gated (NOT eager on mount) so motion stays out of
      the initial paint/INP burst
    - prefers-reduced-motion collapses everything to the shown state instantly

  Do NOT animate via top-of-page mount listeners. That is the documented INP
  regression. Use this contract.
*/
@layer motion {
  /* Content is visible by default. JS adds .js-reveal to <html> when the
     IntersectionObserver is ready; only then do we apply the pre-reveal state.
     This ensures content is never gated on JS loading or the observer firing. */
  .js-reveal .reveal-item {
    opacity: 0;
    transform: translateY(var(--reveal-rise));
    transition: opacity var(--dur-slow) var(--ease-out),
                transform var(--dur-slow) var(--ease-out);
    will-change: opacity, transform;
  }
  .js-reveal .reveal-item.is-shown {
    opacity: 1;
    transform: none;
  }

  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    .reveal-item { opacity: 1; transform: none; transition: none; }
    .cta-primary, .cta-secondary { transition: none; }
  }
}
