/* =====================================================================
   Plume motion system — styles.
   Progressive enhancement: everything here is scoped to html.gsap, which
   motion.js adds only when GSAP loaded and the visitor allows motion. Without
   it, index.html's own CSS/IO motion is untouched.
   ===================================================================== */

/* ScrollToPlugin owns smooth scrolling; native smooth fights pins. */
html.gsap { scroll-behavior: auto; }

/* Reveals are GSAP-driven. Keep the CSS initial state, drop the transitions,
   and make the IntersectionObserver's .in inert — GSAP's inline styles win. */
html.gsap .rv, html.gsap .rv.in,
html.gsap .rv-stagger > *, html.gsap .rv-stagger.in > * { transition: none; transition-delay: 0s; }
html.gsap .rv.in { opacity: 0; transform: translateY(28px); }
html.gsap .rv-stagger.in > * { opacity: 0; transform: translateY(26px); }
/* SplitText words carry their own reveal (no will-change: hundreds of permanent layers cost more than they save). */
html.gsap .ibw { display: inline-block; }
/* Off-screen but in the accessibility tree. */
.sr-only { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

@media (min-width: 721px) {
  /* The old fixed rail is replaced by the document-tall stroke (#rail). */
  html.gsap .ink-progress, html.gsap .ink-nib { display: none; }
  /* Marquee: GSAP loop tied to scroll velocity replaces the keyframe + bob. */
  html.gsap .marquee .track { animation: none; }
  html.gsap .marquee span { animation: none; }
  /* The finale's own swash is drawn by the rail's last stroke instead. */
  html.gsap .finale .ink-underline.swash { display: none; }

  /* ---- hero: layered art (img + traced ink stroke + clean-paper patch + gleam) ---- */
  html.gsap .hero-art { background-image: none; overflow: hidden; will-change: transform; }
  html.gsap .hero-img { display: block; position: absolute; left: 50%; bottom: 0;
                        transform: translateX(-50%); width: max(100%, 1440px); height: auto; max-width: none; }
  html.gsap .hero-ink, html.gsap .hero-patchwrap, html.gsap .hero-gleam { display: block; position: absolute; z-index: 1; pointer-events: none; }
  html.gsap .hero-ink path { fill: none; stroke: var(--teal-bright); stroke-width: 11;
                             stroke-linecap: round; stroke-linejoin: round; opacity: .9; }
  html.gsap .hero-patchwrap { overflow: hidden; }
  html.gsap .hero-patch { position: absolute; inset: 0; background-repeat: no-repeat;
                          /* feathered on every side so the clean paper has no seam */
                          -webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 84%, transparent), linear-gradient(180deg, transparent, #000 18%, #000 82%, transparent);
                          -webkit-mask-composite: source-in;
                          mask-image: linear-gradient(90deg, transparent, #000 14%, #000 84%, transparent), linear-gradient(180deg, transparent, #000 18%, #000 82%, transparent);
                          mask-composite: intersect; }
  html.gsap .hero-gleam { width: 46px; opacity: .55; mix-blend-mode: soft-light; transform: skewX(-18deg);
                          background: linear-gradient(90deg, transparent, rgba(255,255,255,.95), transparent); }

  /* ---- the stage: hero + demo window pinned as one set piece ---- */
  html.gsap #stage { position: relative; height: 100vh; height: 100svh; overflow: clip; }
  html.gsap #stage header.hero { min-height: 0; height: 100%; }
  html.gsap #stage .hero-spacer { display: none; }
  html.gsap #stage .watch-panel { position: absolute; inset: 0; padding: 0 !important; margin: 0; z-index: 3; pointer-events: none; }
  html.gsap #stage .watch-panel .wrap { display: grid; grid-template-columns: 36% 1fr; align-items: center; gap: 28px;
                                       height: 100%; max-width: none; padding: 0 5vw; text-align: left !important; }
  html.gsap #stage .watch-copy { grid-column: 1; }
  html.gsap #stage .watch-copy .lede { margin: 12px 0 0 !important; }
  html.gsap #stage .watch-demo { grid-column: 2; margin: 0 !important; pointer-events: auto; width: 100%; }
  html.gsap #stage .watch-demo .demo-stage { max-width: 600px; margin-left: auto; }
  html.gsap #stage .ink-underline path, html.gsap #stage .ink-blot { animation: none !important; }
  html.gsap #stage .ink-underline { margin: 12px 0 0; }
  /* GSAP owns the hero load story (word rise, fade-ups, wet "Plume"). */
  html.gsap .hero h1 .w > span, html.gsap .hero p.sub, html.gsap .hero .cta, html.gsap .hero .fine, html.gsap .mac-pill { animation: none; }
  html.gsap .hero h1 em { animation: none; background: none; -webkit-text-fill-color: currentColor; color: var(--teal); }
  html.gsap .hero .fine { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(246,244,240,.85); }
  html.gsap .scroll-cue { display: none; }
  html.gsap .lc, html.gsap .lw { display: inline-block; }
  /* The veil paints over every art layer, so the clean-paper cover and patch are veiled like the pixels they replace. */
  html.ink-pending .hero-art::after, html.gsap .hero-art::after { z-index: 2; }
  #lift { position: absolute; inset: 0; z-index: 2; pointer-events: none; }

  /* ---- the proofreader: one manuscript sheet, pinned ---- */
  html.gsap #ramble { height: 100vh; height: 100svh; display: flex; flex-direction: column; padding: 84px 0 20px; }
  html.gsap #ramble .wrap { width: 100%; margin: auto 0; }   /* centred, but never pushed under the nav */
  html.gsap #ramble .stats { margin-top: 26px; }
  html.gsap #ramble .stat { transform: translateY(34px) rotate(-1.2deg); transition: box-shadow .35s var(--ease); }
  html.gsap #ramble .stat:nth-child(2) { transform: translateY(34px) rotate(1.2deg); }
  .proof-sheet { position: relative; margin: 26px 0 0; padding: 24px 32px 30px; background: var(--card); border: 1px solid var(--stroke);
                 border-radius: 18px; box-shadow: 0 24px 60px rgba(31,29,26,.10), inset 0 1px 0 #fff; }
  .proof-head { display: block; position: relative; height: 14px; margin-bottom: 14px; font-size: 11px; font-weight: 700;
                letter-spacing: 1.2px; text-transform: uppercase; color: var(--ink2); }
  .proof-head span { position: absolute; left: 0; top: 0; white-space: nowrap; }
  .proof-head .landed { color: var(--teal); }
  .proof-body { position: relative; }
  .ms { position: absolute; inset: 0; margin: 0; font-family: "Fraunces", Georgia, serif; font-size: clamp(22px, 2.5vw, 30px); line-height: 1.5; color: var(--ink); }
  .ms.ital { font-style: italic; font-weight: 400; color: #4a463f; }
  .ms.clean { font-weight: 450; }
  .ms .w { display: inline-block; white-space: nowrap; }
  .proof-marks, .proof-dust { position: absolute; left: 0; top: 0; pointer-events: none; overflow: visible; }
  .proof-marks path { fill: none; stroke: var(--teal-bright); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
  .proof-marks path.under { stroke: var(--teal); stroke-width: 2.5; }
  .proof-marks .blot { fill: var(--teal-bright); stroke: none; }
  .proof-marks text { font: italic 15px "Fraunces", Georgia, serif; fill: var(--teal-bright); }
  .proof-nib { position: absolute; left: 0; top: 0; width: 14px; height: 16px; opacity: 0; pointer-events: none; z-index: 2;
               filter: drop-shadow(0 2px 2px rgba(31,29,26,.28)); }
  #rail .rail-nib.held { opacity: 0; }

  /* ---- vocabulary sweep ---- */
  /* #how: one line of ink through the steps */
  html.gsap #how .steps { position: relative; }
  html.gsap #how .how-line { position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; z-index: 0; }
  html.gsap #how .how-line path { fill: none; stroke: var(--teal); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
  html.gsap #how .how-line .nib { fill: var(--teal); stroke: none; }
  html.gsap #how .step { position: relative; z-index: 1; }
  html.gsap #how .keycap { animation: none; }
  html.gsap #how .step::after { display: none; }
  /* #privacy: the page turn */
  html.gsap #privacy { position: relative; }
  html.gsap #privacy .wrap { position: relative; z-index: 1; }
  html.gsap .turn { position: absolute; inset: 0; pointer-events: none; will-change: clip-path; }
  html.gsap .turn-dark { background: var(--charcoal); }
  html.gsap .turn-light { background: var(--bg); z-index: 2; }
  html.gsap .privacy::before { display: none; }
  html.gsap .privacy-diagram { display: none; }
  @media (min-width: 1000px) {
    html.gsap .privacy ul { max-width: 56%; }
    html.gsap .privacy-diagram { display: block; position: absolute; right: 56px; top: 50%; transform: translateY(-46%); width: 300px; height: 170px; overflow: visible; pointer-events: none; }
    html.gsap .privacy-diagram path, html.gsap .privacy-diagram rect { fill: none; stroke: rgba(255,255,255,.85); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
    html.gsap .privacy-diagram .wave { stroke: var(--teal-bright); }
    html.gsap .privacy-diagram .dash { stroke-dasharray: 5 6; stroke: rgba(255,255,255,.5); }
    html.gsap .privacy-diagram .strike { stroke: var(--teal-bright); stroke-width: 2.6; }
  }
  /* manifesto */
  html.gsap .manifesto blockquote .hl { background-size: 0% 100%; transition: none; }
  html.gsap .manifesto .line { overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
  /* #features: sticky heading, index cards */
  html.gsap .feature { transition: box-shadow .35s var(--ease); will-change: transform, opacity; }
  @media (min-width: 1000px) {
    html.gsap #features .wrap { display: grid; grid-template-columns: 280px 1fr; gap: 48px; align-items: start; }
    html.gsap #features .features-head { position: sticky; top: 120px; }
    html.gsap #features .grid { margin-top: 0; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }
  /* #why: drawn marks, inked column */
  html.gsap .compare-wrap { position: relative; }
  html.gsap .compare .mark { display: inline-block; width: 14px; height: 14px; vertical-align: -2px; margin-right: 5px; overflow: visible; }
  html.gsap .compare .mark path { fill: none; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
  html.gsap .compare .mark.tick path { stroke: var(--teal); }
  html.gsap .compare .mark.cross path { stroke: #a9a49a; }
  html.gsap .why-col { position: absolute; pointer-events: none; overflow: visible; }
  html.gsap .why-col rect { fill: none; stroke: var(--teal); stroke-width: 2; rx: 14; }
  /* marquee assembly */
  html.gsap .marquee .mc { display: inline-block; }
  /* #faq: drawn rule on open */
  html.gsap details .faq-rule { display: block; width: 100%; height: 6px; overflow: visible; }
  html.gsap details .faq-rule path { fill: none; stroke: var(--teal); stroke-width: 1.5; stroke-linecap: round; }
  .odo { display: inline-flex; vertical-align: bottom; }
  .odo-slot { display: inline-block; overflow: hidden; height: 1.1em; line-height: 1.1; }
  .odo-strip { display: flex; flex-direction: column; }
  .odo-strip span { display: block; height: 1.1em; line-height: 1.1; }
  .stage-cap { position: absolute; z-index: 3; font-family: "Fraunces", Georgia, serif; font-style: italic; font-size: 15px;
               color: var(--ink2); opacity: 0; pointer-events: none; white-space: nowrap;
               padding: 4px 12px; border-radius: 999px; background: rgba(246,244,240,.82); }   /* a paper pill: legible over the ink cloud */
}
@media (min-width: 721px) and (max-width: 1180px) { html.gsap .hero-img { width: 122%; } }
.hero-img, .hero-ink, .hero-patchwrap, .hero-gleam { display: none; }

/* ---- the ink cover: present from first paint so the line is WRITTEN, not flashed.
   Clean paper cut from the same photograph (34% higher) laid over the ink zone;
   geometry mirrors the art's own sizing rules via container units. ---- */
.hero-art { container-type: inline-size; }
.hero-sheet { display: none; }
html.ink-pending .hero-sheet, html.gsap .hero-sheet {
  display: block; position: absolute; bottom: 0; z-index: 1; pointer-events: none;
  left: calc(50cqw - max(50cqw, 720px) + 0.353 * max(100cqw, 1440px));
  width: calc(0.647 * max(100cqw, 1440px));
  height: calc(0.2139 * max(100cqw, 1440px));
  background-image: url(/assets/hero@2x.jpg); background-repeat: no-repeat;
  background-size: max(100cqw, 1440px) auto;
  background-position: calc(-0.353 * max(100cqw, 1440px)) calc(-0.1801 * max(100cqw, 1440px));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 2.5%); mask-image: linear-gradient(90deg, transparent, #000 2.5%);
}
@media (max-width: 1180px) {
  html.ink-pending .hero-sheet, html.gsap .hero-sheet {
    left: 32.07cqw; width: 78.93cqw; height: 26.10cqw; background-size: 122cqw auto; background-position: -43.07cqw -21.97cqw;
  }
}
@media (max-width: 720px) { .hero-sheet { display: none !important; } }

/* ---- the rail: one unbroken stroke down the margin, ending as the swash ---- */
#rail-host { position: absolute; left: 0; top: 0; width: 100%; overflow: hidden; z-index: 49; pointer-events: none; }
#rail { position: absolute; left: 0; top: 0; pointer-events: none; overflow: visible; will-change: transform; }
#rail .rail-path { fill: none; stroke: var(--teal); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
#rail .rail-under { fill: none; stroke: var(--teal); stroke-width: 3; opacity: .07; stroke-linecap: round; }
#rail .rail-blot { fill: var(--teal); pointer-events: auto; cursor: pointer; opacity: 0;
                   transform-box: fill-box; transform-origin: center; transition: opacity .35s ease, transform .35s cubic-bezier(.22,.9,.24,1); }
#rail .rail-blot.on { opacity: 1; }
#rail .rail-blot:hover { transform: scale(1.6); }
#rail .rail-nib { fill: var(--teal); opacity: 0; transition: opacity .3s ease; }
#rail .rail-nib.on { opacity: 1; }
#rail .rail-note { font: 500 12px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: var(--ink2);
                   opacity: 0; pointer-events: none; transition: opacity .25s ease; }
#rail .rail-blot:hover + .rail-note { opacity: 1; }

/* ---- the ink ribbon breathes with scroll velocity while idle (transform/opacity only) ---- */
html.gsap .demo:not(.listening) .ribbon .ribbon-wave { opacity: var(--amp, 0); transform: scaleY(calc(0.35 + var(--amp, 0) * 0.65)); transition: opacity .18s, transform .18s; }

/* ---- wax seal (capped at three uses across the page) ---- */
.seal { position: absolute; width: 64px; height: 64px; border-radius: 50%; pointer-events: none; z-index: 2;
        background: radial-gradient(circle at 36% 32%, #22aa9b, var(--teal) 58%, #0a655b);
        box-shadow: inset 0 0 0 2.5px rgba(217,164,65,.9), inset 0 0 0 5px rgba(14,133,121,1),
                    inset 0 0 0 6px rgba(217,164,65,.45), 0 8px 18px rgba(14,133,121,.32);
        opacity: 0; transform: scale(1.7) rotate(-9deg); }
/* Vector feather, painted white directly through a mask. The old 128px PNG was
   upscaled inside a seal that GSAP scales 1.7x, and `filter: invert(1)` forced
   WebKit to rasterise the layer and stretch that bitmap -- pixelated in Safari.
   A masked vector re-renders at whatever scale the seal is drawn at. */
.seal::after { content: ""; position: absolute; inset: 15px; opacity: .92;
               background: url(/assets/feather.svg) center/contain no-repeat; filter: invert(1); }
/* Where masking is available, paint the feather white directly: that drops the
   filter, and with it the rasterised layer WebKit was stretching. The rule above
   stays as the fallback -- still vector, and never a bare white square. */
@supports ((-webkit-mask: url("")) or (mask: url(""))) {
  .seal::after { background: #fff; filter: none;
                 -webkit-mask: url(/assets/feather.svg) center/contain no-repeat;
                         mask: url(/assets/feather.svg) center/contain no-repeat; }
}
.seal-dent { position: absolute; width: 64px; height: 64px; border-radius: 50%; pointer-events: none; z-index: 1;
             box-shadow: 0 2px 10px rgba(31,29,26,.12) inset; opacity: 0; }
.seal-spatter { position: absolute; width: 4px; height: 4px; border-radius: 50%; background: var(--teal); pointer-events: none; z-index: 2; opacity: 0; }
.privacy .seal, .privacy .seal-dent { top: 22px; right: 22px; }
.finale .seal, .finale .seal-dent { right: 16%; bottom: 44px; }
.finale h2 .finale-dust { position: absolute; pointer-events: none; z-index: 2; }
html.gsap .fc { display: inline-block; }
.price-card .seal, .price-card .seal-dent { top: 14px; right: 14px; width: 56px; height: 56px; }
.price-card .seal::after { inset: 13px; }

/* Reduced motion: motion.js never boots, so none of the above applies. */

/* Print: no pins, no spacers, everything in flow and visible. */
@media print {
  .pin-spacer { padding: 0 !important; height: auto !important; }
  html.gsap #stage, html.gsap #ramble, html.gsap .finale { position: static !important; transform: none !important; height: auto !important; overflow: visible !important; }
  html.gsap #stage .watch-panel { position: static !important; opacity: 1 !important; }
  html.gsap #stage .watch-panel .wrap { display: block; height: auto; }
  html.gsap #ramble .morph { position: static !important; width: auto; height: auto; clip: auto; clip-path: none; overflow: visible; white-space: normal; }
  .proof-sheet, #rail-host, #lift, .stage-cap, .hero-sheet, .hero-patchwrap, .hero-gleam, .turn, .seal, .seal-dent, .seal-spatter { display: none !important; }
  /* #why rows and the drawn icons animate outside the .rv system: opacity for
     the rows, stroke dash offsets for the marks and feature icons. */
  html.gsap .compare tbody tr { opacity: 1 !important; }
  html.gsap .compare .mark path, html.gsap .feature .icon svg path, html.gsap .feature .icon svg rect {
    stroke-dasharray: none !important; stroke-dashoffset: 0 !important; opacity: 1 !important; }
  html.gsap .rv, html.gsap .rv.in, html.gsap .rv-stagger > *, html.gsap .rv-stagger.in > *, html.gsap .ibw, html.gsap .lc, html.gsap .lw, html.gsap .fc, html.gsap .mc,
  html.gsap .hero h1 .w > span, html.gsap .hero p.sub, html.gsap .hero .cta, html.gsap .hero .fine, html.gsap .feature, html.gsap #stage .watch-demo,
  html.gsap #stage .watch-copy .rv { opacity: 1 !important; transform: none !important; visibility: visible !important; filter: none !important; }
}
